本文阐述了每个以太坊开发者都需要了解的4大安全性原则,以及基本的权衡。
撰文: ConsenSys Diligence, 我们的区块链安全专家团队。
虽然区块链行业正在走向成熟,但智能合约的发展仍是一个相对较新的、有待成熟的领域。因此,随着新的 bug 和安全风险被发现,新的最佳实践被开发,你应该预计的是,智能合约的安全性格局在不断变化。学习和跟进最佳实践只是你作为一名智能合约开发者需要进行的安全性工作的开始。
智能合约编程需要一种不同于你所习惯的工程思维。出现故障的代价可能很高,更改可能很困难,这使得智能合约编程在某些方面更类似于硬件编程或金融服务编程,而不是 web 或移动应用开发。因此,仅仅防御已知的漏洞是不够的。相反,你需要学习一种新的开发哲学。
任何重要的合约都存在错误。因此,你的代码必须能够优雅地应对 bug 和漏洞。
·当出现问题时暂停合约 (“断路器”)
·对风险资金的数额进行管理 (速率限制、最大使用量等)
·为 bug 修复和改进提供有效的升级路径。
在完整的产品发布之前,捕获 bug 总是更好的。
·彻底地测试合约,且当新的攻击向量被发现时,增加对合约的测试。
·从测试网 alpha 版本发布的时候就开始提供 bug 赏金。
·通过几个阶段来发布,每个阶段增加使用量和测试。
复杂性会增加出现错误的可能性。
·确保合约逻辑很简单。
·对代码进行模块化,以保持合约和功能较小。
·尽可能地使用已经编写好的工具或代码 (比如,无需开发你自己的随机数生成器)。
·相比于性能,应尽可能地更加追求明确性。
·只对系统中需要去中心化的部分使用区块链。
追踪新的安全性开发。
·一旦发现任何新的 bug,请立即检查你的合约。
·尽可能地将任何工具或库升级到最新版本。
·采用有效的新安全技术。
虽然你的许多编程经验都将与以太坊编程有关,但仍有一些陷阱需要注意。
·需要特别小心外部合约调用,这可能会执行恶意代码和更改控制流。
·要知道你的公共函数是公开的,可能会以任何顺序被恶意调用。任何人也都可以查看智能合约中的隐私数据。
·请记住 gas 成本和区块 gas 上限。
·要知道区块链上的时间戳是不精确的:矿工可以在几秒钟内影响交易的执行时间。
·区块链中的随机性很重要,在区块链上生成随机数的大多数方法都是可以操纵的。
评估智能合约系统的结构和安全性时,需要考虑一些基本的权衡。对于任何智能合约系统的一般建议是,为这些基本的权衡找到合适的平衡。
从软件工程的角度来看,一个理想的智能合约系统应该是模块化的,重用代码而不是复制代码,且支持可升级的组件。从安全性倾向来说,一个理想智能合约系统可能会认同这种思维,特别是对于更加复杂的智能合约系统。
然而,也有一些重要的例外,其中安全性和软件工程最佳实践可能不一致。在这些情况中,通过确定以下这些合约系统维度来确定最优性能组合,从而获得适当的平衡:
·严格性 vs. 可升级性
·单块 vs. 模块化
·复制 vs. 重用
虽然许多资源 (包括本文) 强调可塑性特征 (如可销毁、可升级或可修改的模式),但在可塑性和安全性之间存在一个 基本的权衡 。
从定义上看,可塑性模式增加了复杂性和潜在的攻击面。当智能合约系统在某个预先定义的有限时间内执行非常有限的功能集时,比如一个没有治理的、在有限的时间框架内进行代币发售的合约系统,在这些情况下,合约的简单性比复杂性更为有效。
一个单块式独立合约保持所有的信息在本地可识别和可读。虽然少数单块式智能合约系统被高度重视,但对于数据和流的极端本地化存在争议,比如在优化代码审查效率的情况中。
与这里考虑的其他权衡一样,在简单的短期合约中,安全性最佳实践会偏离软件工程最佳实践,而在更加复杂的长久性合约系统中,则会趋向于软件工程最佳实践。
从软件工程的角度来看,智能合约系统希望在合理的时候使代码的重用最大化。有很多方法可以可靠地重用 Solidity 合约代码。使用 属于你的 、在之前被验证和部署的合约,是实现代码重用的最安全方式。
而在没有自有的、之前部署的合约的情况下,人们经常依赖代码复制。诸如 OpenZeppelin 的 Solidity 库等试图提供一些模式,使安全的代码可以在不复制的情况下被重用。所有合约安全分析必须包括任何重用的代码,这些代码在之前尚未建立一个与目标智能合约系统中的风险资金相称的信任水平。
在以太坊上搭建和发布应用程序无疑是让当今软件工程师最兴奋的前沿领域,但这需要持续的威胁建模 (threat modeling)、安全审计和事件响应计划。
Diligence 团队可以为你效劳,帮助你保持警惕,为你在部署过程中建立信心。
我们为期1天的审查将帮助你从一开始就将安全性构建到你的区块链代码中,从长远来看,你将节省时间和成本。
请马上与我们联系
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!