本文介绍了智能合约工厂模式,它通过一个智能合约来部署、初始化和跟踪其他合约,实现标准化、可发现性、初始化安全和确定性部署。文章通过一个 Foundry 示例,展示了如何使用工厂合约部署和交互合约,并解释了为什么现代协议几乎都包含工厂模式。
到目前为止,我们已经了解了合约是如何部署的(CREATE 和 CREATE2),以及如何通过 EIP-1967 和 EIP-1822 等代理进行升级。
但是,大多数实际系统并不会止步于此,它们需要部署多个合约,而不仅仅是一个。
这就是工厂模式的用武之地。
工厂是一个智能合约,它知道如何在链上部署、初始化和跟踪其他合约。 你无需手动部署每个实例,而是调用一次工厂,它会处理所有事情:创建、配置和事件发布以进行索引。
从 DEX 交易对到 vault、钱包和 DAO,任何协议都需要可预测的标准化部署,此模式都可以为此提供支持。
在这篇文章中,我们将介绍:
1. 工厂模式如何在底层使用
CREATE和CREATE22. 为什么确定性的部署对于可发现性和安全性至关重要
3. 通过工厂部署合约并与之交互的完整 Foundry 示例
最后,你将了解为什么几乎每个现代协议都包含一个工厂,以及如何构建自己的工厂以安全地在 EVM 上扩展部署。
到目前为止,我们已经了解了合约是如何部署的,以及代理如何帮助进行升级。 但是,你会在生产 EVM 代码中看到另一种模式:工厂。
工厂只是一个知道如何部署其他合约的合约。 你无需手动部署每个新合约,而是与单个工厂合约进行交互,该合约:
CREATE 或 CREATE2)可以把它想象成合约的装配线。 你向工厂提供参数,它会返回一个新实例。
几乎所有主要的协议都使用工厂,因为它们带来了:
CREATE2,工厂甚至可以在实例存在之前预先计算出实例的地址(非常适合“反事实”钱包或确定性的资金池地址)。basicfactory.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Counter {
address public owner;
uint256 public value;
constructor(address _owner, uint256 start) {
owner = _owner;
value = start;
}
function inc() external {
require(msg.sender == owner, "not owner");
value += 1;
}
}
contract CounterFactory {
event CounterCreated(address indexed counter, address indexed owner, uint256 start);
function createCounter(address owner_, uint256 start_) external returns (address addr) {
for (uint256 i = 0; i < 5; i++) {
Counter c = new Counter(owner_, start_);
addr = address(c);
emit CounterCreated(addr, owner_, start_);
}
}
}
注意: 这里的
createCounter不是通过CREATE2部署的,但是可以通过获取Counter合约的 bytecode 并执行create2(...)轻松实现
设置节点:
anvil
部署合约并调用它
// Deploy the factory contract
// 部署工厂合约
forge create src/basicfactory.sol:CounterFactory \
--rpc-url localhost:8545 \
--private-key <YOUR-ANVIL-PK>
// Expected output:
// 预期输出:
// [⠊] Compiling...
// [⠒] Compiling 1 files with Solc 0.8.30
// [⠢] Solc 0.8.30 finished in 52.99ms
// Compiler run successful!
// Deployer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
// Deployed to: 0x610178dA211FEF7D417bC0e6FeD39F05609AD788
// Transaction hash: 0x5c25685d15aacde7128a648d48dcd8b975ffc6e20aac9605bce2f582125b6437
// Call the factory
// 调用工厂
cast send 0x610178dA211FEF7D417bC0e6FeD39F05609AD788 \
"createCounter(address,uint256)(address)" \
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 42 \
--rpc-url localhost:8545 --private-key <YOUR-ANVIL-PK>
// Logs expected in after this call with topics for each emited event
// 在此调用之后,带有每个发布事件的主题的预期日志
// and there you will find the contract addresses
// 在那里你会找到合约地址
工厂将合约创建变成一个可重复的过程。
你无需手动部署每个实例,而是获得一个受信任的入口点,该入口点处理部署、初始化和跟踪,从而使大型链上系统更安全且更易于管理。
它们是 DeFi 中可扩展架构的支柱,从流动性池到 vault 和智能钱包。
一旦你理解了工厂,你就可以开始设计自动部署和管理整个合约生态系统的协议。
最后,你将了解为什么几乎每个现代协议都包含一个工厂,以及如何构建自己的工厂以安全地在 EVM 上扩展部署。
- 原文链接: medium.com/@andrey_obruc...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!