人力资源

当前位置:首页 > 人力资源 > 文化活动 >

在Solidity智能合约中使用Enums之前要三思-十博中文网站

编辑:十博 来源:十博 创发布时间:2021-05-21阅读53538次
  本文摘要:想象一下,你正在写出一个Solidity智能合约,其中一个属性可以被叙述为类型或状态。

想象一下,你正在写出一个Solidity智能合约,其中一个属性可以被叙述为类型或状态。换句话说,来自一组受限的选项。

你立刻对自己说道:“太好了,我只不会用于枚举类型来回应这个状态变量。”一方面,这种方法有一些益处,比如减少可读性。另一方面,它很更容易让你踏上一条有可能造成问题的棘手道路。好吧,如果枚举(ENUM)成员仅有PCB在一个合约中并且未曾在其他文件中提到过,那么一切都可以。

十博

然而DAPP一般来说由几个相互连接的合约构成。当完全相同的枚举(ENUM)经常出现时,我要辩论的问题不会经常出现:1. 枚举成员经常出现在多个合约中2. 在DApp生命周期中展开改动例如您有2份合约。

第一个是存储十分最重要的信息。您还声明了一个具有枚举定义的模块以提到它。contract IStorage { enum RecordState {StateA, StateB}function setState(address user, RecordState newState) public;}contract Storage is IStorage {mapping(address=RecordState) public states;constructor() public {}function setState(address user, RecordState newState) public { states[user] = newState; }}每个用户的记录都用一个包括两个有可能选项的枚举来回应:statea和stateb。

setState函数可以变更用户的状态。还有另一个合约,终端用户应当与之交互(为了非常简单起见,我在存储合约中省略了访问控制修改器)。

contract StorageUser { IStorage public recordStorage; constructor(IStorage _recordStorage) public { recordStorage = _recordStorage; } function changeStateA() public { recordStorage.setState(msg.sender, IStorage.RecordState.StateA);} function changeStateB() public {recordStorage.setState(msg.sender, IStorage.RecordState.StateB);} }然后将这些合约部署到区块链。一切都很好:你调用changeStateA或changeStateB,并通过自己的setState函数适当地改动存储合约的数据。但是有一天你意识到你必须一个全新的状态选项来构建一些全新的功能。

你称作Statec(哇!多好的名字啊!)。首先,通过在IStorage中加到新的枚举成员来改动源代码…enum RecordState {StateA, StateB, StateC}和StorageUser的新方法。function changeStateC() public { recordStorage.setState(msg.sender, IStorage.RecordState.StateC);}此外,作为一个负责任的开发人员,您撰写调用新方法的测试并报告顺利。

您的计划是仅有重新部署StorageUser合约,并且您不期望重新部署存储,因此很多最重要数据都使用同构形式,很难迁入。因此,StorageUser将用于当前存储作为其结构函数参数展开重新部署。

你调用新的changeStateC函数......它告终了。告终的根源你看,改版后的StorageUser告诉RecordState枚举的3个成员,但原有的Storage没关于新的StateC选项的线索。

它无法将setState函数参数StateC切换为其枚举版本,因此告终。更加最重要的是,您的测试可能会愚弄您,因为他们用于了两个合约的改版版本。实质上,网卓新闻网,你甚至可以在官方文件中看见关于这个问题的警告。从整数显式切换在运营时检查该值否在枚举范围内,否则将造成告终的断言。

要汲取的教训首先,在如上所述的情况下,用普通整数更换枚举更佳。是的,它们看上去不那么好但结果结构更加可信和可拓展。其次,不要舍弃用于枚举字段的整个点子。

十博

如果这样的领域只在一个合约内,那意味著是安全性的。如果您可以保证在改动的情况下几乎重新部署用于枚举的所有合约,这也是安全性的。

请求忘记,当枚举首次从IStorage导入到StorageUser合约时经常出现问题,并且只有在改动初始成员后才重新部署后者。只是不要记得,如果你知道想要在合约中用于枚举,最差三思而后行。


本文关键词:十博,十博中文网站

本文来源:十博-www.apakatjah.com

0576-286805359

联系我们

Copyright © 2010-2014 阜新市十博中文网站科技股份有限公司 版权所有  辽ICP备81388668号-2