【问题标题】:Problem with signing smart contract transaction tnvolving ecrecover, keccak256, abi.encodePacked签署智能合约交易涉及 ecrecover、keccak256、abi.encodePacked 的问题
【发布时间】:2021-03-10 21:28:01
【问题描述】:

我正在尝试在本地智能合约(在 ganache 上运行)上调用以下方法,该合约是 Rarible 智能合约 0xd07dc4262BCDbf85190C01c996b4C06a461d2430 的副本,并且在哈希处理方面遇到了一些问题。

function mint(uint256 id, uint8 v, bytes32 r, bytes32 s, Fee[] memory fees, uint256 supply, string memory uri) public {
        require(isSigner(ecrecover(keccak256(abi.encodePacked(this, id)), v, r, s)), "signer should sign tokenId");
        _mint(id, fees, supply, uri);
    }

相关python代码:

from eth_account.messages import encode_intended_validator

def to_32byte_hex(val):
    return w3.toHex(Web3.toBytes(val).rjust(32, b'\0'))

local_contract_address = "0x5a965a6aC0769ca1077b4a3C902709c4b50ea302"
item_number = 777777777

message = encode_intended_validator(w3.toChecksumAddress(local_contract_address), item_number)
signed_msg = w3.eth.account.sign_message(message,private_key=privateKey)
msg = signed_msg.messageHash
v = signed_msg['v']
r = to_32byte_hex(signed_msg['r'])
s = to_32byte_hex(signed_msg['s'])

options = {'gas':50000}
mint = contract.get_function_by_name('mint')
transaction = mint(777777777,v,r,s,[],10,'a').buildTransaction(options)

etc...

输出:

使用 hacky 的 to_32byte_hex 函数,参数是有效的,但我肯定不会超过 mint 函数中的 ecrecover 步骤。

我不确定如何解决这个问题。我尝试将合同地址和 item_number 一起散列,然后签名。我假设 v、r、s 是消息签名过程的输出,并且被签名的消息是 local_contract_addressitem_number 串联的哈希。

如果答案不明显,您有什么推荐的资源吗?

ValueError: {'message': 'VM Exception while processing transaction: revert signer should sign tokenId'

【问题讨论】:

  • 你能检查一下吗? 1)ecrecover() 是返回预期地址还是0x0(应该是地址)? 2) 如果期望地址,isSigner() 的返回值是什么(应该是真的)? ...我对 Python 不是很熟悉,但是根据我对 Solidity 的了解,其中一个可能会产生意外的输出并修复它的原因(通过将正确的参数发送到 ecrecover 或添加signers 变量的地址)将解决此问题。

标签: ethereum solidity smartcontracts web3


【解决方案1】:

我找到了通过使用“ethereumjs-util”解决此问题的另一种方法

const util = require('ethereumjs-util');
// ...

const hash = web3.utils.soliditySha3(
  '0xE5df7fD6756bb8ffD1Cb95e8e3E7f81D9a3b56A2', // contract address
  TOKEN_ID
);
const privateKey = Buffer.from(SIGNER_PRIVATE_KEY, 'hex');
const signature = util.ecsign(util.toBuffer(hash), privateKey);
const v = signature.v;
const r = util.bufferToHex(signature.r);
const s = util.bufferToHex(signature.s);

await raribleToken.mint(
  TOKEN_ID,
  v,
  r,
  s,
  [{ recipient: user1, value: ROYALTY }],
  SUPPLY,
  URI,
  {
    from: user1,
  }
);

【讨论】:

    猜你喜欢
    • 2020-05-26
    • 2021-04-03
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2022-11-12
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多