本文介绍了如何结合AI辅助(Vibe coding)和人工验证来高效地为Solidity智能合约编写fuzzing测试。强调了AI在生成重复性代码结构方面的优势,以及人工验证在确保测试逻辑正确性、数据准确性和覆盖率完整性方面的必要性。通过定义测试流程的四个阶段,并提供实际代码示例,展示了如何在保证安全性的前提下,利用AI加速智能合约的安全测试。
为 Solidity 合约编写全面的模糊测试是必要的,但非常耗时。手动代码审查无法捕获所有漏洞,因为智能合约的复杂状态机有太多的执行路径和状态。
Vibe coding——使用 AI 生成样板代码,同时让人类负责逻辑,提供了一个更好的工作流程。在 Python 中使用 Wake 测试智能合约支持这种方法,因为切换语言需要思考行为,而不是语法。
本指南定义了在手动引导的模糊测试中,AI 可以安全生成的内容与始终需要人工验证的内容之间的界限。
MGF 涉及编写大量重复性代码,其中主要是导入 pytypes、python 状态定义和静态逻辑。
用于迭代帐户的 Python for 循环可以通过 vibe coding 实现。If-elif 控制结构可以通过 vibe coding 实现。错误消息字符串可以通过 vibe coding 实现。测试的结构元素是机械工作。
但是,有三个组件每次都需要手动验证。
缺少这三项中的任何一项都会使你的测试看起来完美,但什么也抓不到。

