EIP-1559升级后的Web3j使用方法

1 简介

EIP-1159不能兼容之前的版本,因此将导致硬分叉。包含EIP-1159升级的分叉被称为伦敦分叉,大约在8月4日发生。

EIP-1559是V神和Ethhub_io创始人Eric Conner于2019年3月联合提出的以太坊交易手续费机制改进提案。核心是更改了向矿工支付 Gas 费用的方式。Gas 费将分为两部分:基础费(Basefee)和矿工小费(Tip)。

EIP-1559提案通过将Gas费的费率根据实际的使用需求进行调整,从而保证区块的使用率维持在半满状态,并动态地调整Gas 费的上限,更好地应付短时的需求峰值,避免需求旺盛时导致的网络拥堵,从而改善用户体验。

基础费是用户必须支付的最低价格,以便将其交易打包进区块之中,不过基础费不归矿工所有而是将其销毁。

但另一方面,由于销毁基础费(Basefee)形成的通缩机制,是提升每一个 ETH的价值,却定向减少了以太坊矿工的区块奖励。

2 EIP-1559交易

2.1新术语:

首先,复习一下:EIP-1559改变了以太坊交易费用的计算方式以及这些费用的去向。现在必须注意三个独立的值,而不是一个单一的Gas价格。

  1. 基本费用(Base Fee),这是由网络本身决定的,随后被销毁。
  2. 最高优先费(Max Priority Fee),这是可选的,由用户决定,并直接支付给矿工。
  3. 每单位Gas的最高费用(Max Fee Per Gas),这是你愿意支付每单位Gas费用的最高绝对值,以使你的交易纳入到区块中。为了简洁明了,我们将它称为最高费用。

包括这些新字段的交易被称为类型2,而带有原始Gas价格字段的传统交易仍被支持,被称为类型0。注意:EIP-1559并没有对"Gas限额"(即交易被授权消耗的最高Gas量)带来变化。

2.2基本费用的确定

基本费用由以太坊网络决定,而不是由寻求交易的终端用户或寻求验证交易的矿工设定。基本费用的目标是使区块完整度在50%,并基于最近确认的区块内容。根据新区块的完整程度,基本费用会自动增加或减少。

比如:

如果上一个区块完整度正好是50%,那么基本费用将保持不变。

如果上一个区块是完整区块(100%),那么下一个区块的基本费用将增加最多12.5%。

如果上一个区块完整度超过50%,但不到100%,那么基本费用将增加12.5%以下。

如果上一个区块是空白区块(0%),那么下一个区块的基本费用将减少最多12.5%。

如果上一个区块完整度超过0%,但低于50%,那么基本费用将减少12.5%以下。

这个新机制是为了帮助平滑交易费用,防止Gas费用突然飙升。谈到基本费用,最重要的是要记住:它是100%自动的,可直接从网络上读取。

2.3设置优先费

最高优先费--通常也被称为矿工小费--是一种 "可选的"额外费用,直接支付给矿工,以激励他们将你的交易纳入区块。

虽然最高优先费在技术上是可选的,但目前大多数网络参与者估计,交易一般需要至少2.0 GWEI的小费才能被纳入。尽管如此,特定的矿池可能会选择设置替代的最低纳入标准。

对于在正常、不拥挤的网络条件下提交的"典型"交易,最高优先费需要接近2.0 GWEI。但是,对于顺序或包含在下一个区块中很重要的交易,或者当网络高度拥堵时,可能需要更高的最高优先费来优先处理你的交易。

最高优先费的一个微妙差别是,它代表了你愿意支付给矿工的最高小费。然而,如果基本费用加上最高优先费用超过了最高费用(见下文),最高优先费将被减少,以满足最高费用的上限。这意味着实际小费可能需要小于你的最高优先费,在这种情况下,你的交易对矿工的吸引力可能会降低。

2.4 计算最高费用

在介绍了基本费用和最高优先费用的基本情况后,来了解一下最高费用这个有点反直觉的概念吧。

最高费用是你愿意为每单位Gas支付的绝对最高金额,以使你的交易得到确认。在这里,事情可能会变得有点混乱--因为在大多数情况下,你的实际交易费用将低于你预先指定的最高费用。以下是原因阐述:

你交易的最低Gas价格是当前的基本费用。

然而,如果在你交易尚未完成时,基准费用增加了呢?那么,你的交易就有可能被卡住,或失败或被放弃。

因此,为了在EIP-1559下实现可预测的交易结算,目前认为最好的做法是设置一个预期基本费用增加的最高费用。但应该增加多少?理由又是什么?

我们符合EIP-1559标准的Gas估算器目前使用以下简单的启发式方法来计算任何给定的基本费用和最高优先费用组合的推荐最高费用。

最高费用 = (2 * 基本费用) + 最高优先费用

在计算最高费用时,将基本费用翻倍,可确保您的交易在连续六个100%完整的区块内保持可被纳入。以下是相关例子。

以太坊主网浏览器

Tx: 0x957653fbac8e57910fd8f00365ecd0dc956e67e23204601cdc72d3368be87f41

Gas Used by Transaction:   182,723 (66.67%)

Base Fee Per Gas:    0.000000062838077631 Ether (62.838077631 Gwei)

Max Fee Per Gas:    0.000000114862686488 Ether (114.862686488 Gwei)

Max Priority Fee Per Gas:   0.000000001 Ether (1 Gwei)

