如何使用 truffle 控制台的 testrpc `evm_increaseTime` 参数?
How to use the testrpc `evm_increaseTime` parameter from truffle console?
我正在使用 truffle 和 testrpc 创建智能合约。在编写单元测试时,我希望更改块时间以模拟可能调用智能合约的不同时间。一套 evm_increaseTime
inside truffle console 如何?
解决方案是覆盖 solidity 中的 now
关键字,将其设置为一个值,然后稍后在应用程序中使用该值(用于测试目的)。
通过示例扩展 OP 的答案(摘自 Status)
我建议在正常情况下创建一个getTime()
函数到return now
,并在测试时设置一个可设置的时间。
/// @notice This function is overriden by the test Mocks.
function getTime() internal returns (uint256) {
return now;
}
uint256 mock_time;
function SNTPlaceHolderMock(...)
SNTPlaceHolder(...) {
mock_time = now;
}
function getTime() internal returns (uint256) {
return mock_time;
}
function setMockedTime(uint256 _t) public {
mock_time = _t;
}
我们现在可以使用 await sntPlaceHolderMock.setMockedTime(t);
设置模拟时间
- 1.
evm_increaseTime
:增加下一个区块的时间。
- 2.
evm_mine
: 开采一个新区块。
这种时间旅行甚至不需要 Tardis 或 DeLorean。
让我解释一下这些函数是如何工作的:
每次开采一个新区块时,矿工都会为其添加一个时间戳。假设创建僵尸的交易在区块 5 中被开采。
接下来,我们调用 evm_increaseTime
但是,由于区块链是不可变的,因此无法修改现有区块。所以,当合约检查时间时,不会增加。
如果我们 运行 evm_mine
,第 6 个区块被开采(并加上时间戳),这意味着,当我们让僵尸战斗时,智能合约将“看到”一天有通过。
综上所述,我们可以通过如下时间旅行来修复我们的测试:
await web3.currentProvider.sendAsync({
jsonrpc: "2.0",
method: "evm_increaseTime",
params: [86400], // there are 86400 seconds in a day
id: new Date().getTime()
}, () => { });
web3.currentProvider.send({
jsonrpc: '2.0',
method: 'evm_mine',
params: [],
id: new Date().getTime()
});
我正在使用 truffle 和 testrpc 创建智能合约。在编写单元测试时,我希望更改块时间以模拟可能调用智能合约的不同时间。一套 evm_increaseTime
inside truffle console 如何?
解决方案是覆盖 solidity 中的 now
关键字,将其设置为一个值,然后稍后在应用程序中使用该值(用于测试目的)。
通过示例扩展 OP 的答案(摘自 Status)
我建议在正常情况下创建一个getTime()
函数到return now
,并在测试时设置一个可设置的时间。
/// @notice This function is overriden by the test Mocks.
function getTime() internal returns (uint256) {
return now;
}
uint256 mock_time;
function SNTPlaceHolderMock(...)
SNTPlaceHolder(...) {
mock_time = now;
}
function getTime() internal returns (uint256) {
return mock_time;
}
function setMockedTime(uint256 _t) public {
mock_time = _t;
}
我们现在可以使用 await sntPlaceHolderMock.setMockedTime(t);
- 1.
evm_increaseTime
:增加下一个区块的时间。 - 2.
evm_mine
: 开采一个新区块。
这种时间旅行甚至不需要 Tardis 或 DeLorean。
让我解释一下这些函数是如何工作的:
每次开采一个新区块时,矿工都会为其添加一个时间戳。假设创建僵尸的交易在区块 5 中被开采。
接下来,我们调用 evm_increaseTime
但是,由于区块链是不可变的,因此无法修改现有区块。所以,当合约检查时间时,不会增加。
如果我们 运行 evm_mine
,第 6 个区块被开采(并加上时间戳),这意味着,当我们让僵尸战斗时,智能合约将“看到”一天有通过。
综上所述,我们可以通过如下时间旅行来修复我们的测试:
await web3.currentProvider.sendAsync({
jsonrpc: "2.0",
method: "evm_increaseTime",
params: [86400], // there are 86400 seconds in a day
id: new Date().getTime()
}, () => { });
web3.currentProvider.send({
jsonrpc: '2.0',
method: 'evm_mine',
params: [],
id: new Date().getTime()
});