智能合约升级方案设计

智能合约的升级

目前智能合约不支持传统的migration方式,链上的数据与合约的地址紧密地绑定在一起。

这种方式给智能合约的升级带来了相应的困难。

智能合约的外部调用

目前主流的智能合约的升级基于智能合约具备外部调用的能力。

pragma solidity ^0.4.18;

contract C {
    uint public data;

    address public callAddress;

    uint[10] intArray;// size must be fixed

    mapping (address => uint) public campaigns;

    function getIntArray() constant returns (uint[10])
    {
        return intArray;
    }

//      Internal type can not be returned.
//    function getMapData() constant returns( mapping (address => uint)){
//        return campaigns;
//    }

    function f(uint a) external returns(uint b){
        data = a+2;
        return a+2;
    }

    function f(uint a,address caller) external returns(uint b) {
        data = a+2;
        callAddress = caller;
        return a + 2;
    }

    function setData(uint a) external {
        intArray[0]=12;
        intArray[1]=13;
        intArray[2]=14;
        intArray[3]=15;
        intArray[4]=16;
        intArray[5]=12;
        data = a;
    }

    //for external call
    function getData() external returns(uint) { return data; }
    function compute(uint a, uint b) external returns (uint) { return a+b; }
}

contract D {
    C c;
    address public cAddr ;

    uint public local = 234;

    function setAddress(address cAddress) public{
        c = C(cAddress);
        cAddr = cAddress;
    }

    function callF() public {
        local = c.f(7,msg.sender);
    }

    function callFSingle() public{
        local = c.f(8);
    }


    function setCData() public{
        c.setData(3);
        local = c.getData();
    }

    function useCcompute(uint a,uint b) public{
        local = c.compute(a,b);
    }
}

上述例子中,C智能合约提供了基本的数据类型和围绕数据类型的简单接口,

在D智能合约中保存C智能合约的地址,并调用C智能合约中的读写接口。

需要说明的是:用户A用自己的钱包在D中调用C智能合约,在C中检测msg.sender,发现是C的智能合约中的地址

如果C智能合约涉及到数据的权限写入,需要在智能合约中做权限的认证。

权限验证暂时的解决方法:函数重载和命名空间智能合约的验证。

Screenshot from 2018-04-17 20-05-44.png

解决方法:
数据智能合约的基本数据结构的读写访问智能通过拥有相关证书的人访问,在数据智能合约中所有的写的实现均具有重载函数,只有通过当前版本的控制器合约的验证或者数据智能合约的验证才能够写入数据。

命名空间智能合约作为存储智能合约的地址的核心,和其它的智能合约多次交互,存储最核心的内容。类似于k8s的etcd。

智能合约升级最佳实践参考文档:

http://www.qukuaiwang.com.cn/news/3451.html

设计

以某银行的业务为例:

代理控制器合约:面向Dapp,是所有业务合约的入口,提供命名空间服务,提供了命名空间到合约地址的映射。使得Dapp对链上合约升级导致的地址变更无感知。例如,Dapp对A银行的存款请求只需要(“BankA",deposit,args) 即可。对B银行的取款请求只需要(”BankB",withdraw,args)即可。代理器控制合约实现上应该是区块链底层内置的、固化的,或者是业务上极少变更的。Dapp在业务运行之前已经明确知道代理控制器合约的地址。

