无法更改合约中的状态变量
Unable to change a state variable in a contract
我正在使用 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.
我认为问题在于您一直在使用 .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);
});
});
我正在使用 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.
我认为问题在于您一直在使用 .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);
});
});