stratus/eth/primitives/
account.rs

1use display_json::DebugAsJson;
2use revm::primitives::KECCAK_EMPTY;
3use revm::state::Bytecode;
4
5use crate::alias::RevmAccountInfo;
6use crate::alias::RevmAddress;
7use crate::eth::primitives::Address;
8use crate::eth::primitives::Nonce;
9use crate::eth::primitives::Wei;
10
11/// Ethereum account (wallet or contract).
12///
13/// TODO: group bytecode, code_hash, static_slot_indexes and mapping_slot_indexes into a single bytecode struct.
14#[derive(DebugAsJson, Clone, Default, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
15#[cfg_attr(test, derive(fake::Dummy))]
16pub struct Account {
17    /// Immutable address of the account.
18    pub address: Address,
19
20    /// Current nonce of the account. Changes every time a transaction is sent.
21    pub nonce: Nonce,
22
23    /// Current balance of the account. Changes when a transfer is made or the account pays a fee for executing a transaction.
24    pub balance: Wei,
25
26    /// Contract bytecode. Present only if the account is a contract.
27    #[cfg_attr(test, dummy(default))]
28    pub bytecode: Option<Bytecode>,
29}
30
31impl Account {
32    /// Creates a new empty account.
33    pub fn new_empty(address: Address) -> Self {
34        Self::new_with_balance(address, Wei::ZERO)
35    }
36
37    /// Creates a new account with initial balance.
38    pub fn new_with_balance(address: Address, balance: Wei) -> Self {
39        Self {
40            address,
41            nonce: Nonce::ZERO,
42            balance,
43            bytecode: None,
44        }
45    }
46}
47
48// -----------------------------------------------------------------------------
49// Conversions: Other -> Self
50// -----------------------------------------------------------------------------
51impl From<(RevmAddress, RevmAccountInfo)> for Account {
52    fn from(value: (RevmAddress, RevmAccountInfo)) -> Self {
53        let (address, info) = value;
54
55        Self {
56            address: address.into(),
57            nonce: info.nonce.into(),
58            balance: info.balance.into(),
59            bytecode: info.code,
60        }
61    }
62}
63
64// -----------------------------------------------------------------------------
65// Conversions: Self -> Other
66// -----------------------------------------------------------------------------
67
68impl From<Account> for RevmAccountInfo {
69    fn from(value: Account) -> Self {
70        Self {
71            nonce: value.nonce.into(),
72            balance: value.balance.into(),
73            code_hash: KECCAK_EMPTY,
74            code: value.bytecode,
75        }
76    }
77}
78
79// -----------------------------------------------------------------------------
80// Utilities
81// -----------------------------------------------------------------------------
82
83/// Accounts to be used only in development-mode.
84pub fn test_accounts() -> Vec<Account> {
85    use hex_literal::hex;
86    [
87        hex!("f39fd6e51aad88f6f4ce6ab8827279cfffb92266"), // ALICE
88        hex!("70997970c51812dc3a010c7d01b50e0d17dc79c8"), // BOB
89        hex!("3c44cdddb6a900fa2b585dd299e03d12fa4293bc"), // CHARLIE
90        hex!("15d34aaf54267db7d7c367839aaf71a00a2c6a65"), // DAVE
91        hex!("9965507d1a55bcc2695c58ba16fb37d819b0a4dc"), // EVE
92        hex!("976ea74026e726554db657fa54763abd0c3a0aa9"), // FERDIE
93        hex!("e45b176cad7090a5cf70b69a73b6def9296ba6a2"), // ?
94    ]
95    .into_iter()
96    .map(|address| Account {
97        address: address.into(),
98        balance: Wei::TEST_BALANCE,
99        ..Account::default()
100    })
101    .collect()
102}