0x71pp17/modern-solidity-patterns

GitHub: 0x71pp17/modern-solidity-patterns

面向 Solidity 0.8.x 和 EVM 的防御性智能合约编码参考,通过纵深防御模式、可编译示例和对抗性测试帮助开发者编写更安全的合约代码。

Stars: 0 | Forks: 0

# 现代 Solidity 模式 一份**防御性代码构建参考**,应用纵深防御技术,面向当前的 Solidity (0.8.x) 和当今的 EVM,从构建者的角度编写更安全的智能合约。这是基于实践审查,结合相关 EIP 和经过审计的库,随着时间推移整理出的一套个人技术合集。 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/0x71pp17/modern-solidity-patterns/actions/workflows/ci.yml) ![Solidity](https://img.shields.io/badge/Solidity-0.8.36-363636?logo=solidity) ![EVM](https://img.shields.io/badge/EVM-Osaka-blue) ![License](https://img.shields.io/badge/License-MIT-green) ## 适用人群 适用于在 EVM 上进行构建、希望了解*原因*而不仅仅是代码片段的开发者:每种模式都说明了它所防止的故障模式,展示了一个可编译的 ≥0.8.x 示例,并包含一段关于实践如何演变为当前方法的简短**历史说明**。(审计员可能会发现它作为判定何为*正确*的基准很有用,但本文主要是从构建者的角度编写的,而不是作为审计清单。)[`src/`](src/) 中的每个示例都能在针对 Osaka EVM (Fusaka) 的 `solc 0.8.36` 下编译通过。 ## 模式 共有十种模式已完整编写。每一页都说明了它所防止的故障模式,指出了应使用的经过审计的库,展示了来自 [`src/`](src/) 的可编译示例,并以关于当前形式如何演变而来的历史说明作为结尾。 | 模式 | 类别 | 防止问题 | |---|---|---| | [检查-生效-交互模式与重入锁](patterns/checks-effects-interactions.md) | 安全与访问控制 | 在状态写入前,回调在函数更新过程中重入 | | [状态机](patterns/state-machine.md) | 安全与访问控制 | 函数在不合理的生命周期阶段运行 | | [访问控制](patterns/access-control.md) | 安全与访问控制 | 单个被盗密钥控制一切,以及因地址输入错误而丢失所有权 | | [安全价值转移](patterns/safe-value-transfer.md) | 价值与代币处理 | 导致向合约钱包的支付失效(Bricked),以及非标准 ERC-20 上的静默失败 | | [ERC-4626 金库记账](patterns/erc4626-vault.md) | 价值与代币处理 | 首个存款者的通胀攻击,以及因舍入误差将价值泄漏给调用者 | | [UUPS 与命名空间存储](patterns/uups-upgradeability.md) | 可升级性 | 升级过程中的存储布局冲突 | | [价格预言机集成](patterns/price-oracle-staleness.md) | 外部数据与熵 | 在链上信任过时的或单一来源的价格 | | [可验证随机数](patterns/verifiable-randomness.md) | 外部数据与熵 | 调用者可以通过区块变量预测、暴力破解或操纵结果 | | [EIP-712 签名与重放保护](patterns/eip712-signatures.md) | 签名与账户 | 在多次调用、不同合约或不同链上重放链下授权 | | [存储打包](patterns/storage-packing.md) | Gas 与存储 | 为经常一起读写的值支付单独的存储槽费用 | ### 规划中 以下各项都已确定范围,存根页面包含一行意图说明;完整的文档正在编写中。 **安全与访问控制** [熔断器 (可暂停)](patterns/circuit-breaker.md) · [输入验证与自定义错误](patterns/input-validation-custom-errors.md) · [拉取支付 (提取)](patterns/pull-payment.md) · [特权操作时间锁](patterns/timelock-privileged-actions.md) · [抢跑与 MEV 抵抗](patterns/front-running-mev.md) · [Merkle 证明白名单](patterns/merkle-allowlist.md) **价值与代币处理** [Permit / 无 Gas 授权](patterns/permit-approvals.md) **可升级性** [最小代理克隆](patterns/minimal-clones.md) **签名与账户** [ERC-1271 智能账户签名](patterns/erc1271-smart-account-signatures.md) · [账户抽象 (4337 / 7702)](patterns/account-abstraction.md) · [元交易 (ERC-2771)](patterns/meta-transactions-erc2771.md) **Gas 与存储** [瞬态存储](patterns/transient-storage.md) · [未检查算术](patterns/unchecked-math.md) · [批处理 / Multicall](patterns/multicall-batching.md) ## 标准与安全 这里的每项技术都基于特定的 EIP/ERC。[**REFERENCES.md**](REFERENCES.md) 将每个标准映射到*从安全角度来看它管辖的内容*,即在针对其实施时至关重要的条款或故障模式,因为大多数实现错误都是由于代码未遵守规范性要求造成的。 ## 运行示例 这些示例是独立的(没有外部导入),因此它们可以用纯净的编译器进行编译。使用 [Foundry](https://book.getfoundry.sh/): ``` forge build ``` 或者直接使用 `solc`: ``` solc --evm-version osaka src/EtherBank.sol ``` ## 测试 测试套件依赖于 `forge-std`,这是代码库中唯一的外部依赖项: ``` forge install foundry-rs/forge-std forge test ``` 这些测试是刻意设计的**对抗性测试**:每一个测试都运行了该模式旨在防止的攻击,并断言其失败。一个只测试了正常路径的测试套件,在面对相同代码的未防御版本时同样会轻易通过,这证明不了任何问题。 以下是这在实践中意味着什么的两个例子: - `test/EtherBank.t.sol` 部署了一个活跃的重入攻击者,该攻击者从 `receive()` 中回调到 `withdraw()`,并断言其离开时只带走它自己的存款,没有多拿一分钱。 - `test/VirtualSharesVault.t.sol` 包含一个具有相同记账方式但减去了虚拟份额偏移量的 `NaiveVault` 对照组,对两者都运行了首个存款者捐赠攻击,并断言受害者在未受保护的金库中份额被舍入为**零**,而在加固后的金库中份额保持非零。 [`src/`](src/) 中的每个示例都有一个测试套件。测试覆盖率随文档同步更新:已完成模式的示例在提交时即经过测试。 ## 关于示例的说明 [`src/`](src/) 中的 Solidity 代码是一组**参考示例**。它们用尽可能少的代码行说明了一项技术:它们**未经审计**,不打算按原样部署,并刻意省略了实际部署所需的加固措施、事件、访问控制和边缘情况处理。每个示例都带有一个 `DEFENSIVE-PATTERN REFERENCE` 头文件予以说明。 每个完整页面的开头都**指出了你实际应该使用的经过审计的库**(如 OpenZeppelin 的 `ReentrancyGuardTransient`、`SafeERC20` / `Address`、`UUPSUpgradeable`、`EIP712`,以及 Chainlink 数据源)。某些示例刻意重新实现了这些库已经提供的功能,纯粹是为了让机制具有更好的可读性;自己重新实现安全原语本身就是一种反模式,因此这些文件是用来*阅读*的,而不是用来*部署*的。 ## 纵深防御不能替代审计 分层防御技术可以降低风险;它并不能证明代码是安全的。**使用本仓库中的任何代码、模式或技术,绝不能替代独立的安全审计。** 每个将要处理真实价值的代码构建都需要首先进行审计。 永远要审计,时刻要审计。 ## 许可证 MIT,详见 [LICENSE](LICENSE)。这是一个防御性参考代码库:此处的代码未经审计,绝不能替代独立审计。
标签:Solidity, 以太坊, 区块链安全, 智能合约, 防御性编程