Renaissance Labs

Posted on Jan 18, 2022Read on Mirror.xyz

技术角度分析Etherscan上14020984区块信息

0.账户 交易 消息

账户

以太坊账户与我们所知的账户概念有一定相似之处,却又有很大的区别,更不同于比特币中UTXO。 账户分两类:

  • 外部拥有账户(EOA),也就是普通账户
  • 合约账户

1.普通账户

所谓的普通账户就是我们存放以太币的账户,可以随意生成,它具有以下特性:

  • 拥有以太币余额(以太币存放的地方,与比特币的UTXO模式不同)的balance。
  • 用于确定每笔交易只能被处理一次的计数器(nonce)。
  • 发送交易(以太币转账、发布合约、调用智能合约)
  • 通过私钥控制
  • 没有相关联的代码

2. 合约账户

合约账户也是最激动人心的概念和底层代码实现,它是功能和数据的集合,存在于以太坊的特定地址(发布智能合约的地址上),拥有一下特性:

拥有以太币余额 有相关联的代码 通过交易或消息调用的方式触发并由以太坊虚拟机(EVM)解释执行 当被执行时:

运行在随机复杂度(图灵完备性) 只能操作其拥有的特定储存,例如可以拥有其永久state 可以call其他合约 所有以太坊区块链上的操作都是由各账户发起的交易来出发。智能合约账户收到一笔交易,交易所带的参数都会成为代码的入参。合约代码会被以太坊虚拟机(EVM)在每一个参与网络的节点上运行,以作为它们新区块的验证。

交易

“交易”术语通俗来讲就是一个账户向另外一个账户发送一笔被签名的消息数据包的过程,区块链会记录并存储相应的数据。延伸一下,调用智能合约改变一个合约账户的数据状态,也是一笔交易,同样需要花费手续费。

交易包括:

消息的发送者 消息的接收者 签名信息,用来证明发送者有意向通过区块链向接收者发送消息 价值域,从发送方转移到接受方的以太币的数量 可选的数据域,用来储存智能合约或调用智能合约的代码 gasLimit,该交易的执行时使用gas的上限 gasPrice,交易发送者愿意支付的gas费用的价格。一个单位的gas表示了执行一个基本指令,例如一个计算步骤。

消息

合约具有发送”消息”到其他合约的能力。消息是一个永不串行且只在以太坊执行环境中存在的虚拟对象。它们可以被理解为函数调用(function calls)。曾有人咨询,智能合约是否可以调用比特币转账,这里的解释已经给出了明确的答复。

消息包括:

  • 消息发送者
  • 消息的接收者
  • 可选的数据域,合约实际上的输入数据
  • gasLimit,同交易。

总体来说,一个消息就是一笔交易,除了它不是由外部账户生成,而是合约账户生成。当合约正在执行的代码中运行了call 或者delegatecall这两个命令时,就会生成一个消息。消息有的时候也被称为”内部交易”。与一个交易类似,一个消息会引导接收的账户运行它的代码。因此,合约账户可以与其他合约账户发生关系。

1. Gas

Gas 定义

Gas 用来衡量执行某些动作需要多少“工作量”,这些“工作量”就是为了执行该动作支付给网络的费用额。Gas 是给矿工的佣金,并以 ETH 支付,无论是交易、执行智能合约并启动 DApps,还是支付数据存储费用,都需要用到 Gas。

对于每个被执行的命令都会有一个特定的消耗,用单位gas计数。每个合约可以利用的命令都会有一个相应的gas值。gas使用ETH来支付。

Gas 组成

指令价目表:

指令价目表

举几个例子:

  • ADD:加法操作 3Gas
  • MUL:乘法操作 5Gas
  • SUB:减法操作 3Gas
  • DIV:除法操作 5Gas
  • HASH:计算哈希值 30Gas

GasPrice以Gwei为单位。

以太主网的区块情况全景图

