Solidity和Web3 sha3()方法返回其他内容

时间:2018-10-05 11:42:52

标签: ethereum solidity smartcontracts web3 web3js

在我的合同中,我有一个函数,该函数返回一组特定值的sha3哈希。在运行一些测试时,我发现此函数返回的值与web3.utils.sha3()(具有相同参数)生成的哈希值不同。

这是代码:

固体

function hashInfo() public onlyOwner view returns (bytes32) {
      bytes32 hash = sha3(
        '0x969A70A4fa9F69D2D655E4B743abb9cA297E5328',
        '0x496AAFA2960f3Ff530716B5334c9aFf4612e3c27',
        'jdiojd',
        'oidjoidj',
        'idjodj',
        12345
      )  
      return hash;
  }

JS(web3)

async function testHash(instance){
  const contractHash = await instance.methods.hashInfo().call({from: '0x969A70A4fa9F69D2D655E4B743abb9cA297E5328'});
  const localHash = web3.utils.sha3(
    '0x969A70A4fa9F69D2D655E4B743abb9cA297E5328',
    '0x496AAFA2960f3Ff530716B5334c9aFf4612e3c27',
    'jdiojd',
    'oidjoidj',
    'idjodj',
    12345
  )
  console.log(contractHash);
  console.log(localHash);
  console.log('local == contract: ' + (contractHash == localHash));
}

结果控制台输出为:

0xe65757c5a99964b72d217493c192c073b9a580ec4b477f40a6c1f4bc537be076
0x3c23cebfe35b4da6f6592d38876bdb93f548085baf9000d538a1beb31558fc6d
local == contract: false

有什么想法吗?这与将多个参数传递给函数有关系吗?我还尝试将所有内容转换为字符串并将它们连接为一个字符串,但是也没有成功。

谢谢!

  

更新

我还在那里发现了一个名为web3.utils.soliditySha3()的web3方法。这也行不通,并得到以下结果:

0xe65757c5a99964b72d217493c192c073b9a580ec4b477f40a6c1f4bc537be076
0x0cf65f7c81dab0a5d414539b0e2f3807526fd9c15e197eaa6c7706d27aa7a0f8
local == contract: false

1 个答案:

答案 0 :(得分:2)

很高兴我在您更新后加入,因为我只是建议solditySHA3。现在,您已经有了正确的功能,很可能是因为Soldity包装了它的参数而引起的问题。

您可以看到here,sha3是keccak256的别名,它紧密地包装了其参数。跟随该页面上的链接,您将进入here,其中充分说明了其处理方式。基本上,只需将输入输入到soliditySHA3并打包位,就好像它们是您使用的变量的大小一样。因此,如果您对两个uint32(每个32位,总共64个)进行哈希处理,则需要使用2个64 bit Javascript numbers并将其压缩为1个Javascript数字。

对于需要超过64位的情况,我相信您可以将连续的整数(64位集合)传递给soliditySHA3,也可以使用BigInt。就个人而言,我通常只尝试将256位变量哈希在一起,以避免必须在JS端手动打包我的位,但是我们都知道Solidity中的空间限制非常大。希望我能提供帮助,如果您还有其他问题,请告诉我。