Eth1.x 术语表
Eth1.x 术语表
## 数据 ### **Header(区块头)** 即以太坊协议所定义的 `Header` 对象。(译者注:区块头包含一个区块的元信息) ### **Block(区块)** 一个区块由两部分数据组成: * 区块头 * Block Body(区块体);区块体又由两部分内容组成: * Transactions(交易,事务) * Uncles(叔块信息) ### **Block Body(区块体)** 就是一个区块中的事务和叔块信息的集合。 ### **事务** 即以太坊协议所定义的 `Transaction` 对象。(译者注:事务可视为触发以太坊协议状态变更的操作的基本单元) **事务的构建** 创建一条完全签名的事务的过程: * 必须知道发起事务的 Account(账户)的 `nonce`(流水号)。 * 一般来说需要使用 `eth_estimateGas` 方法来确定该事务需要使用的 `gas` 消耗量。 * 需要该账户的私钥,用于生成数字签名。 ### **叔块信息** 即被该区块视作叔块的区块的区块头。(译者注:对于任一区块来说,叔块指的是那些上溯 7 代及以内、并非其祖先区块的有效区块;一个区块可标记两个叔块;标记叔块可使区块挖出者获得额外的 “侄块奖励”,也会使叔块挖出者获得奖励,奖励大小随叔块与侄块之间的代际距离递减;叔块内的所有事务视作没有上链,除非另一些区块中包含了这些事务,否则都回到待打包事务的内存池中) ## 区块链历史 ### **Header Chain(全部区块头)** 所有历史区块的区块头的集合 * 截至 2021 年 1 月 29 日,约有 1100 万个区块头 * 截至 2021 年 1 月 29 日,全体区块头约占用 5 GB 的存储空间 * 是验证其余大部分链数据所必需的数据 * 如果使用 Header Accumulator(区块头累加器),我们将能证明某个区块头存在于主链上 ### **Block Body History(区块体历史)** 所有由事务和叔块信息所组成的历史区块的集合 * 截至 2021 年 1 月 29 日,约有 1100 万个区块体 * 截至 2021 年 1 月 29 日,所有区块体需占用约 120 GB 的存储空间 ### **Receipt History(收据历史)** 由历史事务所产生的所有收据的集合 * 截至 2021 年 1 月 29 日,约有 10 亿条收据 * 截至 2021 年 1 月 29 日,所有收据需占用约 60 GB 存储 ## **State(状态)** 所有账户及 contract storage(合约存储项)的集合 **账户** 由 `Header.state_root` 所代表的主状态树的一部分 * 字段:`balance/nonce/state_root/code_hash` **合约存储项** 每个账户的 `Account.state_root` 标识的单个存储值 * 所有数据都以 `0 - 2^^256-1` 范围内的整数作为键 (该整数也被当作存储槽的序号) **Contract Code(合约代码)** 合约代码仅使用 `Account.code_hash` 来指代;并非状态的显式部分。 ### **Archive State(归档状态)** 所有历史状态的集合。详见 Archive Node(归档节点) * 使用 Naive Database Layout,存储归档状态需占用约 7 TB 的存储 * 使用一些基于 Flat Database Layout 的高级技巧,Trube Geth 客户端使用约 800 GB 实现了归档状态存储 ### **Recent State(近期状态)** 指作为 *近期* 状态根一部分的状态。 * “近期” 一般来说是 128~256 个区块内 维护这一数据需要某种形式的垃圾回收技术,以清除不再是近期状态一部分的状态对象 ### **Cold State(冷状态)** 指的是很长一段时间没有被触及(访问 及 修改)的状态对象 ### Database Layouts(数据库布局) **Naive Database Layout** 该数据库实现将所有的状态对象都存储为单个的树节点,通过节点哈希值来访问 * 导致性能低下以及高硬盘读写开销 * 相对易于理解和实现 * 此方案下的垃圾回收算法更加复杂 **Flat Database Layout** 将所有的状态对象都存储为树的路径,某种程度上有点类似于 键值对 存储 * 性能更高、硬盘开销更小 * 更难以理解和实现 ## Witness(见证数据) 即以一种可验证的形式存储的状态数据 ### **Block Witness(区块见证数据)** 一种类型的见证数据,提供了执行区块所需的所有状态数据 ### **Transaction Witness(事务见证数据)** 一种类型的见证数据,提供了一笔事务的 EVM 执行所需的所有状态数据 ## Node Type(节点类型) ### **Full Node(全节点)** 指一个满足了下列要求的节点: * 存储了所有的区块头 * 存储了全部区块体历史 * 存储了全部收据历史 * 存储着近期状态 * 维护者一个主链区块索引系统 * 维护者一个主链事务索引系统 * 参与 `ETH` DevP2P 协议(译者注:该协议用于在以太坊网络的对等节点之间传输数据,如区块、事务、状态数据等;以太坊交易的广播就是靠这个协议实现的) ### **Archive Node(归档节点)** 其他特点与全节点都一样,但归档节点会存储全部归档状态。一般都需要执行 Full Sync(全量同步)。 ### **LES Light Node(LES 轻节点)** 连接到 `LES` DevP2P 协议的客户端,意图是跟上区块链并暴露 JSON-RPC API。 此类客户端依赖于链接到至少一个 LES Server(LES 服务器)来满足对数据的需求。 ### **Stateless Node(无状态节点)** 一个仍在计划中的客户端类型,如果能够实现区块见证数据的话,就可使之成真。 * 此类客户端不需要状态数据来执行区块,因为它们可以使用见证数据 (TODO:还需增加对其他功能所需技术的描述) **Ultra Light Node(极轻节点)** > 增加这个术语只是为了区分当前类型的轻节点和一种新类型的轻节点 —— Piper 一种仅暴露 JSO-RPC API 的节点。 ## P2P 协议 ### **`ETH` DevP2P 协议** DevP2P 网络中所用的点对点协议,是所有主网客户端的基石 作为这个点对点网络中的一部分,一个节点需要: * 参与 Transaction Gossip(事务广播) * 参与 Block Gossip(区块广播) * 拥有近期状态 * 拥有完整的区块链历史 ### **`LES` DevP2P 协议** 作为轻客户端基础的 DevP2P 网络所用的点对点协议 **LES 服务器** 参与 LES 网络、向 LES 客户端提供数据的节点。 在这个网络中成为一个服务器需要: * 完整的近期状态 * 全部区块链历史 * 主链 区块索引/事务索引 * 有能力参与事务广播 * 有能力参与区块广播 **LES 客户端** 参与 LES 网络、向 LES 服务器请求数据的节点。 ## 节点行为 ### **Gossip** **事务广播** * P2P 网络的功能,帮助分发 *新的* 事务到网络中的所有节点 * 依赖于节点能够访问 `ETH` DevP2P Protocol 或者 `LES` DevP2P Protocol * 依赖于执行事务验证的能力来防止对节点的 DoS 攻击 * 而验证事务是计算密集型的(译者注:计算密集是重点吗?还是具备相关状态数据的需求才是重点?) **区块广播** * 广播最新的区块 * 依赖于区块验证的能力 ### **历史数据检索** * 检索区块头 * 根据哈希 * 根据区块号 * 可批请求,所请求内容必须是连续的,或者其前后之间有一致的间隔 * 检索区块体 * 所得数据需要根据 `Header.transactions_root` 和 `Header.uncles_root` 来验证(译者注:即依据本地已有的区块头数据来验证相应区块体的完整性) * 检索收据 * 根据区块分批检索 * 所得数据需要根据 `Header.receipts_root` 来验证 ### **状态检索** * 根据哈希值来检索单个状态树节点 * 在未来的协议中有可能会移除,因为这种检索机制与 flat database layout 有冲突 ### **追随区块链** * 依赖于节点能访问区块广播网络 * 依赖于具有从全体区块头中获得的近期区块头 * 依赖于执行区块验证的能力来防止 DoS 攻击 ### **事务验证** 验证事务需要: * 有能力执行 `ecrecover` 操作来确定发送者(译者注:即从签名数据中恢复出发送者的地址) * 确认该事务的 nonce *正是* 该发起事务的账户的下一个 nonce * 确认该账户的余额足以支付该事务的 gas(译者注:该检查的方法应为 `余额 > 该交易指定的 gas price * gas limit`) * 需要了解 EVM 的规则来计算事务的 gas 值 ### **区块验证** 区块验证包含下述事项中的所有内容: * 检查工作量证明的 seal * 计算密集型 * 比较同一高度上其它竞争区块的挖矿总难度 * 执行交易,以验证 `Header.state_root` 的正确性 * 需要区块执行能力 * 计算密集型 ## 主链索引 ### **主链区块索引** 把区块号映射为该高度的主链区块的哈希值 * 需要从全部区块头中构建 * 每 100 万个区块,存储映射需占用 61 MB * 每个条目需要 64 bytes(字节) * 区块号需要 32 字节 * 可以使用更高效的变长编码方法来减少长度 * 区块哈希值也要 32 字节 * 截至 2021 年 1 月 29 日,主链区块索引总共占用约 600 MB 的空间 * 只能够通过验证所得区块哈希是否等于该高度上已知主链的区块哈希值来证明 * 如果能为协议引入区块头累加器的话,证明效率可以更高 ### **主链事务索引** 把事务的哈希值映射成该事务所在主链区块的哈希值,以及该事务在该块内的索引值。 * 需要从历史区块体中构建 * 截至 2021 年 1月 29 日,总共有 10 亿笔历史事务 * 每个条目都需要占用 70 字节 * 事务哈希值 32 字节 * 主链区块哈希值 32 字节 * 事务索引 4 字节 * 可以使用变长编码方法来稍微减少长度 * 截至 2021 年 1 月 29 日,这些索引总共占用 65 GB 空间 * 可以使用根据 `Header.transactions_root` 生成的默克尔证据来证明 ### **区块头累加器** 一类能让我们高效证明某个区块头来自主链的机制。基于 [https://ethresear.ch/t/double-batched-merkle-log-accumulator/571](https://ethresear.ch/t/double-batched-merkle-log-accumulator/571) ## 同步 ### **历史同步** **区块头同步** 即一个节点追赶区块链的顶端时所用的进程。基于不同的安全等级,有几种同步方法“ * 完全验证 * 从创世块起下载全体区块头 * 检查点式下载法 * 使用一个自己信任的较近区块的区块头,并从该区块头开始追及区块链 * 追随 HEAD(区块链最新区块) * 只需追随最新区块头,就可以相当有自信(自己同步得到的是主链而非伪链)。区块链越长,攻击者要制造伪链所需付出的代价就越大 当前,只有掌握了全体区块头,才能够任意地验证其他历史数据。区块头累加器可以改善这个状态,使得一个客户端可以把检查点设在区块链顶端,而仍然能够验证历史数据。 **区块同步** 客户端用来 pull(拉取)历史事务和叔块信息的进程。 * 验证这些数据需要先有全体区块头,然后根据 `Header.transactions_root` 和 `Header.uncles_root` 来检查 **收据同步** 不执行 Full Sync(完全同步)的客户端往往需要通过 ETH DevP2p 协议来取得历史收据 * 验证这些数据需要先有全体区块头,然后根据 `Header.receipts_root` 和来检查 ### **状态同步** 节点获得近期状态完整副本的机制。 **Full Sync(完全同步)** 下载所有历史区块并按顺序执行这些区块。 * 最简单的同步方法 * 计算量非常大 * 需要区块头同步 * 需要区块同步 **快速同步** 下载全部历史区块,以及近期状态数据的副本 * 使用了一个安全假设:从历史区块中得到的状态根都是正确的 * 要求历史同步 * 会给提供这些状态数据的节点造成很大的负担 * Flat Dtatabase Layout 不容易满足快速同步的要求 **Snap Sync(快照同步)** 下载全部历史区块以及近期状态数据的副本 * 使用了一个安全假设:从历史区块中得到的状态根都是正确的 * 要求历史同步 * 非常适合 Flat Dtatabase Layout * 带宽、硬盘读写和耗费时间都有指数级节省 **Stateless Sync(无状态同步)** > 这个术语并不常用,其定义也可能随时调整 不像其它状态同步方法,这一方法最终无法使节点获得近期状态数据的完整副本。就其自身而言,其用法是免去维护状态数据本地副本之需、仍能验证区块;或者,它可以与其他同步方法结合,从而能即时验证区块,然后慢慢在本地构建出可访问的完整状态数据。 * 需要区块广播 * 需要区块见证数据 **Beam Sync(光子同步)** 光子同步本质上就是一种无状态同步,但不要求网络提供区块见证数据。相反,客户端是按需从网络中请求所需的状态 * 需要区块广播 * 需要按需状态检索 * Access list(访问列表)的可得性大大提高了这种方法的效率 ### **On Demand State Retrieval(按需状态检索)** 即从网络中检索任意状态元素的能力。 `GetNodeData` [`ETH` DevP2P 协议](https://github.com/ethereum/stateless-ethereum-specs/wiki/Glossary#ETH-DevP2P-Protocol)会暴露信息对 `GetNodeData/NodeData`,允许检索任意状态。此消息格式可能会被弃用。 **基于 DHT 的状态网络** 一种设想:我们可以让状态分散在网络中的所有节点中,并使这些数据能够按需被发现及检索到。 ## 执行 ### **挖矿** 要求节点能够: * 访问待打包事务池 * 运行 EVM ### **Access List(访问列表)** 在某些形式的 EVM 执行过程中会触及的账户和合约存储位置的列表 ### **State Access Patterns(状态访问模式)** **Static State Access(静态访问模式,SSA)** EVM 执行在某些时候会具备的一种属性:调用者可以准确地预知该次执行会触及哪些状态 **Dynamic State Access(动态访问模式,DSA)** EVM 执行在某些时候会具备的一种属性:调用者无法准确地预知到底会触及哪些状态 ### **区块执行** * 需要 EVM 执行 * 就是执行给定区块中所有事务的过程 * 计算密集型 ### **EVM 执行** * 举要 EVM 的某种实现 * 要求能够访问该次执行所触及的状态 * 可以使用近期状态来实现 * 也可使用区块见证数据来实现 ## 账户管理 * 管理用于签署事务的私钥 * 账户一般会存储在一个 Keyfile (密钥文件)里 ### **密钥文件** 一种加密的存储格式,用于存储私钥 * Eth2 BLS Keystore 规范:[https://eips.ethereum.org/EIPS/eip-2335](https://eips.ethereum.org/EIPS/eip-2335) * Eth1 Keystore 规范:[https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) 解密一般来说依赖于一些密码学元件,如: `keccak`、 `scrypt`、 `pbkdf2` 和 ECC/BLS12-381 ## JSON-RPC ### `eth_protocolVersion` * 传到 DevP2P 网络的元信息(meta information); * 面向没有实现这个功能的客户端,很容易伪造这个信息 ### `eth_syncing` * 关于该节点同步状态的元信息 * 面向没有实现这个功能的客户端,很容易伪造这个信息 ### `eth_coinbase` * 表示该客户端使用的默认地址 * 面向没有实现这个功能的客户端,很容易伪造这个信息 * 仅对实现了账户管理功能的客户端有效 ### `eth_mining` * 该节点挖矿状态的元信息 * 仅对正在挖矿的节点有效 * 面向没有实现这个功能的客户端,很容易伪造这个信息 ### `eth_hashrate` * 挖矿的元信息 * 仅对正在挖矿的节点有效 * 面向没有实现这个功能的客户端,很容易伪造这个信息 ### `eth_gasPrice` * 该节点 *认为* 此时 gasPrice 是多少的元信息 * 面向没有实现这个功能的客户端,很容易伪造这个信息 > 取出一个合适的 gas price 值是一个与需求高度相关的操作,没有哪种策略适合所有的应用场景。 ### `eth_accounts` * 该节点所管理的账户的列表。 * 面向没有实现这个功能的客户端,很容易伪造这个信息 * 仅对实现了账户管理功能的客户端有效 ### `eth_blockNumber` * 返回该节点认定为最新区块的区块号 * 需要 “全体区块头” 和 “追随区块链” 功能的结合 > 并不能完全确定,该节点是能提供该区块号处的 事务/收据/状态 数据,还是仅仅接受了该区块号是最新高度。 ### `eth_getBalance` * 提供地址后,可返回该账户的 ETH 余额(以 wei 为单位) * 需要响应节点能访问账户状态 ### `eth_getStorageAt` * 提供账户及存储槽序号后,可返回该处存储的值 * 需要响应节点能访问合约存储项 ### `eth_getTransactionCount` * 提供地址后,可返回该地址的 nonce * 需要响应节点能访问账户状态 ### `eth_getBlockTransactionCountByHash` * 提供一个区块的哈希值,返回该块中的事务数量 * 需要响应节点能访问区块体历史 ### `eth_getBlockTransactionCountByNumber` * 提供一个区块的区块号,返回该块中的事务数量 * 需要响应节点能访问区块体历史 * 需要响应节点能访问主链区块索引 ### `eth_getUncleCountByBlockHash` * 返回给定哈希值的区块中的叔块数量 * 需要响应节点能访问区块体历史 ### `eth_getUncleCountByBlockNumber` * 返回给定区块号的区块中的叔块数量 * 需要响应节点能访问区块体历史 * 需要响应节点能访问主链区块索引 ### `eth_getCode` * 返回给定账户处的字节码(bytecode) * 需要响应节点能访问账户状态 * 需要响应节点能访问合约代码 ### `eth_sign` * 返回给定地址的签名 * 仅对实现了账户管理功能的客户端有效 ### `eth_signTransaction` * 为给定事务生成签名并返回已签名事务的 RLP 编码数据 * 仅对实现了账户管理功能的客户端有效 * 需要响应节点能访问账户状态以取得合适的 nonce ### `eth_sendTransaction` * 为给定事务生成签名并广播 * 仅对实现了账户管理功能的客户端有效 * 需要响应节点能访问账户状态以取得合适的 nonce * 需要响应节点能参与事务广播 ### `eth_sendRawTransaction` * 广播一条经过签名的事务 * 需要响应节点能参与事务广播 ### `eth_call` * 在响应节点最新的状态上执行特定事务并返回执行结果 * 要求响应节点能执行 EVM ### `eth_estimateGas` * 在响应节点最近的状态上执行特定事务并返回执行该事务消耗的 gas 数量 * 要求响应节点能执行 EVM * 最经常的用途是建构交易 ### `eth_getBlockByHash` * 返回由哈希值指定的区块的数据 * 要求响应节点拥有全体区块头 * 要求响应节点能访问区块体历史 ### `eth_getBlockByNumber` * 返回由区块号指定的区块的数据 * 要求响应节点拥有全体区块头 * 要求响应节点能访问区块体历史 * 要求响应节点能访问主链区块索引 > 对这个操作的调用可以直接映射成对 `eth_getBlockByHash` 的等价调用,只要能访问主链区块索引 ### `eth_getTransactionByHash` * 提供哈希值,返回对应事务的数据 * 要求响应节点拥有全体区块头 * 要求响应节点能访问区块体历史 * 要求响应节点能访问主链事务索引 > 对这个操作的调用可以直接映射成对 `eth_getTransactionByBlockHashAndIndex` 的等价调用,只要能访问主链事务索引 ### `eth_getTransactionByBlockHashAndIndex` * 返回由区块哈希值和事务索引号指定的事务的数据 * 要求响应节点拥有全体区块头 * 要求响应节点能访问区块体历史 ### `eth_getTransactionByBlockNumberAndIndex` * 返回由区块号和事务索引号指定的事务的数据 * 要求响应节点拥有全体区块头 * 要求响应节点能访问区块体历史 * 要求响应节点能访问主链区块索引 > 对这个操作的调用可以直接映射成对 `eth_getTransactionByBlockHashAndIndex` 的等价调用,只要能访问主链区块索引 ### `eth_getTransactionReceipt` * 返回由哈希值指定的事务的收据 * 要求响应节点拥有全体区块头 * 要求响应节点能访问区块体历史 * 要求响应节点能访问主链事务索引 ### `eth_getUncleByBlockHashAndIndex` * 返回由区块哈希值和索引指定的叔块信息 * 要求响应节点拥有全体区块头 * 要求响应节点能访问区块体历史 ### `eth_getUncleByBlockNumberAndIndex` * 返回由区块哈希号和索引指定的叔块信息 * 要求响应节点拥有全体区块头 * 要求响应节点能访问区块体历史 * 要求响应节点能访问主链区块索引 > 对这个操作的调用可以直接映射成对 `eth_getUncleByBlockHashAndIndex` 的等价调用,只要能访问主链区块索引 (译者注:以下操作码暂未给出解释) ### `eth_newFilter` ### `eth_uninstallFilter` ### `eth_getFilterChanges` ### `eth_getFilterLogs` ### `eth_getLogs` * * * **原文链接:** [https://github.com/ethereum/stateless-ethereum-specs/wiki/Glossary](https://github.com/ethereum/stateless-ethereum-specs/wiki/Glossary) **作者:** Piper Merriam **翻译:** 阿剑 本文首发于:https://ethfans.org/posts/eth1x-glossary
数据
Header(区块头)
即以太坊协议所定义的 Header
对象。(译者注:区块头包含一个区块的元信息)
Block(区块)
一个区块由两部分数据组成:
- 区块头
- Block Body(区块体);区块体又由两部分内容组成:
- Transactions(交易,事务)
- Uncles(叔块信息)
Block Body(区块体)
就是一个区块中的事务和叔块信息的集合。
事务
即以太坊协议所定义的 Transaction
对象。(译者注:事务可视为触发以太坊协议状态变更的操作的基本单元)
事务的构建
创建一条完全签名的事务的过程:
- 必须知道发起事务的 Account(账户)的
nonce
(流水号)。 - 一般来说需要使用
eth_estimateGas
方法来确定该事务需要使用的gas
消耗量。 - 需要该账户的私钥,用于生成数字签名。
叔块信息
即被该区块视作叔块的区块的区块头。(译者注:对于任一区块来说,叔块指的是那些上溯 7 代及以内、并非其祖先区块的有效区块;一个区块可标记两个叔块;标记叔块可使区块挖出者获得额外的 “侄块奖励”,也会使叔块挖出者获得奖励,奖励大小随叔块与侄块之间的代际距离递减;叔块内的所有事务视作没有上链,除非另一些区块中包含了这些事务,否则都回到待打包事务的内存池中)
区块链历史
Header Chain(全部区块头)
所有历史区块的区块头的集合
- 截至 2021 年 1 月 29 日,约有 1100 万个区块头
- 截至 2021 年 1 月 29 日,全体区块头约占用 5 GB 的存储空间
- 是验证其余大部分链数据所必需的数据
- 如果使用 Header Accumulator(区块头累加器),我们将能证明某个区块头存在于主链上
Block Body History(区块体历史)
所有由事务和叔块信息所组成的历史区块的集合
- 截至 2021 年 1 月 29 日,约有 1100 万个区块体
- 截至 2021 年 1 月 29 日,所有区块体需占用约 120 GB 的存储空间
Receipt History(收据历史)
由历史事务所产生的所有收据的集合
- 截至 2021 年 1 月 29 日,约有 10 亿条收据
- 截至 2021 年 1 月 29 日,所有收据需占用约 60 GB 存储
State(状态)
所有账户及 contract storage(合约存储项)的集合
账户
由 Header.state_root
所代表的主状态树的一部分
- 字段:
balance/nonce/state_root/code_hash
合约存储项
每个账户的 Account.state_root
标识的单个存储值
- 所有数据都以
0 - 2^^256-1
范围内的整数作为键 (该整数也被当作存储槽的序号)
Contract Code(合约代码)
合约代码仅使用 Account.code_hash
来指代;并非状态的显式部分。
Archive State(归档状态)
所有历史状态的集合。详见 Archive Node(归档节点)
- 使用 Naive Database Layout,存储归档状态需占用约 7 TB 的存储
- 使用一些基于 Flat Database Layout 的高级技巧,Trube Geth 客户端使用约 800 GB 实现了归档状态存储
Recent State(近期状态)
指作为 近期 状态根一部分的状态。
- “近期” 一般来说是 128~256 个区块内
维护这一数据需要某种形式的垃圾回收技术,以清除不再是近期状态一部分的状态对象
Cold State(冷状态)
指的是很长一段时间没有被触及(访问 及 修改)的状态对象
Database Layouts(数据库布局)
Naive Database Layout
该数据库实现将所有的状态对象都存储为单个的树节点,通过节点哈希值来访问
- 导致性能低下以及高硬盘读写开销
- 相对易于理解和实现
- 此方案下的垃圾回收算法更加复杂
Flat Database Layout
将所有的状态对象都存储为树的路径,某种程度上有点类似于 键值对 存储
- 性能更高、硬盘开销更小
- 更难以理解和实现
Witness(见证数据)
即以一种可验证的形式存储的状态数据
Block Witness(区块见证数据)
一种类型的见证数据,提供了执行区块所需的所有状态数据
Transaction Witness(事务见证数据)
一种类型的见证数据,提供了一笔事务的 EVM 执行所需的所有状态数据
Node Type(节点类型)
Full Node(全节点)
指一个满足了下列要求的节点:
- 存储了所有的区块头
- 存储了全部区块体历史
- 存储了全部收据历史
- 存储着近期状态
- 维护者一个主链区块索引系统
- 维护者一个主链事务索引系统
- 参与
ETH
DevP2P 协议(译者注:该协议用于在以太坊网络的对等节点之间传输数据,如区块、事务、状态数据等;以太坊交易的广播就是靠这个协议实现的)
Archive Node(归档节点)
其他特点与全节点都一样,但归档节点会存储全部归档状态。一般都需要执行 Full Sync(全量同步)。
LES Light Node(LES 轻节点)
连接到 LES
DevP2P 协议的客户端,意图是跟上区块链并暴露 JSON-RPC API。
此类客户端依赖于链接到至少一个 LES Server(LES 服务器)来满足对数据的需求。
Stateless Node(无状态节点)
一个仍在计划中的客户端类型,如果能够实现区块见证数据的话,就可使之成真。
- 此类客户端不需要状态数据来执行区块,因为它们可以使用见证数据
(TODO:还需增加对其他功能所需技术的描述)
Ultra Light Node(极轻节点)
增加这个术语只是为了区分当前类型的轻节点和一种新类型的轻节点 —— Piper
一种仅暴露 JSO-RPC API 的节点。
P2P 协议
ETH
DevP2P 协议
DevP2P 网络中所用的点对点协议,是所有主网客户端的基石
作为这个点对点网络中的一部分,一个节点需要:
- 参与 Transaction Gossip(事务广播)
- 参与 Block Gossip(区块广播)
- 拥有近期状态
- 拥有完整的区块链历史
LES
DevP2P 协议
作为轻客户端基础的 DevP2P 网络所用的点对点协议
LES 服务器
参与 LES 网络、向 LES 客户端提供数据的节点。
在这个网络中成为一个服务器需要:
- 完整的近期状态
- 全部区块链历史
- 主链 区块索引/事务索引
- 有能力参与事务广播
- 有能力参与区块广播
LES 客户端
参与 LES 网络、向 LES 服务器请求数据的节点。
节点行为
Gossip
事务广播
- P2P 网络的功能,帮助分发 新的 事务到网络中的所有节点
- 依赖于节点能够访问
ETH
DevP2P Protocol 或者LES
DevP2P Protocol - 依赖于执行事务验证的能力来防止对节点的 DoS 攻击
- 而验证事务是计算密集型的(译者注:计算密集是重点吗?还是具备相关状态数据的需求才是重点?)
区块广播
- 广播最新的区块
- 依赖于区块验证的能力
历史数据检索
- 检索区块头
- 根据哈希
- 根据区块号
- 可批请求,所请求内容必须是连续的,或者其前后之间有一致的间隔
- 检索区块体
- 所得数据需要根据
Header.transactions_root
和Header.uncles_root
来验证(译者注:即依据本地已有的区块头数据来验证相应区块体的完整性)
- 所得数据需要根据
- 检索收据
- 根据区块分批检索
- 所得数据需要根据
Header.receipts_root
来验证
状态检索
- 根据哈希值来检索单个状态树节点
- 在未来的协议中有可能会移除,因为这种检索机制与 flat database layout 有冲突
追随区块链
- 依赖于节点能访问区块广播网络
- 依赖于具有从全体区块头中获得的近期区块头
- 依赖于执行区块验证的能力来防止 DoS 攻击
事务验证
验证事务需要:
- 有能力执行
ecrecover
操作来确定发送者(译者注:即从签名数据中恢复出发送者的地址) - 确认该事务的 nonce 正是 该发起事务的账户的下一个 nonce
- 确认该账户的余额足以支付该事务的 gas(译者注:该检查的方法应为
余额 > 该交易指定的 gas price * gas limit
)- 需要了解 EVM 的规则来计算事务的 gas 值
区块验证
区块验证包含下述事项中的所有内容:
- 检查工作量证明的 seal
- 计算密集型
- 比较同一高度上其它竞争区块的挖矿总难度
- 执行交易,以验证
Header.state_root
的正确性- 需要区块执行能力
- 计算密集型
主链索引
主链区块索引
把区块号映射为该高度的主链区块的哈希值
- 需要从全部区块头中构建
- 每 100 万个区块,存储映射需占用 61 MB
- 每个条目需要 64 bytes(字节)
- 区块号需要 32 字节
- 可以使用更高效的变长编码方法来减少长度
- 区块哈希值也要 32 字节
- 截至 2021 年 1 月 29 日,主链区块索引总共占用约 600 MB 的空间
- 只能够通过验证所得区块哈希是否等于该高度上已知主链的区块哈希值来证明
- 如果能为协议引入区块头累加器的话,证明效率可以更高
主链事务索引
把事务的哈希值映射成该事务所在主链区块的哈希值,以及该事务在该块内的索引值。
- 需要从历史区块体中构建
- 截至 2021 年 1月 29 日,总共有 10 亿笔历史事务
- 每个条目都需要占用 70 字节
- 事务哈希值 32 字节
- 主链区块哈希值 32 字节
- 事务索引 4 字节
- 可以使用变长编码方法来稍微减少长度
- 截至 2021 年 1 月 29 日,这些索引总共占用 65 GB 空间
- 可以使用根据
Header.transactions_root
生成的默克尔证据来证明
区块头累加器
一类能让我们高效证明某个区块头来自主链的机制。基于 https://ethresear.ch/t/double-batched-merkle-log-accumulator/571
同步
历史同步
区块头同步
即一个节点追赶区块链的顶端时所用的进程。基于不同的安全等级,有几种同步方法“
- 完全验证
- 从创世块起下载全体区块头
- 检查点式下载法
- 使用一个自己信任的较近区块的区块头,并从该区块头开始追及区块链
- 追随 HEAD(区块链最新区块)
- 只需追随最新区块头,就可以相当有自信(自己同步得到的是主链而非伪链)。区块链越长,攻击者要制造伪链所需付出的代价就越大
当前,只有掌握了全体区块头,才能够任意地验证其他历史数据。区块头累加器可以改善这个状态,使得一个客户端可以把检查点设在区块链顶端,而仍然能够验证历史数据。
区块同步
客户端用来 pull(拉取)历史事务和叔块信息的进程。
- 验证这些数据需要先有全体区块头,然后根据
Header.transactions_root
和Header.uncles_root
来检查
收据同步
不执行 Full Sync(完全同步)的客户端往往需要通过 ETH DevP2p 协议来取得历史收据
- 验证这些数据需要先有全体区块头,然后根据
Header.receipts_root
和来检查
状态同步
节点获得近期状态完整副本的机制。
Full Sync(完全同步)
下载所有历史区块并按顺序执行这些区块。
- 最简单的同步方法
- 计算量非常大
- 需要区块头同步
- 需要区块同步
快速同步
下载全部历史区块,以及近期状态数据的副本
- 使用了一个安全假设:从历史区块中得到的状态根都是正确的
- 要求历史同步
- 会给提供这些状态数据的节点造成很大的负担
- Flat Dtatabase Layout 不容易满足快速同步的要求
Snap Sync(快照同步)
下载全部历史区块以及近期状态数据的副本
- 使用了一个安全假设:从历史区块中得到的状态根都是正确的
- 要求历史同步
- 非常适合 Flat Dtatabase Layout
- 带宽、硬盘读写和耗费时间都有指数级节省
Stateless Sync(无状态同步)
这个术语并不常用,其定义也可能随时调整
不像其它状态同步方法,这一方法最终无法使节点获得近期状态数据的完整副本。就其自身而言,其用法是免去维护状态数据本地副本之需、仍能验证区块;或者,它可以与其他同步方法结合,从而能即时验证区块,然后慢慢在本地构建出可访问的完整状态数据。
- 需要区块广播
- 需要区块见证数据
Beam Sync(光子同步)
光子同步本质上就是一种无状态同步,但不要求网络提供区块见证数据。相反,客户端是按需从网络中请求所需的状态
- 需要区块广播
- 需要按需状态检索
- Access list(访问列表)的可得性大大提高了这种方法的效率
On Demand State Retrieval(按需状态检索)
即从网络中检索任意状态元素的能力。
GetNodeData
ETH
DevP2P 协议会暴露信息对 GetNodeData/NodeData
,允许检索任意状态。此消息格式可能会被弃用。
基于 DHT 的状态网络
一种设想:我们可以让状态分散在网络中的所有节点中,并使这些数据能够按需被发现及检索到。
执行
挖矿
要求节点能够:
- 访问待打包事务池
- 运行 EVM
Access List(访问列表)
在某些形式的 EVM 执行过程中会触及的账户和合约存储位置的列表
State Access Patterns(状态访问模式)
Static State Access(静态访问模式,SSA)
EVM 执行在某些时候会具备的一种属性:调用者可以准确地预知该次执行会触及哪些状态
Dynamic State Access(动态访问模式,DSA)
EVM 执行在某些时候会具备的一种属性:调用者无法准确地预知到底会触及哪些状态
区块执行
- 需要 EVM 执行
- 就是执行给定区块中所有事务的过程
- 计算密集型
EVM 执行
- 举要 EVM 的某种实现
- 要求能够访问该次执行所触及的状态
- 可以使用近期状态来实现
- 也可使用区块见证数据来实现
账户管理
- 管理用于签署事务的私钥
- 账户一般会存储在一个 Keyfile (密钥文件)里
密钥文件
一种加密的存储格式,用于存储私钥
- Eth2 BLS Keystore 规范:https://eips.ethereum.org/EIPS/eip-2335
- Eth1 Keystore 规范:https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition
解密一般来说依赖于一些密码学元件,如: keccak
、 scrypt
、 pbkdf2
和 ECC/BLS12-381
JSON-RPC
eth_protocolVersion
- 传到 DevP2P 网络的元信息(meta information);
- 面向没有实现这个功能的客户端,很容易伪造这个信息
eth_syncing
- 关于该节点同步状态的元信息
- 面向没有实现这个功能的客户端,很容易伪造这个信息
eth_coinbase
- 表示该客户端使用的默认地址
- 面向没有实现这个功能的客户端,很容易伪造这个信息
- 仅对实现了账户管理功能的客户端有效
eth_mining
- 该节点挖矿状态的元信息
- 仅对正在挖矿的节点有效
- 面向没有实现这个功能的客户端,很容易伪造这个信息
eth_hashrate
- 挖矿的元信息
- 仅对正在挖矿的节点有效
- 面向没有实现这个功能的客户端,很容易伪造这个信息
eth_gasPrice
- 该节点 认为 此时 gasPrice 是多少的元信息
- 面向没有实现这个功能的客户端,很容易伪造这个信息
取出一个合适的 gas price 值是一个与需求高度相关的操作,没有哪种策略适合所有的应用场景。
eth_accounts
- 该节点所管理的账户的列表。
- 面向没有实现这个功能的客户端,很容易伪造这个信息
- 仅对实现了账户管理功能的客户端有效
eth_blockNumber
- 返回该节点认定为最新区块的区块号
- 需要 “全体区块头” 和 “追随区块链” 功能的结合
并不能完全确定,该节点是能提供该区块号处的 事务/收据/状态 数据,还是仅仅接受了该区块号是最新高度。
eth_getBalance
- 提供地址后,可返回该账户的 ETH 余额(以 wei 为单位)
- 需要响应节点能访问账户状态
eth_getStorageAt
- 提供账户及存储槽序号后,可返回该处存储的值
- 需要响应节点能访问合约存储项
eth_getTransactionCount
- 提供地址后,可返回该地址的 nonce
- 需要响应节点能访问账户状态
eth_getBlockTransactionCountByHash
- 提供一个区块的哈希值,返回该块中的事务数量
- 需要响应节点能访问区块体历史
eth_getBlockTransactionCountByNumber
- 提供一个区块的区块号,返回该块中的事务数量
- 需要响应节点能访问区块体历史
- 需要响应节点能访问主链区块索引
eth_getUncleCountByBlockHash
- 返回给定哈希值的区块中的叔块数量
- 需要响应节点能访问区块体历史
eth_getUncleCountByBlockNumber
- 返回给定区块号的区块中的叔块数量
- 需要响应节点能访问区块体历史
- 需要响应节点能访问主链区块索引
eth_getCode
- 返回给定账户处的字节码(bytecode)
- 需要响应节点能访问账户状态
- 需要响应节点能访问合约代码
eth_sign
- 返回给定地址的签名
- 仅对实现了账户管理功能的客户端有效
eth_signTransaction
- 为给定事务生成签名并返回已签名事务的 RLP 编码数据
- 仅对实现了账户管理功能的客户端有效
- 需要响应节点能访问账户状态以取得合适的 nonce
eth_sendTransaction
- 为给定事务生成签名并广播
- 仅对实现了账户管理功能的客户端有效
- 需要响应节点能访问账户状态以取得合适的 nonce
- 需要响应节点能参与事务广播
eth_sendRawTransaction
- 广播一条经过签名的事务
- 需要响应节点能参与事务广播
eth_call
- 在响应节点最新的状态上执行特定事务并返回执行结果
- 要求响应节点能执行 EVM
eth_estimateGas
- 在响应节点最近的状态上执行特定事务并返回执行该事务消耗的 gas 数量
- 要求响应节点能执行 EVM
- 最经常的用途是建构交易
eth_getBlockByHash
- 返回由哈希值指定的区块的数据
- 要求响应节点拥有全体区块头
- 要求响应节点能访问区块体历史
eth_getBlockByNumber
- 返回由区块号指定的区块的数据
- 要求响应节点拥有全体区块头
- 要求响应节点能访问区块体历史
- 要求响应节点能访问主链区块索引
对这个操作的调用可以直接映射成对
eth_getBlockByHash
的等价调用,只要能访问主链区块索引
eth_getTransactionByHash
- 提供哈希值,返回对应事务的数据
- 要求响应节点拥有全体区块头
- 要求响应节点能访问区块体历史
- 要求响应节点能访问主链事务索引
对这个操作的调用可以直接映射成对
eth_getTransactionByBlockHashAndIndex
的等价调用,只要能访问主链事务索引
eth_getTransactionByBlockHashAndIndex
- 返回由区块哈希值和事务索引号指定的事务的数据
- 要求响应节点拥有全体区块头
- 要求响应节点能访问区块体历史
eth_getTransactionByBlockNumberAndIndex
- 返回由区块号和事务索引号指定的事务的数据
- 要求响应节点拥有全体区块头
- 要求响应节点能访问区块体历史
- 要求响应节点能访问主链区块索引
对这个操作的调用可以直接映射成对
eth_getTransactionByBlockHashAndIndex
的等价调用,只要能访问主链区块索引
eth_getTransactionReceipt
- 返回由哈希值指定的事务的收据
- 要求响应节点拥有全体区块头
- 要求响应节点能访问区块体历史
- 要求响应节点能访问主链事务索引
eth_getUncleByBlockHashAndIndex
- 返回由区块哈希值和索引指定的叔块信息
- 要求响应节点拥有全体区块头
- 要求响应节点能访问区块体历史
eth_getUncleByBlockNumberAndIndex
- 返回由区块哈希号和索引指定的叔块信息
- 要求响应节点拥有全体区块头
- 要求响应节点能访问区块体历史
- 要求响应节点能访问主链区块索引
对这个操作的调用可以直接映射成对
eth_getUncleByBlockHashAndIndex
的等价调用,只要能访问主链区块索引
(译者注:以下操作码暂未给出解释)
eth_newFilter
eth_uninstallFilter
eth_getFilterChanges
eth_getFilterLogs
eth_getLogs
原文链接: https://github.com/ethereum/stateless-ethereum-specs/wiki/Glossary 作者: Piper Merriam 翻译: 阿剑
本文首发于:https://ethfans.org/posts/eth1x-glossary
区块链技术网。
- 发表于 2021-03-01 10:28
- 阅读 ( 636 )
- 学分 ( 4 )
- 分类:以太坊
评论