liujie
liujie
Published on 2024-09-02 / 3 Visits
0
0

以太坊-交易

https://liaoxuefeng.com/books/blockchain/ethereum/transaction/index.html

在比特币中,交易就是消耗已有UTXO,并通过执行脚本产生新的UTXO,其中隐含的新旧差额即为矿工手续费。

在以太坊中,交易也需要手续费,手续费被称为Gas(汽油),它的计算比比特币要复杂得多。

以太坊除了最基本的转账:即从一个账户支付Ether到另一个账户,还支持执行合约代码。合约代码是图灵完备的编程语言,通过EVM(以太坊虚拟机)执行。如果某个合约编写了一个无限循环,那么所有节点执行该合约代码,岂不是永远无法结束?

为了保证合约代码的可靠执行,以太坊给每一个虚拟机指令都标记了一个Gas基本费用,称为gasUsed。例如,加减计算的费用是3,计算SHA3的费用是30,输出日志的费用是375,写入存储的费用高达20000。总的来说,消耗CPU比消耗存储便宜,简单计算比复杂计算便宜,读取比写入便宜。

除了gasUsed外,用户还需要提供一个gasPrice,以Gwei(1Gwei=109Wei)为单位。通过竞价得到一个矿工愿意接受的gasPrice。如果一个交易消耗了120000的gasUsed,而gasPrice是50 Gwei,则交易费用是:

120000 x 50 Gwei = 6000000 Gwei = 0.006 Ether

但是在执行代码的时候,存在条件判断、循环等语句,同一段代码,执行的结果也可能不同,因此,事前预计一个合约执行要花费多少Gas,不现实。

所以以太坊规定,一笔交易,先给出gasPrice和gasLimit,如果执行完成后有剩余,剩余的退还,如果执行过程中消耗殆尽,那么交易执行失败,但已执行的Gas不会退。

太复杂了是不是?我们还是举个例子。

假定某个账户想执行一笔交易,他给出gasPrice为50 Gwei,预估gasUsed约120000,设定gasLimit为150000,则预支付的Ether为:

150000 x 50 Gwei = 7500000 Gwei = 0.0075 Ether

如果账户的Ether余额不足0.0075,则该交易根本无法发送。如果账户余额等于或超过0.0075,例如余额为0.008,则矿工可以将该交易打包。假设实际执行消耗的gasUsed为120000,则交易费用0.006,账户剩余0.002。

很少有交易能准确预估gasUsed,只有标准转账交易是21000,因此,标准的转账交易gasLimit可以设置为21000(即恰好消耗完毕无剩余)。

Gas Price是全网用户竞价产生的,它时刻在波动。如果交易少,Gas Price将下降,如果交易多,网络拥堵,则Gas Price将上升。以太坊的Gas价格可以在Etherscan跟踪。

交易回执

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

  • status:执行结果,1表示成功,0表示失败;

  • gasUsed:已消耗的Gas数量;

  • txHash:交易Hash;

  • logs:交易产生的日志;

  • ……

转账交易

转账交易是指两个外部账号转移Ether,我们以交易0xb940...4ad7为例,可以看到:

  • Transaction Hash: 0xb940...4ad7,这是交易Hash,即交易的唯一标识;

  • Status: Success,表示交易成功;

  • From: 0x0FFf...bBc4,交易的发送方;

  • To: 0x5b2a...5a46,交易的接收方;

  • Value: 1.6912 Ether,交易发送的Ether;

  • Gas Price: 82 Gwei,Gas的价格;

  • Gas Limit: 21,000,转账交易恰好消耗21000Gas,因此总是21000;

  • Usage by Txn: 21,000 (100%),消耗的Gas占比,这里恰好全部消耗完;

  • Nonce:0,发送方的nonce,0表示第1笔交易;

  • Input Data: 0x,因为是转账交易,没有输入数据,因此为空。

合约交易

合约交易就是指一个外部账号调用某个合约的某个public函数。我们以交易0x8aff...8cd0为例,可以看到:

  • From: 0x2329...BA3a,交易的发起方,该地址一定是外部账户;

  • To: 0x7a25...488D,交易的接收方,这里地址是一个合约地址;

  • Value: 4.5 Ether,即向合约发送4.5 Ether;

  • Gas Limit: 152,533,这是交易发起前设定的最大Gas;

  • Usage by Txn: 125,290 (82.14%),这是交易实际消耗的Gas;

  • Input Data: 0x7ff36ab5...,这是交易的输入数据,其中包含了调用哪个函数,以及传递的参数,解码后可知调用函数是swapExactETHForTokens

可见,转账交易的Gas费用是固定的,而合约交易只能预估,具体费用以实际执行后消耗的为准。

小结

以太坊的交易需要消耗Gas,而Gas价格和实际消耗的数量决定了一个交易实际消耗的Ether,即交易成本。

合约交易无法精确地确定Gas数量,只能预估并给出Gas Limit。


Comment