Skip to content

Commit 7c07b49

Browse files
authored
eth/tx: add eip-4844 transactions (#345)
1 parent 3033608 commit 7c07b49

5 files changed

Lines changed: 460 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
33

44
## [0.5.15]
55
### Added
6+
* Eth/tx: add support for EIP-4844 transactions [#345](https://github.com/q9f/eth.rb/pull/345)
67
* Eth/contract: support solidity custom errors as per ERC-6093 [#344](https://github.com/q9f/eth.rb/pull/344)
78

89
## [0.5.14]

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ What you get:
3333
- [x] EIP-2028 Call-data intrinsic gas cost estimates (plus access lists)
3434
- [x] EIP-2718 Ethereum Transaction Envelopes (and types)
3535
- [x] EIP-2930 Ethereum Type-1 Transactions (with access lists)
36+
- [x] EIP-4844 Ethereum Type-3 Transactions (with shard blobs)
3637
- [x] EIP-7702 Ethereum Type-4 Transactions (with authorization lists)
3738
- [x] ABI-Encoder and Decoder (including type parser)
3839
- [x] Packed ABI-Encoder for Solidity smart contracts

lib/eth/tx.rb

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
require "eth/chain"
1818
require "eth/tx/eip1559"
1919
require "eth/tx/eip2930"
20+
require "eth/tx/eip4844"
2021
require "eth/tx/eip7702"
2122
require "eth/tx/legacy"
2223
require "eth/unit"
@@ -87,6 +88,8 @@ class ParameterError < TypeError; end
8788

8889
# Creates a new transaction of any type for given parameters and chain ID.
8990
# Required parameters are (optional in brackets):
91+
# - EIP-4844: chain_id, nonce, priority_fee, max_gas_fee, gas_limit, max_fee_per_blob_gas, blob_versioned_hashes(, from, to,
92+
# value, data, access_list)
9093
# - EIP-1559: chain_id, nonce, priority_fee, max_gas_fee, gas_limit(, from, to,
9194
# value, data, access_list)
9295
# - EIP-2930: chain_id, nonce, gas_price, gas_limit, access_list(, from, to,
@@ -99,9 +102,10 @@ class ParameterError < TypeError; end
99102
# @param chain_id [Integer] the EIP-155 Chain ID (legacy transactions only).
100103
def new(params, chain_id = Chain::ETHEREUM)
101104

102-
# if we deal with blobs, attempt EIP-4844 (not implemented)
105+
# if we deal with blobs, attempt EIP-4844
103106
unless params[:max_fee_per_blob_gas].nil?
104-
raise NotimplementedError, "EIP-4844 blob transactions are not implemented"
107+
params[:chain_id] = chain_id if params[:chain_id].nil?
108+
return Tx::Eip4844.new params
105109
end
106110

107111
# if we deal with authorizations, attempt EIP-7702
@@ -148,7 +152,7 @@ def decode(hex)
148152
when TYPE_4844
149153

150154
# EIP-4844 transaction (type 3)
151-
raise NotimplementedError, "EIP-4844 blob transactions are not implemented"
155+
return Tx::Eip4844.decode hex
152156
when TYPE_7702
153157

154158
# EIP-7702 transaction (type 4)
@@ -182,7 +186,7 @@ def unsigned_copy(tx)
182186
when TYPE_4844
183187

184188
# EIP-4844 transaction (type 3)
185-
raise NotimplementedError, "EIP-4844 blob transactions are not implemented"
189+
return Tx::Eip4844.unsigned_copy tx
186190
when TYPE_7702
187191

188192
# EIP-7702 transaction (type 4)
@@ -278,6 +282,24 @@ def validate_eip1559_params(fields)
278282
return fields
279283
end
280284

285+
# Validates that the type-3 transaction blob fields are present
286+
#
287+
# @param fields [Hash] the transaction fields.
288+
# @return [Hash] the validated transaction fields.
289+
# @raise [ParameterError] if max blob fee or blob hashes are invalid.
290+
def validate_eip4844_params(fields)
291+
if fields[:max_fee_per_blob_gas].nil? or fields[:max_fee_per_blob_gas] < 0
292+
raise ParameterError, "Invalid max blob fee #{fields[:max_fee_per_blob_gas]}!"
293+
end
294+
if fields[:blob_versioned_hashes].nil? or !fields[:blob_versioned_hashes].is_a? Array or fields[:blob_versioned_hashes].empty?
295+
raise ParameterError, "Invalid blob versioned hashes #{fields[:blob_versioned_hashes]}!"
296+
end
297+
if fields[:to].nil? or fields[:to].empty?
298+
raise ParameterError, "Invalid destination address #{fields[:to]}!"
299+
end
300+
return fields
301+
end
302+
281303
# Validates that the type-4 transaction field authorization list is present
282304
#
283305
# @param fields [Hash] the transaction fields.
@@ -372,6 +394,22 @@ def sanitize_list(list)
372394
return list
373395
end
374396

397+
# Populates the blob versioned hashes field with a serializable empty
398+
# array in case it is undefined; also ensures the hashes are binary
399+
# not hex.
400+
#
401+
# @param list [Array] the blob versioned hashes.
402+
# @return [Array] the sanitized blob versioned hashes.
403+
def sanitize_hashes(list)
404+
list = [] if list.nil?
405+
list.each_with_index do |value, index|
406+
if Util.hex? value
407+
list[index] = Util.hex_to_bin value
408+
end
409+
end
410+
return list
411+
end
412+
375413
# Allows to check wether a transaction is signed already.
376414
#
377415
# @return [Bool] true if transaction is already signed.

0 commit comments

Comments
 (0)