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