智能合约安全准则
solidity智能合约安全性
中级遵循这些高级建议,构建更安全的智能合约。
设计准则
编写代码之前,务必先讨论行智能合约的设计。
文档和规范
文档可以在不同级别编写,在执行合约时应进行更新:
- 系统的简要英文描述,描述合约的行为和所使用的代码库
- 数据模型和架构图,包括合约的交互概述图和系统的状态转换图。 可以使用Slither打印机(opens in a new tab)生成相关图示。
- 完整的代码文档, 可以为Solidity使用Natspec格式(opens in a new tab)。
链上计算与链下计算
- 保持尽可能多的链下代码。 保持链上代码层的最小化。 用链下代码的方式对数据进行预处理,使链上验证变得简单。 是否需要已排序列表? 在链下对列表进行排序,然后在链上只检查其顺序。
升级
我们在我们的博客文章(opens in a new tab)中讨论了不同的升级解决方案。 在编写任何代码之前,请慎重选择是否支持可升级性。 该决定将影响你如何构建你的代码。 一般来说,我们建议:
- 优先考虑合约迁移(opens in a new tab)而不是可升级性。迁移系统具有许多与可升级系统相同的优点,但没有其缺点。
- 使用数据分离模式而不是delegatecallproxy模式。如果你的项目有明确的抽象分离,则使用数据分离的可升级性只需要进行一些调整。 delegatecallproxy需要EVM专业知识,并且非常容易出错。
- 在部署前记录迁移/升级程序。如果你不得不在没有任何指导的情况下在压力下做出反应,你就会犯错。 提前写好要遵循的程序。 其中应包括:
- 启动新的智能合约的调用
- 密钥存放在哪里以及如何获取它们
- 如何检查部署! 开发和测试部署后的脚本。
实施指南
力求简洁。 尽可能使用最简单的解决方案来实现你的目的。 所有的团队成员都应当能够理解解决方案。
功能组成
使用便于检查的代码库架构, 避免选择不利于正确性验证的架构。
- 通过多个合约或将相似的功能分到一组(例如,身份验证、算术等)来拆分你的系统逻辑。
- 编写小的函数,并且目的明确。这将便于审查并允许对单个组件进行测试。
继承
- 使继承易于管理。继承应用于划分逻辑,但是,你的项目应以最小化继承树的深度和宽度为目标。
- 使用Slother的inheritance printer(opens in a new tab)检查合约层级结构。inheritance printer可帮助你审查层级结构的大小。
事件
- 记录所有关键操作。事件有助于在开发过程中调试合约,并在部署后对其进行监控。
规避已知漏洞
- 了解最常见的安全问题。有大量的用于常见问题的网络资源,例如Ethernaut CTF(opens in a new tab)、Capture the Ether(opens in a new tab)或Not so smart contracts(opens in a new tab)。
- 了解Solidity文档(opens in a new tab)中的警告部分, 警告部分将通知你该语言的非明显行为。
依赖关系
- 使用经过充分测试的库。从经过充分测试的库中导入代码将降低编写错误代码的可能性。 如果你打算编写一个ERC20合约,请使用OpenZepelin(opens in a new tab)。
- 使用依赖关系管理器,不要直接复制粘贴代码。 如果依赖于外部来源,请保持与原始来源的的同步。
测试和验证
- 编写详尽的单元测试。全面的测试套件对于构建高质量的软件至关重要。
- 编写Slither(opens in a new tab)、Echidna(opens in a new tab)和Manticore(opens in a new tab)自定义检查和属性。自动化工具将帮助确保你的合约安全。 查看本指南的其余部分,了解如何编写高效的检查和属性。
- 使用crytic.io(opens in a new tab)。Crytic与Github集成,提供对私有Slither探测器的访问,并从Echidna运行自定义属性检查。
Solidity
- 使用Solidity 0.5,而不是0.4和0.6。在我们看来,相较于0.4,Solidity 0.5更加安全,具有更好的内部实践。 Solidity 0.6对于发布级产品而言过于不稳定,还需要时间才能趋于成熟。
- 使用稳定版本进行编译;使用最新版本进行警告检查。 保证代码中不存在最新版本编译器报告的问题。 然而,Solidity的发布周期很快,编译器中存在错误,所以我们不推荐最新版本进行部署(请参阅Slither的solc版本建议(opens in a new tab))。
- 不要使用内联汇编。使用汇编需要EVM专业知识。 如果对黄皮书没有很好的理解,请不要写EVM代码。
部署准则
合约开发和部署完成后:
- 监测合约。关注日志,在合约或钱包发生异常时随时做出反应。
- 将联系信息添加到blockchain-security-contacts(opens in a new tab)。如果发现安全缺陷,此列表可以帮助第三方与你联系。
- 保护特权用户的钱包。 如果使用硬件钱包存储密钥,请按照最佳实践(opens in a new tab)进行操作。
- 制定事故响应计划。 以合约可能发生错误为前提进行考量。 即使合约本身没有错误,攻击者也可能有机会控制合约拥有者的密钥。
p
上次修改时间: @pettinarip(opens in a new tab), 2023年12月8日