由两个部分组成: Gas limit(限制)* Gas Price(价格)

  • Gas Price 是 Gwei 的数量,是指用户愿意花费于每个 Gas 单位的价钱,frontier版 默认为 0.05 Gwei。
  • Gas Limit根据扮演角色的主客观区分,分为用户交易gaslimit(代码中通常记tx.Gas())与旷工区块gaslimit(代码中通常记herader.GasLimit)。
  1. 用户交易Gas limit:用户愿意为执行某个操作或确认交易支付的最大Gas量(最少21,000),至于花费这些Gas量是否能完成工作是不确定的。
  2. 旷工区块gaslimit:区块Gas limit是单个区块允许的最多gas总量,以此可以用来决定单个区块中能打包多少笔交易。
 例如,我们有5笔交易的gas limit分别是10、20、30、40和50.如果区块gas limit是100,那么前4笔交易就能被成功打包进入这个区块。矿工有权决定将哪些交易打包入区块。所以,另一个矿工可以选择打包最后两笔交易进入这个区块(50+40),然后再将第一笔交易打包(10)。如果你尝试将一个会使用超过当前区块Gas limit的交易打包,这个交易会被网络拒绝,你的以太坊客户端会反馈错误"交易超过区块Gas limit",( Gas limit最少21,000 )。

以太币单位换算 单位

单位 wei值 Wei wei 1 1 wei Kwei (babbage) 1e3 wei 1,000 Mwei (lovelace) 1e6 wei 1,000,000 Gwei (shannon) 1e9 wei 1,000,000,000 microether (szabo) 1e12 wei 1,000,000,000,000 milliether (finney) 1e15 wei 1,000,000,000,000,000 ether 1e18 wei 1,000,000,000,000,000,000 ————————————————

Gas 实际花费

一个交易的实际交易费由两个因素组成:

  • gasUsed:每个EVM中的命令都被设置了相应的gas消耗值。gasUsed是所有被执行的命令的gas消耗值总和。
  • gasPrice:该交易中单位gas的价格(用以太币计算)
   交易费 = gasUsed * gasPrice

以太坊关于交易的结构体,和其包含的Price、GasLimit:

type Transaction struct {
	data txdata
	// caches
	hash atomic.Value
	size atomic.Value
	from atomic.Value
}
 
type txdata struct {
	AccountNonce uint64          `json:"nonce"    gencodec:"required"`
	Price        *big.Int        `json:"gasPrice" gencodec:"required"`//用户为每个gas出单价
	GasLimit     uint64          `json:"gas"      gencodec:"required"`//用户愿意支付的最大gas量
	Recipient    *common.Address `json:"to"       rlp:"nil"` // nil means contract creation
	Amount       *big.Int        `json:"value"    gencodec:"required"`
	Payload      []byte          `json:"input"    gencodec:"required"`
 
	// Signature values
	V *big.Int `json:"v" gencodec:"required"`
	R *big.Int `json:"r" gencodec:"required"`
	S *big.Int `json:"s" gencodec:"required"`
 
	// This is only used when marshaling to JSON.
	Hash *common.Hash `json:"hash" rlp:"-"`
}

区块的高度的花费情况

Gas Used:30,009,820 (99.94%) +100% Gas Target
Gas Limit:30,029,295
Base Fee Per Gas:0.000000131296607397 Ether (131.296607397 Gwei)
Burnt Fees:🔥 3.94018755459463854 Ether
Extra Data:七彩神仙鱼H" (Hex:0xe4b883e5bda9e7a59ee4bb99e9b1bc480422)
Ether Price:$3,210.90 / ETH

其中Burnt Fees显示烧毁的交易费和其占比,以适应 EIP-1559带来的变化。

在EIP-1559下,不再采用GasPrice,而是采用交易费用的计算公式如下:

交易费用= baseFee + min(maxFee - baseFee, priorityFee)

