1

在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 网络中得到错误的签名者地址

4

4 回答 4

1

您是要签署字符串还是签署交易?@ashwin

我在签署字符串时遇到了同样的问题,下面的内容帮助了我。Tronweb 使用不同的方法来签署交易和签署字符串。

1)对于交易,您可以参考:https ://github.com/TRON-US/tronweb/blob/master/src/lib/trx.js#L651 ,

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

ethers.utils.SigningKey.signDigest ()

以太坊的:https ://docs.ethers.io/ethers.js/html/api-advanced.html?highlight=signingkey#id8 ,请注意最后的v字节将始终为 Solidity 规范化(27 或 28)

如果您尝试按照此处提到的方式签署味精

var 签名 = 等待 tronWeb.trx.sign(msg);

你可以关注第二个。

于 2020-05-12T12:11:12.563 回答
1

您可以参考文章https://medium.com/@coredevs/verifying-elliptic-curve-digital-signature-with-tron-smart-contract-5d11347e7b5b。这将有助于完成对字符串的签名,以及@Aldo 提供的上述答案。快乐编码。

于 2020-05-13T17:50:39.017 回答
0

取自这里

智能合约代码:

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();
于 2020-06-07T20:53:17.387 回答
0

根据https://github.com/tronprotocol/tronweb/blob/1435436f83b910f19e9205998e348ea093732ce5/src/lib/trx.js#L629

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

  1. 传入 32 字节的哈希值
  2. 需要先添加前缀“\x19TRON Signed Message:\n32”
  3. keccak256使用算法生成新哈希
  4. 签名(TronLink 或私钥)

因此,在使用solidity的时候ecrecover,会传入第3步的hash。

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
    ])
}
于 2021-03-25T07:35:24.170 回答