@@ -16,6 +16,7 @@ pub enum Transaction {
16
16
LegacyTransaction ( LegacyTransaction ) ,
17
17
EIP2930Transaction ( EIP2930Transaction ) ,
18
18
EIP1559Transaction ( EIP1559Transaction ) ,
19
+ EIP4844Transaction ( EIP4844Transaction ) ,
19
20
}
20
21
21
22
#[ derive( Clone , Debug , PartialEq , Eq ) ]
@@ -64,6 +65,24 @@ pub struct EIP1559Transaction {
64
65
pub signature_s : U256 ,
65
66
}
66
67
68
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
69
+ pub struct EIP4844Transaction {
70
+ pub chain_id : u64 ,
71
+ pub nonce : u64 ,
72
+ pub max_priority_fee_per_gas : u64 ,
73
+ pub max_fee_per_gas : u64 ,
74
+ pub gas : u64 ,
75
+ pub to : Address ,
76
+ pub value : U256 ,
77
+ pub data : Bytes ,
78
+ pub access_list : Vec < ( Address , Vec < H256 > ) > ,
79
+ pub max_fee_per_blob_gas : u64 ,
80
+ pub blob_versioned_hashes : Vec < H256 > ,
81
+ pub signature_y_parity : bool ,
82
+ pub signature_r : U256 ,
83
+ pub signature_s : U256 ,
84
+ }
85
+
67
86
#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
68
87
pub enum TxType {
69
88
Legacy = 0x00 ,
@@ -90,6 +109,7 @@ impl Transaction {
90
109
Transaction :: LegacyTransaction ( _) => TxType :: Legacy ,
91
110
Transaction :: EIP2930Transaction ( _) => TxType :: EIP2930 ,
92
111
Transaction :: EIP1559Transaction ( _) => TxType :: EIP1559 ,
112
+ Transaction :: EIP4844Transaction ( _) => TxType :: EIP4844 ,
93
113
}
94
114
}
95
115
}
@@ -100,6 +120,7 @@ impl RLPEncode for Transaction {
100
120
Transaction :: LegacyTransaction ( t) => t. encode ( buf) ,
101
121
Transaction :: EIP2930Transaction ( t) => t. encode ( buf) ,
102
122
Transaction :: EIP1559Transaction ( t) => t. encode ( buf) ,
123
+ Transaction :: EIP4844Transaction ( t) => t. encode ( buf) ,
103
124
} ;
104
125
}
105
126
}
@@ -183,6 +204,27 @@ impl RLPEncode for EIP1559Transaction {
183
204
}
184
205
}
185
206
207
+ impl RLPEncode for EIP4844Transaction {
208
+ fn encode ( & self , buf : & mut dyn bytes:: BufMut ) {
209
+ Encoder :: new ( buf)
210
+ . encode_field ( & self . chain_id )
211
+ . encode_field ( & self . nonce )
212
+ . encode_field ( & self . max_priority_fee_per_gas )
213
+ . encode_field ( & self . max_fee_per_gas )
214
+ . encode_field ( & self . gas )
215
+ . encode_field ( & self . to )
216
+ . encode_field ( & self . value )
217
+ . encode_field ( & self . data )
218
+ . encode_field ( & self . access_list )
219
+ . encode_field ( & self . max_fee_per_blob_gas )
220
+ . encode_field ( & self . blob_versioned_hashes )
221
+ . encode_field ( & self . signature_y_parity )
222
+ . encode_field ( & self . signature_r )
223
+ . encode_field ( & self . signature_s )
224
+ . finish ( ) ;
225
+ }
226
+ }
227
+
186
228
impl RLPDecode for LegacyTransaction {
187
229
fn decode_unfinished ( rlp : & [ u8 ] ) -> Result < ( LegacyTransaction , & [ u8 ] ) , RLPDecodeError > {
188
230
let decoder = Decoder :: new ( rlp) ?;
@@ -278,6 +320,45 @@ impl RLPDecode for EIP1559Transaction {
278
320
}
279
321
}
280
322
323
+ impl RLPDecode for EIP4844Transaction {
324
+ fn decode_unfinished ( rlp : & [ u8 ] ) -> Result < ( EIP4844Transaction , & [ u8 ] ) , RLPDecodeError > {
325
+ let decoder = Decoder :: new ( rlp) ?;
326
+ let ( chain_id, decoder) = decoder. decode_field ( "chain_id" ) ?;
327
+ let ( nonce, decoder) = decoder. decode_field ( "nonce" ) ?;
328
+ let ( max_priority_fee_per_gas, decoder) =
329
+ decoder. decode_field ( "max_priority_fee_per_gas" ) ?;
330
+ let ( max_fee_per_gas, decoder) = decoder. decode_field ( "max_fee_per_gas" ) ?;
331
+ let ( gas, decoder) = decoder. decode_field ( "gas" ) ?;
332
+ let ( to, decoder) = decoder. decode_field ( "to" ) ?;
333
+ let ( value, decoder) = decoder. decode_field ( "value" ) ?;
334
+ let ( data, decoder) = decoder. decode_field ( "data" ) ?;
335
+ let ( access_list, decoder) = decoder. decode_field ( "access_list" ) ?;
336
+ let ( max_fee_per_blob_gas, decoder) = decoder. decode_field ( "max_fee_per_blob_gas" ) ?;
337
+ let ( blob_versioned_hashes, decoder) = decoder. decode_field ( "blob_versioned_hashes" ) ?;
338
+ let ( signature_y_parity, decoder) = decoder. decode_field ( "signature_y_parity" ) ?;
339
+ let ( signature_r, decoder) = decoder. decode_field ( "signature_r" ) ?;
340
+ let ( signature_s, decoder) = decoder. decode_field ( "signature_s" ) ?;
341
+
342
+ let tx = EIP4844Transaction {
343
+ chain_id,
344
+ nonce,
345
+ max_priority_fee_per_gas,
346
+ max_fee_per_gas,
347
+ gas,
348
+ to,
349
+ value,
350
+ data,
351
+ access_list,
352
+ max_fee_per_blob_gas,
353
+ blob_versioned_hashes,
354
+ signature_y_parity,
355
+ signature_r,
356
+ signature_s,
357
+ } ;
358
+ Ok ( ( tx, decoder. finish ( ) ?) )
359
+ }
360
+ }
361
+
281
362
impl Transaction {
282
363
pub fn sender ( & self ) -> Address {
283
364
match self {
@@ -338,6 +419,28 @@ impl Transaction {
338
419
& Bytes :: from ( buf) ,
339
420
)
340
421
}
422
+ Transaction :: EIP4844Transaction ( tx) => {
423
+ let mut buf = vec ! [ self . tx_type( ) as u8 ] ;
424
+ Encoder :: new ( & mut buf)
425
+ . encode_field ( & tx. chain_id )
426
+ . encode_field ( & tx. nonce )
427
+ . encode_field ( & tx. max_priority_fee_per_gas )
428
+ . encode_field ( & tx. max_fee_per_gas )
429
+ . encode_field ( & tx. gas )
430
+ . encode_field ( & tx. to )
431
+ . encode_field ( & tx. value )
432
+ . encode_field ( & tx. data )
433
+ . encode_field ( & tx. access_list )
434
+ . encode_field ( & tx. max_fee_per_blob_gas )
435
+ . encode_field ( & tx. blob_versioned_hashes )
436
+ . finish ( ) ;
437
+ recover_address (
438
+ & tx. signature_r ,
439
+ & tx. signature_s ,
440
+ tx. signature_y_parity ,
441
+ & Bytes :: from ( buf) ,
442
+ )
443
+ }
341
444
}
342
445
}
343
446
@@ -346,6 +449,7 @@ impl Transaction {
346
449
Transaction :: LegacyTransaction ( tx) => tx. gas ,
347
450
Transaction :: EIP2930Transaction ( tx) => tx. gas_limit ,
348
451
Transaction :: EIP1559Transaction ( tx) => tx. gas_limit ,
452
+ Transaction :: EIP4844Transaction ( tx) => tx. gas ,
349
453
}
350
454
}
351
455
@@ -354,6 +458,7 @@ impl Transaction {
354
458
Transaction :: LegacyTransaction ( tx) => tx. gas_price ,
355
459
Transaction :: EIP2930Transaction ( tx) => tx. gas_price ,
356
460
Transaction :: EIP1559Transaction ( tx) => tx. max_fee_per_gas ,
461
+ Transaction :: EIP4844Transaction ( tx) => tx. max_fee_per_gas ,
357
462
}
358
463
}
359
464
@@ -362,6 +467,7 @@ impl Transaction {
362
467
Transaction :: LegacyTransaction ( tx) => tx. to . clone ( ) ,
363
468
Transaction :: EIP2930Transaction ( tx) => tx. to . clone ( ) ,
364
469
Transaction :: EIP1559Transaction ( tx) => TxKind :: Call ( tx. destination ) ,
470
+ Transaction :: EIP4844Transaction ( tx) => TxKind :: Call ( tx. to ) ,
365
471
}
366
472
}
367
473
@@ -370,6 +476,7 @@ impl Transaction {
370
476
Transaction :: LegacyTransaction ( tx) => tx. value ,
371
477
Transaction :: EIP2930Transaction ( tx) => tx. value ,
372
478
Transaction :: EIP1559Transaction ( tx) => tx. amount ,
479
+ Transaction :: EIP4844Transaction ( tx) => tx. value ,
373
480
}
374
481
}
375
482
@@ -378,6 +485,7 @@ impl Transaction {
378
485
Transaction :: LegacyTransaction ( _tx) => None ,
379
486
Transaction :: EIP2930Transaction ( _tx) => None ,
380
487
Transaction :: EIP1559Transaction ( tx) => Some ( tx. max_priority_fee_per_gas ) ,
488
+ Transaction :: EIP4844Transaction ( tx) => Some ( tx. max_priority_fee_per_gas ) ,
381
489
}
382
490
}
383
491
@@ -386,6 +494,7 @@ impl Transaction {
386
494
Transaction :: LegacyTransaction ( _tx) => None ,
387
495
Transaction :: EIP2930Transaction ( tx) => Some ( tx. chain_id ) ,
388
496
Transaction :: EIP1559Transaction ( tx) => Some ( tx. chain_id ) ,
497
+ Transaction :: EIP4844Transaction ( tx) => Some ( tx. chain_id ) ,
389
498
}
390
499
}
391
500
@@ -394,6 +503,7 @@ impl Transaction {
394
503
Transaction :: LegacyTransaction ( _tx) => Vec :: new ( ) ,
395
504
Transaction :: EIP2930Transaction ( tx) => tx. access_list . clone ( ) ,
396
505
Transaction :: EIP1559Transaction ( tx) => tx. access_list . clone ( ) ,
506
+ Transaction :: EIP4844Transaction ( tx) => tx. access_list . clone ( ) ,
397
507
}
398
508
}
399
509
@@ -402,6 +512,7 @@ impl Transaction {
402
512
Transaction :: LegacyTransaction ( tx) => tx. nonce ,
403
513
Transaction :: EIP2930Transaction ( tx) => tx. nonce ,
404
514
Transaction :: EIP1559Transaction ( tx) => tx. signer_nonce ,
515
+ Transaction :: EIP4844Transaction ( tx) => tx. nonce ,
405
516
}
406
517
}
407
518
@@ -410,6 +521,25 @@ impl Transaction {
410
521
Transaction :: LegacyTransaction ( tx) => & tx. data ,
411
522
Transaction :: EIP2930Transaction ( tx) => & tx. data ,
412
523
Transaction :: EIP1559Transaction ( tx) => & tx. payload ,
524
+ Transaction :: EIP4844Transaction ( tx) => & tx. data ,
525
+ }
526
+ }
527
+
528
+ pub fn blob_versioned_hashes ( & self ) -> Vec < H256 > {
529
+ match self {
530
+ Transaction :: LegacyTransaction ( _tx) => Vec :: new ( ) ,
531
+ Transaction :: EIP2930Transaction ( _tx) => Vec :: new ( ) ,
532
+ Transaction :: EIP1559Transaction ( _tx) => Vec :: new ( ) ,
533
+ Transaction :: EIP4844Transaction ( tx) => tx. blob_versioned_hashes . clone ( ) ,
534
+ }
535
+ }
536
+
537
+ pub fn max_fee_per_blob_gas ( & self ) -> Option < u64 > {
538
+ match self {
539
+ Transaction :: LegacyTransaction ( _tx) => None ,
540
+ Transaction :: EIP2930Transaction ( _tx) => None ,
541
+ Transaction :: EIP1559Transaction ( _tx) => None ,
542
+ Transaction :: EIP4844Transaction ( tx) => Some ( tx. max_fee_per_blob_gas ) ,
413
543
}
414
544
}
415
545
}
0 commit comments