一、交易
在比特币中,交易就是消耗已有 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。
区块链 第10.5章 以太坊交易