I've already completed most of the work on this, I'm just testing now, but am creating this issue for tracking purposes.
The related EIPs are:
This will need a change to the interface, but as all new properties are optional, this should not be too much of an issue.
The initial support for this has been added in 5.1.0.
Currently AlchemyAPI and Pocket do not fully/properly support EIP-2930 transactions, and Etherscan has limited support for it. If you need typed transactions, please use INFURA (via the InfuraProvider is fine).
As these services update their nodes and fix their configurations, I will turn them back on and push out newer versions of the 5.1 packages.
Please try them out though, and let me know if there are any issues! Thanks! :)
Minor feedback on this: transaction receipts for typed transactions have a type field. The JSON-RPC in geth returns it, and we are going to do the same in Hardhat.
More feedback (although this one is more opinionated): doing getTransaction with a legacy transaction returns an accessList: null. I think it would be better to remove it altogether in those cases.
@fvictorio I’ll double check this in a week or so, but I don’t see the type field coming back in the receipts on all backends.
But this far there has been pretty wide-spread inconsistent behaviours between even the most popular services. I expect this to be resolved more quickly once Berlin is on mainnet.
Obviously, that is not ideal, but for now I am keeping it off the TransactionReceipt object, so that all backends continue to match. I’ll add it once the popular third-party services agree again.
Etherscan currently still incorrectly calculates estimateGas, but I’m trying to reach out to them to get that fixed. Once that is all straightened out, I’ll reiterate over all the services to make sure their output matches and contact the ones that don’t again.
Berlin has been exhausting. :p
I think I prefer to keep type and accessList as null for typed transactions, but I will think about that more. I’m not hard-set on that though, so feel free to make arguments to sway me. It was a deliberate decision though. :)
Whatever choice is made will continue on with EIP-1559.
One motivating reason is the move to strictNullChecks in v6, so I can use things like type: null | number. If I remove it, then it becomes type: null | undefined | number or needs to be set optionally (i.e. type?), which I’m trying to reduce in result types, which are also moving to concrete classes instead of just objects with properties.
Are there any docs on the right way to use these changes, specifically the accessList changes? I cant find anything on the docs
Great point. I will add information to the docs today.
Are there any docs on the right way to use these changes, specifically the
accessListchanges? I cant find anything on the docs
I've been using ethers to test access list transactions and just passing it has worked fine:
myContract.myFunction(arg1, arg2, {
accessList: [{
address: "0x...",
storageKeys: ["0x...", "0x...", ...]
}, { ... }, ...]
})
If you are using a node that supports eth_createAccessList, you'll need to call that method directly. I don't know how you call a "raw" RPC method, but in hardhat you would do something like this:
const result = await network.provider.send("eth_createAccessList", { from, to, data, ... })
// result.accessList can be used as a parameter for ethers
Not saying that docs are not needed, I'm just commenting in case anyone can't wait to use this :sweat_smile:
Thanks for the info, looks simple enough @fvictorio.
I was wondering if there would be helper methods like estimateGas, something along these lines e.g.
const gasLimit = await myContract.myMethod.estimateGas(data, {from, to});
const accessList = await myContract.myMethod.createAccessList(data, {from, to});
const tx = await myContract.myMethod(data, {
from: account,
gasLimit,
accessList
})
(sample code only 😄 )
Docs have been update. I've added the field to the TransactionRequest (which accepts any AccessListish) and TransactionResponse (which will contain a normalized AccessList) as well as documented the accessListify method, which allows others to normalize AccessListish into an AccesList.
I have experimented with eth_createAccessList, and have found it is not very widely/well supported on deployed backends right now. In the future I may add this, but for now I will probably try to make a utility function which will call that on a JsonRpcProvider.
Ideally, it is something that would preferably be handled within a Signer (with the option to explicitly override), using logic akin to:
const [ untypedEstimate, typedEstimate ] = await Promise.all([
provider.estimateGas(untypedTx),
provider.estimateGas(typedTx),
]);
if (untypedEstimate.lt(typedEstimate)) {
this.sendTransaction(untypedTx);
} else {
this.sendTransaction(typedTx);
}
But time will tell. :)
Thanks for updating the docs @ricmoo 👍🏻 .
I have also been playing around with eth_createAccessList and doesnt look like it has wide support yet which is a shame.
Would be great to get that utility method in place for when it does.
Closing this for now. Hopefully once createAccessList has more adoption we can re-address it… :)
Most helpful comment
The initial support for this has been added in 5.1.0.
Currently AlchemyAPI and Pocket do not fully/properly support EIP-2930 transactions, and Etherscan has limited support for it. If you need typed transactions, please use INFURA (via the InfuraProvider is fine).
As these services update their nodes and fix their configurations, I will turn them back on and push out newer versions of the 5.1 packages.
Please try them out though, and let me know if there are any issues! Thanks! :)