Burnt Fees:  

   0.011481962058969213 Ether    = GasUsed * BaseFeePerGas   基本费用燃烧掉

Txn Savings   

 0.009323369604177611 Ether

 =MaxFeePerGas -(BaseFeePerGas + MaxPriorityFeePerGas)*GasUsed

3 使用新版本的web3j库

原来的3.x、4.x版本都不能用了,最新的版本是4.8.7,必须使用这个才能支持EIP-1559。

官方手册: Quickstart - Web3j

在maven项目中引入依赖包:

<dependency>

            <groupId>org.web3j</groupId>

            <artifactId>core</artifactId>

            <version>4.8.7</version>

        </dependency>

4 如何发出新类型交易

我在以太坊通用空投机项目升级中支持EIP-1559,具体代码可以查看源码:

https://cszy-server:8443/svn/code/DAPP-ETH/Eth-AirDrop2

net.genesiscloud.eth_airdrop.control.EthTransferEIP1559.java

4.1 ETH转账

调用函数sendFundsEIP1559

TransactionReceipt transactionReceipt = Transfer

                .sendFundsEIP1559(web3j, credentials, to, BigDecimal.valueOf(value.longValue()), // value

                      Convert.Unit.WEI, // unit

                      BigInteger.valueOf(21000), // gasLimit

                      maxPriorityFee, maxFeePerGas // maxFeePerGas (max fee transaction willing to pay)

                ).send();

必须填写gasLimitmaxPriorityFeemaxFeePerGas这样发出的交易就是类型2的新交易。

4.2 ERC20代币转账

有两种方法:

(1)组装交易,然后签名,最后广播交易。异步方法,返回交易tx,由调用方轮询检查交易状态是否成功。优点是可以指定nonce。

 (2)组装交易,签名+广播一体化。异步方法,返回交易tx,由调用方轮询检查交易状态是否成功。 这种方法比较简便,推荐使用。

 

4.3 合约调用

一般采用上述方法(2),指定调用函数名称,输入参数列表,输出参数列表,生成调用data,然后发送给合约地址就可以了。

5 如何发出原类型交易

只要使用原来的函数就可以发出0类型交易,参看函数sendERC20AsyncLegacy

需要正确设置gasPrice, gasLimit

 

6 如何估算出基本费用和小费

6.1 读取基本费用

目前在手册中没有发现专门的获取基本费用函数,需要自己手动读取计算。

基本思路:

  1. 读取最新区块号,
  2. 根据最新区块号,读取最新区块数据
  3. 获得区块的基本费用
  4. 单位转换

 

 

6.2 读取优先费用

思路: 读取最新区块的第一笔交易,获得该笔交易的优先费用。

说明: 这个方法有时无效,返回0。

原因:区块中无交易,在测试网中常出现。第一笔交易是普通交易,读不到优先费用。

 

6.3 读取最高费用

思路:读取最新区块的第一笔交易,获得该笔交易的最高费用。

说明: 这个方法有时无效,返回0。原因与上一个方法相同。

String maxfee   = trans.getMaxFeePerGas()

6.4 计算新交易的最高费用

思路: 采用2倍原则计算:最高费用 = (2 * 基本费用) + 最高优先费用。可以保证在接下来的连续6个区块一定成交。

6.5 读取gasPrice

思路:获取当前以太坊网络中最近一笔交易的gasPrice

 

Go-Ethereum(Geth)是一个实现了Ethereum协议的开源客户端,其中EIP-1559是关于交易费用处理的一项重要升级,它引入了基础费和上限费的概念。在EIP-1559中,用户需要支付两部分费用:一部分是固定的基础费,用于保证网络的基本服务;另一部分是可变的上限费,取决于市场供需。 下面是一个简化的示例,展示了如何在Golang中通过`go-ethereum`库实现基于EIP-1559的交易创建: ```go package main import ( "context" "fmt" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rpc" ) func main() { // 连接到本地的Ethereum节点(假设你已经启动了一个Geth节点) client, err := rpc.Dial("http://localhost:8545") if err != nil { fmt.Println("Failed to connect to node:", err) return } // 创建一个新的交易 senderAddress := "0xYourSenderAddress" // 用实际地址替换 receiverAddress := "0xYourReceiverAddress" // 用实际地址替换 value := types.NewUnits(10) // 转账价值,单位为wei feeCap := types.NewUnits(1) // 上限费,这里设为较低值以便于演示 maxPriorityFeePerGas := types.NewUnits(1) // 最高优先级费用率 // 使用EIP-1559计算交易费用 transaction, _, _ := client.Eth.SendTransaction( rpc.Transaction{ From: senderAddress, To: receiverAddress, Value: value, GasLimit: types.GWei(21000), // 高效交易一般设置较高的gas limit FeeCap: feeCap, PriorityFeeCap: maxPriorityFeePerGas, MaxFeePerGas: maxPriorityFeePerGas, // 也可以省略,因为会被FeeCap自动控制 }, ) // 输出交易哈希便于跟踪 hashStr := hexutil.Encode(transaction.Hash()) fmt.Printf("Transaction hash: %s\n", hashStr) } ``` 请注意,这只是一个基本示例,实际应用中还需要处理错误、网络延迟以及链上状态的变化等复杂情况。同时,EIP-1559的具体实现细节可能会随着Ethereum主网的更新而有所变化。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快活林高老大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值