ethers_types_rs/request/
eip2930.rs

1use ethabi::ethereum_types::{Signature, H256};
2use ethers_hash_rs::keccak256;
3use rlp::Encodable;
4use serde::{Deserialize, Serialize};
5
6use crate::{signature::SignatureVRS, Bytecode};
7
8use super::{rlp_opt, LegacyTransactionRequest};
9
10#[derive(Debug, Serialize, Deserialize, Clone, Default)]
11#[serde(rename_all = "camelCase")]
12pub struct Eip2930TransactionRequest {
13    #[serde(flatten)]
14    pub tx: LegacyTransactionRequest,
15
16    pub access_list: AccessList,
17}
18
19impl Encodable for Eip2930TransactionRequest {
20    fn rlp_append(&self, s: &mut rlp::RlpStream) {
21        s.begin_unbounded_list();
22
23        self.rlp_base(s);
24
25        s.finalize_unbounded_list();
26    }
27}
28
29impl Eip2930TransactionRequest {
30    /// Generate legacy transaction sign hash.
31    pub fn sign_hash(&self) -> H256 {
32        keccak256(self.rlp()).into()
33    }
34
35    fn to_bytecode(mut buff: Vec<u8>) -> Bytecode {
36        buff.insert(0, 0x1);
37
38        buff.into()
39    }
40    pub fn rlp(&self) -> Bytecode {
41        let mut s = rlp::RlpStream::new();
42
43        self.rlp_append(&mut s);
44
45        Self::to_bytecode(s.out().freeze().to_vec())
46    }
47
48    fn rlp_base(&self, s: &mut rlp::RlpStream) {
49        rlp_opt(s, &self.tx.chain_id);
50
51        self.tx.rlp_base(s);
52
53        s.append(&self.access_list);
54    }
55
56    /// Returns signed tx rlp encoding stream.
57    pub fn rlp_signed(&self, signature: Signature) -> Bytecode {
58        let mut rlp = rlp::RlpStream::new();
59
60        rlp.begin_unbounded_list();
61
62        self.rlp_base(&mut rlp);
63
64        rlp.append(&signature.v());
65        rlp.append(&signature.r());
66        rlp.append(&signature.s());
67
68        rlp.finalize_unbounded_list();
69
70        Self::to_bytecode(rlp.out().freeze().to_vec())
71    }
72}
73
74#[derive(Debug, Serialize, Deserialize, Default, Clone)]
75pub struct AccessList(Vec<Access>);
76
77impl Encodable for AccessList {
78    fn rlp_append(&self, s: &mut rlp::RlpStream) {
79        s.begin_unbounded_list();
80
81        // s.append_list(&self.0);
82
83        for v in &self.0 {
84            s.append(v);
85        }
86
87        s.finalize_unbounded_list();
88    }
89}
90
91#[derive(Debug, Serialize, Deserialize, Default, Clone)]
92#[serde(rename_all = "camelCase")]
93pub struct Access {
94    pub address: crate::Address,
95
96    pub storage_keys: Vec<H256>,
97}
98
99impl Encodable for Access {
100    fn rlp_append(&self, s: &mut rlp::RlpStream) {
101        s.begin_unbounded_list();
102        s.append(&self.address);
103
104        {
105            s.begin_unbounded_list();
106
107            for k in &self.storage_keys {
108                s.append(k);
109            }
110
111            s.finalize_unbounded_list();
112        }
113
114        s.finalize_unbounded_list();
115    }
116}