产品中心
本文主要解释以太坊的注册表合约、代理合约、承继的存储可升级性,以及更好的可升级性方法。在软件工程中,当找到新的bug和安全性风险时,一般来说不会对它们展开修复,并动态启动时改版的版本。在智能合约研发中,可升级性并不是那么非常简单。
因此,我们必需采行有所不同的作法。以太坊仍正处于跟上阶段,关于如何升级智能合约版本的争议很多,但我们将讲解一些当今最差的自由选择。留意:智能合约版本的可升级性依然是研究的活跃领域。以下任何一种方法都有可能由于欺诈或新发现的漏洞而造成智能合约告终。
智能合约可升级性的基本方法在这里,我们将讲解一些更加平易近人但不过于合适的智能合约可升级性解决方案。尽管这些不是最佳方法,但它们是当今用于的核心。
登记合约注册表合约有可能是最简单的可升级性方法,但是在这种方法,非常简单性带给了一些相当严重的缺失。它用于两个智能合约的工作:注册表合约和逻辑合约。注册表协议仅有用作将用户指向逻辑协议的当前版本。
每当逻辑合约被升级时,注册表合约的所有者就可以改版逻辑合约被升级的地址。contract SomeRegister {address backendContract;address[] previousBackends;address owner;function SomeRegister() {owner = msg.sender;}modifier onlyOwner() {require(msg.sender == owner)_;}function changeBackend(address newBackend) publiconlyOwner()returns (bool){if(newBackend != backendContract) {previousBackends.push(backendContract);backendContract = newBackend;return true;}return false;}}这种方法是十分有利的,因为当用户想用于合约时,他们必需首先查询当前地址。否则有可能造成资金损失。
将数据迁入到新的合约中也十分艰难,因此必需细心考虑到此过程以防止告终。代理合约代理合约用作将数据和调用发送到逻辑合约。用于代理合约,用户可以一直调用完全相同的合约地址,并且将其非常简单地发送到当前逻辑合约。
这种方法通过用于DELEGATECALL操作码来工作。DELEGATECALL是EVM获取的用作程序集的操作码。它的工作方式与普通调用类似于,只是目标地址的代码是在调用协议的上下文中继续执行的。
这意味著像“msg.sender”和“msg.value”这样的值将被保有。实质上,DELEGATECALL容许目标协议代表被调用方展开调用。
contract Relay {address public currentVersion;address public owner;modifier onlyOwner() {require(msg.sender == owner);_;}function Relay(address initAddr) {currentVersion = initAddr;owner = msg.sender; // this owner may be another contract with multisig, not a single contract owner}function changeContract(address newVersion) publiconlyOwner(){currentVersion = newVersion;}function() {require(currentVersion.delegatecall(msg.data));}}尽管这种方法防止了与注册表合约有关的问题,但它也有其自身的问题。例如如果管理失当,数据存储很更容易告终。如果新的合约的存储布局与以前的合约有所不同,则数据有可能已损坏。
此构建还避免您从函数接管返回值,从而容许了其用例。储存合约与以前的方法一样,此方法必须您的逻辑合约以及辅助合约。在这种情况下,辅助合约是永久存储合约。该技术通过分离出来逻辑和数据来起起到。
逻辑合约可以随时升级,并且由于数据存储在外部,因此您的数据受到维护。
本文来源:彩神Vll-www.weierde.net