从nodejs api路由调用(get)时如何解决AbiError:参数解码错误或耗尽气体错误?

问题描述 投票:0回答:1

我正在使用 web3.js v4.7.0 使用 nodejs/express 与我的智能合约进行交互。下面是我的 Contract

的代码片段
pragma solidity ^0.8.10;

contract Transactions {
    uint public count = 0;

    struct Transaction {
        uint id;
        string name;
        uint amount;
    }

    mapping(uint => Transaction) public transactions;

    constructor() {
        createTransaction("derived", 2000);
    }

    function createTransaction(string memory _name, uint _amount) public {
        count++;
        transactions[count] = Transaction(count, _name, _amount);
    }

    function getAllTransactions() public view returns (Transaction[] memory) {
        Transaction[] memory allTransactions = new Transaction[](count);
        for (uint256 index = 1; index <= count; index++) {
            Transaction storage transaction = transactions[index];
            allTransactions[index - 1] = transaction;
        }
        return allTransactions;
    }
}

  • 我已经初始化了地址,并且 ABI 是从 REMIX IDE 复制的,我确信它可以工作,因为智能合约在那里表现良好。
  • 现在问题出现在尝试发出 get 请求,但 post 请求有效时。下面是 API Route.js 的代码
function routes(app, db, accounts, transactionList) {
  app.get("/transactions", async (req, res) => {
    try {
      const gasLimit = 20000000;
      const allTransactions = await transactionList.methods
        .getAllTransactions()
        .call({ gas: gasLimit });
      res.json({ allTransactions });
    } catch (error) {
      console.error("Error getting all transactions:", error);
      res.status(500).json({ error: "Error getting all transactions" });
    }
  });
  app.post("/transactions", async (req, res) => {
    try {
      const { name, amount } = req.body;
      await transactionList.methods
        .createTransaction(name, amount)
        .send({ from: accounts[0] });
      const transaction = {
        name: name,
        amount: amount,
      };
      const result = await db.collection("transactions").insertOne(transaction);
      res.status(201).json({
        message: "Transaction created Successfully",
        contactId: result.insertedId,
      });
    } catch (e) {
      console.log("Error creating transaction:", e);
      res.status(500).json({ error: "Internal server error" });
    }
  });
}

module.exports = routes;
  • 下面是我尝试 post 方法后生成的错误。

获取所有交易时出错:AbiError:参数解码错误:返回值无效,是否耗尽了 Gas?如果您没有为从中检索数据的合约使用正确的 ABI、从不存在的区块号请求数据或查询未完全同步的节点,您也可能会看到此错误。 在decodeParametersWith(/home/steve/Projects/vcis_wallet_blockchain/node_modules/web3/node_modules/web3-eth-abi/lib/commonjs/api/parameters_api.js:103:15) 在decodeParameters(/home/steve/Projects/vcis_wallet_blockchain/node_modules/web3/node_modules/web3-eth-abi/lib/commonjs/api/parameters_api.js:213:75) 在decodeMethodReturn(/home/steve/Projects/vcis_wallet_blockchain/node_modules/web3/node_modules/web3-eth-contract/lib/commonjs/encoding.js:125:56) 在ContractBuilder。 (/home/steve/Projects/vcis_wallet_blockchain/node_modules/web3/node_modules/web3-eth-contract/lib/commonjs/contract.js:672:61) 在 Generator.next() 处 已履行(/home/steve/Projects/vcis_wallet_blockchain/node_modules/web3/node_modules/web3-eth-contract/lib/commonjs/contract.js:21:58) 在 process.processTicksAndRejections (节点:内部/进程/task_queues:95:5){ 内部错误:未定义, 代码:205, 道具:{ 内部错误:AbiError:返回值无效,是否耗尽了 Gas?如果您没有为从中检索数据的合约使用正确的 ABI、从不存在的区块号请求数据或查询未完全同步的节点,您也可能会看到此错误。 在decodeParametersWith(/home/steve/Projects/vcis_wallet_blockchain/node_modules/web3/node_modules/web3-eth-abi/lib/commonjs/api/parameters_api.js:94:19) 在decodeParameters(/home/steve/Projects/vcis_wallet_blockchain/node_modules/web3/node_modules/web3-eth-abi/lib/commonjs/api/parameters_api.js:213:75) 在decodeMethodReturn(/home/steve/Projects/vcis_wallet_blockchain/node_modules/web3/node_modules/web3-eth-contract/lib/commonjs/encoding.js:125:56) 在ContractBuilder。 (/home/steve/Projects/vcis_wallet_blockchain/node_modules/web3/node_modules/web3-eth-contract/lib/commonjs/contract.js:672:61) 在 Generator.next() 处 已履行(/home/steve/Projects/vcis_wallet_blockchain/node_modules/web3/node_modules/web3-eth-contract/lib/commonjs/contract.js:21:58) 在 process.processTicksAndRejections (节点:内部/进程/task_queues:95:5){ 内部错误:未定义, 代码:205, 道具:{} } } }

  • 了解更多背景信息。这是 ABI
