美文网首页
如何编写可升级合约

如何编写可升级合约

作者: _南星_ | 来源:发表于2018-06-13 10:50 被阅读14次

    以太坊智能合约部署到链上就无法在修改,这样就导致链上合约bug无法修复只能修复bug后重新部署一份合约,替换原来的合约地址。这样也就导致了合约数据的丢失。

    解决这样的问题一般有两种解决方案:

    1)使用代理合约

    使用delegatecall操作码将函数的调用转移到可更新的目标合约中。

    2)分离合约逻辑和数据

          将合约拆分成两个合约:

           包含数据的合约(变量、结构、映射等)以及提供getter setter方法修改          数据合约。

           包含逻辑的合约  (业务逻辑+如何更新数据的)

    示例:

    pragma solidity ^0.4.2;

    contract DataContract{

      //访问控制

      maping(address=>bool) accessAllowed;

      mapiing(address => uint256) balances;

    function  DataContract(){

        accessAllowed[msg.sender] = true;

      }

      function setAccessAllow(address addr) public allowed {

        accessAllowed[addr ] = true;

      }

      function denyAccessAllow(address addr) public allowed {

        accessAllowed[addr] = false;

      }

      function setBalance(address addr,uint256 value) public {

        balances[addr] +=value;

      }

      function getBalance(address addr) public returns(uint256){

        return  balances[addr];

      }

      modifier allowed{

        require(accessAllowed[msg.sender]==true);

        _;

      }

    }

    逻辑合约:

    pragma solidity ^0.4.2;

    interface DataContract{

      function setAccessAllow(address addr) external ;

      function denyAccessAllow(address addr) external ;

      function setBalance(address addr,uint256 value);

      function getBalance(address addr) public returns(uint256);

      }

    contract upgradeContract{

    // 0xe07294a5432231055eb64ec44917a8cd3b7aa44a

      DataContract dataContract;

      uint256 balaceValue public;

    function upgradeContract(address dataAddr){

      dataContract = DataContract(dataAddr);

    }

    function setBalance(address addr,uint256 value){

        dataContract.setBalance(addr,value);

    }

    function getBalance(address addr){

        balaceValue = dataContract.getBalance(addr);

    }

    }

    部署方法: 

    1. 先部署DataContract合约 

    2. 使用DataContract合约地址作为部署ControlContract合约的参数 

    3. 用ControlContract合约地址作为参数调用DataContract合约的allowAccess方法。 

    如果需要更新控制合约(如修复了addTen)则重新执行第2-3步,同时对老的控制合约执行denyAccess()。

    结语

    我们在写智能合约的时候最好仔细审计合约,确保无误后在部署到主网上,避免不必要的损失,升级合约必然要升级与之关联的dapp,频繁的更新合约会导致用户的不信任。

    相关文章

      网友评论

          本文标题:如何编写可升级合约

          本文链接:https://www.haomeiwen.com/subject/xotjeftx.html