本教程介绍了如何使用Echidna进行智能合约的模糊测试和断言测试,详细说明了Incrementor合约及其修改版本EchidnaIncrementorAssert的实现。文章深入探讨了断言的使用、事件的处理以及模糊测试如何帮助发现潜在漏洞,以确保区块链应用的完整性。
Echidna 是一个强大的工具,用于测试和验证智能合约,利用断言、事件和模糊测试来揭示隐藏的漏洞和确保区块链应用程序的完整性。
它作为一个强大的工具,用于测试和验证智能合约,提供了一种全面的方法来检测和防止潜在问题。
在本章中,我们将学习如何在断言模式下运行 Echidna 测试,如何实现,以及其他需要考虑的提示。
在视频版本中观看完整和扩展的版本
这是我们将为此目的使用的第一个合约。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Incrementor {
uint256 public counter = 2 ** 200;
function increase(uint256 val) public returns (uint256) {
uint256 newCounter = counter;
unchecked {
counter += val;
}
return (counter - newCounter);
}
}
Echidna 结合了断言和事件来增强合约测试。断言作为自我可验证的陈述,确保合约代码中某些条件为真。
通过结合断言,开发人员可以主动识别和解决潜在错误。另一方面,事件提供了一种机制,当合约中发生特定事件时,通知外部系统,从而实现更广泛的测试和监测。
以下是两种在生产代码上测试合约的方法:
assert(newCounter <= counter)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Incrementor {
uint256 private counter = 2 ** 200;
function inc(uint256 val) public returns (uint256) {
uint256 newCounter = counter;
unchecked {
counter += val;
}
assert(newCounter <= counter);
return (counter - tmp);
}
}
2. 通过使用事件 AssertionFailed()
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Incrementor {
// event AssertionFailed(uint256 amount);
uint256 private counter = 2 ** 200;
function inc(uint256 val) public returns (uint256) {
uint256 newCounter = counter;
unchecked {
counter += val;
}
// if(newCounter <= counter) {
// emit AssertionFailed(counter);
// }
return (counter - newCounter);
}
}
现在我们想稍微修改我们的 Incrementor 合约,以引入一种新方法。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Incrementor {
uint256 public counter = 2 ** 200;
uint256 public newCounter;
function increase(uint256 val) public {
newCounter = counter;
unchecked {
counter += val;
}
}
function calculate() public view returns (uint256 amount) {
return (newCounter - counter);
}
}
EchidnaIncrementor 合约继承自原始的 Incrementor 合约,并包含一个额外的函数,叫做 assert_counterIsEqualOrBigger()
。此函数明确断言新的计数器值小于或等于当前计数器值。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "./Incrementor.sol";
contract EchidnaIncrementorAssert is Incrementor {
function assert_counterIsEqualOrBigger() public {
uint256 amount = 25;
increase(amount);
assert(newCounter <= counter);
calculate();
}
}
为了增强测试,Echidna 可以在合约内部进行部署。这种方法简化了测试并促进了断言的集中管理。Echidna 能够忽略具有 echidna_
前缀的函数,确保自定义断言不会被 Echidna 生成的测试用例意外覆盖。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "./Incrementor.sol";
contract EchidnaIncrementorAssert {
Incrementor incrementor;
constructor() {
incrementor = new Incrementor();
}
function assert_counterIsEqualOrBigger() public {
uint256 amount = 25;
incrementor.increase(amount);
assert(incrementor.newCounter() <= incrementor.counter());
incrementor.calculate();
}
}
Echidna 的武器库不仅限于断言和事件,还结合了模糊测试,以揭示隐藏的漏洞。
模糊测试涉及生成大量随机输入,并模拟与合约的真实交互。这种方法有效地暴露出边缘案例和可能通过传统测试方法未被发现的潜在漏洞。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "./Incrementor.sol";
contract EchidnaIncrementorAssert {
Incrementor incrementor;
constructor() {
incrementor = new Incrementor();
}
function assert_counterIsEqualOrBigger(uint256 amount) public {
incrementor.increase(amount);
assert(incrementor.newCounter() <= incrementor.counter());
incrementor.calculate();
}
}
这里是智能合约黑客课程的 $50 折扣。
https://smartcontractshacking.com/?referral=bloqarl
在 Twitter 上关注我 https://twitter.com/TheBlockChainer 获取我的最新更新
深入了解知识和资源,在 https://www.theblockchainerhub.xyz/ 和订阅新闻通讯以获取最新动态。
- 原文链接: medium.com/@bloqarl/echi...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!