Wake 中的每个 flow 函数都遵循相同的模式。了解哪些阶段可以通过 vibe coding 实现,哪些阶段需要手动验证,这决定了测试的有效性。
@flow()
def flow_something(self):
## Phase 1: prepare random input
## 第一阶段:准备随机输入
## Phase 2: run transaction
## 第二阶段:运行事务
## Phase 3: check events
## 第三阶段:检查事件
## Phase 4: update python state
## 第四阶段:更新 python 状态
pass
Python
Copy
Vibe coding 随机选择的结构——选择帐户、生成金额、从集合中选择。AI 可以有效地处理这种机械工作。
手动指定约束。你的业务逻辑决定了有效范围、前提条件和参数关系。这些编码了 AI 缺乏的领域知识。
Vibe coding may_revert() 包装器结构。这是标准的 Python 错误处理。
手动指定从 Python 状态传递的确切参数。事务参数取决于你的测试场景和当前状态。
这个阶段会导致最常见的测试错误。你可以 vibe coding 事件过滤循环结构,但你必须手动验证你断言的内容。
最重要的是,事件验证必须仅依赖于事务之前计算的 Python 状态变量。
永远不要这样写:
if len(tx.events) > 0:
assert events[0].amount == expected_amount
Python
Copy
这检查的是错误的东西。相反,确定性地验证所有参数:
events = [e for e in tx.events if isinstance(e, Contract.Transfer)]
assert len(events) == 1
assert events[0].sender == sender
assert events[0].recipient == recipient
assert events[0].amount == expected_amount
Python
Copy
每个参数都根据你事先计算的状态进行验证。AI 将生成第一个版本。你必须验证它是否变成了第二个版本。
Vibe coding 赋值结构——更新字典和变量的基本语法。
手动验证正在更新哪些值。费用、舍入、极端情况——所有这些都编码了你对合约工作方式的理解。因为不变式函数依赖于准确的状态跟踪,所以错误会传递到每个后续测试中。
当事务 revert 时,需要详尽的错误映射。你可以 vibe coding if-elif 控制结构和错误消息字符串。必须手动验证你正在断言的内容以及你到达的执行分支。
with may_revert() as e:
tx = self.contract.transfer(recipient, amount, from_=sender)
if self.balances[sender] < amount:
assert e.value is not None
assert isinstance(e.value, Contract.InsufficientBalance)
assert e.value.required == amount
assert e.value.available == self.balances[sender]
return "insufficient_balance"
elif recipient == Address.ZERO:
assert e.value is not None
assert isinstance(e.value, Contract.InvalidRecipient)
return "zero_address"
assert e.value is None
Python
Copy
一个细微的错误会降低测试的有效性。许多合约使用特殊值,例如 address(0) 来表示原生代币,从而在合约代码中创建分支。不要在你的 Python 状态中复制这些实现细节。
你可以 vibe coding for 循环结构,但要验证你所断言的内容。
不良版本,镜像合约实现:
@invariant()
def invariant_token_balances(self):
for token in self.tokens + [Address.ZERO]:
for account in self.all_accounts:
if token != Address.ZERO:
assert self.token_balances[token][account] == IERC20(token).balanceOf(account)
else:
assert self.token_balances[token][account] == account.balance
Python
Copy
更好的版本,使用自然的语义表示:
@invariant()
def invariant_erc20_balances(self):
for token in self.erc20_tokens:
for account in self.all_accounts:
assert self.erc20_balances[token][account] == token.balanceOf(account)
@invariant()
def invariant_native_balances(self):
for account in self.all_accounts:
assert self.native_balances[account] == account.balance
Python
Copy
第二个版本区分了语义上不同的事物。你的测试代码反映了代币的实际含义,而不是合约如何实现它们。这种独立模型可以捕获错误,而不是隐藏它们。
考虑你是在验证合约逻辑还是在重现它。如果你的测试具有与合约相同的条件分支,那么你会错过错误。
从合约中最简单的状态更改函数开始。一些其他操作依赖的基础函数。
Vibe coding flow 结构。Flow 函数名称、装饰器、轮廓、事务调用和填充参数。然后手动验证关键部分、从状态中选择参数、完整的 revert 处理、彻底的事件验证、精确的状态更新及其逻辑。
编写验证 python 状态和合约状态的不变式函数。Vibe coding 函数结构和循环。手动验证断言正在验证的内容。
运行模糊测试并检查覆盖率。找到未经测试的分支。验证这些分支是否有意义,而不是死代码。每次迭代都会揭示合约在你未曾考虑的极端情况下的行为方式。
这个完整的示例演示了一个代币转账函数:
@flow()
def flow_transfer_tokens(self):
# Phase 1: Prepare random input (vibe code structure, manually verify constraints)
# 第一阶段:准备随机输入(vibe 代码结构,手动验证约束)
sender = random_account()
recipient = random_account()
amount = random_int(0, 10**30)
# Phase 2: Run transaction (vibe code wrapper, manually specify parameters)
# 第二阶段:运行事务(vibe 代码包装器,手动指定参数)
with may_revert() as e:
tx = self.token.transfer(recipient, amount, from_=sender)
# Phase 3: Check events (vibe code filtering, manually verify all parameters)
# 第三阶段:检查事件(vibe 代码过滤,手动验证所有参数)
if self.balances[sender] < amount:
assert e.value is not None
assert isinstance(e.value, Token.InsufficientBalance)
assert e.value.required == amount
assert e.value.available == self.balances[sender]
return "insufficient_balance"
assert e.value is None
events = [e for e in tx.events if isinstance(e, Token.Transfer)]
assert len(events) == 1
assert events[0].from_ == sender.address
assert events[0].to == recipient.address
assert events[0].value == amount
# Phase 4: Update Python state (vibe code structure, manually verify values)
# 第四阶段:更新 Python 状态(vibe 代码结构,手动验证值)
self.balances[sender] -= amount
self.balances[recipient] += amount
Python
Copy
AI 生成结构模式,而你验证每个断言、每个值和每个执行分支。
在 Python 中使用 Wake 测试智能合约可以实现 vibe coding 的工作流程,从而在保持安全性的同时加速测试开发。
Vibe coding 机械部分,如导入 pytypes、for 循环、if-elif 结构、错误字符串、函数签名和类型提示。
始终手动验证你正在断言的内容、你正在断言的哪些值以及到达的执行分支。这三个验证点是安全漏洞隐藏的地方。
确定 vibe coding 什么和验证什么的界限决定了你是高效地编写全面的模糊测试,还是发布隐藏在看起来正确的生成代码中的漏洞。
掌握这种平衡,以加强你的 智能合约 安全测试。
Wake 测试框架文档:Wake 模糊测试指南
有关更多模糊测试技术和最佳实践,请关注 @WakeFramework on X。
- 原文链接: ackee.xyz/blog/vibe-fuzz...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!