EIP-867: 标准化以太坊恢复提案
Authors | Dan Phifer <dp@musiconomi.com>, James Levy <james@taptrust.com>, Reuben Youngblom <reuben@taptrust.com> |
---|---|
Created | 2018-02-02 |
Discussion Link | https://ethereum-magicians.org/t/eip-867-standardized-ethereum-recovery-proposals-erps/139 |
Table of Contents
简述
为以太坊恢复提案 (ERPs) 提供一个标准化的格式,这些提案与某些类型的丢失资金的恢复相关。 单个 ERP 将遵循与任何 EIP 相同的流程,但将以标准方式格式化和评估,以确保一致性和透明度。
本 EIP 不提倡或反对接受任何特定的恢复提案,即使其被接受也不会导致区块链的任何状态变更。
摘要
本提案确定了一种通用的解决方案,可用于解决以太坊区块链上某些类型的丢失资金。 特别是,它旨在解决直接受影响方之间对正确结果没有异议的情况,从而能够及时且低风险地解决许多已经发生或可能随着以太坊发展而再次发生的问题。
解决方案分为三个部分:
- 后续任何 ERP 为了考虑获得批准而需要满足的标准。
- 用于 ERP 的通用格式的建议,用于指定客户端可以解释的一组纠正措施。
- 客户端团队实施代码的指南,该代码可以读取、解释并在特定区块应用纠正措施。 可能的纠正措施集合被有意限制,以最大程度地降低与任何 ERP 相关的风险。
动机
以太坊区块链上的资金恢复问题通常存在争议。 由于此类请求的相对临时性以及通常需要主观评估其优点的原因,冻结资金恢复提案几乎从未成功。 此 EIP 试图通过为资金恢复 EIP 提供标准化格式和衡量未来提案的客观标准来消除这些障碍。
规范
本 EIP 描述了 EIP 的一个子类使用的通用格式,称为以太坊恢复提案 (ERPs),该提案提出了一项不规则的状态更改,以解决无法使用标准协议解决的资金恢复情况。 每个 ERP 将引用此 EIP,并将遵循此处提出的指南。
每个 ERP 的目的是 (a) 清楚地描述要更正的问题,(b) 描述为什么不规则的状态更改既必要又合理,以及 (c) 证明所提出的操作将实现 ERP 的目标。
每个 ERP 都需要使用标准格式来表示提议的状态更改集,并且必须包含一个可以可靠地生成这些更改的验证脚本。 不满足(至少)这些要求的 ERP 将不被考虑批准。
每个 ERP 应包含以下项目:
- 前言: EIP (RFC 822) 标头,包含有关 ERP 的元数据,包括 EIP 编号、简短标题(最多 44 个字符)以及每个作者的真实姓名(和可选的联系信息)。
- 简述: ERP 的简化且易于理解的解释。
- 详细描述: 对提议的纠正措施以及用于确定提议措施的标准的人工可读描述。
- 理由: 简明地描述了为什么纠正措施是合理的,并且不太可能受到任何直接受影响方的质疑。
- 验证脚本: 一个机器可读的脚本,输出一个状态更改对象。 该脚本应清楚地实现描述中概述的选择和操作生成逻辑,以便审阅者可以独立地重新生成相同的状态更改对象。
- 状态更改对象: 验证脚本的输出和以太坊客户端的输入。 主要地,它指定了提议的状态更改操作的完整集合。
- 附录(可选): 附带支持性证据。 附录中的附件可能包括验证作为恢复提案描述的一部分指定的详细信息的文档。
以下部分更详细地描述了对理由、验证脚本和状态更改对象格式的期望。
理由
简明地描述了为什么此操作既合理(没有不规则的状态更改就无法完成),也不太可能受到直接受影响方的质疑。
重要示例(简洁,包括支持性证据,无负面影响): 一家名为 XYZ 的公司运营的众筹活动错误地将其众筹合约的测试网地址发布到其公共网站上,时间是 2018 年 1 月 19 日,众筹活动开始时。 328 位用户在主网上将 501 ETH 发送到错误的地址,时间范围是区块 4,235,987 到 4,236,050 之间。 在这里查看测试网合约,在这里查看主网上相同地址的交易。 在这里查看 XYZ 公司在其网站上发表的声明。 由于测试网上此地址存在合约,并且创建者地址的相应 nonce 已在主网上使用,因此可以认为任何人都巧合地持有私钥是不可能的。 我们已经验证所有交易都来自没有关联代码的地址,因此应该没有问题将 eth 退还给发送者。
不充分的示例(细节不够,没有支持性证据): 我们不小心将错误的合约地址放在我们的网站上。 您能否将发送到 0x1234 的任何 eth 退还给发送者。 谢谢。
不可接受的示例(不客观,一个人的话与另一个人的话相抵触): 我向 X 发送代币以换取服务,但他做得不好。 我想要回我的钱,但他不肯退款。 请帮忙!!
验证脚本
一个机器可读的脚本,输出单个状态更改对象。 应该实现此脚本,以便于审阅者进行审核。 验证脚本应该是可以使用 web3.js 库的 JavaScript 文件。
以下是验证脚本的一些指南:
- 脚本应始终编写得尽可能简洁,并且执行验证脚本的任何人都应首先对其进行审核,以验证其不包含任何不安全的操作。
- 任何验证脚本都不应需要解锁的以太坊钱包
- 脚本应硬编码执行期间包含的最高区块(否则结果可能会因运行而异)。
ERP 验证脚本的目的是通过代码明确指定用于计算状态更改操作集的标准。 如上所述,脚本的输出将是所有以太坊客户端使用的输入。 客户端团队应避免手动预处理工件或使用工件来简单地指导代码中的更改。 相反,工件应该与客户端捆绑在一起,并在指定的块由客户端直接处理。 这将最大限度地减少每个 ERP 所需的客户端工作量,并有助于确保客户端之间的兼容性。 我们预计某些 ERP 验证脚本可能很简单,但我们建议将其包含在内以保持一致性。
状态更改对象
状态更改对象是所有以太坊客户端都可解释的标准格式。
它是一个包含以下字段的单个 JSON 对象:
- erpId: 此 ERP 的字符串标识符(可能是关联的 EIP 编号,例如 “EIP-1234”)。 这将从 ascii 转换为十六进制字符串,然后作为额外数据添加到目标块上。
- targetBlock: 应该应用 stateChange 的区块。 客户端将使用它来确定何时应该发生一组状态更改
- actions: 状态更改操作的数组。
- metadata
- sourceBlock: 脚本运行时考虑的最高区块。
- version: 脚本运行时验证脚本的版本。
状态更改操作
状态更改操作是一个 JSON 对象,其中包括 “type” 字段和一组 “data” 字段,其中数据字段的内容取决于类型,并且必须遵循为该类型定义的架构。 这允许客户端最初支持一组有限的操作,并根据后续 EIP 添加更多操作(如果需要)。 客户端应在采用此 EIP 后实现对以下操作类型的支持:
weiTransfer
weiTransfer
操作将 ETH 从一个地址转移到另一个地址。
数据字段
- type (string):
weiTransfer
- fromAddress (hex string): 应该从中转移 ETH 的地址
- toAddress (hex string): 应该将 ETH 发送到的地址
- value (decimal string): 要转移的 ETH 金额,以 wei 为单位。 该值必须是大于零的整数。
storeCode
storeCode
操作将给定的代码存储在给定的地址。
数据字段
- type (string):
storeCode
- toAddress (hex string): 应该将合约恢复到的地址。
- expectedCodeHash (hex string): toAddress 上已存在的代码的预期哈希值。如果 toAddress 上没有预期代码,则应使用空字符串。在所有其他情况下,“0x” 前缀是可选的。
- code (hex string): 与合约关联的新字节码
附录(可选)
附录可以包括其他支持性证据或附件,以帮助审阅者理解或验证 ERP 中提出的声明。
对于 storeCode 操作,它应包括提议的合约源代码(例如 Solidity)以及其他所需细节,以便审阅者可以编译源代码并生成相同的字节码。 如果可能/适用,它还应包括最初存储在该地址的源代码。 如果两个合约不相同,则应注明更改。 如果它们相同,作者应说明为什么不需要任何更改(这不太可能)。 此外,任何相关的审查、审核和测试用例都应包含在内,以解决原始合约遇到的问题。
如果被接受,ERP 可以轻松地编译要进行更改的区块,以及操作的来源(这将是脚本的输出,以标准化的对象输出)。 这些可以与客户端捆绑在一起以实现无缝执行。
ERP 批准流程
ERPs 是 EIP 的子类,因此将遵循相同的批准流程。
测试
ERP 作者目前正在寻求客户端团队对适当测试程序的反馈
以太坊客户端实现
选择采用此 EIP 中概述的提案的客户端将实现一个模块,该模块扫描指定的目录以查找 SCO 文件(每次客户端进程启动时),以构建目标块和 SCO 文件名之间的映射。 在开始处理新块时,客户端应首先查阅已发现的 SCO 目标块集,并确定当前块是否需要任何恢复操作。
例如,在此示例中,erpsByTargetBlock
是每个 ERP 的状态更改对象关联的目标块号与对具有实际数据的资源的引用(即文件名)之间的映射。
if (erpsByTargetBlock.get(currentBlock) != null) {
try {
applyRecoveryActions(erpsByTargetBlock.get(currentBlock));
}
catch (e) {
// recovery actions should be treated as a batch.
// If one fails, they all fail.
}
}
// continue with normal block processing...
applyRecoveryActions
方法必须按照它们存储在 SCO 文件中的相同顺序应用恢复操作。 客户端负责确保没有任何状态更改操作会导致帐户转移的金额大于其当前余额。 weiTransfer
和 storeCode
的 toAddress
应该始终是一个有效的地址(即永远不是 0x0
)。
此外,受 ERP 影响的每个块都应包含额外数据,以指示状态更改已发生。 块中包含的额外数据应该是 SCO 文件中找到的 erpId,转换为十六进制(即 hexStringToBytes(asciiToHex(erpId))
)。 如果从对等方收到块,客户端还应验证目标块中是否出现预期的标头。
ERP 应链接到每个客户端存储库的拉取请求,并且这些拉取请求应链接回 ERP,并且还应包含其 EIP 前言和摘要。
与 ERP 关联的每个 PR 应由添加到客户端指定 SCO 目录的单个文件(SCO 文件)组成。 不需要额外的客户端代码。
此 EIP 的局限性
此 EIP 专注于标准化恢复提案的格式,以优化可读性并消除或尽可能减少错误或故意滥用的可能性。
以下内容被认为不在本 EIP 的范围内:
- 哪些资金恢复提案(如果有)应被接受以进行实施。
- 常见的恢复提案原告如何组织代表个人集体团体的 ERP
理由
上述方法的主要考虑因素是最大限度地减少与原本没有可行解决方案的恢复操作相关的风险。 第二个考虑因素是标准化在恢复操作提案中使用的格式。
首先,包含验证脚本可以保证确定恢复操作的方式是明确的。 这并不意味着恢复操作一定是正确的,只是用于确定它们的逻辑已完全指定且可审核。
其次,要求验证脚本的输出可由客户端程序直接解释,从而最大限度地减少了每个客户端采用特定 ERP 所需的工作。 它还降低了两个客户端对特定 ERP 的实施做出不同决定的风险。
第三,操作类型被有意限制且不灵活,这降低了意外后果或恶意构造的文件影响区块链状态的可能性。 如果需要,可以使用新的操作类型轻松扩展格式,但这需要单独的 EIP。
实现
已为 EthereumJ 平台编写了参考实现。 请在此处查看拉取请求 here。
ERP 示例
本节将包括示例和 SCO 资源文件,以及有关如何使用私有测试网进行测试的简短教程。
版权
通过 CC0 放弃版权和相关权利。
Citation
Please cite this document as:
Dan Phifer <dp@musiconomi.com>, James Levy <james@taptrust.com>, Reuben Youngblom <reuben@taptrust.com>, "EIP-867: 标准化以太坊恢复提案 [DRAFT]," Ethereum Improvement Proposals, no. 867, February 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-867.