欧博平台怎么打赢www.aLLbet8.vip)是欧博集团的官方网站。欧博平台怎么打赢开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

问:我们常提到的智能合约破绽真的是现实中威胁最大、发生最频仍的平安破绽吗?

答:完全不是那样。例如“溢出”、“外部挪用”等常提到的智能合约平安破绽并不是最常发生,威胁最大的。

到底哪些平安威胁从发生频率和危害性上能称为Top10的呢?SharkTeam合约平安系列课程之【十大智能合约平安威胁】,第五课【详解合约升级破绽】。

一、什么是合约升级?

智能合约部署后默认是不能变的,一旦你确立了它们,就没有设施改变它们。每个智能合约都有一个唯一的地址,用户将生意发送到智能合约的地址,来执行存储在该合约中的代码。然则,在现实应用中,开发者通常由于营业升级或平安升级的需求需要通过手艺的手段来更新合约逻辑,因此合约升级的开发模式应运而生。常见的几种合约升级模式如下。

1.1继续存储模式

继续存储模式通过为署理合约和逻辑合约所需的状态变量提供严酷的存储顺序来解决状态碰撞问题,署理合约委托逻辑合约举行挪用。因此,只有署理合约的存储在使用。继续了公共存储合约的署理合约可以接见其父合约的所有状态变量,每个状态变量凭证其索引占有适当的内存位置。

初始化流程如下:

(1)部署Registry合约

(2)部署合约的初始版本 (v1),确保它继续了“可升级”合约

(3)将初始版本的地址注册到Registry

(4)请求Registry合约确立UpgradeabilityProxy实例

(5)挪用UpgradeabilityProxy来升级到合约的初始版本

升级流程如下:

(1)部署从初始版本继续的新版本的合约 (v2),以确保它保留署理的存储结构和合约初始版本中的存储结构

(2)将合约的新版本注册到Registry

(3)挪用UpgradeabilityProxy实例以升级到新的注册版本

虽然继续存储模式解决了可升级合约的存储碰撞问题,但这种方式也有自己的瑕玷。由于所有先前声明的状态变量都需要被复制到新部署的版本中,因此升级变得昂贵。其中一些可能没有被使用,最终会不需要地占用内存。由于公共存储模式,逻辑合约变得与署理合约慎密耦合。因此,不能能将这些逻辑合约用于不继续公共存储合约的任何其他署理。

1.2非结构化存储模式

在这种模式中,署理合约往往是具有一些基本函数的最小化合约,大部门的营业逻辑都在逻辑合约内里完成,新的逻辑合约保持了最新的实现合约中存在的状态变量的顺序。署理合约一样平常需要所有者和实现变量来维持所有权和版本控制,署理合约将这些属性指定为常量,它们被设置在合约的字节码内。OpenZepplin在其可升级的合约服务中使用了非结构化的存储模式。

初始化流程如下:

(1)部署OwnedUpgradeabilityProxy实例

(2)部署合约的初始版本 (v1)

(3)挪用OwnedUpgradeabilityProxy实例来升级到初始版本的地址

(4)若是逻辑合约依赖它的组织函数来设置一些初始状态,那么在它与署理链接后,就必须重新举行设置,由于署理的存储不知道这些值。OwnedUpgradeabilityProxy有一个函数upgradeToAndCall,专门用来挪用逻辑合约上的一些函数,在署理升级到它之后重新举行设置

升级流程如下:

(1)部署新版本的合约 (v2),确保它继续以前版本中使用的状态变量结构

(2)挪用OwnedUpgradeabilityProxy实例来升级到新合约版本的地址

1.3永远存储模式

这种模式的目的是只管削减存储复制的要求。在这种模式中,一个单独的合约被维护为永远存储合约。因此,所有的逻辑版本都行使这个永远存储合约来知足其存储需求。因此,存储复制的要求被从升级模式中移除,这种方式大大降低了升级成本。

初始化流程如下:

(1)部署一个EternalStorageProxy实例

(2)部署一个初始版本的合约(v1)

(3)挪用EternalStorageProxy实例来升级到初始版本的地址

