版本化的 Solidity 智能合约

Versioned Solidity Smart Contracts

我正在学习 Solidity 并且对合约升级能力感到困惑。据我了解,已部署的智能合约是不可变的,无法更改。如果我需要向合约添加额外的功能,我可以对合约进行版本控制并部署新版本。但旧合约中的存储数据保持原样。

我有如下合同

pragma solidity >=0.5.10 <0.7.0;

contract User {

struct UserEntity {
   address userAddress;
   uint8 UserID; 
   string  UserName;
}

UserEntity public _UserEntity;
mapping (address=> UserEntity) UserMapping;

function addUser(address _userAddress, uint8 _UserID, string memory _UserName) public {
   _UserEntity = UserEntity(_userAddress, _UserID, _UserName);
   UserMapping[_userAddress] = _UserEntity;
}

function getUserID(address _userAddress) public view returns(uint8) {
   return(UserMapping[_userAddress].UserID);
}
}

如果我需要搜索UserID,我可以使用上面的getter。但是如果我部署新版本的合约,映射 UserMapping 不可用。能够在整个存储中搜索我需要的条目的最佳方法是什么?我在某处读到 NameRegistry 可能是一个选项,但我不确定如何实现它。我的最终目标是 UI 查询此数据并且合同升级应该对 UI

透明

N.B. 我正在使用合约的单个部署来添加多个用户,方法是从它的部署地址加载合约,使用 web3js 创建一个外部拥有的帐户然后调用函数 addUser 并将此 EOA 作为参数传递。

问题已使用 EternalStorage 解决。进一步研究更优雅的升级技术。不过问题暂时解决了。

可升级的智能合约
您可以使用 OpenZeppelin SDK 创建可升级的智能合约。
https://docs.openzeppelin.com/sdk/2.5/

OpenZeppelin 使用 "unstructured storage" 代理模式。
详情见文档:https://docs.openzeppelin.com/sdk/2.5/pattern

如果您对使用 OpenZeppelin 有任何疑问,可以在社区论坛中提问:https://forum.openzeppelin.com/

披露:我是 OpenZeppelin

的社区经理