知世金融网专注于股票行情,期货开户,外汇储备等最新相关资讯信息提供投资者参考学习!

当前位置:网站首页 > 区块链 > 正文

以太坊智能合约版本升级的核心方法

原创
文章作者
知世-金融领域资深作者
知名金融领域作者,从事金融超过十余年,在行业内有一定影响力。
金融风险管理师认证证书 常识职业资格认证 特许金融分析师 国际金融理财师认证证书
发布时间:2020-02-16 20:27:26 发布来源:区块链研究实验室 文章点击:93

本文主要说明以太坊的注册表合约、代理合约、继承的存储可升级性,以及更多的可升级性方法。 在软件工程中,当发现新的bug和安全风险时,通常会对它们进行修补,并实时推送更新...

目录

    本文标题以太坊智能合约版本升级的核心方法,作者:知世,本文有1887个文字,大小约为8KB,预计阅读时间5分钟,请您欣赏。知世金融网众多优秀文章,如果想要浏览更多相关文章,请使用网站导航的搜索进行搜索。本站虽然不乏优秀之作,但仅作为投资者学习参考。

    本文主要说明以太坊的注册表合约、代理合约、继承的存储可升级性,以及更多的可升级性方法。

    在软件工程中,当发现新的bug和安全风险时,通常会对它们进行修补,并实时推送更新的版本。在智能合约开发中,可升级性并不是那么简单。因此,我们必须采取不同的做法。

    以太坊仍处于起步阶段,关于如何升级智能合约版本的争议很多,但我们将介绍一些当今最好的选择。

    注意:智能合约版本的可升级性仍然是研究的活跃领域。以下任何一种方法都可能由于滥用或新发现的漏洞而导致智能合约失败。

    智能合约可升级性的基本方法

    在这里,我们将介绍一些更平易近人但不太适合的智能合约可升级性解决方案。尽管这些不是最佳方法,但它们是当今使用的核心。

    注册合约

    注册表合约可能是最简单的可升级性方法,但是在这种方法,简单性带来了一些严重的缺陷。

    它使用两个智能合约的工作:注册表合约和逻辑合约。注册表协定仅用于将用户指向逻辑协定的当前版本。每当逻辑合约被升级时,注册表合约的所有者就可以更新逻辑合约被升级的地址。

    contract SomeRegister {
    address backendContract;
    address[] previousBackends;
    address owner;

    function SomeRegister() {
    owner = msg.sender;
    }

    modifier onlyOwner() {
    require(msg.sender == owner)
    _;
    }

    function changeBackend(address newBackend) public
    onlyOwner()
    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) public
    onlyOwner()
    {
    currentVersion = newVersion;
    }

    function() {
    require(currentVersion.delegatecall(msg.data));
    }
    }

    尽管这种方法避免了与注册表合同有关的问题,但它也有其自身的问题。 例如如果管理不当,数据存储很容易失败。如果新合约的存储布局与以前的合约不同,则数据可能已损坏。此实现还防止您从函数接收返回值,从而限制了其用例。

    储存合约

    与以前的方法一样,此方法需要您的逻辑合约以及辅助合约。在这种情况下,辅助合约是永久存储合约。该技术通过分离逻辑和数据来起作用。逻辑合约可以随时升级,并且由于数据存储在外部,因此您的数据受到保护。

    当然,这种方法也存在根本缺陷。如果在存储合约中发现错误或漏洞,则在不破坏当前数据存储的情况下无法对其进行升级。 这种方法的另一个问题是逻辑协定需要使用额外的气体来进行外部调用以查看或修改数据。

    更合适的升级方法

    现在让我们来看看一些更复杂、更合适的智能合约升级方法。

    继承的存储可升级性

    这种技术使用三种不同的合约:代理合约来委托调用并充当永久存储;逻辑合约将处理数据;还有存储合约。代理合约和逻辑合约都继承自存储合约,因此它们的存储引用是对齐的。

    当逻辑合约更新时,我们只需要更改代理合约所指向的位置即可使用仅管理员功能。由于代理和逻辑协定具有相同的存储指针,因此无需进行外部调用即可查看和修改数据。

    不幸的是,这种方法也有其自身的陷阱。由于代理合约和存储合约都是永恒的,因此,如果在任何一个合约中发现错误或漏洞,都无法修复。 因此务必仔细考虑您的代理和存储结构。

    非结构化存储可升级性

    非结构化存储可能是当前最大的可升级性方法,它使我们能够利用存储中状态变量的布局。此方法仅需要两个合约-代理合约和实施合约-实施合约包含数据和存储。

    该技术的工作原理是将可升级性所需的数据保存在存储中的固定位置,以防止被新数据覆盖。我们可以使用SLOAD和SSTORE操作码进行汇编。由于存储插槽只是从0x0开始递增,因此我们使用很高的存储插槽来防止覆盖 我们可以通过对常量变量进行散列来生成存储槽。 由于恒定状态变量不会占用存储空间,因此我们不必担心它会被覆盖。

    bytes32 private constant implementationPosition =
    keccak256("org.zeppelinos.proxy.implementation");

    由于代理不再从存储合约继承而来,因此我们现在也可以更新存储,从而防止存储错误/漏洞变成灾难性的。 但是在升级实施合约时,我们必须继承以前的合约。由于不需要更改实施合约,因此该方法甚至可以与现有合约一起使用。

    尽管这可能是当前可升级性最好的方法,但也有不少批评。代理所有者拥有巨大的权力,并且需要一定程度的信任。对于更复杂的系统,这可能也不是合适的解决方案。

    升级依赖于构造函数的合约

    当使用依赖于构造函数的合约来设置一些初始状态时,与代理工作并不太简单。由于构造函数只运行一次,而代理不知道逻辑合约构造函数中设置的值,因此我们需要一种方法在代理中初始化其中的一些值。

    创建逻辑合约后,EVM会丢弃构造函数,因此我们不能简单地重用代码。相反,我们必须采取独特的方法来解决此问题。

    初始化函数

    一种可能的替代方法是在常规函数中使用构造函数代码。我们只需确保这个函数(我们将调用初始化函数)只能运行一次。

    contract Initializable {

    /**
    * @dev Indicates that the contract has been initialized.
    */
    bool private initialized;

    /**
    * @dev Indicates that the contract is in the process of being initialized.
    */
    bool private initializing;

    /**
    * @dev Modifier to use in the initializer function of a contract.
    */
    modifier initializer() {
    require(initializing || !initialized, "Contract instance has already been initialized");

    bool wasInitializing = initializing;
    initializing = true;
    initialized = true;
    _;

    initializing = wasInitializing;
    }
    }

    在使用初始值设定项函数时,必须打起十二分精神。考虑逻辑合约继承的基本合约也很重要。这部分特别复杂,因为Solidity也支持多重继承。

    结论

    确保智能合约是可升级的,并仔细考虑可升级过程,这两点都很重要。虽然这并不是一个关于智能合约可升级性的选项的详尽列表,但这应该是关于这个主题的适当指南。

    本文相关推荐: 以太网交换机、IndusCloud工业私有云方案和大网管软件等可用于透明工厂

    以上便是知世金融网给大家分享的关于以太坊智能合约版本升级的核心方法/qkl/28678.html的相关信息了,希望能帮助到大家,更多金融相关信息,敬请关注知世金融网!

    网站内容均来自互联网,如侵害您的利益联系客服进行删除!

    关键词:以太
    (0)
    (0)

    上一篇:世链财经专访中国民营企业促进会会长张维新

    下一篇:世链财经专访域名商城副总裁袁世芳

    本文标题:以太坊智能合约版本升级的核心方法

    本文地址:/index.php?s=article&c=search&keyword=%E4%BB%A5%E5%A4%AA

    金融知名领域

    南方财富网 | 金融界 | 金融界 |

    更多推荐

    • 茅台吃饱,经销商哭倒
      茅台吃饱,经销商哭倒
    • 汇金的五次增持从短期看具有一定的“稳定器“作用,但从市场表现看效果逐次递减
      汇金的五次增持从短期看具有一定的“稳定器“作用,但从市场表现看效果逐次递减
    • 158亿元!比亚迪收购!
      158亿元!比亚迪收购!
    • 9月价格回落近五成 “冷静期”酒店业备战“十一”市场
      9月价格回落近五成 “冷静期”酒店业备战“十一”市场
    • 2023哈马博览会哈尔滨银行展区精彩纷呈
      2023哈马博览会哈尔滨银行展区精彩纷呈
    • 大额解禁撂倒股价 医疗影像龙头跌出千亿俱乐部 葛兰二季度大幅减仓
      大额解禁撂倒股价 医疗影像龙头跌出千亿俱乐部 葛兰二季度大幅减仓
    • A股,又上了热搜!数字要素概念走高多股涨停,锂电池板块走低恩捷股份大举跌停
      A股,又上了热搜!数字要素概念走高多股涨停,锂电池板块走低恩捷股份大举跌停
    • 最新!巨头出手,加仓宁王51%
      最新!巨头出手,加仓宁王51%
    • 600亿巨头暴雷
      600亿巨头暴雷
    • 一天32家!科创板回购潮涌来
      一天32家!科创板回购潮涌来
    • 提振信心实招来了!30余家上市公司密集出手 最高要买10亿
      提振信心实招来了!30余家上市公司密集出手 最高要买10亿
    • 高盛再发50年后预测:2075年印度股市全球市值占比将升4倍 中国升3成
      高盛再发50年后预测:2075年印度股市全球市值占比将升4倍 中国升3成

    新闻资讯栏目

    站长QQ: 2397470084