原文链接
当使用OpenZeppelinUpgrades编写可升级合约时,有一些在编写Solidity代码时需要记住一些注意事项。
值得一提的是,这些限制源于以太坊虚拟机的工作方式,并且适用于所有使用可升级合约的项目,而不仅仅是OpenZeppelinUpgrades。
初始化器
在编写Solidity合约使用OpenZeppelinUpgrades,无需任何修改,只需要修改构造函数。由于基于代理的可升级性系统的要求,可升级合约中不能使用构造函数。要了解这个限制背后的原因,请查看代理。
这意味着,当使用OpenZeppelin可升级的合约时,您需要将其构造函数改为一个常规函数,通常命名为initialize,在那里执行所有的初始化逻辑。
//NOTE:Donotusethiscodesnippet,it'sincompleteandhasacriticalvulnerability!pragmasolidity^0
}
然而,虽然Solidity确保一个构造函数constructor在合约的生命周期内只被调用一次,但一个普通函数可以被多次调用。为了防止一个合约被多次初始化,你需要添加一个检查来确保初始化函数只被调用一次。
以太坊开发人员将注意力转向隐私、可扩展性和用户友好性:金色财经消息,在ETHSeoul 2022区块链的技术会议上,以太坊开发人员将注意力转向隐私解决方案、可扩展性和增强用户的友好性。[2022/8/10 12:15:36]
//contracts/MyContract
}
由于这种模式在编写可升级合约时非常常见,OpenZeppelinUpgrades提供了一个Initializable基础合约,它有一个initializermodifier来处理这个问题。
//contracts/MyContract
}
构造函数constructor和普通函数的另一个区别是,Solidity负责自动调用一个合约的所有基类的构造函数。在编写初始化器initializer时,你需要特别注意手动调用所有父合约的初始化器initializer。
//contracts/MyContract
}contractMyContractisBaseContract{uint256publicx;functioninitialize(uint256_x)publicinitializer{BaseContract
}
以太坊基础设施开发公司:以太坊合并将彻底改变构建和访问以太坊的方式:金色财经消息,以太坊基础设施开发公司ConsenSys发推称,以太坊合并将彻底改变构建和访问以太坊的方式,以下是合并后的4个关键。
1.多元化和开放的股权证明将使网络参与民主化,并通过新机制、验证者和创新更公平地分配奖励。
2.能源效率改进网络达成共识的方法可确保以太坊能够在不损害地球的情况下可持续地支持下一代 Web3 创造者和开发者。
3.无缝过渡在以太坊上工作的开发人员可以高枕无忧,因为他们知道用于合并前后架构的通用 API 和以太坊执行客户端的重用,@HyperledgerBesu和 Geth,确保无缝过渡的不间断开发者体验。
4.超稳健货币 Merge 将带来更新的加密经济模型,减少以太币的发行,并为最终用户和 DeFi 行业提供更强大的安全保障。
合并后,比以往任何时候都更多的人将能够在 Web3 的基础上进行构建、访问和受益。这四大支柱支撑着我们对更自由、去中心化社会的承诺。[2022/4/19 14:32:35]
使用可升级的智能合约库
请记住,这个限制不仅会影响你的合约,还会影响你从库中导入的合约。例如考虑OpenZeppelin合约中的ERC20:该合约在其构造函数中初始化了token的名称、符号和小数位数。
字节跳动收购元宇宙社交厂商波粒子科技:金色财经报道,元宇宙社交厂商波粒子科技团队已经被字节收购,波粒子是一家专注于二次元虚拟社交世界的科技公司,主打产品 \"Vyou 微你 \" 是一款虚拟形象换装娱乐 App,用户可以化身二次元虚拟形象,穿越到虚拟世界,结识新世界的小伙伴,一起互动、拍摄、玩乐、创造。据悉,去年字节花费 15 亿美元收购 Pico 后,VR 端的软件内容生态成为其之后重要发力点。除了不断引进优质 VR 游戏、3D 影视资源外,网传字节将在美国也开始发力海外市场,试图进军美国市场。(ZAKER)[2022/6/26 1:32:29]
//
这意味着你不应该在你的OpenZeppelinUpgrades项目中使用这些合约。相反,请确保使用...}
无论是使用OpenZeppelin合约还是其他智能合约库,都要确保软件包被设置为处理可升级合约。
在合约中了解更多关于OpenZeppelin合约可升级的信息:Contracts:UsingwithUpgrades。
避免在字段声明中使用初始值
Solidity允许在合约中声明字段时为其定义初始值。
contractMyContract{uint256publichasInitialValue=42;//equivalenttosettingintheconstructor}
摩根大通:加密市场去杠杆化激烈阶段似乎已经结束:7月21日消息,摩根大通在一份报告中指出,随着以太坊的合并预期加密市场出现反弹,散户投资者的需求正在回升,去杠杆化的激烈阶段似乎已经结束。(CoinDesk)[2022/7/21 2:29:23]
这相当于在构造函数中设置了这些值,因此,对于可升级的合约是无效的。请确保所有初始值都在如下所示初始化函数中设置;否则,任何可升级的实例都不会设置这些字段。
contractMyContractisInitializable{uint256publichasInitialValue;functioninitialize()publicinitializer{hasInitialValue=42;//setinitialvalueininitializer}}
注意定义_常量_状态变量还是可以的,因为编译器并没有为这些变量预留存储槽,每出现一次就会被相应的常量表达式所替代。所以下面的内容在OpenZeppelinUpgrades中仍然可以使用:
contractMyContract{uint256publicconstanthasInitialValue=42;//defineasconstant}
从合约代码中创建新实例
当从合约代码中创建一个新的合约实例时,这些创建直接由Solidity处理,而不是由OpenZeppelinUpgrades处理,这意味着这些合约将无法升级。
加密货币交易所Blockchain因向三箭资本发放贷款面临2.7亿美元的损失:7月8日消息,加密货币交易所Blockchain因向三箭资本发放贷款面临2.7亿美元的损失。加密货币交易所Blockchain CEO在股东信中表示,Blockchain.com仍保持流动性、偿付能力,我们的客户不会因此受到影响。(Coindesk)[2022/7/8 2:00:55]
例如,在下面的例子中,即使MyContract被部署为可升级,创建的token合约也是不可升级的:
//contracts/MyContract
}
潜在的不安全操作
在使用可升级的智能合约时,你将始终与合约实例进行交互,而不是底层逻辑合约。然而我们却无法阻止恶意行为者直接向逻辑合约发送交易。这不会构成威胁,因为逻辑合约状态的任何变化都不会影响你的合约实例,因为你的项目中从未使用过逻辑合约的存储。
然而,有一个例外。如果对逻辑合约的直接调用触发了自毁操作selfdestruct,那么逻辑合约就会被销毁,你的所有合约实例最终都会将所有的调用委托给一个地址,而不会有任何代码。这会破坏你项目中的所有合约实例。
如果逻辑合约中包含委托调用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意味着什么?
标签:NTRMYC以太坊PENDecentralizedUnitedCMYC以太坊交易付费的成本是apenft币的未来价值
根据QKL123行情显示,波卡DOT继续刷新历史新高,突破16美元,现报16.2美元,日内涨幅达15.62%。目前行情波动较大,提醒投资者注意风险.
火币交易所是由香港上市企业火币科技旗下的比特币交易平台,火币经过多年的努力已经获得了许多国家的金融许可证,并按照该国的牌照发放要求,在日本、韩国等地建设了本土化专业团队.
1月15日,以太坊的价格在日线图上再次飙升超过9%,突破1200美元,这是又一次尝试突破其历史高位的尝试。截至发稿时,ETH的交易价格为1150美元左右,市值为1360亿美元.
多言不可与谋,多动不可与久处,交易与其冲动,还不如一动不动!大家好,我是席幕枫。心存阳光必有诗与远方,认识老席何惧再遇荒凉?席幕枫:1.16比特币行情分析大饼,日线由阳转阴,昨日凌晨最低止泻34.
尊敬的BiONE用户: 一、IPFS云算力释放说明:BiONE香港矿池IPFS云算力于2021年1月15日11:00正式启动,1月16日10:00-15:00开始正式释放FIL.
亲爱的用户: DigiFinex将于2021年1月18日17:00(GMT8)上线LNG并开放LNG/USDT交易服务.