gpt4 book ai didi

interface - 使用 Solidity : interface vs library? 的可升级智能合约

转载 作者:行者123 更新时间:2023-12-04 14:54:22 25 4
gpt4 key购买 nike

在可升级智能合约的背景下,什么时候应该使用接口(interface),什么时候使用库 ?
我阅读了几个类似的问题和博客文章,但没有一个给出直截了当的答案:

  • (Sub) contract vs. library vs. struct vs. Interface
  • How to improve smart contact design in order to distinguish data and their manipulation functions for the same domain object?
  • Writing upgradable contracts in Solidity
  • Interfaces make your Solidity contracts upgradeable
  • Library Driven Development in Solidity
  • Proxy Libraries in Solidity
  • Exploring Code Reuse in Solidity

  • 我了解 考虑的主要标准 (除了安全性)设计可升级性时:
  • 模块化——可重用性和更容易维护
  • gas limit - 拆分大量合约,以便它们可以部署在多个交易中,以免达到 gas 限制
  • 升级成本 - 每个契约(Contract)升级成本是多少。在一个契约(Contract)发生(小)变化后,需要重新部署哪些其他契约(Contract)?
  • 执行成本 - 单独的契约(Contract)可能会导致每次调用的 gas 开销。尽量保持低开销。

  • This Medium post建议使用库来封装逻辑(例如,与“存储合约”交互时)并使用接口(interface)来解耦合约间通信。其他帖子提出了不同的技术。据我了解,库在部署之前已链接到契约(Contract),因此一旦契约(Contract)发生更改,库就需要重新部署。为什么使用接口(interface)与存储合约交互不是更好?

    下面我将介绍我目前看到的两种解决方案——一种带有库,一种带有接口(interface)。 (我想避免使用内联汇编的解决方案......)

    图书馆解决方案

    StorageWithLib.sol :
    contract StorageWithLib {
    uint public data;

    function getData() public returns(uint) {
    return data;
    }
    }

    StorageLib.sol :
    import './StorageWithLib.sol';

    library StorageLib {

    function getData(address _storageContract) public view returns(uint) {
    return StorageWithLib(_storageContract).getData();
    }
    }

    ActionWithLib.sol :
    import './StorageLib.sol';

    contract ActionWithLib {
    using StorageLib for address;
    address public storageContract;

    function ActionWithLib(address _storageContract) public {
    storageContract = _storageContract;
    }

    function doSomething() public {
    uint data = storageContract.getData();
    // do something with data ...
    }
    }

    带接口(interface)的解决方案

    IStorage.sol :
    contract IStorage {     
    function getData() public returns(uint);
    }

    StorageWithInterface.sol :
    import './IStorage.sol';

    contract StorageWithInterface is IStorage {
    uint public data;

    function getData() public returns(uint) {
    return data;
    }
    }

    ActionWithInterface.sol :
    import './IStorage.sol';

    contract ActionWithInterface {
    IStorage public storageContract;

    function ActionWithInterface(address _storageContract) public {
    storageContract = IStorage(_storageContract);
    }

    function doSomething() public {
    uint data = storageContract.getData();
    // do something with data ...
    }
    }

    考虑到上述标准, 哪种解决方案更适合分离存储和逻辑,为什么 ?在哪些其他情况下,其他解决方案更好?

    最佳答案

    我希望有人可以提出更好的答案,但这是一个很好的问题,想发表我的意见。

    简而言之,由于它特别涉及可升级契约(Contract),我认为这两种方法之间没有真正的区别。无论采用哪种实现方式,您仍然有一个单独的存储契约(Contract),并且您仍在签发 call到存储合约(一个通过接口(interface)来自 Action 合约,另一个通过库间接来自 Action 合约)。

    唯一的具体区别在于气体消耗。通过界面,您发出一个 call手术。通过一个库,您添加了一层抽象,最终得到 delegatecall后跟 call .不过,gas 开销并不是很大,所以归根结底,我认为这两种方法非常相似。您采取的方法是个人喜好。

    这并不意味着图书馆通常没有用处。我经常将它们用于常见数据结构或操作的代码重用(例如,由于在 Solidity 中迭代很痛苦,我有一个库可用作基本的可迭代集合)。我只是看不到将它们用于我的存储契约(Contract)集成的值(value)。我很想知道 Solidity 专家是否有不同的看法。

    关于interface - 使用 Solidity : interface vs library? 的可升级智能合约,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50022369/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com