(4)若是逻辑合约依赖其组织函数来设置一些初始状态,那就必须在其链接到署理后重新举行,由于署理的存储不知道这些值。EternalStorageProxy有一个函数upgradeToAndCall,专门用来挪用逻辑合约上的一些函数,在署理升级到它之后重新举行设置

升级流程如下:

(1)部署一个新版本的合约(v2),确保它拥有永远存储结构

(2)挪用EternalStorageProxy实例来升级到新版本

1.4 Diamond 模式

Solidity 合约的最大限制为 24KB。因此,每个合约的巨细永远不能跨越 24KB。Diamond 模式使开发职员能够编写没有巨细限制的智能合约。此模式还支持升级,而无需重新部署现有功效,详细Diamond 尺度可见EIP 2535。

Diamond 是一个合约,它将挪用委托给称为面的实现合约。Diamond 合约实现了一个 diamondCut 函数,它提供了添加/替换/删除的能力。除了 diamondCut 函数之外,还实现了一组 loupe 函数。这些函数显示了关于所实现的Diamond 的信息。Diamond 合约维护了一个selectorToFacet的映射,这基本上是一个函数署名到实现合约地址的映射。当用户挪用一个函数时,Diamond 署理的回退函数使用函数署名来寻找这个映射中的实现地址。在找到函数署名的地址后,回退函数只是将挪用委托给实现合约,并将响应返回给用户。

Diamond 署理依赖的是一种存储模式。该署理被一些被称为面的实现合约所共享。理想情形下,每个切面都有自己的存储。然而,凭证实行要求,面可以与其他面共享存储。DiamondStorage和AppStorage是一些盛行的存储模式,划分用于隔离和共享存储。

Diamond 模式为确立模块化的智能合约应用程序提供了一种精练的方式,没有任何最大尺寸限制。因此,它似乎是那些希望在未来扩大规模的大型智能合约应用程序的完善选择。

1.5 create2

create操作码用于在以太坊区块链上部署合约。合约地址是通过散列部署者的地址和该地址的nonce来天生的。Nonce是一个标量值,即是从部署者的地址发送的生意数目。同样,在合约账户的情形下,nonce是该账户确立合约的数目。nonce有助于保持生意的顺序(来自一个地址的低nonce生意会先被开采),并防止重入攻击。nonce是一个递增的数字,防止create操作码发生重复的地址。只要在当前和下一个nonce之间没有新的生意发生,就有可能通过简朴散列下一个nonce和地址来知道下一个合约的地址。

create2操作码被添加到以太坊虚拟机中,作为君士坦丁堡硬分叉的一部门,这个操作码也被用来部署智能合约。create2使用一些用户控制的输入来推导出智能合约的地址。换句话说,这个操作码提供了一种方式,在将智能合约部署到区块链之前盘算其地址。这个操作码不是对部署者的地址和nonce举行散列,而是对部署者的地址、salt(由部署者提供的32字节的字符串)和合约的字节码的哈希举行散列。由于这个操作码的所有参数都由用户控制,create2提供了一种预先确定合约地址的方式。这个方式在推导出优化gas的合约地址和实现像状态通道这样的扩展解决方案时异常有用。在可升级性方面,create2提供了确立可变合约(metamorphic contract)的能力,这些合约可以用新的字节码重新部署到统一地址。

EVM包罗一个selfdestruct 操作码,智能合约可以通过这个操作码来删除。为了在原始地址上部署一个新的字节码,该地址必须是自由的,由于智能合约是不能改变的。有几种方式可以将新的字节码部署到原始地址上,一个低效的方式是找到salt的参数,与新的字节码相连系,天生原始地址,寻找准确的salt参数的盘算可以在链下完成。然而,这并不是一个很好的方式。另一个选择是部署一个可变合约。如上所述,可变合约可以使用差其余字节码重新部署到原始地址。