baseFee:根据网络拥塞和最新值(对于区块空间)浮动的费用,可以通过新的JSON RPC调用eth_feeHistory来获取。在以太坊上发送交易或完成操作所需的最低Gas价格。基本费由协议设置,它是可变的,基本费是会被销毁的。

priorityFee(也称为小费、矿工小费):用于吸引区块生产者参与交易的费用,也就是小费,用户为了让矿工优先处理自己的交易或者操作,支付给矿工的小费,由用户自行设置,默认情况下,预计这笔小费是2 gwei。

maxFee:为了交易完成,用户愿意支付的最高网络费用。

2. Total Difficulty & Difficulty

Difficullty:以太坊黄皮书中4.3 The Block中有描述。该字段是表征挖矿(开采一个当前block)的难度。Block的Difficulty由共识算法基于parentBlock的Time和Difficulty计算得出,它会应用在区块的‘挖掘’阶段。 totalDifficulty:以太坊黄皮书中10. BLOCKTREE TO BLOCKCHAIN有描述。含义是从第一个块到当亲块的总难度。

Difficulty:11,896,361,285,881,238
Total Difficulty:39,150,746,388,980,509,547,746

3. Block Height

一个区块的高度是指在区块链中它和创世区块之间的块数。

Block Height: 14020984

4. Timestamp

区块被mined的时间和日期

Timestamp:1 day 1 hr ago (Jan-17-2022 04:59:41 AM +UTC)

5. Transactions

交易对象数组。

Transaction就是外部账户发起的,比如说向某个账户转账,调用合约函数等;而Internal Transaction则是合约账户发起的,比如 A 合约调用了 B 合约的gift()函数,那么这个动作就会被 etherscan 标记为内部交易。

Internal Transaction并不是一个真正的Transaction,它是在一笔交易执行过程中,合约根据一定条件,进行转账或者是调用新合约等一系列动作产生的结果,正如 etherscan 上标注的一样,Internal Transactions as a result of Contract Execution

Transactions: 457 transactions and 14 contract internal transactions in this block

457 transactions

457 transactions

14 contract internal transactions

14 contract internal transactions

典型特点是内部call

6. Reward

以太坊的区块有两种,普通区块和叔块,我们需要分情况来讨论每种区块的奖励。

总奖励 = 固定奖励 + Gas开销 + 包含叔块奖励

普通区块奖励:

  • 固定奖励NETH,每个普通区块都有
  • 区块内包含的所有程序的Gas花费的总和
  • 如果普通区块包含了叔块,叔块奖励见下面公式。

叔块奖励

叔块奖励 = ( 叔块高度 + 8 - 包含叔块的区块的高度 ) * 普通区块奖励 / 8

  • 打包区块高度在[0,5000000)区间时,计算公式:

reward = (uncle_height - block_height + 8)/8 * N ETH

  • 打包区块高度在[5000000, 当前),计算公式:

reward = 挖矿奖励/32

  • 包含叔块奖励指什么意思?

  • 叔块的高度是多少?

  • 为什么叫叔块?

  • 叔块中的交易怎么办?

  • 可以接受多少个叔块?

  • 叔块率含义?

    以太网状态分析平台

叔块(Uncle Block)

Mined by:0x829bd824b016326a401d083b33d092293333a830 (F2Pool Old) in 22 secs
Block Reward:21.83401614942464323 Ether (2 + 23.77420370401928177 - 3.94018755459463854)
Uncles Reward:0

8. 区块大小 Size

当前区块的字节大小,代表了一个区块能容纳多少数据的能力。大小由什么来决定呢?Gas limit

Size:60,659 bytes

9. Hash

  • Block(区块)是Ethereum的核心数据结构之一。所有账户的相关活动,以交易(Transaction)的格式存储,每个Block有一个交易对象的列表;每个交易的执行结果,由一个Receipt对象与其包含的一组Log对象记录;所有交易执行完后生成的Receipt列表,存储在Block中(经过压缩加密)。
  • Hash: 当前区块的哈希值。如果区块没有被确认,这个字段会是null值。
  • ParentHash: 父区块头的Hash值,不同Block之间,通过前向指针ParentHash一个一个串联起来成为一个单向链表。
  • receiptsRoot: 包含此区块所列的所有交易收据的树的根节点Hash值
  • Sha3Uncles: 数据块的哈希值
  • StateRoot: 区块状态树的根哈希
