月亮链 月亮链
Ctrl+D收藏月亮链

CON:【翻译】编写可升级的智能合约_Decentral Games [new]

作者:

时间:1900/1/1 0:00:00

原文链接

当使用OpenZeppelinUpgrades编写可升级合约时,有一些在编写Solidity代码时需要记住一些注意事项。

值得一提的是,这些限制源于以太坊虚拟机的工作方式,并且适用于所有使用可升级合约的项目,而不仅仅是OpenZeppelinUpgrades。

初始化器

在编写Solidity合约使用OpenZeppelinUpgrades,无需任何修改,只需要修改构造函数。由于基于代理的可升级性系统的要求,可升级合约中不能使用构造函数。要了解这个限制背后的原因,请查看代理。

这意味着,当使用OpenZeppelin可升级的合约时,您需要将其构造函数改为一个常规函数,通常命名为initialize,在那里执行所有的初始化逻辑。

//NOTE:Donotusethiscodesnippet,it'sincompleteandhasacriticalvulnerability!pragmasolidity^0

}

然而,虽然Solidity确保一个构造函数constructor在合约的生命周期内只被调用一次,但一个普通函数可以被多次调用。为了防止一个合约被多次初始化,你需要添加一个检查来确保初始化函数只被调用一次。

Glassnode:BTC目前已实现市值稳定:金色财经报道,Glassnode发推表示,在经历了一段时间的资本大量流出之后, BTC目前已实现市值稳定,并开始再次出现净资本流入。然而,与之前的牛市条件相比,这种趋势在持续时间和幅度上仍处于起步阶段。[2023/6/3 11:55:39]

//contracts/MyContract

}

由于这种模式在编写可升级合约时非常常见,OpenZeppelinUpgrades提供了一个Initializable基础合约,它有一个initializermodifier来处理这个问题。

//contracts/MyContract

}

构造函数constructor和普通函数的另一个区别是,Solidity负责自动调用一个合约的所有基类的构造函数。在编写初始化器initializer时,你需要特别注意手动调用所有父合约的初始化器initializer。

//contracts/MyContract

}contractMyContractisBaseContract{uint256publicx;functioninitialize(uint256_x)publicinitializer{BaseContract

Aptos官方域名服务Aptos Name在Aptos主网上线:10月19日消息,Aptos Labs团队开发的官方域名服务Aptos Name(ANS)在Aptos主网上线,支持Aptos用户为其Aptos钱包地址使用人类可读的.apt名称。ANS开放3位及以上字符名称的注册,每个域名都将按照年租模式注册,之后将启用更长的注册期限。[2022/10/19 17:32:08]

}

使用可升级的智能合约库

请记住,这个限制不仅会影响你的合约,还会影响你从库中导入的合约。例如考虑OpenZeppelin合约中的ERC20:该合约在其构造函数中初始化了token的名称、符号和小数位数。

//

这意味着你不应该在你的OpenZeppelinUpgrades项目中使用这些合约。相反,请确保使用...}

无论是使用OpenZeppelin合约还是其他智能合约库,都要确保软件包被设置为处理可升级合约。

在合约中了解更多关于OpenZeppelin合约可升级的信息:Contracts:UsingwithUpgrades。

避免在字段声明中使用初始值

Solidity允许在合约中声明字段时为其定义初始值。

高盛、摩根大通因推特收购事件被马斯克要求传唤出庭:8月3日消息,高盛、摩根大通因推特收购事件被特斯拉CEO埃隆·马斯克要求传唤出庭,特斯拉CEO埃隆·马斯克向推特的交易顾问寻求相关文件。(金十)[2022/8/3 2:57:23]

