智能合约的形式化验证与 AI 辅助审计
智能合约审计中的形式化验证
形式化验证是指使用基于数学和逻辑的技术来证明智能合约的正确性和安全性。在实践中,这涵盖了一系列方法:从基于属性的模糊测试和符号执行,到严格的定理证明和模型检查。其目标是确保合约满足其规范,并且在所有可能的输入和状态下不包含可利用的漏洞。鉴于 DeFi 协议中锁定了数十亿美元的巨额资金,形式化方法对于以太坊和其他区块链平台变得越来越重要。
传统方法: 以太坊早期的形式化方法包括像 Oyente 和 Mythril 这样的符号执行工具,以及像 Slither 和 Securify 这样的静态分析器。符号执行通过符号输入探索程序路径以检测问题(例如重入、整数溢出),而静态分析则使用基于规则的模式匹配。这些工具取得了一定的成功,但也存在局限性:例如,Oyente 即使在简单的合约上也会产生许多误报,而 Slither 基于模式的检测器也可能产生一些假阳性。此外,2023 年的一项研究发现,超过 80% 的可利用合约漏洞(尤其是复杂的“业务逻辑”漏洞)被现有工具所忽略,这凸显了对更强大验证技术的需求。
全面验证的前景与挑战: 理论上,形式化验证可以通过对所有状态进行详尽的不变量检查来证明漏洞不存在。像 Certora Prover 或以太坊基金会的 KEVM 框架等工具旨在根据形式化规范对智能合约进行数学验证。例如,Certora 的“自动化数学审计器”使用一种规范语言 (CVL) 来证明或反驳用户定义的规则。然而,在实践中,完全证明真实世界合约的属性通常是无法实现或非常耗费人力的。代码可能需要重写为简化的形式以便验证,必须编写自定义规范,循环和复杂算术可能需要手动设置边界或进行抽象,而 SMT 求解器在处理复杂逻辑时经常超时。正如 Trail of Bits 的工程师所指出的,在非平凡的代码库上*“证明漏洞不存在通常是无法实现的”*,并且实现这一目标通常需要大量的用户干预和专业知识。因此,形式化验证工具传统上仅用于代码的关键部分(例如,验证代币的不变量或共识算法),而不是端到端地验证整个合约。
Foundry 的模糊测试和不变量测试
近年来,基于属性的测试已成为完全形式化证明的一种实用替代方案。Foundry 是一个流行的以太坊开发框架,它内置了对模糊测试和不变量测试的支持——这些技术极大地增强了测试覆盖率,可以被视为轻量级的形式化验证。Foundry 的模糊测试会自动生成大量输入,试图违反指定的属性,而不变量测试则将此扩展到一系列改变状态的 操作:
-
模糊测试: 开发者不再为特定输入编写单元测试,而是指定应在任何输入下都成立的属性或不变量。然后,Foundry 生成成百上千个随机输入来测试该函数,并检查该属性是否始终成立。这有助于捕捉开发者可能不会手动想到去测试的边缘情况。例如,模糊测试可能会断言函数的返回值始终为非负数,或者某个后置条件在任何输入下都为真。Foundry 的引擎使用智能启发式方法——它分析函数签名并引入边缘情况值(0, max uint 等)——以触及可能破坏属性的角落案例。如果断言失败,Foundry 会报告一个违反该属性的反例输入。
-
不变量测试: Foundry 的不变量测试(也称为状态模糊测试)更进一步,它会按顺序执行多个函数调用和状态转换。开发者编写在合约生命周期内应始终为真的不变量函数(例如,总资产 = 用户余额之和)。然后,Foundry 随机生成调用序列(带有随机输入)来模拟多种可能的使用场景,并定期检查不变量条件是否仍然为真。这可以发现只有在特定操作序列后才会显现的复杂漏洞。本质上,不变量测试更彻底地探索了合约的状态空间,确保任何有效的交易序列都不能违反所声明的属性。
Foundry 的重要性: Foundry 使这些先进的测试技术变得易于使用。模糊测试和不变量功能原生于开发者工作流——不需要特殊的测试工具或外部工具,测试与单元测试一起用 Solidity 编写。得益于基于 Rust 的引擎,Foundry 可以快速执行数千个测试(并行化它们),并为任何不变量违规提供详细的失败跟踪。开发者报告说,Foundry 的模糊测试器易于使用且性能高,只需要少量配置(例如,设置迭代 次数或添加假设来约束输入)。Foundry 文档中的一个简单例子是 divide(a,b)
函数的模糊测试,它使用 vm.assume(b != 0)
来避免无意义的无效输入,然后断言数学后置条件,如 result * b <= a
。通过用数千个随机的 (a,b)
对运行这样的测试,Foundry 可能会迅速发现难以通过手动推理找到的边缘情况(如溢出边界)。
比较: Foundry 的方法建立在社区先前工作的基础上。Trail of Bits 的 Echidna 模糊测试器是早期用于以太坊的基于属性的测试工具。Echidna 同样生成随机交易来寻找违反不变量的情况,这些不变量表示为返回布尔值的 Solidity 函数。它以“智能”输入生成(结合了覆盖率引导的模糊测试)而闻名,并已用于发现许多漏洞。事实上,安全研究人员指出,Echidna 的引擎非常有效——“Trail of Bits 的 Echidna 是目前最好的模糊测试器,因为它有智能的随机数选择”——尽管 Foundry 的集成工作流使开发者编写测试更简单。在实践中,Foundry 的模糊测试通常被视为安全 Solidity 开发的新的**“最低标准”**,补充了传统的单元测试。它不能证明漏洞不存在(因为它是随机的而不是详尽的),但通过覆盖大量的输入和状态组合,它极大地增加了信心。
超越模糊测试:形式化证明和高级工具
虽然模糊测试和不变量测试能捕捉到许多问题,但在某些情况下会使用更强的形式化方法。模型检查和定理证明涉及用形式化逻辑指定期望的属性,并使用自动证明器来对照合约代码进行检查。Certora Prover(最近已开源)是这一类别中的一个著名工具。它允许开发者用一种领域特定语言 (CVL) 编写规则,然后自动检查合约是否违反这些规则。Certora 已被用于验证 MakerDAO 和 Compound 等协议中的关键不变量;例如,它识别出了 MakerDAO 中被忽视了四年的“DAI 债务不变量”漏洞(一个微妙的记账不一致问题)。值得注意的是,Certora 的引擎现在支持多个平台(EVM、Solana 的 VM 和 eWASM),并且通过在 2025 年开源,它使得工业级的形式化验证在以太坊、Solana 和 Stellar 上免费可用。此举承认了形式化证明不应只是资金雄厚的团队的奢侈品。
其他形式化工具包括运行时验证方法(例如,以太坊的 KEVM 语义,或用于 Move-based 链的 Move Prover)。特别是 Move Prover 内置于 Move 语言中(被 Aptos 和 Sui 区块链使用)。它允许在代码旁边编写形式化规范,并能以类似于 linter 或类型检查器的用户体验自动证明某些属性。这种紧密的集成降低了这些平台上的开发者在开发过程中使用形式化验证的门槛。
总结: 如今的智能合约审计融合了这些方法。模糊测试和不变量测试(以 Foundry 和 Echidna 为代表)因其易用性和在捕捉常见漏洞方面的有效性而被广泛采用。符号执行和静态分析器仍然用于快速扫描已知的漏洞模式(像 Slither 这样的工具通常被集成到 CI 管道中)。与此同时,形式化验证工具正在成熟并扩展到多个链,但由于其复杂性,它们通常被保留用于特定的关键属性或由专业的审计公司使用。在实践中,许多审计结合了这些方法:例如,使用模糊测试器查找运行时错误,使用静态工具标记明显的错误,并对关键不变量(如“代币余额不超过总供应量”)进行形式化规范检查。
使用大语言模型的 AI 辅助审计
像 OpenAI 的 GPT-3/4 (ChatGPT) 和 Codex 这样的大语言模型 (LLMs) 的出现,为智能合约分析引入了一种新的范式。这些模型在大量代码和自然语言上进行训练,能够推理程序行为、解释代码,甚至通过模式识别和“常识”知识检测某些漏洞。问题是:AI 能否增强甚至自动化智能合约审计?
基于 LLM 的漏洞分析工具
已经出现了几项将 LLM 应用于智能合约审计的研究工作和原型工具:
-
OpenAI Codex / ChatGPT (通用模型): 早期的实验只是简单地向 GPT-3 或 Codex 提供合约代码并询问潜在的漏洞。开发者发现 ChatGPT 可以识别一些众所周知的漏洞模式,甚至建议修复方案。然而,响应时好时坏,并不可靠地全面。最近的一项学术评估指出,在基准数据集上,天真地提示 ChatGPT 进行漏洞检测*“与随机预测相比,并未产生显著更好的结果”*——基本上,如果模型没有得到适当的引导,它可能会捏造不存在的问题或错过真正的漏洞。这凸显了需要精心设计的提示词或微调才能获得有用结果。
-
AuditGPT (2024): 这是一个学术工具,专门利用 ChatGPT (GPT-3.5/4) 来检查以太坊合约中的 ERC 标准合规性。研究人员观察到,许多 ERC20/ERC721 代币合约违反了标准的微妙规则(这可能导致安全或兼容性问题)。AuditGPT 的工作方式是将审计分解为小任务,并为每种规则类型设计专门的提示词。结果令人印象深刻:在对真实合约的测试中,AuditGPT “成功地指出了 418 个 ERC 规则违规,并且只报告了 18 个误报”,展示了高准确性。事实上,该论文声称 AuditGPT 在发现 ERC 合规性漏洞方面优于专业的审计服务,且成本更低。这表明,对于定义明确、范围狭窄的领域(如执行一系列标准规则),一个带有良好提示词的 LLM 可以非常有效和精确。
-
LLM-SmartAudit (2024): 另一个研究项目 LLM-SmartAudit 采用更广泛的方法,使用多代理对话系统来审计 Solidity 代码。它设置了多个专门的 GPT-3.5/GPT-4 代理(例如,一个“审计员”专注于正确性,一个“攻击者”思考如何利用),它们相互交谈来分析一个合约。在他们的评估中,LLM-SmartAudit 能够检测到广泛的漏洞。值得注意的是,在与传统工具的对比测试中,基于 GPT-3.5 的系统实现了最高的整体召回率 (74%),超过了他们测试的所有传统静态和符号分析器(次好的是 Mythril,召回率为 54%)。它还能够找到他们测试套件中所有 10 种类型的漏洞(而每个传统工具都在某些类别上表现不佳)。此外,通过切换到 GPT-4 并集中分析(他们称之为目标分析模式),该系统可以检测到像 Slither 和 Mythril 完全错过的复杂逻辑缺陷。例如,在一组真实世界的 DeFi 合约上,基于 LLM 的方法发现了数百个逻辑漏洞,而静态工具*“在检测这些问题上没有表现出任何 效果”*。这些结果展示了 LLM 在捕捉超出传统分析器模式匹配范围的微妙漏洞方面的潜力。
-
Prometheus (PromFuzz) (2023): 一种混合方法是使用 LLM 来指导其他技术。一个例子是 PromFuzz,它使用一个基于 GPT 的“审计员代理”来识别代码中的可疑区域,然后自动生成不变量检查器并将其输入到模糊测试引擎中。本质上,LLM 进行第一遍分析(从善意和攻击者的角度),以将模糊测试集中在可能的漏洞上。在评估中,这种方法实现了非常高的漏洞发现率——例如,在某些基准测试集中召回率超过 86%,且零误报——显著优于独立的模糊测试器或以前的工具。这是一个有前途的方向:使用 AI 来协调和增强像模糊测试这样的经典技术,结合两者的优势。
-
其他 AI 工具: 社区已经看到了各种其他 AI 辅助审计的概念。例如,Trail of Bits 的“Toucan”项目将 OpenAI Codex 集成到他们的审计工作流中(下文将详细介绍其发现)。一些安全初创公司也在宣传 AI 审计器(例如,“ChainGPT Audit”服务),通常是用自定义提示词包装 GPT-4 来审查合约。开源爱好者在论坛上创建了基于 ChatGPT 的审计机器人,可以接收 Solidity 代码片段并输出潜在问题。虽然其中许多是实验性的,但总体趋势是明确的:AI 正在安全审查过程的各个层面被探索,从自动代码解释和文档生成到漏洞检测,甚至建议修复方案。
LLM 审计器的能力与局限性
LLM 在智能合 约审计中展示了显著的能力:
-
广泛的知识: 像 GPT-4 这样的 LLM 已经在无数的代码和漏洞上进行了训练。它“知道”常见的安全陷阱(重入、整数溢出等),甚至一些历史上的漏洞利用。这使得它能够识别可能表明存在漏洞的模式,并从文档中回忆起最佳实践。例如,它可能记得 ERC-20 的
transferFrom
应该检查授权(并将缺少此类检查标记为违规)。与只标记已知模式的静态工具不同,LLM 可以对新颖的代码应用推理,并推断出工具开发者没有明确编码进去的问题。 -
自然的解释: AI 审计器可以提供人类可读的潜在问题解释。这对开发者体验非常有价值。传统工具通常输出需要专业知识才能解释的神秘警告,而基于 GPT 的工具可以生成一段用通俗英语解释漏洞的段落,甚至建议修复方案。例如,AuditGPT 不仅标记了 ERC 规则违规,还描述了代码为何违反规则以及其影响。这有助于引导经验较少的开发者了解安全概念。
-
灵活性: 通过提示词工程,可以引导 LLM 关注不同的方面或遵循自定义的安全策略。它们不受固定规则集的限制——如果你能用语言描述一个属性或模式,LLM 就可以尝试检查它。这使得它们在审计可能具有独特不变量或逻辑的新协议时很有吸引力(在这种情况下,从头开始编写自定义静态分析是不可行的)。
然而,也观察到了重大的挑战和可靠性问题:
-
推理限制: 当前的 LLM 有时难以进行安全分析所需的复杂逻辑推理。Trail of Bits 报告说,“这些模型无法很好地推理某些更高级别的概念,例如合约的所有权、重入和函数间关系”。例如,GPT-3.5/4 可能在理论上理解什么是重入(甚至可以解释它),但如果需要理解跨函数的调用序列和状态变化,它可能无法识别出重入漏洞。模型也可能错过涉及多合约交互或时间依赖逻辑的漏洞,因为这些超出了单个代码片段分析的范围。
-
误报和幻觉: 一个主要问题是 LLM 可能会产生听起来自信但实际上不正确的结论。在审计中,“幻觉”可能是标记一个实际上不存在的漏洞,或误解代码。Trail of Bits 使用 Codex (GPT) 的实验发现,当他们扩展到更大的真实世界合约时,“误报和幻觉率变得过高”,以至于会因为太多虚假的报告而减慢审计员的速度。这种不可预测性是有问题的——一个经常“狼来了”的工具不会被开发者信任。AuditGPT 在保持低误报率(数百个发现中只有 18 个)方面的成功令人鼓舞,但那是在一个受限的领域。在通用用途中,需要仔细的提示词设计和可能的人工审查循环来过滤 AI 的发现。
-
上下文限制: LLM 有上下文窗口限制,这意味着它们一次只能“看到”一定数量的代码。复杂的合约通常跨越多个文件和数千行代码。如果 AI 无法消化整个代码库,它可能会错过重要的联系。像代码切片(分块提供合约)这样的技术被使用,但它们有失去全局视野的风险。LLM-SmartAudit 团队指出,使用 GPT-3.5 的 4k token 限制,他们无法分析一些大型的真实世界合约,直到他们切换到具有更大上下文的 GPT-4。即便如此,将分析分成部分也可能导致它忽略只有在考虑整个系统时才会显现的漏洞。这使得 AI 对整个协议(具有多个交互合约)的分析目前仍然是一个真正的挑战。
-
集成和工具: 围绕 AI 审计器的强大开发者工具仍然缺乏。运行 LLM 分析不像运 行 linter 那样直接。它涉及对模型的 API 调用、处理提示词工程、速率限制以及解析 AI 的响应。正如一个审计团队所说,“围绕将 LLM 与传统软件集成的软件生态系统过于粗糙,一切都很麻烦”。几乎没有现成的框架可以在 CI 管道中持续部署 AI 审计器,同时管理其不确定性。这种情况正在慢慢改善(一些项目正在探索使用 GPT-4 进行代码审查的 CI 机器人),但这还处于早期阶段。此外,调试 AI 给出某个结果的原因很困难——与确定性工具不同,你无法轻易地追踪导致模型标记或错过某事的逻辑。
-
成本和性能: 使用像 GPT-4 这样的大型模型是昂贵的,而且可能很慢。如果你想将 AI 审计集成到 CI/CD 管道中,它可能会为每个合约增加几分钟的时间,并为大型代码产生显著的 API 成本。微调模型或开源 LLM 可以降低成本,但它们的能力往往不如 GPT-4。目前正在进行关于用于代码安全的更小、更专业模型的研究,但目前最好的结果来自大型专有模型。
总而言之,LLM 辅助审计前景广阔,但并非万能药。 我们看到的是混合方法,其中 AI 帮助生成测试或分析特定方面,而不是端到端地完成整个审计。例如,AI 可能会建议潜在的不变量或风险区域,然后由人工或其他工具进行调查。正如一位安全工程师所说,鉴于推理差距和集成障碍,该技术尚未准备好取代人类审计员来完成关键任务。然而,它已经可以成为一个有用的助手——在传统工具不足的情况下,“不完美的东西可能比什么都没有要好得多”。