Skip to content

以太坊

约 2996 个字 预计阅读时间 15 分钟

以太坊与比特币的异同

  • 是一个去中心的区块链平台
  • 多个节点参与组成 P2P 网络,没有任何节点有特殊权限
  • 各节点可以发出 transaction,也可以记录并执行网络上发出的 transaction
  • 交易被节点打包成一个“区块”,每个区块加上索引一次连接,形成区块链
  • 以太坊引入了可编程智能合约,为开发者提供更大灵活性
  • 以太坊有更快出块速度更先进奖励机制
    • 比特币约 10min 出一个块,以太坊约 13-15s 出一个块
  • 以太坊像安卓一样提供了丰富 API 和接口,社区活跃,容易开发应用
  • 以太坊以前采用 PoW(Power of Work)机制,现在采用 PoS(Power of Stake),一个区块奖励 2 个以太币
  • 比特币使用的 UTXO 模型是一种对开发友好、易于结算的模型;而以太坊使用余额模型,对用户更友好,这与传统金融账户一致

简介

比特币和以太坊是区块链中目前应用最广的两条主链。相比于比特币只实现了最基本的转账功能,以太坊能够有更多方面的应用。

以太坊(Ethereum)是一个去中心化、开源并且具备智能合约功能的公共区块链平台,其核心组件为以太坊虚拟机(Ethereum Virtual Machine, EVM)。EVM 是智能合约代码程序的专用运行环境,这使得每个节点的设备环境都能运行智能合约。

以太坊整体架构

eth_1.png

以太坊使用加密货币以太币(Ether, ETH)作为内部交易的 gas,用于支付交易费用和计算服务。以太币的最小单位是 wei(为纪念密码学家 Wei Dai),其换算关系如下:

eth_2.png

以太坊还允许使用代币(NFT),许多其它加密货币在以太坊上使用 ERC-20 标准发行

另外,以太坊还致力于移除先前比特币采用的工作量证明机制(PoW),逐渐转向更有效率的权益证明(PoS)

2022 年主网和 PoS 共识层信标链结合,宣布以太坊正式进入 2.0 时代,告别了大规模挖矿时代

工作量证明虽然保证了区块链的安全,但是消耗的计算资源太多。因此,以太坊在 2022 年终结了工作量证明机制,并开始采用权益证明,在权益证明机制下,以太坊交易执行过程是这样的:

首先,用户需要将一定数量的以太币(至少 32 ETH)质押到网络中的智能合约中,成为验证者。这些质押的代币作为抵押品,确保验证者的行为符合网络规则。多个验证者共同组成验证者委员会,参与网络的共识过程。

在每个区块周期内,系统会随机选择一位验证者作为区块提议者。该验证者负责创建新区块,并将新区块发送给网络上的其他节点进行验证。这个随机选择验证者的过程确保了网络的去中心化和安全性。

此处的随机时伪随机,抵押的代币越多,称为区块提议者的概率越大

新区块生成后,其他验证者会验证区块中的交易正确性。他们检查交易的签名、余额、Gas费用等,确保所有交易都符合网络规则。只有经过验证的交易才会被包含在区块中,从而确保区块链的数据完整性和一致性。

当验证者提议区块或者参与验证时,如果他们的投票与大多数其他验证者一致,他们会获得奖励。相反,如果验证者行为不当,如双签或提议无效区块,他们的质押资金会被没收,以维护网络的安全性。

质押时代的共识奖励包括质押奖励、油费小费、MEV收益:

TODO: 权益证明具体

智能合约

智能合约是以太坊最重要的技术贡献,它是存储在区块链上的程序,可以协助和验证合约的谈判和执行。智能合约可以通过数种图灵完备的编程语言编写,它会被编译成字节码发布在区块链上。

因为合约内容代码均公开,因此合约可以证明其宣称的功能是真实的;另一方面,合约的公开性也让合约中的漏洞可以被任何人看到。

以太坊账户模型

不同于比特币采用 UTXO 模型记录交易历史,以太坊用账户记录系统当前状态,包括账户余额信息、智能合约代码、每个合约的状态变量等。

以太坊账户是参与以太坊网络活动的基本实体,对以太坊状态的改变都需要通过账户来执行。以太坊账户类型分为外部账户和合约账户,其中外部账户相当于用户,而合约账户存储了合约代码,只能被外部账户调用激活。

eth_3.png

不管是外部账户还是合约账户,它们都具有四个属性,只不过有些属性可以置空或特殊值:

  • nonce: 对于外部账户,表示已发送的交易数量;对于合约账户,表示已创建的合约数量
  • balance: 余额,不管是外部账户还是合约账户都有余额
  • strorageRoot: 存储合约账户智能合约状态树的根,外部账户中该值为空
  • codeHash: 对于外部账户,为对空串的哈希值;对于合约账户,为对合约代码的哈希值

因此,对于外部账户,有效信息为发送的交易数 + 余额

外部账户由私钥来控制,每一个外部账户都拥有一对公私钥(采用的 ECC 算法),用于签署交易。账户地址通常由公钥通过一系列算法计算。

