For the complete documentation index, see llms.txt. This page is also available as Markdown.

智能合约安全开发最佳实践

智能合约一旦部署就几乎无法修改,且往往控制着大量资金,因此需要比传统软件更高的安全标准。本节总结了业界公认的最佳实践,帮助开发者在整个生命周期中防止安全事故。

1. 设计阶段最佳实践

1.1 最小化复杂度原则

核心理念:代码越简单,越容易被审计和验证,漏洞越少。

实践建议

  • 单一职责:每个合约应该只负责一个核心功能,避免臃肿合约

  • 模块化设计:将复杂逻辑分解为多个独立的小合约

  • 避免过度优化:可读性和安全性比 Gas 优化更重要

示例 - 不好的做法

pragma solidity ^0.8.24;

// 一个合约承载了太多职责:转账、质押、治理、预言机等
contract Monolith {
    // 数百行代码,混杂各种逻辑
    function complexFunction() public {
        // 代码越长,越容易出现漏洞
    }
}

示例 - 好的做法

实际合约中,unstakeclaim 等共享 stakes 状态的外部入口也应使用同一套 CEI 和重入保护策略;若代币存在转账税或 rebasing 行为,应改用余额差额记账。

1.2 状态机设计

核心理念:为合约定义明确的状态转换规则,防止非法状态。

1.3 明确定义业务规则和约束

在代码中清晰地记录所有约束条件,这些将成为后续审计的依据。

2. 编码阶段最佳实践

2.1 Checks-Effects-Interactions 模式

这是防止重入攻击的标准模式。

2.2 使用重入锁

对于无法完全避免重入的复杂场景,使用重入锁提供保护。

2.3 显式处理低级调用的返回值

2.4 使用自定义错误表达失败原因

Solidity 0.8.x 中可以用 custom errors 替代长字符串错误。它们更适合 ABI 解码、测试断言和 gas 成本控制。

测试中应断言具体错误,而不是只匹配字符串:

2.5 避免依赖 block.timestamp 进行关键判断

2.6 严格的权限控制

3. 测试阶段最佳实践

3.1 全面的单元测试

3.2 覆盖率目标

4. 审计阶段最佳实践

4.1 内部审计清单

4.2 自动化审计

5. 部署后最佳实践

5.1 合约验证

5.2 监控和告警

链下监控示例:

5.3 升级机制

6. 常见漏洞快速参考表

漏洞
表现
防护措施
工具检测

重入

余额被重复扣除

CEI 模式、重入锁

Slither, Mythril

整数溢出

余额变为负数

Solidity 0.8.0+

Slither

权限缺失

任何人可调用关键函数

onlyOwner, AccessControl

Slither

外部调用失败忽略

状态不一致

检查返回值、SafeERC20

Slither

时间戳依赖

矿工操纵

添加时间范围、预言机

Mythril

闪电贷相关操纵

预言机或流动性被瞬时扭曲

多源预言机、TWAP、价格影响限制、熔断

属性测试、链上监控

MEV 抢跑

交易被插队

批处理、承诺-reveal

链上分析

7. 资源与工具链

必读资源

  • OpenZeppelin Contracts:经审计的合约库(示例默认按 v5 路径和构造函数书写)

  • Solidity 官方文档:语言规范和安全警告

  • OWASP SCSVS / SCSTG / SCWE:智能合约安全需求、测试指南和弱点枚举

  • EEA EthTrust Security Levels:审计和验收时可使用的安全等级基线

  • SWC Registry:历史漏洞编号参考;不应作为当前唯一基线

工具集

  • Hardhat:开发和测试框架

  • Truffle:成熟的开发套件(ConsenSys 已于 2023-09 宣布 sunset,存量项目可参考迁移说明,新项目推荐选 Hardhat 或 Foundry)

  • Foundry:高性能的 Rust 实现

  • etherscan API:链上数据获取

这些最佳实践的系统应用,能够从设计、编码、测试、审计到部署,全面保护智能合约的安全性。

最后更新于