确立一个优越的升级模式,需要一个可变合约工厂。这个可变合约工厂的目的是通过改变实在现而不改变其地址来促进升级。在部署合约时,对应的部署函数使用create2预先盘算可变合约的地址,实现合约是使用传统的create操作码部署的。这个操作码使用地址和nonce来天生地址,并将合约部署到该地址。要求实现地址不能为零。否则,实现合约没有被准确部署,函数必须返回。部署完实现合约后,工厂状态被更新来存储当前的实现合约。

值得注重的是,实现合约必须是自毁的,这也会使可变合约自毁。在重新部署可变合约之前,要确保可变合约使用selfdestruct操作码举行自我销毁。由于create2操作码的存在,可变合约的地址总是提前知道的。此外,由于它能够改变实在现,可变合约每次都可以用差其余实现重新部署。

使用create2是有优势的,但它也有自己的风险。最主要的风险是,每次合约被重新部署时,其存储都市被抹去。另外,带有selfdestruct操作码的实现合约可能不是一个可靠的资金存储方式。因此,在接纳这种智能合约升级模式之前,开发者必须郑重行事。

二、攻击事宜剖析

2.1 Uranium Finance

2021年4月28日,币安智能链上区块链项目 Uranium Finance在流动性迁徙历程中被攻击,涉及资金为 5000 万美元。攻击合约地址:0x2b528a28451e9853F51616f3B0f6D82Af8bEA6Ae。

我们从攻击合约中找到的项目合约地址并举行了攻击原理剖析,攻击流程如下:

(1)首先查看攻击合约的代码发现,这个合约的源码没有公然,通过反编译查看其源码

,

联博统计

,

足球博彩平台www.hg108.vip)是一个开放皇冠即时比分、代理最新登录线路、会员最新登录线路、皇冠代理APP下载、皇冠会员APP下载、皇冠线路APP下载、皇冠电脑版下载、皇冠手机版下载的皇冠新现金网平台。足球博彩平台上登录线路最新、新2皇冠网址更新最快,足球博彩平台开放皇冠会员注册、皇冠代理开户等业务。

,

www.u-healer.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。

,

(2)通过浏览器查看最早的攻击生意

0x5a504fe72ef7fc76dfeb4d979e533af4e23fe37e90b5516186d5787893c37991,可获得攻击者挪用的合约方式对应的署名为52f18fc3

(3)从反编译代码中寻找这个编码后的合约方式,可以找到这个合约攻击的项目方合约地址,也就是 Uranium 项目所在的地址:0xa943ea143cd7e79806d670f4a7cf08f8922a454f

(4)通过剖析,Uranium 项目合约中的破绽泛起在 UraniumPair.sol 合约中的 swap 函数中,这个破绽会导致任何人可以随意的转出合约中的数字资产,而只需要支出一点点的价值。可以看到 swap 中,最后是一个10的8次方数和一个10的6次方数的对照,这是一个险些是恒等的判断,这就意味着只要根据一定的套路不停的执行 swap 函数,就可以清空这个合约中所有的数字资产。

我们看到UniswapV2Pair.sol的合约中的写法是相同的,然则它是两个10的6次方数字的对照。

问题剖析:造成这次事宜的缘故原由应该是项目方更新升级这个合约的时刻,遗忘了将后面的1000的2次方改为10000的二次方。

2.2 Audius

2022年7月24日,黑客从音乐流媒体协议Audius转移了1800万个AUDIO代币。攻击者提议了两次攻击,其中第一次攻击失败,第二次攻击乐成。我们主要来剖析第二次攻击,攻击者在确立了攻击合约后,通过攻击合约提议了攻击,包罗4笔生意:

(1)txHash1: 0xfefd829e246002a8fd061eede7501bccb6e244a9aacea0ebceaecef5d877a984

(2)txHash2: 0x3c09c6306b67737227edc24c663462d870e7c2bf39e9ab66877a980c900dd5d5

(3)txHash3: 0x4227bca8ed4b8915c7eec0e14ad3748a88c4371d4176e716e8007249b9980dc9

(4)txHash4: 0x82fc23992c7433fffad0e28a1b8d11211dc4377de83e88088d79f24f4a3f28b3

在txHash1中,主要生意流程如下:

(1)通过Audius的署理合约对Governance合约举行初始化

