Solidity
從本地安全帽部署呼叫方法
我正在嘗試通過 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()
。如果你的方法是
view
或pure
,_contract.getList()
會做一個eth_call
,類似於 web3 的.call()
. 如果沒有,那麼它將繼續建構事務並發送它,類似於 web3 的.send()
.const list = await _contract.getList()