以太坊地址计算流程

eth_4.png

合约账户是由外部账户创建的包含合约代码的账户,其不是由私钥控制,而是由合约代码控制。合约账户的地址是由合约创建时合约创建者的地址以及该地址发出的交易共同计算出来的。

合约账户也拥有一定以太币余额,这使得合约可以成为资金池,常在金融等相关领域中应用。合约被执行时,只能操作合约账户拥有的特定存储(主要是存储合约各状态变量的值)。

每当合约账户收到一条交易消息时,其合约代码将被交易输入的参数调用执行。而合约代码将会在参与到网络的每一个节点上执行,执行结果将作为新块验证的一部分。

可以认为合约发布在区块链就是生成一个对象的实例,用户会得到合约账户的地址,相当于对象的指针

以太坊交易

交易(Transaction)是由账户发出,带签名的消息。交易类型可分为三类:

  • 转账: 将一定数量以太币发送到另一个外部账户或合约账户
  • 创建合约: 将合约代码部署到以太坊区块链上,生成新的合约账户
  • 调用合约: 对已部署的合约代码中的函数进行调用,以执行合约中的特定逻辑

eth_5.png

  • nonce: 相当于计数器,一个账户可以发起多笔交易,为了防止重放攻击,以太坊使用该字段唯一标识和排序这些交易
  • gasPrice: gas 的单价,即每个基本操作的价格,以 wei 为单位
    • 该字段的值视当时区块链拥堵情况而定,更高的 GasPrice 更容易被打包
    • 实际消耗的费用为 gasPrice * gasUsed
    • 其中转账交易的消耗固定为 21000 Gas,其它操作视合约代码而定
  • gasLimit: 交易发起者愿意为执行该笔交易支付的最大 Gas 上限
    • 用户发起交易要预先支付 gasPrice * gasLimit 费用,交易打包后多给的部分会退还
    • 如果达到了 gasLimit 上限仍未执行完,该费用不会退还
  • from: 发送交易的地址
  • to: 交易的目标地址
    • 该字段为空则是创建合约
    • 该字段为合约地址则是调用合约接口
    • 该字段为普通地址则是以太坊交易转账
  • value: 转账金额,以 wei 为单位
  • data: 传递数据,可为空
    • 调用合约时,为参数
    • 创建合约时,为合约的字节码
  • 签名: 发送方的签名

以太坊区块会为每一笔交易都产生一笔回执(Recipt),表示交易的最终状态。一个回执信息主要包括:

  • status: 执行结果,1 表示成功,0 表示失败
  • gasUsed: 已消耗的 Gas 数量
  • txHash: 交易哈希
  • logs: 交易产生的日志
  • ...

以太坊区块

eth_6.png

交易被打包进区块中,并按照时间顺序形成一条区块链。区块由区块头和区块体组成,其中区块体中主要是交易列表,而区块头存储区块的元信息,用于对区块内容进行一些标识、校验和说明等,具体字段包括:

  • ParentHash: 父区块哈希值
  • UncleHash: 叔块列表的哈希值
  • Coinbase: 打包者地址
  • Root: 状态数根节点哈希
  • TxHash: 交易树根节点哈希
  • ReceiptHash: 交易收据树根节点哈希
  • Bloom: Bloom 日志过滤器,用来加速交易信息查找
  • Number: 区块号
  • GasLimit: 区块内所有 gas 消耗上限
  • GasUsed: 区块内所有交易执行消耗 gas 的总和
  • Time: 区块时间戳
  • Extra: 附加数据
  • Difficulty*: 区块难度
  • MixDigest*: 工作量证明哈希值
  • Nonce*: 工作量证明中的随机数

对于 PoS,上面三个星标都可以为空

更进一步来说,对于非公链场景(如联盟链),Coinbase、Difficulty、GasLimit、GasUsed、MixDigest、Nonce、Uncle 可能都不需要;其它的字段视链的设计也不一定存在。

世界状态是地址(账户)到账户状态的映射,它并不直接保存在区块链上,区块头中只存储了世界状态的根,即上面说的字段 Root

世界状态使用树作为数据结构,此树也被称为状态数据库或状态树。世界状态会随着交易的执行而持续更新。

eth_7.png

具体而言,以太坊存储账户数据的数据结构为帕特里夏树(Merkle Patricia Tree, MPT),这是一种改进的 Merkle Tree,属于压缩前缀树。

从全局来看,以太坊就是一个状态机,每当有账户状态改变时,其对应的 Root 也会改变,因此,Root 被称为当前的世界状态。每个区块头中的 Root 都表示了一个完全状态的逻辑树,但每个区块交易体中记录的数据只包括修改的部分,如此保证区块的数据量不会越堆越大。

例如区块内只有一笔转账,那这个区块只记录修改的两个账户,以及两个账户因修改后导致的上层路径哈希值变化

应用

DeFi, 客户端软件(Geth, Parity), 游戏,企业软件...

跨境支付、供应链管理、医疗保健、预付费卡...

Comments: