Web3 中人人都在谈论的代理设置
技术概述:最小可升级代理的兴起(ERC1967 /通用代理标准)
在经历了多次治理攻击和代价高昂的升级错误之后,Web3 社区最终采用了一种新的代理设置——一种在可升级性、安全性和 Gas 效率之间取得平衡的设置。最小可升级代理,通常遵循以下原则实施: ERC1967 标准,已成为事实上的模式。这种设置,有时被称为通用代理标准,不仅仅是技术上的演进;它更是对过去代理模式痛点的有力回应。
关键组件及其作用
| 成分 | 目的 | 地址槽示例 |
|---|---|---|
| 代理合同 | 委托调用逻辑合约 | 无 |
| 实施(逻辑)合同 | 包含实际的业务逻辑 | 无 |
| 管理员(所有者) | 控制升级 | 0xb53127684a568b3173ae13b9f8a6016 |
| 存储槽(ERC1967 标准) | 防止存储碰撞 | 0x360894a13ba1a3210667c828492db98 |
| 升级逻辑 | 由管理员通过安全功能管理 | 无 |
韩国镜报:为什么采用这种代理模式?
就像赵正来笔下的“太白山脉”中坚忍不拔的人物为了创造更美好的未来而忍受艰辛一样,这种代理设置也是 Web3 集体创伤的结晶——升级失败和资金损失。早期的代理,例如 EIP-897 “DelegateProxy” 即 OpenZeppelin 透明代理,存在存储冲突或管理模式复杂等问题。ERC1967 最小代理的设计兼具弹性和优雅性。
逐步实现 ERC1967 最小代理
- 部署逻辑合约
- 将您的业务逻辑编写并部署为标准合约(无需升级逻辑)。
坚固性
//合约/MyLogic.sol
实用程序可靠性^0.8.0;
合约 MyLogic {
uint256 公共值;
函数setValue(uint256 _value)公共{
值=_值;
}
}
- 部署代理合约
- 使用引用逻辑合约地址的最小代理实现。
坚固性
// 合约/MyProxy.sol
实用程序可靠性^0.8.0;
合约 ERC1967Proxy {
构造函数(地址_logic,字节内存_data){
bytes32插槽= 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
集会 {
sstore(插槽,_logic)
}
如果(_data.length> 0){
(bool 成功,) = _logic.delegatecall(_data);
需要(成功,“初始化失败”);
}
}
fallback() 外部应付款 {
集会 {
让 impl := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc)
calldatacopy(0, 0, calldatasize())
让结果:= delegatecall(gas(),impl,0,calldatasize(),0,0)
返回数据复制(0,0,返回数据大小())
切换结果
案例 0 { 恢复(0,returndatasize()) }
默认 { return(0, returndatasize()) }
}
}
}
- 通过构造函数数据初始化
-
传递初始化数据(例如,
abi.encodeWithSignature("初始化(uint256)", 42))设置初始状态。 -
升级逻辑
- 只有管理员可以升级存储在ERC1967插槽的逻辑合约地址。
坚固性
函数upgradeTo(地址newImplementation)外部onlyAdmin {
bytes32插槽= 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
集会 {
sstore(插槽,新实现)
}
}
存储槽完整性:避免碰撞
此设置将实现地址存储在确定性槽中(0x3608…BBC),避免了以往代理模式中常见的悲剧性冲突。这类似于韩国村落守护神图腾的守卫,确保合约存储的神圣性。
| 代理类型 | 仓储碰撞风险 | 升级模式 | 燃气效率 | 管理分离 |
|---|---|---|---|---|
| 透明代理 | 中等的 | 管理员控制 | 缓和 | 是的 |
| UUPS(ERC1822) | 低的 | 可自行升级 | 高的 | 选修的 |
| ERC1967 最小代理 | 非常低 | 管理员控制 | 非常高 | 选修的 |
来之不易的教训:实际考虑
- 升级安全性: 管理员使用多重签名或时间锁。韩国谚语说“虎踞虎威,只留皮毛”——因此,你也必须确保升级权限,以免你的项目被攻击者掏空。
- 初始化: 始终通过构造函数或专用函数初始化代理的存储,而不要通过逻辑合约的构造函数初始化。
- 测试: 在测试网上模拟升级。使用 铸造厂 或者 安全帽 编写脚本升级并验证存储完整性。
代码示例:使用 Hardhat 进行部署和升级
部署代理
const logic = await MyLogic.deploy(); const proxy = await ERC1967Proxy.deploy(logic.address, "0x"); // 初始化数据
升级实施
等待 proxy.upgradeTo(newLogic.address); // 仅可由管理员调用
更深入的洞察:天然气成本比较
| 手术 | 透明代理 | UUPS代理 | ERC1967 最小代理 |
|---|---|---|---|
| 部署 | 高的 | 缓和 | 低的 |
| 升级 | 缓和 | 低的 | 低的 |
| 函数调用 | 缓和 | 低的 | 低的 |
韩寒实践:为什么不直接使用 EIP-1167 克隆版?
EIP-1167 最小代理高效,但缺乏内置的可升级性。ERC1967 最小可升级代理则体现了 han 解析的中点:简约却持久——如同全州的韩屋,经得起时间和变革的考验。
最后说明:生产最佳实践
- 分散管理: 使用链上治理或 Gnosis Safe。
- 监控升级: 发出升级事件,并像风水师观察山风一样监视它们。
- 审计: 在部署或升级生产代理之前委托外部审计。
示例表:核心模式摘要
| 图案 | 可升级 | 储存安全 | 燃气效率 | 生产就绪 |
|---|---|---|---|---|
| EIP-1167 最小代理 | 不 | 是的 | 是的 | 有限的 |
| 透明代理 | 是的 | 缓和 | 缓和 | 是的 |
| UUPS(ERC1822) | 是的 | 是的 | 是的 | 是的 |
| ERC1967 最小代理 | 是的 | 是的 | 是的 | 是的 |
ERC1967 最小可升级代理是 Web3 中每个人都在谈论的设置,不仅因为它的技术优点,还因为它是行业潮流的活生生的记录:对创新和安全、速度和弹性的渴望。
评论 (0)
这里还没有评论,你可以成为第一个评论者!