命名控制器合约:面向链上合约,提供命名空间服务,提供了命名空间到合约地址的映射。使得链上合约可以在运行时根据命名获得实际的合约地址。例如,A银行控制器合约向命名控制器合约请求(“BankA-Data"),可以获得A银行数据合约地址,使得A银行控制器合约可以在运行时访问A银行数据合约。它与代理控制器合约的主要不同在于服务对象的不同,代理控制器合约面向Dapp,命名控制器合约面向链上合约。另外,命名控制器合约包含有版本控制的设计(下文第3.2节介绍),可以根据需要配合灰度策略的实施。

业务A控制器合约:提供了存款服务接口deposit。部署初始化时已经明确知道自己的身份”BankA"。运行时通过命名控制合约获得”BankA-Data“的合约地址。

A银行数据合约:保存了A银行的当前余额。提供add和sub接口给A银行控制器合约来更新余额信息。

对A银行的存款请求的流程是这样的:

Dapp指定代理控制器合约地址,请求存款交易(“BankA",deposit,money)

代理控制器合约,运行时得到”BankA"对应的A银行控制器合约地址,并向A银行控制器合约请求存款交易(deposit,money)

A银行控制器合约的deposit接口向命名控制器合约请求“BankA-Data"获得A银行数据数据合约地址,并访问到A银行数据合约的数据,然后执行一些存款业务逻辑。返回结果。

依次返回结果到Dapp。

智能合约的升级

智能合约的升级有三种情形:

150669122160666.jpg

控制器智能合约的升级不涉及到数据的变更,因此可以直接升级,设置代理控制器合约中的跳转地址,设置命名空间控制器合约中的最新版本的地址。

数据智能合约的升级涉及到数据的变更,首先需要更新命名控制器智能合约中的地址。其次考虑数据迁移的问题。

数据迁移

数据迁移有三种办法:

硬编码迁移法

硬编码迁移法指的是,新版本的数据合约中保存一个指向旧版本数据合约的合约地址,新版本数据合约保存的是增量的数据内容。

这样相当于新版本合约保留了一份旧版本数据的指针,当新版本需要使用旧数据的时候,直接调用旧数据合约地址对应数据接口即可。这样,新旧版本数据合约可以并存,即使是在异常情况下,数据被误写到了旧版本合约上,它依然可以被新版本所访问到。

这个方法的优点是:新旧合约可以同时并存,不增加区块链存储压力,简单灵活,较强的升级容错能力。缺点:持续不断的版本升级会导致形成较长的链式逻辑关系,维护成本较高。

硬拷贝迁移法

硬拷贝迁移法指的是,新版本和旧版本之间切断逻辑关系,利用外部迁移工具,将旧版本数据逐步拷贝到链下,再从链下重新存储到新版本合约的过程。

这个方法的优点是:无历史包袱。缺点是:大幅度增加区块链存储压力;数据迁移工具需要适配不同的数据合约,开发成本较高;迁移过程需要停止服务,否则容易出现脏数据;数据量大时,耗时长,操作复杂,容易出错,基本无法实操。

默克尔树迁移法

默克尔数迁移法要点如下:

利用智能合约语言的面向对象的继承特性,使得新版本合约存储结构完全兼容旧版本合约存储结构。

利用智能合约在区块链上的storage树原理,使得新版本合约的storeage树直接从旧版本合约上衍生。无需显式的迁移过程。

利用区块链交易的原子性,使得新版本合约的部署、数据迁移、升级,原子完成。

这个方法拥有前面两个方法的所有优点,且简单高效,安全,实操性强。缺点:需要区块链底层功能特性的支持。

目前采取第一种解决方案,且根据请求类型决定访问哪个数据智能合约版本的数据。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • 本文翻译自:https://github.com/ConsenSys/smart-contract-best-pr...
    tolak阅读 4,947评论 4 21
  • 社会情感学习课程 各位爱孩子的父母们: 为了让孩子们能感受到你们为他们的学习和成长所付出的心血,让他们理解你们的爱...
    黄小五998阅读 1,417评论 0 1
  • 我本是个丁克,却辗转成了妈。 丁克一族大都有其自身的原因,可爱的宝宝谁人不喜欢,尤其人到了一定的年纪,自然会萌生出...
    子Mu阅读 771评论 0 0
  • 郭相麟 人活在世上希望自己有一个好名声,随着名声大震,一方面满足自己和家庭的虚荣心,可以光宗耀祖,名利双收,另一...
    郭相麟阅读 156评论 0 0