如何部署以太 坊可升级智能合约
根据设计,智能合约是不可变的。另一方面,软件质量在很大程度上取决于升级和修补源代码以生成迭代版本的能力。尽管基于区块链的软件从技术的不变性中获益匪浅,但修复错误和潜在的产品改进仍然需要一定程度的可变性。OpenZeppelin Upgrades 通过为智能合约提供易于使用、简单、健壮和可选的升级机制来解决这一明显的矛盾,该机制可以由任何类型的治理控制,无论是多重签名钱包、简单地址还是复杂的 DAO。
需要部署三个合约,分别是逻辑合约,代理管理合约,代理合约。逻辑合约就是我们自己的业务合约,需要满足OpenZeppelin可升级合约的条件。以下业务合约以逻辑合约为例进行说明。 本文使用remix部署合约,如需快速部署请参考:【翻译】用 Hardhat 进行升级部署(Using with Hardhat) | 登链社区
首先部署逻辑合约。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
contract Logic is Initializable, OwnableUpgradeable {
function initialize() public initializer {
__Ownable_init();
}
mapping(string => uint256) private logic;
event logicSetted(string indexed _key, uint256 _value);
function SetLogic(string memory _key, uint256 _value) external {
logic[_key] = _value;
emit logicSetted(_key, _value);
}
function GetLogic(string memory _key) public view returns (uint256){
return logic[_key];
}
function GetInitializeData() public pure returns(bytes memory){
return abi.encodeWithSignature("initialize()");
}
}
选中逻辑合约并部署。
逻辑合约地址:0x358AA13c52544ECCEF6B0ADD0f801012ADAD5eE3
部署管理合约,用于升级逻辑合约。
管理合约地址:0xd2a5bC10698FD955D1Fe6cb468a17809A08fd005
代理合约,用于存储逻辑合约数据。
部署需要参数如下:
代理合约地址:0xddaAd340b0f1Ef65169Ae5E41A8b10776a75482d
至此,可升级合约已部署完成,开始测试
注意:此处应调用代理合约而不是直接调用业务合约
首先选中业务合约,使用At Address填入代理合约地址(0xddaAd340b0f1Ef65169Ae5E41A8b10776a75482d)后生成已代理的可升级合约。
此处应使用生成出的合约,而不是部署的合约!
先将旧的逻辑合约GetLogic方法替换,替换后为要部署的新逻辑合约。
function GetLogic(string memory _key) public view returns (uint256){
return logic[_key] + 99;
}
部署新的业务合约,结束后应有三个逻辑合约实例
新的逻辑合约地址:0xb27A31f1b0AF2946B7F582768f03239b1eC07c2c
此时调用部署好的管理合约进行升级,此合约提供了两个升级方法
由于数据是保存在代理合约中,这份数据已经初始化过了,不需要再初始化,所以调用upgrade方法即可,传入参数如下:
此时升级已完成,也是最后一步。
此时不需要修改任何地方,只需要使用已经传入代理合约地址的At Address方法。
生成后将有四个逻辑合约实例: 1.首次部署的逻辑合约,2.代理后的逻辑合约,3.部署的新逻辑合约,4.以升级的逻辑合约
调用生成的新逻辑合约中的GetLogic方法,传入("test"),此时应返回100,这证明您的合约以成功升级,因为旧的逻辑合约传入了(1),修改后的逻辑合约中GetLogic方法在返回值上加上了(99),若为99证明升级失败。
至此,可升级的代理合约就部署并测试完成。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!