如何在 web3.js 中獲取 byte32 相似數據並返回與乙太坊錢包相同的索引?
Solidity byte32 在 web3 中返回不同的值,重新混合瀏覽器編譯器和乙太坊錢包
在契約中,我剛剛添加了 byte32 值並將其返回,但在 web3 api 中,remix 瀏覽器編譯器和乙太坊錢包在返回時顯示不同的值和索引。
乙太坊錢包用 0x 顯示準確數據
重新混合瀏覽器編譯器顯示不同的值
Web3 api顯示不同的數據和索引
契約 :
pragma solidity ^0.4.11; contract ABC{ struct Data{ bytes32 data; bytes32 data2; bytes32 data3; bytes32 data4; bytes32 data5; } mapping(uint => Data) public metaData; function ABC(){ } function addData(bytes32 data, bytes32 data2, bytes32 data3, bytes32 data4, bytes32 data5){ metaData[0]=Data(data,data2,data3,data4,data5); } function getData() returns(bytes32,bytes32,bytes32,bytes32,bytes32){ return (metaData[0].data,metaData[0].data2,metaData[0].data3,metaData[0].data4,metaData[0].data5); } }
輸入數據 :
"d4967590eb024589dfb6b9e48a576eb49ebc19d764b0d1d67dc21975e7258e97","1","1","1","065e0be95fb43db528a20ba65c0e575e33cd4a9e1ca089dba4efff24596e8553"
這個問題是因為 javascript 沒有原生 bytes32 類型引起的。以及將字元串解釋為 bytes32 值的歧義。
如果您想避免麻煩,您必須在十六進製字元串前面加上“0x”,並在必要時用零填充 64 個字元。
像這樣的例子:
["0xd4967590eb024589dfb6b9e48a576eb49ebc19d764b0d1d67dc21975e7258e97", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x065e0be95fb43db528a20ba65c0e575e33cd4a9e1ca089dba4efff24596e8553"]
解釋問題:
當您傳遞
"d4967590eb024589dfb6b9e48a576eb49ebc19d764b0d1d67dc21975e7258e97"
沒有"0x"
前面的字元串時,它將被解釋為原始 64 字節。導致十進製字元串"64343936373539306562303234353839646662366239653438613537366562343965626331396437363462306431643637646332313937356537323538653937"
。這是您的 web3.js 範例中顯示的結果。這裡另一個更嚴重的問題是第一個參數沒有被截斷為 32 字節,而是滑到第二個參數推送其他參數。當您不驗證數據時會發生這種情況。如果您傳遞值 1 並且參數格式化程序期望一個字元串,javascript 會很樂意將您的數字解釋為字元串,我們將有兩種情況:
- 它被解釋為原始字元串 0x31 是字元 ‘1’ 的 ascii 值。它將填充 ‘0’ 以獲得 32 個字節或 64 個十六進制數字,給出 ‘0x310000000000000000000000000000000000000000000000000000000000000000’ 這是 Remix 範例中的錯誤顯示。
- 它被解釋為十六進製字元串,它將填充“0”以獲得 32 個字節或 64 個十六進制數字。這會在您的乙太坊錢包範例中給出 ‘0x10000000000000000000000000000000000000000000000000000000000000000’ 的結果。
如果您想避免出現問題,只需添加“0x”前綴並指定完整的 64 位十六進制數字。