const TRANSACTION_ADDRESS = "0x0766512529e545515d908c2cf8962455c430D3d7";

const TRANSACTION_ABI = [
  {
    inputs: [
      {
        internalType: "string",
        name: "_name",
        type: "string",
      },
      {
        internalType: "uint256",
        name: "_amount",
        type: "uint256",
      },
    ],
    name: "createTransaction",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  },
  {
    inputs: [],
    stateMutability: "nonpayable",
    type: "constructor",
  },
  {
    inputs: [],
    name: "count",
    outputs: [
      {
        internalType: "uint256",
        name: "",
        type: "uint256",
      },
    ],
    stateMutability: "view",
    type: "function",
  },
  {
    inputs: [],
    name: "getAllTransactions",
    outputs: [
      {
        components: [
          {
            internalType: "uint256",
            name: "id",
            type: "uint256",
          },
          {
            internalType: "string",
            name: "name",
            type: "string",
          },
          {
            internalType: "uint256",
            name: "amount",
            type: "uint256",
          },
        ],
        internalType: "struct Transactions.Transaction[]",
        name: "",
        type: "tuple[]",
      },
    ],
    stateMutability: "view",
    type: "function",
  },
  {
    inputs: [
      {
        internalType: "uint256",
        name: "",
        type: "uint256",
      },
    ],
    name: "transactions",
    outputs: [
      {
        internalType: "uint256",
        name: "id",
        type: "uint256",
      },
      {
        internalType: "string",
        name: "name",
        type: "string",
      },
      {
        internalType: "uint256",
        name: "amount",
        type: "uint256",
      },
    ],
    stateMutability: "view",
    type: "function",
  },
];

module.exports = {
  TRANSACTION_ABI,
  TRANSACTION_ADDRESS,
};

  • 还有index.js
const express = require("express");
const cors = require("cors");
const { MongoClient } = require("mongodb");
const { Web3 } = require("web3");
const routes = require("./router/routes");
const { TRANSACTION_ABI, TRANSACTION_ADDRESS } = require("./config");

const app = express();

app.use(cors());
app.use(express.json());

// Define MongoDB connection URI
const uri = "";

// Define the async function to connect to MongoDB and perform operations
async function run() {
  let client;
  try {
    client = new MongoClient(uri);
    await client.connect();

    const db = client.db("Cluster0");

    const web3 = new Web3(
      new Web3.providers.HttpProvider("http://127.0.0.1:7545")
    );
    const accounts = await web3.eth.getAccounts();

    const transactionList = new web3.eth.Contract(
      TRANSACTION_ABI,
      TRANSACTION_ADDRESS
    );

    routes(app, db, accounts, transactionList);
    app.listen(process.env.PORT || 3001, () => {
      console.log("Listening on port " + (process.env.PORT || 3001));
    });

    console.log("Connected to MongoDB and started server successfully!");
  } catch (error) {
    console.error("Error connecting to MongoDB:", error);
  }
}

run().catch(console.error);
  • 我尝试将 app.get 路由中的 GasLimit 增加到一个荒谬的数字,但这没有用。
  • 我尝试更改 ABI 和合约函数来更改返回类型,但仍然遇到相同的错误。
node.js ethereum solidity web3js abi
1个回答
0
投票

(抱歉,我无法发表评论)我的所有

get
函数都遇到相同的错误。您能找出问题所在吗?

© www.soinside.com 2019 - 2024. All rights reserved.