Hash:
0xcb9412b2d60c93a4e7296951129770aef07c131bf3f830c5d11f5ba40e64d308
Parent Hash:
0x04f964549bbd6809096d013a4b72fa880167b437ea46867eef9f2888b70244da
Sha3Uncles:
0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
StateRoot:
0xfb55fa95d8c8dc0594267ae31481a02af131088bce98f11676df24020569104c

10. Nonce

nonce: QUANTITY - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.

这里的是交易下的nonce值,是账户发起交易所维护的nonce,一个交易对应一个nonce值,注意区分区块中的nonce,区块中的nonce是用于POW的nonce。每发起一笔交易,nonce就会加一(nonce 计数从 0 开始,如果你的账户有5笔转出交易,那么最后一次的nonce值会是4)。

    对于发起的解释:
    1.外部账户(EOA)每发送一笔交易;
    2.合约账户 (Contract Wallet)  每创建一个合约

    而转入交易、合约调用其他合约等属于内部调用,因此 nonce 值不变。

作用

  • 确定交易顺序,如果你前后发送了两笔交易,想要它们被顺序打包,那么矿工就可以按照 nonce 的顺序进行打包。
  • 防止重放攻击,如果没有 nonce ,交易信息被生成序列别人可以看到并重复提交,从而掏空你的钱包。有了 nonce ,生成序列后同一 nonce 的交易只能被打包一次。
  • 加速交易,基于 nonce 的特性,自增和唯一性,使用相同的 nonce 重新发起交易即可实现加速。例:如果一笔交易A gas price = 5,nonce = 1,广播后交易处于pending状态,创建交易B设置 gas price 更高,如10、20 , nonce=1,再次发布交易,此时在矿工的交易池端,B 交易先被打包了,矿工会检查 A 交易,发现 nonce 已经存在了,认为 A 是不合理的交易,则会自动丢弃该交易。(如果交易被打包,即非 pending 状态,则是不可逆的,就无法取消或加速了)
  • 取消交易。基于加速交易的案例。创建交易 B,设置 value =0 nonce = 1(也就是 A 交易的nonce值),收款方=发送方,设置更高的 gas price ,广播交易,原来的交易被丢弃了,新交易会被矿工打包,不会丢失任何资金。但是你还是需要为 B 交易付出矿工费。

使用规则

  • 当nonce太小(小于当前的nonce值),交易会被直接拒绝,Transactions with too low a nonce get immediately rejected;
  • 当 nonce 太大,大于当前 nonce,交易会一直处于队列之中,Transactions with too high a nonce get placed in the transaction pool queue;
  • 当发送一个比较大的nonce值,然后补齐开始 nonce 到那个值之间的nonce,那么交易依旧可以被执行,If transactions with nonces that fill the gap between the last valid nonce and the too high nonce are sent and the nonce sequence is complete, all the transactions in the sequence will get processed and mined.
  • 交易队列只保存最多64个从同一个账户发出的交易,也就是说,如果要批量转账,同一节点不要发出超过64笔交易。 The transaction pool queue will only hold a maximum of 64 transactions with the same From:address with nonces out of sequence.
  • 当某节点 queue 中还有交易,但此时停止 geth 客户端,queue 中的交易会被清除掉,When the geth instances are shut down and restarted, transactions in the transaction pool queue disappear. 当前 nonce 合适,但是账户余额不足时,会被以太坊拒绝;
Nonce:0x38e71300043edacf

11. Mined by

取得该区块记账权的矿工

Mined by:
0x829bd824b016326a401d083b33d092293333a830 (F2Pool Old) in 22 secs