Solidity
Web3 在具有不同提供者的客戶端和伺服器上表現不同
我正在嘗試從區塊鏈讀取映射儲存變數。下面是我的嘗試,來自客戶端和伺服器。在 Rinkeby 網路上進行測試。
從客戶端: 已安裝 Metamask,我正在從瀏覽器控制台嘗試。Web3 版本為 0.2.x。
const index = "0000000000000000000000000000000000000000000000000000000000000005"; const key = web3.toHex('my_key'); web3.eth.getStorageAt( 'contract_address_here', web3.sha3(key + index, { encoding: 'hex' }), (err, result) => { console.log(result); // Returns 0x00.....1; // Key exists } );
有用。密鑰確實存在於 Rinkeby 網路上。
從伺服器嘗試: 請注意,web3 版本是
1.0.0-beta.26
並且我使用 Infura 作為提供程序。// Init web3 const Web3 = require('web3'); const provider = new Web3.providers.HttpProvider( "my rinkeby infura link here" ); const web3 = new Web3(provider); const index = "0000000000000000000000000000000000000000000000000000000000000005"; const key = web3.utils.toHex('my_key'); web3.eth.getStorageAt( 'contract_address_here', web3.utils.sha3(key + index, { encoding: 'hex' }), (err, result) => { console.log(result); On the server, the result is always 0x...0 } );
有誰知道這裡發生了什麼?我再次確定,契約地址是 Rinkeby 上的地址,我的 Infura 連結也是來自 Rinkeby 的地址。
編輯:
- 看起來 web3 版本是問題所在。如果我嘗試在伺服器上使用 web3 0.2.x 並將其與 Infura 提供程序連接起來,它執行良好。
修復語法後,這兩個範例都對我有用。
我使用的 Solidity 程式碼,部署到
ganache
:pragma solidity ^0.4.20; contract Test { uint256 a; uint256 b; uint256 c; uint256 d; uint256 e; mapping (string => bool) exists; function Test() public { exists["my_key"] = true; } }
我在瀏覽器中使用的 web3.js 0.2xx 程式碼,MetaMask 指向
ganache
:var index = "0000000000000000000000000000000000000000000000000000000000000005"; var key = web3.toHex('my_key'); web3.eth.getStorageAt( "0x6d533f202b5bece917de226d7d588480e0ba7c0e", web3.sha3(key+index, { encoding: 'hex' }), (err, result) => { console.log(result); });
這是我使用的 web3.js 1.0.0-beta 程式碼,也指向
ganache
:const Web3 = require('web3'); const web3 = new Web3('http://localhost:8545'); var index = "0000000000000000000000000000000000000000000000000000000000000005"; var key = web3.utils.toHex('my_key'); web3.eth.getStorageAt( "0x6d533f202b5bece917de226d7d588480e0ba7c0e", web3.utils.sha3(key+index), (err, result) => { console.log(result); });
(您在 1.0 beta 程式碼中使用的第二個參數
web3.utils.sha3
是無害的,但被忽略了。無論有沒有它,該程式碼都可以工作。與 0.2xx 對應的不同,web3.utils.sha3
如果它以 . 開頭,則將其第一個參數解釋為十六進制0x
。)編輯
您的密鑰看起來已經像十六進制了,所以在 0.2xx 中
web3.utils.toHex
轉換它的方式不同。假設您確實想將鍵視為字元串,web3.toHex
您可能應該在這兩種情況下都使用。fromAscii
此程式碼適用於 1.0.0-beta26:const Web3 = require('web3'); const web3 = new Web3('https://rinkeby.infura.io/<key redacted>'); var index = "0000000000000000000000000000000000000000000000000000000000000005"; var key = web3.utils.fromAscii('708d343ff29ab3350d9a9499d7db1cfefc919bce'); web3.eth.getStorageAt( "0x670c3ee20d857ECD9A1C6024a2701443C3F7f2e2", web3.utils.sha3(key+index), (err, result) => { console.log(result); });