阅读本文前,你应该对以太坊、智能合约及Solidity语言有所了解,如果你还不了解,建议你先看以太坊是什么。
一方面正式由于智能合约的不可修改的特性,因为只要规则确定之后,没人能够修改它,大家才能够信任它。但另一方面,如果规则的实现有Bug, 可能会造成代币被盗,或是调用消耗大量的gas。这时就需要我们去修复错误。
我们知道一个智能合约包含两部分: 代码逻辑和数据,而代码逻辑又是最容易出问题的部分, 如在实现如下合约时,由于手抖在写addTen()时,10写成了11。
pragma solidity ^0.4.18;
contract MyContract {
mapping (address => uint256) public balanceOf;
function setBlance(address _address,uint256 v) public {
balanceOf[_address] = v;
}
function addTen(address addr) public returns (uint){
return balanceOf[addr] + 11;
}
}
假如我们在部署之后发现了这个问题,想要修复这个bug的话,只好重新部署合约,可是这时会有一个尴尬的问题,原来的合约已经有很多人使用,如果部署新的合约,老合约的数据将会丢失。
那么如何解决上面的问题了,一个解决方案是分离合约中的数据,使用一个单独的合约来存储数据(下文称数据合约),使用一个单独的合约写业务逻辑(下文称控制合约)。
我们来看看代码如何实现。
pragma solidity ^0.4.18;
contract DataContract {
mapping (address => uint256) public balanceOf;
function setBlance(address _address,uint256 v) public {
balanceOf[_address] = v;
}
}
contract ControlContract {
DataContract dataContract;
function ControlContract(address _dataContractAddr) public {
dataContract = DataContract(_dataContractAddr);
}
function addTen(address addr) public returns (uint){
return dataContract.balanceOf(addr) + 11;
}
}
现在我们有两个合约DataContract 专门用来存数据,ControlContract用来处理逻辑,并利用DataContract来读写数据。通过这样的设计,可以在更新控制合约后保持数据合约不变,这样就不会丢失数据,也不用迁移数据。
通过DataContract我们可以单独更新合约逻辑,不过你也许发现了一个新的问题,DataContract的数据不仅仅可以被ControlContract读写,还可以被其他的合约读写,因此需要对DataContract添加读写控制。我们给DataContract添加一个mapping, 用来控制哪些地址可以访问数据,同时添加了修饰器及设置访问的方法,代码如下:
pragma solidity ^0.4.18;
contract DataContract {
mapping (address => uint256) public balanceOf;
mapping (address => bool) accessAllowed;
function DataContract() public {
accessAllowed[msg.sender] = true;
}
function setBlance(address _address,uint256 v) public {
balanceOf[_address] = v;
}
modifier platform() {
require(accessAllowed[msg.sender] == true);
_;
}
function allowAccess(address _addr) platform public {
accessAllowed[_addr] = true;
}
function denyAccess(address _addr) platform public {
accessAllowed[_addr] = false;
}
}
...
部署方法如下:
如果需要更新控制合约(如修复了addTen)则重新执行第2-3步,同时对老的控制合约执行denyAccess()。
当我们在实现数据合约时,它包含的逻辑应该越少越好,并且应该是严格测试过的,因为一旦数据合约部署之后,就没法更改。
大多数情况下,和用户交互的是DApp, 因此当控制合约升级之后,需要升级DApp,使之关联新的控制合约。
尽管合约可以通过本文的方式升级,但我们依然要谨慎升级,因为升级表示你可以重写逻辑,会降低用户对你的信任度。
本文介绍升级方法更多的是一种思路,实际项目中可能会对应多个控制合约及数据合约。
专业承接虚拟币一切相关业务,如开发代币,撰写白皮书,搭建官网,上交易所等,咨询方式:15830024981(手机微信同步)
可以通过这个了解
https://tieba.baidu.com/p/6069014956?pid=124603289007&cid=0&red_tag=0338112375#124603289007