Solidity

Solidity 的 sha3 / keccak256 如何散列 uint?

  • April 19, 2018

這不是關於乙太坊使用非標準 sha3的問題。我找到了正確的 JS 雜湊庫,並且能夠在 JS 和 Solidity 中獲得匹配的雜湊值。我想知道的是如何在將 uint 傳遞給 JS 雜湊庫時表示它,以便它產生與 Solidity sha3 創建的相同的雜湊值。

JS
'0x' + keccak(
 1
)
// 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470

Solidity
sha3(
 1
);
// 0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2

Jehan 的回答很好,但我們還需要解釋一件事:為什麼sha3(1)在solidity 中產生b10e2d...fa0cf6

這是因為solidity 的 sha3 函式根據參數類型對其輸入進行雜湊處理。因此,如果將值儲存為, ,等,則該值1將生成不同的雜湊值。由於作為數字文字傳遞,因此將其轉換為最小的必要類型1bytes8``bytes16``bytes32``sha3(1)``1``uint8

8 位適合 2 個十六進製字元,因此如果您將輸入填充為 2 個字元,您將在 web3 中得到相同的結果:

Javascript:

web3.sha3(leftPad((1).toString(16), 2, 0), { encoding: 'hex' })
// 5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2

同樣,您可以將數字投射到solidity方面:

堅固性:

// uint is equivalent to uint256
sha3(uint(1))
// b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6

Javascript:

// note that the value is padded by 64 characters to fit 256 bits
web3.sha3(leftPad((1).toString(16), 64, 0), { encoding: 'hex' })
// b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6

關於BigNumber類型的說明:

它們不會自動與web3.sha3. 您必須先將它們轉換為十六進制。

堅固性:

sha3(uint(100 ether))
// c7cc234d21c9cfbd4632749fd77669e7ae72f5241ce5895e410c45185a469273

Javascript:

// the .slice is to remove the leading '0x'
web3.sha3(leftPad(web3.toHex(web3.toWei(100)).slice(2).toString(16), 64, 0), { encoding: 'hex' })
// c7cc234d21c9cfbd4632749fd77669e7ae72f5241ce5895e410c45185a469273

編輯:

我寫了一個小庫,它提供了一個與 Solidityweb3.sha3中的行為完全匹配的版本sha3。希望這可以解決您所有的雜湊問題:)。 https://github.com/raineorshine/solidity-sha3

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