Solidity 如何在tron中使用ecrecover获得正确的地址

Solidity 如何在tron中使用ecrecover获得正确的地址,solidity,tron,signer,Solidity,Tron,Signer,在solidity合同代码中,通过ecrecover获取签名者地址的代码块与以太坊配合良好,但在TRON中,它返回了错误的地址 我的合同代码是 function validate(string memory strTest,uint8 v, bytes32 r, bytes32 s) public view returns(address){ bytes32 prefixedHash = keccak256(strTest); return ecrecover(k

在solidity合同代码中,通过ecrecover获取签名者地址的代码块与以太坊配合良好,但在TRON中,它返回了错误的地址 我的合同代码是

    function validate(string memory strTest,uint8 v, bytes32 r, bytes32 s) public view returns(address){
      bytes32 prefixedHash = keccak256(strTest);
      return ecrecover(keccak256(prefixedHash),v,r,s);
      // return ecrecover(prefixedHash,v,r,s):
   }
dapp的边代码是

    msg = tronWeb.sha3("this is test string");
    var signature = await tronWeb.trx.sign(msg);
    var r=signature.substr(0,66);
    var s= "0x" + signature.substr(66,64);
    var v="0x" + signature.substr(signature.length-2);
    retValue = await thisContractInstance.validate("this is test string",v,r,s).call();

但在这两种情况下(一种情况在合同端代码中注释),在TRON shasta网络中获得了错误的签名者地址

您是在尝试对字符串签名还是对事务进行签名@阿什温

我在签署字符串时遇到了同样的问题,下面的内容帮助了我。 Tronweb使用不同的方法对事务和字符串进行签名

1) 对于交易,您可以参考以下内容:

2) 关于签名字符串,它使用

ethers.utils.SigningKey.signDigest()

对于以太坊:,请注意,最后的v字节将始终进行标准化,以确保稳定(27或28)

如果您正试图签署此处提到的msg

var signature=wait tronWeb.trx.sign(msg)


你可以按照第二条去做。

你可以参考这篇文章。 这将有助于完成字符串签名, 连同@Aldo提供的上述答案。 快乐编码。

摘自:

智能合同代码:

contract Verifier {
    function recoverAddr(bytes32 msgHash, uint8 v, bytes32 r, bytes32 s) returns (address) {
        return ecrecover(msgHash, v, r, s);
    }

    function isSigned(address _addr, bytes32 msgHash, uint8 v, bytes32 r, bytes32 s) returns (bool) {
        return ecrecover(msgHash, v, r, s) == _addr;
    }
}
客户端代码:

const ethers = tronWeb.utils.ethersUtils;
let contract = await tronWeb.contract().at(contract_address);
let signingKey = new ethers.SigningKey(tronWeb.defaultPrivateKey);

let message = "This is some message";
let messageBytes = ethers.toUtf8Bytes(message);
let messageDigest = ethers.keccak256(messageBytes);

let signature = signingKey.signDigest(messageDigest);
let hexAddress = await contract.recoverAddr(messageDigest, signature.v, signature.r, signature.s).call();

tronWeb.trx.sign()执行以下操作

  • 传入32字节的散列
  • 需要首先添加前缀“\x19TRON已签名邮件:\n32”
  • 使用
    keccak256
    算法生成新哈希
  • 签名(链接或私钥)
  • 因此,当使用solidity的
    ecrecover
    时,会传入步骤3的散列

    function getHash(hash) {
    
        hash = hash.replace(/^0x/, '')
    
        if (!tronWeb.utils.isHex(hash)) {
            return
        }
    
        if (hash.length !== 64) {
            return
        }
    
        const {
            keccak256,
            toUtf8Bytes
        } = tronWeb.utils.ethersUtils
    
        const hashArray = tronWeb.utils.code.hexStr2byteArray(hash)
    
        const TRX_MESSAGE_PREFIX = toUtf8Bytes('\x19TRON Signed Message:\n32')
    
        return keccak256([
            ...TRX_MESSAGE_PREFIX,
            ...hashArray
        ])
    }