contractMyContract{uint256publichasInitialValue=42;//equivalenttosettingintheconstructor}

这相当于在构造函数中设置了这些值,因此,对于可升级的合约是无效的。请确保所有初始值都在如下所示初始化函数中设置;否则,任何可升级的实例都不会设置这些字段。

contractMyContractisInitializable{uint256publichasInitialValue;functioninitialize()publicinitializer{hasInitialValue=42;//setinitialvalueininitializer}}

注意定义_常量_状态变量还是可以的,因为编译器并没有为这些变量预留存储槽,每出现一次就会被相应的常量表达式所替代。所以下面的内容在OpenZeppelinUpgrades中仍然可以使用:

contractMyContract{uint256publicconstanthasInitialValue=42;//defineasconstant}

链游My Neighbor Alice Alpha Season1已经上线:7月1日消息,区块链NFT游戏My Neighbor Alice在社交媒体上宣布其Alpha Season1版本已经上线,整个赛季将持续四个星期,参与者必须持有游戏内的土地NFT,完成任务将获得相关NFT奖励。此前报道,My Neighbor Alice曾在5月末进行过土地NFT的拍卖。[2022/7/1 1:42:52]

从合约代码中创建新实例

当从合约代码中创建一个新的合约实例时,这些创建直接由Solidity处理,而不是由OpenZeppelinUpgrades处理,这意味着这些合约将无法升级。

例如,在下面的例子中,即使MyContract被部署为可升级,创建的token合约也是不可升级的:

//contracts/MyContract

}

潜在的不安全操作

在使用可升级的智能合约时,你将始终与合约实例进行交互,而不是底层逻辑合约。然而我们却无法阻止恶意行为者直接向逻辑合约发送交易。这不会构成威胁,因为逻辑合约状态的任何变化都不会影响你的合约实例,因为你的项目中从未使用过逻辑合约的存储。

然而,有一个例外。如果对逻辑合约的直接调用触发了自毁操作selfdestruct,那么逻辑合约就会被销毁,你的所有合约实例最终都会将所有的调用委托给一个地址,而不会有任何代码。这会破坏你项目中的所有合约实例。

分析:稳定币MIM可能已经资不抵债:6月18日消息,Autism Capital发推称,Magic Internet Money(MIM)可能已经资不抵债。据悉,MIM是规模较大的稳定币之一,市值约3亿美元。

上个月,在Terra崩盘期间,Abracadabra(MIM背后的协议)产生1200万美元的坏账,因为清算的速度不足以支付协议的MIM负债。这条消息被掩盖了。Abracadabra当时立即关闭其分析仪表板,以便可以进行“升级”。Abra团队之后还表示,分析仪表板出现故障的时间完全是巧合。

MIM核心团队没有使用MIM Treasury资金偿还坏账,而是决定在YOLO市场购买CRV。而CRV价格一直在暴跌,目前协议中有很多坏账。[2022/6/18 4:36:18]

如果逻辑合约中包含委托调用delegatecall操作,也可以达到类似的效果。如果可以将delegatecall变成一个包含自毁的恶意合约,那么调用合约将被破坏。

因此,在你的合约中不允许使用selfdestruct或delegatecall。

修改你的合约

在编写新版本的合约时,无论是由于新功能还是bug修复,都有一个额外的限制需要遵守:你不能改变合约状态变量的声明顺序,也不能改变它们的类型。你可以通过了解Proxies来阅读更多关于这个限制背后的原因。

警告违反这些存储布局限制中的任何一项,都会导致升级版的合约的存储值被混淆,并可能导致你的应用程序出现关键错误。这意味着,如果初始合约看起来像这样:

contractMyContract{uint256privatex;stringprivatey;}

那么不可以修改合约变量类型:

contractMyContract{stringprivatex;stringprivatey;}

也无法改变变量的声明顺序:

contractMyContract{stringprivatey;uint256privatex;}

不能在现有变量之前引入新的变量:

contractMyContract{bytesprivatea;uint256privatex;stringprivatey;}

也不能删除现有变量:

contractMyContract{stringprivatey;}

如果需要引入新的变量,请确保添加到原有变量的后面:

contractMyContract{uint256privatex;stringprivatey;bytesprivatez;}

注意,如果重命名一个变量,那么在升级后,它将保持与之前相同的值。如果新变量和旧变量的语义相同,那么这可能是我们所希望的行为:

contractMyContract{uint256privatex;stringprivatez;//startswiththevaluefrom`y`}

而如果你在合约的最后删除了一个变量,请注意存储不会被清除。随后的更新中如果增加一个新的变量,会导致该变量从被删除的变量中读取遗留的值:

contractMyContract{uint256privatex;}

升级到:

contractMyContract{uint256privatex;stringprivatez;//startswiththevaluefrom`y`}

注意,你也可能会因为改变合约的父合约而无意中改变合约的存储变量。例如,如果你有以下合约:

contractA{uint256a;}contractB{uint256b;}contractMyContractisA,B{}

然后通过调换基础合约的声明顺序或引入新的基础合约来修改MyContract,将改变变量的实际存储方式:

contractMyContractisB,A{}

如果集成合约有任何自己的变量,你也不能在基础合约中添加新的变量。鉴于以下情况:

contractBase{uint256base1;}contractChildisBase{uint256child;}

如果修改Base,增加一个额外的变量:

contractBase{uint256base1;uint256base2;}

然后,变量base2将被分配到上一个版本中那个child的槽位。一个变通的办法是在基础合约上声明未使用的变量,你可能会在未来想要扩展,作为"保留"这些槽位的一种手段。请注意,这个技巧不会增加gas使用量。

请戳↓“阅读原文”↓获取文中链接

免责声明:作为区块链信息平台,本站所发布文章仅代表作者个人观点,与链闻ChainNews立场无关。文章内的信息、意见等均仅供参考,并非作为或被视为实际投资建议。

本文来源于非小号媒体平台:

登链社区

现已在非小号资讯平台发布105篇作品,

非小号开放平台欢迎币圈作者入驻

入驻指南:

/apply_guide/

本文网址:

/news/9579149.html

免责声明:

1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险

2.本文版权归属原作所有,仅代表作者本人观点,不代表非小号的观点或立场

上一篇:

币安为何推出第三条链?这对BNB意味着什么?

标签:CONRACACTNTRFalcontrace币为什么暴涨TractoDecentral Games [new]

比特币价格今日行情热门资讯
ING:老山说币:大资金进入?后市必破4w?_WMINIMA

各位朋友们,你们好,我是老山说币。在这个市场,如果你处于一直亏损的状态,不如换个环境。也许正是你的一次改变,会给你带来不一样的结果.

1900/1/1 0:00:00
BTC:金色DeFi日报 | 市值排名前十的DeFi代币价格全部下跌_DEF

DeFi数据1.DeFi总市值:252.23亿美元市值前十币种涨跌幅,金色财经制图,数据来源Coingecko2.过去24小时去中心化交易所的交易量:24.3亿美元交易量排名前十的DEX数据来源.

1900/1/1 0:00:00
稳定币:LatticeX 基金会:解读美货币监理署稳定币政策影响与市场机遇_LAT

原文标题:《JenniferJiang:OCC放宽稳定币支付网络为银行「永远在线」开绿灯|云图思潮》1月4日,美国货币监理署的第1174号解释性信函发布,制定了道路规则.

1900/1/1 0:00:00
比特币:谈喻凯:多头打响反击战 比特币以太坊或将启动下一轮牛市_NOM

比特币,一波深度回调,让市场不少人慌了神,对于是对于一些散户而言,套牢,爆仓已经成为了韭菜的代名词.

1900/1/1 0:00:00
EFI:2021年五大最有希望的DeFi项目_defi币联合坐庄是局吗

由于DeFi旨在提供分散的银行服务,特别是针对无银行和银行不足的客户,因此DeFi行业的兴起引起了加密界的注意,带来了许多新项目。2020年对于加密货币来说是一个伟大的一年.

1900/1/1 0:00:00
数字货币:邹传伟:数字货币、数字资产与数字金融_数字金融双学士学位

题记:12月31日,由清华大学经济管理学院数字金融资产研究中心主办的“数字金融:创新、发展与监管”高端研讨会在清华大学成功召开.

1900/1/1 0:00:00