revm-trace 4.2.0

High-performance multi-threaded EVM transaction simulator and analyzer with comprehensive tracing capabilities
Documentation
//! Test getting contract address from ExecutionResult
//!
//! This example demonstrates how to get deployed contract address
//! directly from ExecutionResult without using inspectors.

use alloy::{
    primitives::{address, hex, Address, TxKind, U256},
    sol,
};
use anyhow::Result;
use revm::context::ContextTr;
use revm::context_interface::result::ExecutionResult;
use revm::database::Database;
use revm_trace::{SimulationBatch, SimulationTx};

#[cfg(not(feature = "foundry-fork"))]
use revm_trace::create_evm;

#[cfg(feature = "foundry-fork")]
use revm_trace::create_shared_evm;

// Define a simple contract
sol! {
    contract OwnerDemo {
        address private _owner;
        constructor() {
            _owner = msg.sender;
        }
        function getOwner() public view returns (address) {
            return _owner;
        }
    }
}

const BYTECODE: &str = "608060405234801561001057600080fd5b50600080546001600160a01b031916331790556101ca806100326000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063893d20e814610030575b600080fd5b61003861004e565b6040516100459190610146565b60405180910390f35b60008054906101000a90046001600160a01b031690565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061009182610066565b9050919050565b6100a181610086565b82525050565b60006020820190506100bc6000830184610098565b92915050565b600080fd5b6100d081610086565b81146100db57600080fd5b50565b6000813590506100ed816100c7565b92915050565b600060208284031215610109576101086100c2565b5b6000610117848285016100de565b91505092915050565b600061012b82610066565b9050919050565b61013b81610120565b82525050565b60006020820190506101566000830184610132565b9291505056fea2646970667358221220892a63a629c1a45fb9de27ff5b76c3bb4c5ff8e7df8b5c6b4d6e4c3f1c06b42564736f6c63430008110033";
const SENDER: Address = address!("b20a608c624Ca5003905aA834De7156C68b2E1d0");
const ETH_RPC_URL: &str = "https://eth.llamarpc.com";

#[tokio::main]
async fn main() -> Result<()> {
    println!("Testing contract address extraction from ExecutionResult...");

    #[cfg(not(feature = "foundry-fork"))]
    println!("Using AlloyDB backend for EVM simulation");

    #[cfg(feature = "foundry-fork")]
    println!("Using Foundry fork backend for EVM simulation");
    // Create basic EVM instance without inspector
    #[cfg(not(feature = "foundry-fork"))]
    let mut evm = create_evm(ETH_RPC_URL).await?;

    #[cfg(feature = "foundry-fork")]
    let mut evm = create_shared_evm(ETH_RPC_URL).await?;

    // Predict contract address
    let current_account = evm.db().basic(SENDER).unwrap().unwrap();
    let nonce = current_account.nonce;
    let predicted_address = SENDER.create(nonce);
    println!("Predicted contract address: {}", predicted_address);

    // Deploy contract
    let deploy_tx = SimulationTx {
        caller: SENDER,
        transact_to: TxKind::Create,
        value: U256::ZERO,
        data: hex::decode(BYTECODE).unwrap().into(),
    };

    // Execute deployment
    let results = evm.execute_batch(SimulationBatch {
        is_stateful: false,
        transactions: vec![deploy_tx],
        overrides: None,
    });

    // Check the result
    match &results[0] {
        Ok(execution_result) => {
            println!("Deployment successful!");

            // Try to extract contract address from ExecutionResult
            match execution_result {
                ExecutionResult::Success { output, .. } => match output.address() {
                    Some(address) => {
                        println!("✅ Contract deployed at address: {}", address);
                        assert_eq!(
                            *address, predicted_address,
                            "❌ Contract address does not match predicted address"
                        );
                    }
                    None => {
                        println!(
                            "❌ Created contract address is None, expected address: {}",
                            predicted_address
                        );
                    }
                },
                _ => {
                    println!("❌ Deployment failed: {:?}", execution_result);
                }
            }
        }
        Err(e) => {
            println!("❌ Transaction failed: {:?}", e);
        }
    }

    Ok(())
}