Solidity

如何讀取函式返回的數據?

  • January 14, 2020

計數器.sol:

pragma solidity >=0.5.0 <0.7.0;

contract Counter {
   uint public _counter = 0;

   function GenNextID() public returns (uint) {
       return _counter++;
   }
}

我使用 Truffle 和 Ganache 進行本地開發。

我的測試如下所示。出於某種原因**,ctrInstance.GenNextID.call()**不會發生變異_counter,並且始終保持等於 0。

const Counter = artifacts.require("Counter");

contract("Counter", () => {
 it("should increment ocunter", async () => {
   const ctrInstance = await Counter.deployed();

   for (let i = 0; i < 10; i++) {
     const result = await ctrInstance.GenNextID.call();
     const id = result.toNumber();
     assert.equal(result, id); // this fails on second iteration
   }
 });
});

我發現呼叫會const r = await ctrInstance.GenNextID();改變內部狀態,但它總是返回receipt但不返回數據。

{
 tx: '0x9d0ef6530ba5808194612f7bf1b834b4ccab1c8e67aa58d44862d27dd777d57a',
 receipt: {
   transactionHash: '0x9d0ef6530ba5808194612f7bf1b834b4ccab1c8e67aa58d44862d27dd777d57a',
   transactionIndex: 0,
   blockHash: '0xe4883bcdfa9aecf0066228b1dc33ef61045f6a9a158fb0f331eb94afafaf08bf',
   blockNumber: 13,
   from: '0xe821f406192d16f9d7b74ece45e73ba92fb9ba64',
   to: '0x147e70c0babb11232d3df6f750fa9acd28a86460',
   gasUsed: 26700,
   cumulativeGasUsed: 26700,
   contractAddress: null,
   logs: [],
   status: true,
   logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
   v: '0x1c',
   r: '0xdb56e87a6f52c0d03e7e3ddc1248d9cf55c38d0b747bebb4de4b8d21c94a28a',
   s: '0x41d2ba345d4f18be71aaceca1548a357f4ecdfbd6c51972bf6759e51035c67e5',
   rawLogs: []
 },
 logs: []
}

問題是:如何GenNextID像普通函式一樣呼叫,即:

  1. 呼叫此函式會改變內部狀態
  2. 它返回從合約程式碼返回的結果

我看到您在幾個有效/正確答案後修改了問題:

問題是:如何像普通函式一樣呼叫 GenNextID,即:

  • 呼叫此函式會改變內部狀態
  • 它返回從合約程式碼返回的結果

你不

您要麼改變狀態並獲得收據,要麼獲得響應但不改變狀態。冒著攪渾水的風險,返回值可用於其他合約功能,但不能以任何方式提供給外部呼叫者。

請花時間查看答案並將資訊內化。


看看這個以獲得一些重要的澄清,這將使您對真正發生的事情感到困惑。https://blog.b9lab.com/calls-vs-transactions-in-ethereum-smart-contracts-62d6b17d0bc2

這是一個真正的(試執行)呼叫,因為您使用了.call().

ctrInstance.GenNextID.call()

你需要使用ctrInstance.GenNextId();它來改變狀態。

您將遇到的下一個問題是您將僅收到交易收據,並且您需要等待交易被探勘,然後才能檢測到突變。使用 Ganache 幾乎是瞬時的,但請記住這一點。當有明顯的採礦延遲時,它會在以後咬人。

要查看突變,您必須在它探勘後檢查它,使用

myVar = await ctrInstance._counter();

如果不清楚:

  • 第一個非同步響應是挖礦收據。
  • 第二個非同步響應是檢查結果。

希望能幫助到你。

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