RFC: 使用 this.balance
作为无存储停用机制的后Cancun方案
在Cancun升级和EIP-6780引入的变更之后,动态停用和重新激活合约的能力变得更加具有挑战性,特别是在每次交易都需要查询存储的情况下。我提出了一种最小化的机制,使用内置的 this.balance
变量作为控制标志来激活和停用合约(特别是路由器合约)。
使用案例
所讨论的路由器合约:
- 持有用户批准但没有代币或重要的业务逻辑。
- 在正常操作中不持有ETH。
- 需要一种可靠的、无存储的方式来切换激活和停用状态。
这在以下情况特别有用:
- 发现合约中存在bug,需要阻止用户与之交互,直到修复完成。
- 需要快速停用路由器,而不需要手动撤销用户批准。
提议的机制
该机制完全依赖于合约的ETH余额(this.balance
)来切换其状态。逻辑如下:
- 状态定义:
- 停用:
this.balance == 0
。合约拒绝所有交互。 - 激活:
this.balance == 1 wei
。合约正常运行。 - 状态转换:
- 激活合约:
activate()
函数(限制为不可变的DEACTIVATOR地址)向合约发送1 wei,将其设置为激活状态。 - 停用合约:
deactivate()
函数(也有限制)将合约中的所有ETH转回DEACTIVATOR,将余额设置为零。 - 关键特性:
- 路由器没有
receive
函数,确保ETH不会意外或恶意地发送到它。 - 所有状态转换完全依赖于ETH余额,消除了查询或存储自定义状态变量的需要。
- 无存储读取:状态检查依赖于
this.balance
,避免了从存储中读取的gas成本。 - 高效的状态转换:激活或停用只涉及最小的ETH转账。
- 安全性:没有
receive
函数确保路由器不会意外积累ETH。 - 路由器合约中的bug迫使用户手动撤销批准。
- 由于gas成本或复杂性,每次交易都进行状态查询是不可取的。
优势
为什么这很有用
这种机制提供了一种轻量级的方式来处理路由器停用,特别是在以下情况下:
使用合约的ETH余额作为切换开关避免了对存储变量的需求,同时实现了快速高效的状态变更。这种方法可能会使其他需要类似激活/停用机制的合约设计受益,而无需依赖存储。