无法更改合同中的状态变量

时间:2017-07-01 23:44:21

标签: ethereum solidity truffle

我正在使用Truffle和TestRPC开发以太坊合约。但是我无法获得要更新的状态变量。我认为可能只是因为我太早访问它,但其他示例测试似乎工作得很好并且非常相似。

我已将合同缩减到最简单的可能性:

pragma solidity ^0.4.11;

contract Adder {

    uint public total;

    function add(uint amount) {
        total += amount;
    }

    function getTotal() returns(uint){
        return total;
    }
}

这是我的考验:

var Adder = artifacts.require("./Adder.sol");

contract('Adder', accounts => {
  it("should start with 0", () =>
    Adder.deployed()
      .then(instance => instance.getTotal.call())
      .then(total => assert.equal(total.toNumber(), 0))
  );

  it("should increase the total as amounts are added", () =>
    Adder.deployed()
      .then(instance => instance.add.call(10)
        .then(() => instance.getTotal.call())
        .then(total => assert.equal(total.toNumber(), 10))
      )
  );

});

第一次测试通过了。但第二次测试失败,因为getTotal仍然返回0。

1 个答案:

答案 0 :(得分:5)

我认为问题在于您始终使用.call()方法。

实际上,此方法将执行代码,但不会保存到区块链。

只有在阅读区块链或测试.call()时才应使用throws方法。

只需删除添加功能中的.call()即可。

var Adder = artifacts.require("./Adder.sol");

contract('Adder', accounts => {
  it("should start with 0", () =>
    Adder.deployed()
      .then(instance => instance.getTotal.call())
      .then(total => assert.equal(total.toNumber(), 0))
  );

  it("should increase the total as amounts are added", () =>
    Adder.deployed()
      .then(instance => instance.add(10)
        .then(() => instance.getTotal.call())
        .then(total => assert.equal(total.toNumber(), 10))
      )
  );
});

另外,考虑在promise的函数链之外声明instance变量,因为不共享上下文。考虑使用async/await进行测试而不是承诺。

var Adder = artifacts.require("./Adder.sol");

contract('Adder', accounts => {
  it("should start with 0", async () => {
    let instance = await Adder.deployed();
    assert.equal((await instance.getTotal.call()).toNumber(), 0);
  });

  it("should increase the total as amounts are added", async () => {
    let instance = await Adder.deployed();
    await instance.add(10);
    assert.equal((await instance.getTotal.call()).toNumber(), 10);
  });
});