智能合约开发的最佳实践 - 强烈推荐

译者注:这是距今为止行业内最全面的智能合约开发指南,强烈推荐。

软件开发的历史已有数十年之久。我们受益于半个世纪以来积累的最佳实践,设计模式和智慧。

相反,智能合约开发才刚刚开始。2015推出的以太坊和 Solidity 仅有几年的时间。

加密空间是一个不断发展的未知领域。没有确定的工具堆栈来构建去中心化应用。对于智能合约,没有诸如设计模式代码整洁之道之类的开发人员手册。有关工具和最佳实践的信息遍布各处。

你正在阅读我这份希望它已经存在的指南。总结了我从以太坊生态系统中编写智能合约,构建去中心化应用程序和开源项目中学到的经验教训。

💡这本手册是线上的文件。如果你有任何反馈或建议,请随时发表评论或直接给我发送电子邮件

这是给谁的

本手册适用于:

  • 刚开始使用智能合约的开发人员,以及
  • 经验丰富的Solidity开发人员希望将他们的工作提升到一个新的水平。

但是,这并不意味着要介绍Solidity语言。

那就直接开始正文吧,以下我的一些建议:

使用开发环境

使用Truffle之类的开发环境(或者,Embark, Builder dapp.tools)等开发环境可以快速高效地工作。

使用开发环境可以加快经常重复执行的任务,例如:

  • 编译合约
  • 部署合约
  • 调试合约
  • 升级合约
  • 运行单元测试

例如,Truffle 提供以下有用的命令:

  • compile:将Solidity合约编译为其ABI和字节码格式。
  • console:实例化一个交互式JS控制台,你可以在其中调用web3合约并与之交互。
  • test:运行合约的单元测试套件。
  • migrate:将你的合约部署到网络。

Truffle支持提供其他功能的插件。例如,truffle-security提供智能合约安全性验证。 truffle-plugin-verify在区块链浏览器上发布你的合约。你还可以创建自定义插件

同样,Builder 也有越来越多的插件支持给以太坊智能合约开发人员使用。

无论使用哪种开发环境,选择一套好的工具都是必须。

本地开发

使用Ganache(或Ganache CLI)运行本地区块链进行开发,以“加快迭代周期”。

在主网上,以太坊交易得付费,可能需要数分钟才确认。使用本地链跳过所有这些等待。在本地运行合约交易免费且即时。

Ganache带有一个内置的区块浏览器,可显示你解码后的交易、合约和事件。且本地环境是可配置,以满足你的测试需求。

且设置简便快捷。 在这里下载.

使用静态分析工具

静态分析或“linting”通过运行程序分析代码中的编程错误。在智能合约开发中,这对于捕获编译器可能错过的“代码风格不一致”和“易受攻击的代码”很有用。

1. Linters

使用solhintEthlint 分析代码,Solidity的Linter与其他语言(例如JSLint)的linter相似。它们提供安全性和代码风格指南验证。

2.安全性分析

安全分析工具识别智能合约漏洞,这些工具运行一组漏洞检测器,并打印出发现的所有问题的摘要。开发人员可以在整个实现阶段使用此信息来查找和解决漏洞。

可以选择:Mythril·Slither·Manticore·MythX·Echidna·Oyente

额外:使用Pre-Commit Hook

通过使用husky设置Git Hook,使你的开发人员体验变得无缝,Pre-Commit Hook可让你在每次提交之前运行linters。例如:

// package.json
{
  "scripts": {
    "lint": "./node_modules/.bin/solhint -f table contracts/**/*.sol",
  },
  "husky": {
    "hooks": {
      "pre-commit": "npm run lint"
    }
  },
}

上面的代码片段在每次提交之前运行一个预定义的lint 任务,如果代码中存在突出的样式或安全性违规,则会失败。此设置使你团队中的开发人员能够在迭代中与linter一起使用。

了解安全漏洞

编写没有错误的软件非常困难。防御性编程技术只能走这么远。幸运的是,你可以通过部署新代码来修复错误。传统软件开发中的补丁程序频繁且直接。

但是,智能合约是“不可变更的”。有时无法升级已生效的合约。在这方面,智能合约比软件开发更接近于虚拟硬件开发。