(2)评估/执行84号提案,即第一次攻击提交的提案,评估为QuorumNotMet,缘故原由是没有投票

(3)查询Governance署理合约的AUDIO代币余额

(4)提交85号提案,与84号提案相同。该提案的功效就是将Governance署理合约中的AUDIO转移到攻击合约,数目不能跨越Governance署理合约的AUDIO余额

(5)通过署理合约对Staking合约举行初始化,将治理代币地址以及署理合约地址都设置为攻击合约

(6)通过署理合约对DelegateManagerV2合约举行初始化,将治理代币地址以及署理治理地址都设置为攻击合约

(7)通过署理合约将DelegateManagerV2合约中的服务提供者工厂合约为攻击合约

(8)通过署理合约将质押的署理权授权给攻击合约,授权的代币数目为1e31

通过以上步骤,攻击者改动并获取了治理系统的最高权限。

在txHash2中,攻击者在提交了提案85之后的3个区块内举行了投票。

在txHash3中,攻击者在3个区块的投票期以及1个区块的守候期之后对提案85举行了评估/执行。

在txHash4中,执行提案85,将18,56万枚AUDIO转移到攻击合约,攻击合约收到1800万枚AUDIO后,将其兑换为704 枚ETH。

最后,攻击者将兑换的ETH存入到了Tornash平台。

问题剖析:攻击者之以是能够攻击乐成,基本缘故原由在于通过署理合约多次挪用初始化函数,而初始化函数本应该只能挪用一次的。以Governance合约中的初始化函数为例,其代码如下:

这里使用了Openzeppelin内里的初始化器initializer,initializer没有起到任何作用,缘故原由在于署理挪用。

Openzeppelin内里的初始化器initializer中界说的两个bool类型的状态变量initialized和intializing划分占用了存储插槽slot0中的前16个字节。第1个8字节为initialized,第2个8字节为initializing。

由于署理合约自己界说了一个地址类型的状态变量proxyAdmin,其值为0x80ab62886eacfebca74511823d4699eb88fd097e,同样占用了存储插槽slot0,第1个8字节为0,第2个8字节为0x80ab6288,第3个8字节为0x6eacfebca7451182,第4个8字节为0x3d4699eb88fd097e。于是,实现合约中的initialized和intializing与署理合约中的proxyAdmin同时占用了存储插槽slot0,从而引起了存储冲突。

插槽0中的数据漫衍如下:

初始化函数执行到initializer时,从存储插槽slot0的第1个8字节读取initialized,其值为0,即false;从存储插槽slot0的第2个8字节读取initializing,其值为0x80ab6288 > 0,即true。

三、预防措施

我们领会合约升级的几种模式以及回首了相关攻击事宜后,作为开发职员应该接纳哪些适当的措施来防止相关攻击?

(1)可升级智能合约的真正问题是从合约中迁徙存储值,构建可升级智能合约的更好方式是区分差异合约中的存储和逻辑,将合约数据保留在一个仅接受来自逻辑合约挪用的合约中,不停改变逻辑合约的逻辑

(2)在挪用 delegatecall 之前检查目的合约是否存在,Solidity 不会替我们执行此检查,忽略检查可能会导致意外行为和平安问题

(3)仔细思量变量声明的顺序,由于会泛起变量打包存储统一个插槽、影响gas成本、内存结构、delegate挪用效果等问题

(4)仔细思量合约初始化问题,状态变量可能在组织时刻泛起未初始化,应当在初始化时代缓解潜在的竞争条件

(5)思量署理模式中的函数名称,阻止函数名称冲突

(6)项目上线前,需联系专业的第三方专业审计团队举行审计

查看更多 平心在线声明:该文看法仅代表作者自己,与本平台无关。转载请注明:欧博平台怎么打赢:以太坊猜单双(www.326681.com)_一文详解十大智能合约平安威胁之合约升级破绽
发布评论

分享到:

平心在线

平心在线官网版权所有

足球分析专家:Vụ sập tường nhà xưởng khiến 5 người chết: Nạn nhân kể lại giây phút kinh hoàng
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。