Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solidity中的工厂合约 #65

Open
MagicalBridge opened this issue Jun 22, 2024 · 0 comments
Open

Solidity中的工厂合约 #65

MagicalBridge opened this issue Jun 22, 2024 · 0 comments

Comments

@MagicalBridge
Copy link
Owner

基本概念

在Solidity中,工厂合约是一种设计模式,用于创建和管理多个实例合约。通过一个工厂合约,你可以集中管理合约的创建逻辑,方便地部署多个合约实例,跟踪它们的地址,并对它们进行管理。工厂合约模式在开发去中心化应用(DApps)时非常有用,尤其是在需要频繁创建和销毁合约实例的场景下。

工厂合约代码示例

下面是一个生产级别的Solidity工厂合约示例。

Step 1: 定义子合约

首先,我们定义一个简单的子合约,它包含两个地址类型的变量和一个构造函数,两个变量都是在构造函数中进行初始化赋值的。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

contract Account {
    address public bank;
    address public owner;

    constructor(address _owner) payable {
        bank = msg.sender;
        owner = _owner;
    }
}

可以注意到,构造函数添加了payable关键字,是为了接收主币,如果你对payable关键字还不太了解,可以参考我写的这篇文章:Solidity中的payable关键字

Step 2: 定义工厂合约

然后,我们定义工厂合约,用于创建和管理子合约实例,我们通过工厂合约部署子合约相当于在工厂生产产品一样。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

contract Account {
    address public bank;
    address public owner;

    constructor(address _owner) payable {
        bank = msg.sender;
        owner = _owner;
    }
}

// 定义工厂合约
contract AccountFactory {
    Account[] public accounts;
    event ChildContractCreated(address childContractAddress);
    
    function createAccount(address _owner) external payable  {
      Account account = new Account{value: 111}(_owner);
      accounts.push(account);
      emit ChildContractCreated(address(account));
    }
    
    function getChildContracts() public view returns (Account[] memory) {
        return accounts;
    }
}

详细解释

  1. 子合约 Account:

    • bank 是创建该合约的地址(即工厂合约的地址)。
    • owner 是合约的拥有者,由创建合约时传入的 _owner 地址确定。
    • 构造函数 constructor(address _owner) payable 用于初始化合约的 bankowner 地址,同时允许在创建时接收以太币。
  2. 工厂合约 AccountFactory:

    • accounts 是一个 Account 类型的数组,用于存储所有创建的 Account 合约实例。
    • ChildContractCreated 是一个事件,当一个新的 Account 合约实例被创建时,会触发该事件。
    • createAccount(address _owner) external payable 函数用于创建新的 Account 实例,并将其地址存储在 accounts 数组中,同时触发 ChildContractCreated 事件。注意,value: 111 传递了 111 wei 给新创建的 Account 实例。
    • getChildContracts() 是一个公有函数,返回 accounts 数组,方便查看所有创建的 Account 实例。

使用示例

1、我们先要部署工厂合约,部署成功后,拿到工厂合约的地址,并记录下来;

image.png

image.png

部署的工厂合约地址:0xaE036c65C649172b43ef7156b009c6221B596B8b

2、通过工厂合约,创建子合约,创建时候需要传入一些主币

image.png

image.png

3、调用工厂合约的方法,获取部署的子合约的地址

image.png

部署的子合约的地址:0x476915eBDb08CaeeDf98953D7c940146Ff5BAA94

我们可以看到工厂合约的地址余额还剩下 1889 个Wei,我们部署的时候传入了 2000 个Wei,其中有111个Wei发送给了子合约。

4、通过地址加载的方法,将子合约加载出来

image.png

点击 At Address 可以将部署的子合约加载出来;

image.png

bank地址:0xaE036c65C649172b43ef7156b009c6221B596B8b (工厂合约地址)

owner地址:0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 (部署工厂合约的地址)

我们可以看到,子合约中的余额就是我们写死的 111 个Wei

总结

工厂合约模式在Solidity中是一种强大且灵活的设计模式,适用于需要创建和管理多个合约实例的场景。通过工厂合约,可以方便地集中管理子合约的创建逻辑,提高代码的可维护性和可扩展性。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant