实时警报通知:微信告警通知的重要性解析
812
2023-02-07
智能合约的可升级改造实践
近期开发基于以太坊的智能合约,为实验室的分布式电商系统提供可信的“第三方信用担保”功能。
由于初期项目需求变动会比较频繁,并且智能合约一经发布于区块链上就无法修改,即使智能合约中有Bug需要修复或者业务逻辑变更,它也不能直接在原有的合约上直接修改再重新发布。因此在即将发布第一版之前,需要结合业务场景考虑合理的升级改造机制。
初版的智能合约主要包括如下功能:
1. 买家创建订单,合约记录订单基本信息并且需要买方向合约支付交易费用2. 卖家取消订单,卖家在发货前可以取消订单,合约自动将交易费用退回给买家3. 卖家发货,合约记录相应订单的物流信息,修改订单状态4. 买家确认收货,合约将交易费用转移至卖家,并且修改订单状态为已完成5. 基本的订单查询功能
通过简单的需求介绍,可以看出合约中会保存着交易费用,订单数据以及基本的电商交易流程动作。
设计方案
起初写的智能合约全部集中在一个contract,里面会保存交易费用,订单数据以及电商交易的全部流程。一旦发布就不能修改(哪怕是添加一个方法,修改方法逻辑以及数据中添加新的字段,,,),因为重新发布新的合约之后,之前的订单数据以及交易费用全部在旧的合约中,从工程的角度来看,同时维护新旧合约(也许好多个旧合约,,,,)简直不能更糟糕。
因此决定将业务逻辑和数据从合约代码层面就做好分离,即合约分为了两类:逻辑合约以及数据合约。逻辑合约通过访问数据合约获得数据,并对数据做逻辑处理,然后写回数据合约,专注于对数据的逻辑处理和对外提供服务。逻辑合约不存储任何状态;数据合约专注于数据结构定义与所存储数据的读写接口。
逻辑合约与数据合约存在操作关系,逻辑上分为四类:
1. 逻辑合约与数据合约 1对12. 逻辑合约与数据合约 1对多3. 逻辑合约与数据合约 多对14. 逻辑合约与数据合约 多对多
根据本项目的业务场景,采取逻辑合约与数据合约1对1的关系(后续业务复杂,可以改造为多对1),综上,初期的设计图如下:
实践
首先进行数据与逻辑的分离。
数据合约
数据合约包括状态,以及每个状态对应读写方法(set&&get),部分代码如下:
逻辑合约
逻辑合约因为仅包含业务逻辑,不会存储任何的数据状态,因此使用Solidity的library进行编写。
Solidity的library
library的好处是它是单实例,只会更新一个library文件,不会像contract那样因为各种依赖产生‘涟漪’效应,对于经常变动的业务逻辑代码,使用library每次更新会节省大量gas消耗。
library是需要被合约调用才能执行的,调用library的contract(下面简称A),使用的delegatecall方法,因此library执行的上下文环境在A中,也就是library的msg.sender是A,并且可以直接修改A中的storage。直白说,A调用library,就是把library的代码import到自己的内部执行了。
入口合约
因为业务逻辑合约使用了library编写,library的调用是需要合约触发的,因此需要一个入口合约,来去调用library操作数据合约,而且对于本项目的实际需求,上面将数据以及逻辑进行分离后,忘记了一个重要的方面,就是资金存储,引入入口合约后,正好解决了这个问题,客户端调用入口合约代码,将资金充入入口合约,并且由入口合约进行资金的转移过程。
发表评论
暂时没有评论,来抢沙发吧~