热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

借助Solidity来识别智能合约的调配模式

作者|AlbertoCuestaCaada译者|火火酱,责编|李雪敬头图|CSDN下载自视觉中国由于所有已部署合约都有24KB的硬限制,所以除了少数极其

作者 | Alberto Cuesta Cañada

译者 | 火火酱,责编 | 李雪敬

头图 | CSDN 下载自视觉中国

由于所有已部署合约都有 24KB 的硬限制,所以除了少数极其简单的应用程序外,其他所有的 Ethereum 应用都是由多个智能合约组成的。

如何才能确保各智能合约间的安全协作呢?

在将代码分解为多个可操作的合约后,我们便会发现有的合约中的函数需要通过另一个合约才能进行调用。

例如,在 Uniswap v2 中,只有合约工厂(contract factory)可以对 Uniswap Pair 进行初始化。

(Uniswap v2:https://github.com/Uniswap/uniswap-v2-core/tree/master/contracts)

对于 Uniswap 团队来说,只需要稍微检查一下就可以解决的问题对于很多其他项目来说,却需要从头开始重新编写调配解决方案。

在了解问题和开发模式的过程中,我们深入理解了如何借助多个智能合约来构建应用程序,从而使 Yield 更加健壮且安全。

(Yield:http://yield.is/)

在本文中,我们将借助几个知名项目中的实例来深入分析智能合约的调配方式。希望大家在读完本文之后可以对照自己项目的需求,选择出最适合自己的方法。

背景知识

前文提到,我们首先要把项目分解成多个智能合约,这是出于技术和精神两个层面的限制要求。

技术限制源于2016年11月发生的一项改变。当时,Ethereum 主网(包括EIP-170)实施了 Spurious Dragon 硬分叉。此举将已部署的智能合约的大小限制在24576字节以内。

(Spurious Dragon硬分叉:https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/)

(EIP-170:https://github.com/ethereum/EIPs/blob/master/EIPS/eip-170.md)

在没有此项限制时,攻击者可以在部署智能合约期间进行无限次的计算。此举虽然不会对存储在区块链中的数据产生任何影响,但却是一种针对 Ethereum 节点的拒绝服务(Denial-Of-Service)攻击。

由于当时的区块 gas 限制无法支持这种规模的智能合约,所以这项改变当时并没有受到重视:

“该解决方案为储存在区块链中的对象大小设置了最高上限,并使其略高于当前gas上限值(在最坏的情况下,可以使用470万gas,23200字节来创建合约)”

在 DeFi 大爆炸之前,我们为 Yield 编写了2000行智能合约代码,部署后的代码加起来接近 100KB,审核员完全没有觉得项目过于复杂。

但我们仍需把解决方案分解为多个合约。

复杂性和面向对象程序设计

将区块链应用分解为多个智能合约的第二个原因与技术限制无关,而是与“人”的精神限制有关。

在特定的时间内,我们大脑中能储存的信息量是一定的。相比于处理单一且涉及面广的大问题,人们在处理多个相互间存在关联的小问题时表现会更好。

实际上,Object-Oriented Programming(面向对象程序设计)可以提高软件的复杂性。通过定义代表某种概念的“对象”,并将变量和函数看作该对象的属性,开发人员能够在心里更好地描画和理解需要解决的问题。

Solidity 在合约层面使用了面向对象的编程技术。我们可以将合约看作是一个具有变量和函数的“对象”,在脑海中将复杂的区块链应用程序想象成多个合约的集合,每个合约代表一个单独的实体。

例如,在 MakerDAO 中,每种加密货币都有单独的合约,此外还有记录债务的合约、表示债务和外界间网关的单独合约等等。我们不可能将所有内容都编写在同一个合约中——即使可能,也会异常困难。

把一整个大问题分解成具有内在联系的多个小问题可以帮助我们更快地找出解决方案。

实现

接下来,让我们一起来研究一下 Uniswap、MakerDAO 以及 Yield 的实现方式。

从简单的例子开始——Uniswap 和 Ownable.sol

我很喜欢 Uniswap v2,因为它非常简单。开发人员用410行智能合约代码就成功建立了去中心化交易所。仅部署了两类合约:工厂和不限数量的配对交换合约。

其工厂合约的设计方式决定了其配对交易合约的部署需要经过两个步骤。首先部署合约,然后用将要进行交易的两个代币对其进行初始化。

由于需要确保只有创建配对交易合约的工厂才能对合约进行初始化,所以他们重新实施了Ownable 模式。

此举取得的效果还不错,如果你也遇到了同样的问题,可以借鉴这个方法。如果你知道自己的合约只需要给另一个合约开通访问特权的话,可以使用 Ownable.sol。甚至都用不到 Uniswap 这种工厂。你可以在一个用户中部署两个合同(Boss和Minion,Minion继承于Ownable.sol),然后执行 minion.transferOwnership(address(boss))。

更为完善的例子——Yield

Yield 的解决方案就没有 Uniswap v2 那么简单了。其核心由五个合约组成,并且特权访问关系并不是一一对应的。部分合约具备的限制功能可以帮助我们访问其他核心合约。

因此,我们只需扩展 Ownable.sol 以生成两个访问层,其中一层有多个成员:

合约所有者可以向特权列表中添加地址(authorized)。继承合约(Inheriting contracts)可以包含 onlyOrchestrated 修改器以限制对授权地址的访问。

每个地址都会与一个函数签名共同注册,从而收紧对函数的访问权限,增强安全性。

(函数签名:https://www.4byte.directory/)

由于我们会在期间部署 orchestrate 合约,所以没有取消访问权限的函数,owner 会通过调用所有合约上的 transferOwnership(adress(0)) 来放弃其特权访问。

我们自己的平台代币 yDai,将从 Orchestrated 继承并限制 mint 在 owner 放弃其特权之前建立的特定合约:

这种模式相对容易实现和调试,并且可以实现我们合约中的函数。

极具迷惑性的例子——MakerDAO

大家都非常讨厌 MakerDAO 中各种难以理解的术语。但在搞清楚 Yield 的调配模式后,我才发现它们二者的实现方式几乎是完全相同的。

  

1.合约部署者是 wards 的原成员。

2.wards 可以 rely 其他人(usr),并使其同样成为 watds。

3.可以限制函数(auth),只有 wards 可以执行函数。

例如,MakerDAO 的 Vat.sol 合约中的 fold 函数可被用于更新利率累加器,并且只能被其集合中的另一函数调用(Jug.sol合约,drip函数)。如果我们观察一下该函数的话,便会发现用于调配的 auth 修改器,

从某种程度上来说,auth 和其他调配实现是对 private 和 internal 函数概念的扩展,仅适用于在合约间进行访问控制。

MakerDAO 与我们项目的实现方式非常类似。

1.合约部署者是 wards 原成员。在 Yield 中,即 owner。

2. wards可以 rely 其他人并使其成为 wards。在 Yield 中,只有 owner 可以 orchestrate 其他地址并 authorized。

3.函数受限制(auth),因此只有 wards 可以执行受限函数。在 Yield 中,我们提到 onlyOrchestrated 地址可以调用标记函数。进一步限制对函数的访问。

除了在Yield中使用了两个访问层(owner和authorized)以及函数限制以外,二者的实现方式是一样的。可见,合约调配是一种一经实现即可重复使用的常见模式。

从审核员和用户的角度出发,我们还开发了一个收集区块链事件,并展现合约所有权和调配图的脚本(可以在上线时通过我们的网站获取)。

总结

智能合同的调配是一个在很多项目中反复出现的问题,在遇到此类问题,大家往往都会从零开始进行调配。但其实此类问题的解决方案都是十分类似的。

我们可以遵循以上标准来实现安全有效的调配,希望大家可以深入理解文中的示例原理,并形成适合自己的解决方案。

推荐阅读

  • 总计2171个BTC被盗,这个钱包漏洞的受害者越来越多

  • 5个入门网站教你识别去中心化项目

  • 观点 | 勿畏魅影:比特币不需要持续增发

  • 多模、AI 齐上阵,Deepfake 换脸术克星驾到!

  • 35 岁一刀切?任正非:华为没有年龄限制,如只看年龄自己早被淘汰



推荐阅读
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Linux系统中正则表达式的基础知识,包括正则表达式的简介、字符分类、普通字符和元字符的区别,以及在学习过程中需要注意的事项。同时提醒读者要注意正则表达式与通配符的区别,并给出了使用正则表达式时的一些建议。本文适合初学者了解Linux系统中的正则表达式,并提供了学习的参考资料。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 开源Keras Faster RCNN模型介绍及代码结构解析
    本文介绍了开源Keras Faster RCNN模型的环境需求和代码结构,包括FasterRCNN源码解析、RPN与classifier定义、data_generators.py文件的功能以及损失计算。同时提供了该模型的开源地址和安装所需的库。 ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了源码分析--ConcurrentHashMap与HashTable(JDK1.8)相关的知识,希望对你有一定的参考价值。  Concu ... [详细]
  • Python15行代码实现免费发送手机短信,推送消息「建议收藏」
    Python15行代码实现免费发 ... [详细]
  • https:github.comdarcyclarkeFront-end-Developer-Interview-QuestionstreemasterChinese#refere ... [详细]
  • 第五章:集合01
    第三章:集合01一:集合的框架结构图1.集合和数组的区别:2.Collection集合的方法:publicclassCol ... [详细]
author-avatar
爱在逃离
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有