🚧 Stagnant
Standards Track: Core
EIP-101: Serenity 货币和密码学抽象
EIP-101: Serenity 货币和密码学抽象
Authors | Vitalik Buterin (@vbuterin) |
---|---|
Created | 2015-11-15 |
规范
- 账户现在在其 RLP 编码中只有两个字段:代码和存储。
- 以太币不再直接存储在账户对象中;相反,在地址
0
,我们预先部署一个包含所有以太币持有量的合约。web3 中的eth.getBalance
命令会相应地重新映射。 msg.value
不再作为操作码存在。- 现在,一个交易只有四个字段:to,startgas,data 和 code。
- 除了 RLP 有效性检查,以及检查 to 字段是否为 20 个字节长,startgas 是否为整数,以及 code 是空的还是哈希到 to 地址之外,没有其他有效性约束;任何东西都可以。但是,区块 gas 限制仍然存在,因此矿工不会被激励去包含垃圾信息。
- code 中的字节的 gas 收费与 data 相同。
- 当发送交易时,如果接收账户尚不存在,则创建该账户,并将其代码设置为交易中提供的代码;否则代码将被忽略。
- 在索引
0x5c
处,除了现有的msg.gas
之外,还添加了一个tx.gas
操作码;这个新的操作码允许交易访问为该交易分配的原始 gas 量。
请注意,ECRECOVER
、序列号/nonce 递增和以太币现在都不在底层规范中了(注意:以太币将继续在 Casper PoS 中扮演特权角色)。为了在新模型下复制现有功能,我们执行以下操作。
简单的用户账户可以具有以下默认标准化代码:
# 我们假设数据采用以下模式:
# 字节 0-31: v (ECDSA 签名)
# 字节 32-63: r (ECDSA 签名)
# 字节 64-95: s (ECDSA 签名)
# 字节 96-127: 序列号(以前称为 "nonce")
# 字节 128-159: gasprice
# 字节 172-191: to
# 字节 192+: 数据
# 获取用于交易签名的哈希
~mstore(0, msg.gas)
~calldatacopy(32, 96, ~calldatasize() - 96)
h = sha3(96, ~calldatasize() - 96)
# 调用 ECRECOVER 合约以获取发送者
~call(5000, 3, [h, ~calldataload(0), ~calldataload(32), ~calldataload(64)], 128, ref(addr), 32)
# 检查发送者正确性
assert addr == 0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1
# 检查序列号正确性
assert ~calldataload(96) == self.storage[-1]
# 递增序列号
self.storage[-1] += 1
# 进行子调用并丢弃输出
~call(msg.gas - 50000, ~calldataload(160), 192, ~calldatasize() - 192, 0, 0)
# 支付 gas
~call(40000, 0, [SEND, block.coinbase, ~calldataload(128) * (tx.gas - msg.gas + 50000)], 96, 0, 0)
这基本上实现了签名和 nonce 检查,如果两个检查都通过,那么它会使用所有剩余的 gas 减去 50000 来发送实际期望的调用,然后最终支付 gas。
矿工在收到交易时可以遵循以下算法:
- 最多运行 50000 gas 的代码,如果他们看到威胁要超过此限制的操作或调用,则停止
- 在看到该操作时,请确保它至少留出 50000 gas 的余量(通过检查静态 gas 消耗是否足够小,或者通过检查它是否是一个 gas 限制参数为
msg.gas - 50000
的调用) - 进行模式匹配,以确保末尾的 gas 支付代码与上面的代码 完全 相同。
此过程确保矿工在知道是否值得包含交易之前,最多 浪费 50000 gas,并且也具有高度通用性,因此用户可以尝试新的密码学(例如 ed25519、Lamport)、环签名、准原生 multisig 等。从理论上讲,甚至可以创建一个帐户,其中 有效的签名 类型是收据的有效 Merkle 分支,从而创建一个准原生闹钟。
如果有人想发送具有非零值的交易,而不是当前的 msg.sender
方法,我们会将其编译为三个步骤的过程:
- 在调用之前的外部作用域中,调用 ether 合约以创建所需金额的支票
- 在内部作用域中,如果合约在被调用的函数中的任何位置使用
msg.value
操作码,那么我们让合约在函数调用开始时兑现支票,并将兑现的金额存储在内存中的标准化地址中 - 在调用之后的外部作用域中,向 ether 合约发送消息以禁用尚未兑现的支票
理由
这允许大大提高通用性,尤其是在以下几个方面:
- 用于保护帐户的密码学算法(我们可以合理地说以太坊是量子安全的,因为人们可以完全自由地使用 Lamport 签名来保护自己的帐户)。nonce 递增方法现在也对帐户持有者开放以进行修改,从而允许在 k-并行 nonce 技术、UTXO 方案等中进行实验。
- 将以太币提升到一个抽象级别,其特殊好处是允许合约以类似的方式对待以太币和子代币
- 减少自定义策略帐户(如 multisig)所需的间接级别
它还大大简化和 纯化 了底层以太坊协议,从而降低了最小共识实现的复杂性。
实现
即将推出。
Citation
Please cite this document as:
Vitalik Buterin (@vbuterin), "EIP-101: Serenity 货币和密码学抽象 [DRAFT]," Ethereum Improvement Proposals, no. 101, November 2015. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-101.