Solidity

Web3 在具有不同提供者的客戶端和伺服器上表現不同

  • March 2, 2018

我正在嘗試從區塊鏈讀取映射儲存變數。下面是我的嘗試,來自客戶端和伺服器。在 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 的地址。

編輯:

  1. 看起來 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);
 });

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