Solidity

如何在 web3js 中 keccak256 多種類型以匹配 Solidity keccak256?

  • September 25, 2019

如果我keccak256(string1, address1)in Solidity,然後使用web3.sha3(string1, address1)in web3.js,我會得到不同的結果,即使當我只string1使用一個參數時,它們是相同的結果。我嘗試傳遞{encoding: 'hex'}給 web3 呼叫,但它仍然給出不同的結果。

有誰知道如何web3.sha3(...args)使用任何參數(uint、地址、字元串等)與keccak256Solidity 中的完全相同?

我設法在這個問題中找到了適用於所有情況的函式(除了負數,您將在問題的評論中看到):

function keccak256(...args) {
 args = args.map(arg => {
   if (typeof arg === 'string') {
     if (arg.substring(0, 2) === '0x') {
         return arg.slice(2)
     } else {
         return web3.toHex(arg).slice(2)
     }
   }

   if (typeof arg === 'number') {
     return leftPad((arg).toString(16), 64, 0)
   } else {
     return ''
   }
 })

 args = args.join('')

 return web3.sha3(args, { encoding: 'hex' })
}

您可以使用web3.utils.soliditySha3()

或者,您可以嘗試這種方式:

web3.sha3(web3.utils.toHex(string1) + address1, {encoding:"hex"});

請注意,address1不應以 0x 為前綴。

例子:

> web3.sha3(web3.utils.toHex("test1") + "0AbdAce70D3790235af448C88547603b945604ea", {encoding:"hex"});
"0xd7ced52b610c8794965f5bb365f280999a9790b147bd0dfc70dea6edb2616c15"

在 Solidity 中產生與此程式碼相同的結果:

keccak256(abi.encodePacked("test1", 0x0AbdAce70D3790235af448C88547603b945604ea));

有誰知道如何使用任何參數(uint、地址、字元串等)完全等於 Solidity 中的 keccak256 來製作 web3.sha3(…args)?

您需要確保傳遞給web3.sha3()函式的第一個參數等於Solidity 中keccak256函式的緊湊參數。最簡單的方法是對每個參數使用web3.toHex()(地址除外,因為它們已經是十六進制的),然後連接結果並在選項中將編碼設置為十六進制,如我在範例中所示。web3.sha3()

引用自:https://ethereum.stackexchange.com/questions/30024