更糟糕的是,合约错误会导致巨大的财务损失。 DAO Hack损失了超过1150万以太币(在被黑客入侵时为7000万美元,现在超过了20亿美元),第二名Parity Hack损失了2亿美元的用户资金,现在DeFi领域$ 百亿市场规模一旦出错,损失将非常惨重。

智能合约开发需要与Web开发完全不同的心态。 “快速行动并打破常规”在这里不适用。你需要预先投入大量资源来编写无错误的软件。作为开发人员,你必须:

  1. 熟悉Solidity 安全性 漏洞,和

  2. 扎实理解设计模式,例如:付款提取与推送方式 以及遵循 ”检查“ - "更改" - ”交互“等。

  3. 使用防御性编程技术:静态分析和单元测试。

  4. 审计你的代码。

以下各节将详细说明要点(3)和(4)。

💡初学者提示:你可以使用Ethernauts以交互方式练习Solidity安全性。

编写单元测试

借助全面的测试套件,尽早发现错误和意外行为。不同的场景测试协议可帮助你识别极端情况。

Truffle使用Mocha测试框架和Chai进行断言。你可以使用Javascript针对合约的包装器编写单元测试,就像前端DApp如何调用你的合约。

从Truffle v5.1.0开始,你可以中断测试以对测试流程进行debug并启动调试器,从而允许你设置断点,检查Solidity变量等。

Truffle缺少一些对于测试智能合约必不可少的功能。安装openzeppelin-test-helpers可让你访问许多重要的实用工具以验证合约状态,例如匹配合约事件向前移动时间

译者注: 调试智能合约还有一个选择是使用 Build EVM 及 console.log, 它支持在Solidity源码中打印日志查看变量。

或者,如果你更喜欢使用其他测试运行器,OpenZeppelin测试环境提供了与工具无关的选项。

衡量测试覆盖率

编写测试是不够的。你的测试套件必须可靠地捕获回归。测试覆盖率衡量测试的有效性。

具有较高测试覆盖率的程序在测试期间将执行更多代码。这意味着与覆盖率较低的代码相比,它更容易发现未被检测到的错误。

你可以使用solidity-coverage收集Solidity代码覆盖率

配置持续集成

拥有测试套件后,请“尽可能频繁地”运行它。有几种方法可以实现此目的:

  1. 像我们之前介绍的,设置Git Hook,或者
  2. 设置一个CI(持续集成:Continuous integration) 管道,在每次Git推送后执行测试。

如果你要使用现成的CI,请查看Truffle团队super blocks.,它们为连续进行智能合约测试提供了托管环境。

托管CI会定期运行你的单元测试,以最大程度地放心。你还可以监视已部署合约的交易,状态和事件。

安全审计合约

安全审计可帮助你“发现”防御性编程技术(linting,单元测试,设计模式)所遗漏的未知问题。

在这个探索阶段,你需要尽最大努力破坏合约, 如:提供意外的输入,以不同的角色调用函数等。

没有什么可以取代人工安全审计,尤其是当黑客入侵的是整个DeFi生态系统时。

⚠️在进行下一阶段之前,你的代码应该已经通过了前面部分提到的静态分析。

聘请外部审计师

聘请(昂贵的)安全审计员来升级以太坊中的主要协议,他们深入研究其代码以发现潜在的安全漏洞。这些审计员结合使用专有和开源静态分析工具,例如:

  • Manticore - 一个模拟器,能够模拟针对EVM字节码的复杂的多合约和多交易攻击。
  • Ethersplay - 一种图形化EVM反汇编程序,能够进行方法还原,动态跳转计算,源代码匹配和二进制比较。
  • Slither - 静态分析器,它检测常见错误,例如重入错误,构造函数,方法访问等。
  • Echidna - 面向EVM字节码的下一代智能模糊器。

审计员将帮助识别协议中任何设计和架构级别的风险,并知道你关于常见的智能合约漏洞。

在该过程的最后,你将获得一份报告,其中总结了审计师的发现...

剩余50%的内容订阅专栏后可查看

0 条评论

请先 登录 后评论
Tiny熊
Tiny熊

布道者

139 篇文章, 19738 学分