Solidity

從本地安全帽部署呼叫方法

  • July 30, 2021

我正在嘗試通過 web3 與部署在本地安全帽環境中的契約進行互動

我無法從契約中取回數據,這是資訊

我有:

var list = await contract.methods.getList();
console.log("list ", list );

這讓我

list {arguments: Array(0), call: ƒ, send: ƒ, encodeABI: ƒ, estimateGas: ƒ, …}

當我做

var list = await contract.methods.getList().call();
console.log("list ", list );

我在瀏覽器中收到此錯誤:

返回值無效,它是否用盡了 Gas?如果您沒有為從中檢索數據的合約使用正確的 ABI、從不存在的塊號請求數據或查詢未完全同步的節點,您也可能會看到此錯誤。

我願意:

在控制台中設置:

npx hardhat node
>Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/
>Accounts
>========
>...
npx hardhat compile
> Nothing to compile
npx hardhat run scripts/deploy.js --network hardhat    

注意:在 deploy.js 文件中,我做了一個

const list = await contract.getList();
console.log("list", list ); // correctly outputs ["string", "string"]

方法:

mapping(uint256 => address) internal list;
uint256 internal listCount;

function getList() public override view returns (address[] memory) {
   address[] memory assets = new address[](listCount);

   for (uint256 i = 0; i < listCount; i++) {
     assets[i] = list[i];
   }
   return assets;
}

在反應 App.js 中:

import Contract_from './data/abi/Contract_.json'; // Contract_ is a placer

var contract = new web3.eth.Contract(Contract_, address_given_on_deploy);
var contractAddress = await contract .options.address; // correctly outputs


var list= await contract.methods.getList().call();
console.log("list", list);

如您所見,這不會從方法中返回值。我在這裡做錯了什麼?

出於任何原因,可能是問題所在,這是我的配置:

require("@nomiclabs/hardhat-waffle");

// openzeppelin adds
require("@nomiclabs/hardhat-ethers");
require('@openzeppelin/hardhat-upgrades');

//abi
require('hardhat-abi-exporter');



// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async () => {
 const accounts = await ethers.getSigners();

 for (const account of accounts) {
   console.log(account.address);
 }
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
 networks: {
   hardhat: {
     gas: 12000000,
     blockGasLimit: 0x1fffffffffffff,
     allowUnlimitedContractSize: true,
     timeout: 1800000,
     chainId: 1337
   }
 },
 solidity: {
   compilers: [
     {
       version: "0.8.0",
       settings: {
         optimizer: {
           enabled: true,
           runs: 1000
         }
       }
     },
     {
       version: "0.8.2",
       settings: {
         optimizer: {
           enabled: true,
           runs: 1000
         }
       }
     },
   ],
 },
 abiExporter: {
   path: './frontend/src/data/abi',
   clear: true,
   flat: true,
   only: [],
   spacing: 2
 }
}

__

我想也許我會嘗試 ethers.js,因為那是我在相同的問題上做的測試。

無論出於何種原因,我都可以“獲取”契約,列印屬於它們的方法,但我實際上不能呼叫這些方法。

這是我的 ethers.js 簡潔:

provider = new ethers.providers.Web3Provider(window.ethereum);
if(provider != null){
   const _contract = new ethers.Contract(address, _Contract, provider);
   var list= await _contract.getList().call();
   console.log("list", list);
}

我從中得到的錯誤是:

Error: call revert exception (method="getList()", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.4.0)

我已經在協議中嘗試了許多契約,並且每個契約都相同

這裡有兩件事。首先,您在以下情況下得到的錯誤call revert exception

  • 方法在執行期間恢復。
  • 您的契約中沒有方法。
  • 合約未部署在您連接的網路上(或地址放置不正確)。

可能你正面臨第三個問題。

其次,ethers.js 對.call()和有不同的 API .send()

如果你的方法是viewpure_contract.getList()會做一個eth_call,類似於 web3 的.call(). 如果沒有,那麼它將繼續建構事務並發送它,類似於 web3 的.send().

const list = await _contract.getList()

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