利用 Wake 框架进行 Solidity 的 AI 驱动的模糊测试

  • Ackee
  • 发布于 20小时前
  • 阅读 57

本文介绍了如何结合AI辅助(Vibe coding)和人工验证来高效地为Solidity智能合约编写fuzzing测试。强调了AI在生成重复性代码结构方面的优势,以及人工验证在确保测试逻辑正确性、数据准确性和覆盖率完整性方面的必要性。通过定义测试流程的四个阶段,并提供实际代码示例,展示了如何在保证安全性的前提下,利用AI加速智能合约的安全测试。

介绍

Solidity 合约编写全面的模糊测试是必要的,但非常耗时。手动代码审查无法捕获所有漏洞,因为智能合约的复杂状态机有太多的执行路径和状态。

Vibe coding——使用 AI 生成样板代码,同时让人类负责逻辑,提供了一个更好的工作流程。在 Python 中使用 Wake 测试智能合约支持这种方法,因为切换语言需要思考行为,而不是语法。

本指南定义了在手动引导的模糊测试中,AI 可以安全生成的内容与始终需要人工验证的内容之间的界限。

Vibe 代码结构,验证逻辑

MGF 涉及编写大量重复性代码,其中主要是导入 pytypes、python 状态定义和静态逻辑。

用于迭代帐户的 Python for 循环可以通过 vibe coding 实现。If-elif 控制结构可以通过 vibe coding 实现。错误消息字符串可以通过 vibe coding 实现。测试的结构元素是机械工作。

但是,有三个组件每次都需要手动验证。

验证清单

  1. 测试断言的是什么: 要检查的正确属性。所有事件参数都要检查,而不仅仅是事件是否存在。每个错误条件都映射到一个断言。不变式表达的是真实的数学或逻辑属性。
  2. 它们断言的是哪些值: 值与事务之前计算的 Python 状态进行比较。错误参数要完全验证。状态更改反映合约的行为,包括费用和舍入等极端情况。
  3. 达到了哪些执行分支: 使用 Wake 的覆盖率报告和手动引导模糊测试的输出来确认预期的代码路径已执行并经过充分测试。

缺少这三项中的任何一项都会使你的测试看起来完美,但什么也抓不到。

每个 Flow 函数的四个阶段

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 将生成第一个版本。你必须验证它是否变成了第二个版本。

第四阶段:更新 Python 状态

Vibe coding 赋值结构——更新字典和变量的基本语法。

手动验证正在更新哪些值。费用、舍入、极端情况——所有这些都编码了你对合约工作方式的理解。因为不变式函数依赖于准确的状态跟踪,所以错误会传递到每个后续测试中。

处理 Revert 以验证 Python 模型

当事务 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

Python 状态设计

一个细微的错误会降低测试的有效性。许多合约使用特殊值,例如 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

这个完整的示例演示了一个代币转账函数:

@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 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Ackee
Ackee
Cybersecurity experts | We audit Ethereum and Solana | Creators of @WakeFramework , Solidity (Wake) & @TridentSolana | Educational partner of Solana Foundation