usdt教程网(www.caibao.it):看法:务实地作废 SELFDESTRUCT

USDT第三方支付

菜宝钱包(caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

本文将先容 SELFDESTRUCT 对以太坊生态弊大于利的一些理由,正是由于这些理由,我们应该以某种方式移除 SELFDESTRUCT 。鉴于有些合约已经使用了 SELFDESTRUCT ,我提出了一些只需要支出最小的价值就能消除 SELFDESTRUCT 危害的方式。

一段历史: SELFDESTRUCT 已经没有需要了

SELFDESTRUCT (最初叫作 SUICIDE )早在以太坊的极早期便已引入。现实上,它在 2013 年 12 月宣布的以太坊协议 “规范” 预告中就已经泛起了。那时刻,险些没人仔细思量过状态规模治理的久远问题。然则,有个想法我也许另有些印象,为了防止没用的垃圾状态不受限制地膨胀,我们需要让任何确立出来的工具都可以被销毁。详细的思绪是,当外部账户(Externally-owned accounts, EOAs)的余额为零时触发自毁,而合约在没用后可以挪用代码里的一行自毁语句触发自毁。另有一个 gas 退款机制用于激励人人销毁没用的状态。

2014 年 1 月,Andrew Miller 指出了一个异常严重的问题:在 2013 年 12 月的规范设计中,EOA 很容易被重放攻击。若是我有 100 个币,我通过一笔生意发给你 10 个币,你可以简朴地在链上重放这笔生意十次,从而转走我的所有余额。这个问题很快就修复了,为此我们增添了 nonce 字段。然而,nonce 字段的引入让删除 EOA 的愿望彻底破灭了:nonce 是不能被重置为零的(译者注:由于以太坊的状态树是凭证账户地址盘算的一种前缀树,(若是仍然允许 EOA 的 nonce 回退为 0)一旦该账户被再次使用,nonce 又要从零最先,就会被重放攻击)。

2015 年,有人提出了一些方案试图绕过这个问题,使余额为零的账户可以被平安地删除(译者注:nonce 重置时与区块高度关联,而非从零最先)。然而,那时很显著,险些没有合约开发者真正使用自毁功效:由于要弄清晰什么时刻自毁太难了,而奖励也太少了。

到 2019-21 年,事情已经变得很显著了,我们需要的是其他形式的状态治理,好比租金机制或者是耐久未动的状态 “到期作废(expiring)” (即 “部门无状态(partial statelessness)”)。而若是我们接纳这两个方案中的任何一个,只要它是有用的,那么合约是否有能力自动删除自己就一点儿也不主要了。

SELFDESTRUCT 是唯逐一个损坏主要恒常性子(invariant)的操作码

SELFDESTRUCT 不仅没什么用,还会发生危害。它损坏了一些主要的恒常性子,这些性子原本是很好的,然则仅仅由于这一个操作码,我们就失去了这些性子。

SELFDESTRUCT 是唯逐一个能在单个区块中换取无限个状态工具的操作码

其他所有的操作码都只能操作账户中的单个值或者存储树上的单个 key,以是它们能换取若干牢靠巨细的工具是有限制的(通常,挪用一个操作码只能换取一个工具)。然则,SELFDESTRUCT 可以删除整棵存储树。

在现在的状态树结构中,这是可以容忍的。然则,思量一种特殊的情形:当挪用 SELFDESTRUCT 删除许多存储插槽后,下一个事务又在统一个地址上确立一个合约并接见统一些存储槽。为了处置这种情形,需要分外设计庞大的缓存机制。此外,SELFDESTRUCT 还阻碍了我们换取状态存储花样。

以 SELFDESTRUCT 会阻碍的两类状态存储花样为例:

请注重,这不是在梦想,从基本上换取状态存储花样(如接纳二进制树、Verkle 树等)的讨论已经最先了,若是状态存储的数据结构能够靠近单一的的键/值存储结构,而且单个区块中可以换取的状态数目有一个较低的上限,那将大大扩展我们的选择空间。

SELFDESTRUCT 是唯逐一个会导致合约代码更改的操作码

若是在一个特定的地址上存储了一段代码,那么这段代码就会永远保留在链上。这样的恒常性子是有用的,由于在构建应用时不需要忧郁这些代码会泛起更改。

账户抽象化(Account abstraction)异常依赖该恒常性子用以支持库挪用。由于代码存在更改的可能,还会导致应用的平安性变得庞大许多:2017 年 Parity 的多签钱包就曾由于其引用的库代码合约被有时删除而彻底瘫痪。

而唯一损坏代码稳固性的操作码就是 SELFDESTRUCT (是造成 Parity 多签猝死的罪魁罪魁)。

SELFDESTRUCT 是唯逐一个可以未经账户赞成就能修改账户余额的操作码

SELFDESTRUCT 有一个内置的 “转账” 的功效,其并不走正常的转账流程,因而可以绕过阻止合约地址吸收 Ether 的守护功效,以及对转账事宜的日志纪录。这为智能合约钱包埋下了隐患,让一些潜在有用的技巧没法使用,加重了开发者和审计者的心智肩负(需要思量更多的破例条件)。

SELFDESTRUCT 当前的用例

现在 SELFDESTRUCT 有两类主要的应用:

,

usdt收款平台

菜宝钱包(www.caibao.it)是使用TRC-20协议的Usdt第三方支付平台,Usdt收款平台、Usdt自动充提平台、usdt跑分平台。免费提供入金通道、Usdt钱包支付接口、Usdt自动充值接口、Usdt无需实名寄售回收。菜宝Usdt钱包一键生成Usdt钱包、一键调用API接口、一键无实名出售Usdt。

,
  1. 行使 SELFDESTRUCT 实现代码的动态换取:这可用于 dApp 或 DAO 及其他类似用例的 “升级”。

(1)可以被平安地销毁。GasToken 的开发者已经发出了忠告 “虽然对以太坊网络的换取会导致 GasToken 无法使用、不能赎回、不能交流以及/或毫无价值,然则 GasToken 的开发者极可能会拥护该换取”。移除 selfdestruct 退款只会导致有些操作的用度变得更贵(2 倍以上)。

从久远来看,(2)是没需要的,另有其他一些被普遍使用的范式可用于支持动态代码换取。最容易实现的是 DELEGATECALL 转发器,合约从一个存储插槽中获取一个代码地址,然后挪用对应地址的代码;修改这个存储插槽就能更新代码。不外,从短期来看,有少数应用已经使用了(2)。

提案 1:完全移除 SELFDESTRUCT

从某个区块(用 FLAG_BLOCK 示意,好比取 PoW 链与信标链合并发生的谁人区块)最先,完全停用 SELFDESTRUCT 。在这个及之后的区块里,若是 EVM 在执行时遇到 0xff 操作码,只要抛出异常直接退出即可,就像 EVM 执行时遇到不存在的操作码一样。

在完全停用前,为了警示用户阻止使用 SELFDESTRUCT ,我们可以渐进式地增添其 gas 用度:若是 block.number + 10**6 >= FLAG_BLOCK ,则 SELFDESTRUCT 的 gas 用度增添到 10**10 // (FLAG_BLOCK - block.number) 。

提案 2: ***  SELFDESTRUCT

我们也可以保留这个操作码,然则改变其行为,一方面消除其对状态树的损坏,另一方面增添一个新特征,让合约可以标识为不能自毁(un-self-destructible),从而确保代码不能变。

暂时提议新增的行为包罗:

  • 当一个合约挪用 SELFDESTRUCT 时,并不会删除合约账户,而是清空代码,而且将 nonce 值增添 2**40 。没有退款。

  • 通过挪用(转账)将合约中的 ETH 转移到目的地址(要么由父挪用提供所需的所有 gas,要么父挪用并不提供任何 gas)。

  • 可以在代码为空的地址(好比被清空过的)上确立合约。

  • 在合约里挪用 SSTORE 和 SLOAD 操作地址 A 时,现实操作的是 A_offset = (A + A.nonce // 2**40) % 2**160 的存储树。

注重,从 EIP-2929 的角度来看, A_offset 需要 “可达(accessed)”。若是该账户不在可达账户聚集中,则需要分外支付 2600 gas 以加入可达聚集。

另一种选择是调整将 storage key 转换为 tree key 的哈希函数,用 sha3(storage_key + contract_nonce // 2**40) 取代 sha3(storage_key) 。需要注重的是,无论若何都需要做一些类似的调整,以利便合约级其余无状态 key 空间扩展(expanding-key-space statelessness)。

合约可以在代码中指定 0xA8 作为第一个字节,EVM 会将其识别为无操作,但使用它来开启一个标志,在执行历程中完全禁用 SELFDESTRUCT 的功效(注重:这与 SET_INDESTRUCTIBLE 提案是一样的)。

这两种解决方案也可以连系起来:当前立刻 *** ,未来完全移除。或者,这个操作码也可以永远不被完全移除,然则最终只保留一个功效,即向目的地址发送合约当前的所有 ETH 余额,我们可以将这个操作码重命名为 CLEAR 。

添加回复:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。