首页 > 解决方案 > 我无法在智能合约中使用 ecrecover 获取签名者地址

问题描述

坚固性代码:

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.6.2;

    contract Example {
    function signature(uint256 tokenId, uint8 v, bytes32 r, bytes32 s) public view returns(address) {
    return ecrecover(keccak256(abi.encodePacked(this,tokenId)), v, r, s);
    }

JavaScript 代码:

async function sign(){
var message = 1001
var orgmessage = web3.eth.abi.encodeParameter('uint256',message)
var orginal = `0xf8e81D47203A594245E36C48e151709F0C19fBe8${orgmessage.slice(2)}`
var hash = web3.utils.keccak256(orginal);
const accounts = await getCurrentAccount();
var signature = await web3.eth.personal.sign(hash, accounts);
var sig1 = signature.slice(2)
 var r = `0x${sig1.slice(0, 64)}`
 var s = `0x${sig1.slice(64, 128)}`
 var v = web3.utils.toDecimal(`0x${sig1.slice(128, 130)}`)
                                        
 console.log("h",hash)
 console.log("v",v)
 console.log("r",r)
 console.log("s",s)

}

预期签名者地址:0x4CA95df0400676Eb6818Be4601793Af36450F862

实际签名者地址:0x04a02De5b8B422feb7949D4b7cB690aF746Da34E

在我使用 web3.eth.sign 方法对消息进行签名之前,合同会正确返回签名者地址。但是这种签名方法已被废弃。

所以现在我正在尝试使用 web3.eth.personal.sign 用智能合约地址签署一个整数值,不幸的是它不能正常工作。如果有人知道如何解决这个问题,请帮助我!

标签: javascriptsoliditysignpragma

解决方案


但它是什么abi.encodePacked(this,tokenId))?不起作用。
你首先需要前缀。

  function _messageToRecover(address erc20Contract, address destination, uint256 value) private view returns (bytes32) {
    bytes32 hashedUnsignedMessage = generateMessageToSign(erc20Contract, destination, value);
    bytes memory message = bytes32_to_hstring(hashedUnsignedMessage);
    bytes memory prefix = "\x19Ethereum Signed Message:\n64";
    return keccak256(abi.encodePacked(prefix, message));
  }

https://github.com/alexeyneu/bitbill-multisig-contracts/blob/25a4c3e65355d40a873d2186cd10ad28fcc7fde5/OwnbitMultiSigV4.sol#L125-L126

\n64(我的)味精长度在哪里。


推荐阅读