返回值无效,它是不是用尽了 Gas? web3 1.5.0 和 sol-0.5.15

Posted

技术标签:

【中文标题】返回值无效,它是不是用尽了 Gas? web3 1.5.0 和 sol-0.5.15【英文标题】:Returned values aren't valid, did it run Out of Gas? web3 1.5.0 and sol-0.5.15返回值无效,它是否用尽了 Gas? web3 1.5.0 和 sol-0.5.15 【发布时间】:2021-10-15 23:44:39 【问题描述】:

我是区块链和以太坊领域的新手。我一直在尝试使用 truffle 和 ganache 创建一个简单的测试网络,在其中我在 truffle 中创建了一个新的工作场所,并尝试构建一个快速反应的前端应用程序以使用 Web3 连接到以太坊。

一切正常。我确实安装了 MetaMask 并为端口:7545 创建了一个新网络,并且发生在 ganache 上的每一次更改都会影响 MetaMask。

这是web3的代码。

const web3 = new Web3("http://127.0.0.1:7545")
    const accounts = await web3.eth.getAccounts()
    setaccount(accounts)
    const todoList = new web3.eth.Contract(TodoList.abi, ADRESS);
    console.log('here the todo contract');
    console.log(todoList);
    setTodoList(todoList)
    const taskCount = await todoList.methods.taskCount().call()

联系人显示正常,帐户也显示。 但是当我尝试调用该函数时,它向我显示了这个让我感到困惑的错误。

Uncaught (in promise) Error: Returned values aren't valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node that is not fully synced.
    at ABICoder.push../node_modules/web3-eth-abi/lib/index.js.ABICoder.decodeParametersWith (index.js:297)
    at ABICoder.push../node_modules/web3-eth-abi/lib/index.js.ABICoder.decodeParameters (index.js:284)
    at Contract.push../node_modules/web3-eth-contract/lib/index.js.Contract._decodeMethodReturn (index.js:469)
    at Method.outputFormatter (index.js:759)
    at Method.push../node_modules/web3-core-method/lib/index.js.Method.formatOutput (index.js:147)
    at sendTxCallback (index.js:523)
    at index.js:307
    at XMLHttpRequest.request.onreadystatechange (index.js:98)
push../node_modules/web3-eth-abi/lib/index.js.ABICoder.decodeParametersWith @ index.js:297
push../node_modules/web3-eth-abi/lib/index.js.ABICoder.decodeParameters @ index.js:284
push../node_modules/web3-eth-contract/lib/index.js.Contract._decodeMethodReturn @ index.js:469
outputFormatter @ index.js:759
push../node_modules/web3-core-method/lib/index.js.Method.formatOutput @ index.js:147
sendTxCallback @ index.js:523
(anonymous) @ index.js:307
request.onreadystatechange @ index.js:98
async function (async)
loadBlockchainDate @ App.js:36
(anonymous) @ App.js:20
invokePassiveEffectCreate @ react-dom.development.js:23487
callCallback @ react-dom.development.js:3945
invokeGuardedCallbackDev @ react-dom.development.js:3994
invokeGuardedCallback @ react-dom.development.js:4056
flushPassiveEffectsImpl @ react-dom.development.js:23574
unstable_runWithPriority @ scheduler.development.js:468
runWithPriority$1 @ react-dom.development.js:11276
flushPassiveEffects @ react-dom.development.js:23447
(anonymous) @ react-dom.development.js:23324
workLoop @ scheduler.development.js:417
flushWork @ scheduler.development.js:390
performWorkUntilDeadline @ scheduler.development.js:157

这是我的可靠合同

pragma solidity ^0.5.0;

contract TodoList 
  uint public taskCount = 0;

constructor() public 
     createTask("Check out dappuniversity.com");
   

  struct Task 
    uint id;
    string content;
    bool completed;
  

  mapping(uint => Task) public tasks;

  function createTask(string memory _content) public 
    taskCount ++;
    tasks[taskCount] = Task(taskCount, _content, false);
  


