跟我学 Solidity :工厂模式 - 币圈动态 - 找空投网
您当前位置:首页>>币圈动态

跟我学 Solidity :工厂模式

发布日期:2021-01-05 13:00:19

浏览:

  • 译文出自:登链翻译计划 [1]

  • 译者:翻译小组 [2]

  • 校对:Tiny 熊 [3]

欢迎来到学习 Solidity 系列的另一部分。在上一篇文章 [4], 我们讨论了如何从智能合约中创建另一个智能合约。今天,我们将研究这种情况下的典型用例。

什么是工厂模式?

工厂模式的想法是拥有一个合约 (工厂),该合约将承担创建其他合约的任务。在基于类的编程中,此模式的主要动机来自单一职责原则 (一个类不需要知道如何创建其他类的实例),并且该模式为构造函数提供了一种抽象。

跟我学 Solidity :工厂模式UML diagram for factory method

图片来自 Wikipedia[5].

为什么要在 Solidity 中使用工厂模式?

在 Solidity 中,出于以下原因之一,你可能要使用工厂模式:

  • 如果要创建同一合约的多个实例,并且正在寻找一种跟踪它们并简化管理的方法。
    ``` contract Factory {
    Child[] children;
    function createChild(uint data){
    Child child = new Child(data);
    children.push(child);
    }
    }
    contract Child{
    uint data;
    constructor(uint_data){
    data =_data;
    }
    }
  * 节省部署成本:你可以先部署工厂,之后在使用时再来部署其他合约。  * 提高合约安全性 (请参阅本文 [6]).## 如何与已部署的智能合约进行交互在深入探讨如何实现工厂模式的细节之前,我想澄清一下我们与已部署的智能合约进行交互的方式。工厂模式是用来创建子合约的,并且我们可能希望调用它们的某些函数以更好地管理这些合约。调用部署的智能合约,需要做两件事:  1. 合约的 ABI(提供有关函数签名的信息)。如果合约在同一个项目中。你可以使用 import 关键字将其导入。  2. 部署合约的地址。举个例子:
contract A {      address bAddress;      constructor(address b){         bAddress = b;      }    function callHello() external view returns(string memory){         B b = B(bAddress); // 转换地址为合约类型         return b.sayHello();      }  }contract B {       string greeting = "hello world";       function sayHello() external view returns(string memory){           return greeting;       }  }
在 Remix 中,首先部署合约 B,然后复制其地址,并在部署时将其提供给 A 的构造函数。现在你可以调用 `callHello()` 函数,你将获得合约 B 的 `sayHello()` 函数的结果。## 普通工厂模式在此模式下,我们创建具有创建子合约函数的工厂合约,并且可能还会添加其他函数来有效管理这些合约 (例如,查找特定合约或禁用合约)。在 create 函数中,我们使用 `new` 关键字来部署子合约。
contract Factory{       Child[] public children;       uint disabledCount;    event ChildCreated(address childAddress, uint data);     function createChild(uint data) external{         Child child = new Child(data, children.length);         children.push(child);         emit ChildCreated(address(child), data);       }     function getChildren() external view returns(Child[] memory_children){        _children = new Child[](children.length- disabledCount "");         uint count;         for(uint i=0;i          if(children[i].isEnabled()){              _children[count] = children[i];               count  ;            }          }       }     function disable(Child child) external {          children[child.index()].disable();          disabledCount  ;       }}  contract Child{      uint data;      bool public isEnabled;      uint public index;      constructor(uint_data,uint_index){         data =_data;         isEnabled = true;         index =_index;      }    function disable() external{        isEnabled = false;      }  }

```

跟我学 Solidity :工厂模式