这就是 ABI。

[
    
        "inputs": [],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "constructor"
    ,
    
        "constant": true,
        "inputs": [],
        "name": "taskCount",
        "outputs": [
            
                "internalType": "uint256",
                "name": "",
                "type": "uint256"
            
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    ,
    
        "constant": true,
        "inputs": [
            
                "internalType": "uint256",
                "name": "",
                "type": "uint256"
            
        ],
        "name": "tasks",
        "outputs": [
            
                "internalType": "uint256",
                "name": "id",
                "type": "uint256"
            ,
            
                "internalType": "string",
                "name": "content",
                "type": "string"
            ,
            
                "internalType": "bool",
                "name": "completed",
                "type": "bool"
            
        ],
        "payable": false,
        "stateMutability": "view",
        "type": "function"
    ,
    
        "constant": false,
        "inputs": [
            
                "internalType": "string",
                "name": "_content",
                "type": "string"
            
        ],
        "name": "createTask",
        "outputs": [],
        "payable": false,
        "stateMutability": "nonpayable",
        "type": "function"
    
]

这是我在连接到 abi 和地址时从 web3 获得的合同。

Contract
BatchRequest: ƒ ()
clearSubscriptions: ƒ (keepIsSyncing)
currentProvider: (...)
defaultAccount: (...)
defaultBlock: (...)
defaultChain: (...)
defaultCommon: (...)
defaultHardfork: (...)
events: allEvents: ƒ
extend: ƒ (extension)
givenProvider: Proxy _events: …, _eventsCount: 1, _maxListeners: 100, _log: a, _state: …, …
handleRevert: (...)
methods:
0x8d977672: ƒ ()
0x111002aa: ƒ ()
0xb6cb58a5: ƒ ()
createTask: ƒ ()
createTask(string): ƒ ()
taskCount: ƒ ()
taskCount(): ƒ ()
tasks: ƒ ()
tasks(uint256): ƒ ()
[[Prototype]]: Object
options: 
providers: WebsocketProvider: ƒ, HttpProvider: ƒ, IpcProvider: ƒ
setProvider: ƒ ()
setRequestManager: manager => …
transactionBlockTimeout: (...)
transactionConfirmationBlocks: (...)
transactionPollingTimeout: (...)
_address: "0x8c0199C5D6e4B22A1948358F1bf48dD095Ae5300"
_jsonInterface: (4) […, …, …, …]
_provider: HttpProvider withCredentials: false, timeout: 0, headers: undefined, agent: undefined, connected: true, …
_requestManager: RequestManager provider: HttpProvider, providers: …, subscriptions: Map(0)
get currentProvider: () =>  return pkg._provider; 
set currentProvider: value =>  return pkg.setProvider(value); 
get defaultAccount: ƒ ()
set defaultAccount: ƒ (val)
get defaultBlock: ƒ ()
set defaultBlock: ƒ (val)
get defaultChain: ƒ ()
set defaultChain: ƒ (val)
get defaultCommon: ƒ ()
set defaultCommon: ƒ (val)
get defaultHardfork: ƒ ()
set defaultHardfork: ƒ (val)
get handleRevert: ƒ ()
set handleRevert: ƒ (val)
get transactionBlockTimeout: ƒ ()
set transactionBlockTimeout: ƒ (val)
get transactionConfirmationBlocks: ƒ ()
set transactionConfirmationBlocks: ƒ (val)
get transactionPollingTimeout: ƒ ()
set transactionPollingTimeout: ƒ (val)
[[Prototype]]: Contract

当我执行truffle version 时,我明白了

Truffle v5.4.3 (core: 5.4.3)
Solidity v0.5.16 (solc-js)
Node v14.17.0
Web3.js v1.5.0

我安装了 web3 版本 1.5.1,也尝试了 1.5.0,但仍然遇到同样的错误。

这是我正在关注的教程https://www.dappuniversity.com/articles/ethereum-dapp-react-tutorial

编辑:我使用的是 Ganache GUI,而我的 Metamask 自定义坐姿是。

谢谢。

问题:我使用的是节点地址,而不是我申请truffle migrate --reset all后的合约地址。

【问题讨论】:

【参考方案1】:

所以我尝试了使用 truffle 和 ganache 的相同代码,它对我有用。唯一的区别是我在端口8545 上运行ganache,并将metamask 与url 中的那个端口连接起来。我相信您在这里提供了一些不正确的值const todoList = new web3.eth.Contract(TodoList.abi, ADRESS);

确保您的合同的 abi地址 正确无误。阅读有关具有正确值的合约对象实例化的详细信息here

这是我读取 JSON 文件的方式:

const TodoList = JSON.parse(fs.readFileSync('./build/contracts/TodoList.json', 'utf8'));.

我只是像您的代码一样从中提取 abi。对于合同地址部分,我在运行truffle migrate --reset all 后从输出控制台手动获取地址。

在此之后,您将在控制台中获得这样的收据信息

Replacing 'TodoList'
   --------------------
   > transaction hash:    0x00d16b5ee5f4ddad354543a100d7c730114f5668d5f3b35f1a2306764335c32d
   > Blocks: 0            Seconds: 0
   > contract address:    0x5592F579627C9123F2EB77429B3E6e66891C6a9A
   > block number:        11
   > block timestamp:     1628967561
   > account:             0xa0aC73a479e9B6F5b5Ee0b0Fd241bbb1D83C5ec2
   > balance:             99.95728292
   > gas used:            363127 (0x58a77)
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.00726254 ETH

你需要把合约地址复制下来,这样写:"0x5592F579627C9123F2EB77429B3E6e66891C6a9A"

truffle-config.js 文件:使用此配置编译合约

/**
 * Use this file to configure your truffle project. It's seeded with some
 * common settings for different networks and features like migrations,
 * compilation and testing. Uncomment the ones you need or modify
 * them to suit your project as necessary.
 *
 * More information about configuration can be found at:
 *
 * trufflesuite.com/docs/advanced/configuration
 *
 * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
 * to sign your transactions before they're sent to a remote public node. Infura accounts
 * are available for free at: infura.io/register.
 *
 * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
 * public/private key pairs. If you're publishing your code to GitHub make sure you load this
 * phrase from a file you've .gitignored so it doesn't accidentally become public.
 *
 */

// const HDWalletProvider = require('@truffle/hdwallet-provider');
//
// const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();

module.exports = 
  /**
   * Networks define how you connect to your ethereum client and let you set the
   * defaults web3 uses to send transactions. If you don't specify one truffle
   * will spin up a development blockchain for you on port 9545 when you
   * run `develop` or `test`. You can ask a truffle command to use a specific
   * network from the command line, e.g
   *
   * $ truffle test --network <network-name>
   */

  networks: 
    // Useful for testing. The `development` name is special - truffle uses it by default
    // if it's defined here and no other network is specified at the command line.
    // You should run a client (like ganache-cli, geth or parity) in a separate terminal
    // tab if you use this network and you must also set the `host`, `port` and `network_id`
    // options below to some value.
    //
    development: 
     host: "127.0.0.1",     // Localhost (default: none)
     port: 7545,            // Standard Ethereum port (default: none)
     network_id: "*"       // Any network (default: none)
    ,
    // Another network with more advanced options...
    // advanced: 
    // port: 8777,             // Custom port
    // network_id: 1342,       // Custom network
    // gas: 6000000,           // Gas sent with each transaction (default: ~6700000)
    // gasPrice: 20000000000,  // 20 gwei (in wei) (default: 100 gwei)
    // from: <address>,        // Account to send txs from (default: accounts[0])
    // websocket: true        // Enable EventEmitter interface for web3 (default: false)
    // ,
    // Useful for deploying to a public network.
    // NB: It's important to wrap the provider as a function.
    // ropsten: 
    // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
    // network_id: 3,       // Ropsten's id
    // gas: 5500000,        // Ropsten has a lower block limit than mainnet
    // confirmations: 2,    // # of confs to wait between deployments. (default: 0)
    // timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50)
    // skipDryRun: true     // Skip dry run before migrations? (default: false for public nets )
    // ,
    // Useful for private networks
    // private: 
    // provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
    // network_id: 2111,   // This network is yours, in the cloud.
    // production: true    // Treats this network as if it was a public net. (default: false)
    // 
  ,

  // Set default mocha options here, use special reporters etc.
  mocha: 
    // timeout: 100000
  ,

  // Configure your compilers
  compilers: 
    solc: 
      version: "0.5.0",    // Fetch exact version from solc-bin (default: truffle's version)
      docker: false,        // Use "0.5.1" you've installed locally with docker (default: false)
      settings:           // See the solidity docs for advice about optimization and evmVersion
       optimizer: 
         enabled: false,
         runs: 200
       ,
       evmVersion: "byzantium"
      
    
  ,

  // Truffle DB is currently disabled by default; to enable it, change enabled: false to enabled: true
  //
  // Note: if you migrated your contracts prior to enabling this field in your Truffle project and want
  // those previously migrated contracts available in the .db directory, you will need to run the following:
  // $ truffle migrate --reset --compile-all

  db: 
    enabled: false
  
;

【讨论】:

感谢您的回答,您是否使用 ganache-cil 在端口 8545 中运行它?因为我使用了genech GUI,所以默认端口是 7545 。关于 abi 我真的只是从 TodoList.json 复制了 abi 我不确定它是否生成了正确的,同样地址从同一个 Json 文件中获取。如果 MetaMask 的连接不正确,当 ganache 改变​​时它没有改变? . 我不知道您与 Metamask 的连接状态如何。但你说它反映了变化,所以我认为它工作正常。您还可以通过在 Metamask 中导入 ganache 的第一个帐户来进一步检查。只需从 ganache-cli 控制台获取第一个帐户的私钥并将其粘贴到 Metamask 中即可。确保创建帐户后 Metamask 中也显示正确的余额。如果您使用带有 -m "string" 标志的助记符运行 ganache-cli,那就更好了。这样,将从助记词创建相同的帐户以在 Metamask 中使用相同的帐户 是的。我在运行 ganache-cli 时给了一个端口标志 -p 8545。假设您在 Metamask 中正确使用了自定义 RPC 设置,我认为端口号不是问题。关于 ABI 和合同地址部分。这需要有效。从 JSON 文件读取后,我以与您相同的方式传递 ABI。这似乎没问题,因为它需要 ABI 的 JSON 接口。对于地址部分,我在部署合约后像这样手动输入“0xD90d46Ae7427933760A52FE06Ba13C443A4E720C”。我相信这就是您遇到问题的地方。检查 ABI 和地址的输出以确认 MetaMask 中的地址和 web3 对比中的地址是一样的吧?因为我在 ABI 之后添加了一个“0x8c0199C5D6e4B22A1948358F1bf48dD095Ae5300”。真的很烦人。我不知道问题出在哪里。:"( 编辑您的问题并分享您的 Metamask 设置。您必须使用自定义 RPC【参考方案2】:

对我来说,我不得不重新运行 truffle migrate --reset 并且它起作用了。

【讨论】:

以上是关于返回值无效,它是不是用尽了 Gas? web3 1.5.0 和 sol-0.5.15的主要内容,如果未能解决你的问题,请参考以下文章

Web3.js 视图方法 call() 错误,因为返回值无效,是不是耗尽了气体

react-native 上的 web3:错误:返回错误:gas 资金不足 * 价格 + 价值

Web3:从地址中检索 ERC20 代币的余额

web3j - 从签名交易中获取交易详情(金额、gas 价格、gas 限制)

再深刻理解下web3.js中estimateGas如何计算智能合约消耗的gas量

gas 资金不足 * 价格 + 价值