### Metered Contract Call Example Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/budget.md Demonstrates how to use the budget API to track the cost of operations within a Soroban contract. It shows how to get the current budget, perform metered operations like vector creation, and calculate the cost of specific actions. ```rust use soroban_env_host::{Host, Env, budget::AsBudget}; use soroban_env_common::U32Val; fn metered_contract_call(host: &Host) -> Result<(), Box> { // Get budget reference let budget = host.as_budget(); // Check current cost let used = budget.current_time()?; println!("Used {} cost units", used); // Perform metered operations let vec = host.vec_new(U32Val::from(10))?; // Check cost again let used_after = budget.current_time()?; println!("Vector creation cost: {}", used_after - used); Ok(()) } ``` -------------------------------- ### Call Myself Example Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/contract-invocation.md An example demonstrating how a contract can call one of its own functions using `get_current_contract_address` and `invoke_contract`. ```APIDOC ## call_myself ### Description Example function that calls a helper function within the same contract. ### Signature ```rust fn call_myself(env: &impl Env) -> Result; ``` ### Usage ```rust let my_address = env.get_current_contract_address()?; let args = env.vec_new()?; env.invoke_contract( my_address, Symbol::try_from_small_str("helper_function")?, args, ) ``` ``` -------------------------------- ### Example: Invoking a Contract Transfer Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/host.md Shows how to get the current contract address, build arguments, and invoke a 'transfer' function on another contract. ```rust use soroban_env_host::{Host, Env}; use soroban_env_common::{Symbol, AddressObject, VecObject}; fn invoke_transfer( host: &Host, to: AddressObject, amount: u128, ) -> Result<(), Box> { // Get current contract let contract = host.get_current_contract_address()?; // Build arguments let args = host.vec_new()?; let args = host.vec_push_back(args, Val::from_u128(amount))?; // Invoke transfer function host.invoke_contract( contract, Symbol::try_from_small_str("transfer")?, args, )?; Ok(()) } ``` -------------------------------- ### Example Usage of Soroban Storage Operations Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/storage-and-footprint.md This Rust example demonstrates common storage operations: storing persistent data, checking if a key exists, retrieving a value, and deleting a key. Ensure the necessary imports are included. ```rust use soroban_env_host::{Host, Env, storage::{Storage, FootprintMode, Footprint}}; use soroban_env_common::{Val, StorageType, Symbol}; fn store_and_retrieve( host: &Host, ) -> Result<(), Box> { // Create a storage key let key = Symbol::try_from_small_str("mydata")?; let key_val = Val::from(key); // Store persistent data let value = U128Val::from(42u128); host.put_contract_data(key_val, Val::from(value), StorageType::Persistent)?; // Check if key exists let exists = host.has_contract_data(key_val, StorageType::Persistent)?; assert!(bool::from(exists)); // Retrieve value let retrieved = host.get_contract_data(key_val, StorageType::Persistent)?; // Delete value host.del_contract_data(key_val, StorageType::Persistent)?; Ok(()) } ``` -------------------------------- ### Setup Host for Testing Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/configuration.md Configures a Soroban Host for testing purposes by setting budget limits and ledger information. Verifies the protocol version after configuration. ```rust use soroban_env_host::{Host, LedgerInfo, Env}; use soroban_env_common::U32Val; fn setup_host_for_testing() -> Result> { let mut host = Host::default(); // Configure budget { let budget = host.as_budget_mut(); budget.set_limits( 50_000_000, // CPU units 50_000_000, // Memory units 5_000_000, // Ledger units ); } // Configure ledger host.set_ledger_info(LedgerInfo { protocol_version: 27, sequence_number: 50000, timestamp: 1704067200, network_id: b"Test SDF Network ; September 2015".to_vec(), base_reserve_in_stroops: 100_000_000, max_tx_set_size: 1000, })?; // Verify configuration let version = host.get_ledger_version()?; assert_eq!(version, U32Val::from(27)); Ok(host) } ``` -------------------------------- ### Configure Ledger Context with set_ledger_info Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/configuration.md Example demonstrating how to set ledger information for a Host instance using the `set_ledger_info` method. Requires `Host` and `LedgerInfo` imports. ```rust use soroban_env_host::{Host, LedgerInfo}; let mut host = Host::default(); host.set_ledger_info(LedgerInfo { protocol_version: 27, sequence_number: 1000, timestamp: 1704067200, // Jan 1, 2024 network_id: Vec::from(&[/* 32 bytes */]), base_reserve_in_stroops: 100_000_000, max_tx_set_size: 1000, })?; ``` -------------------------------- ### Val Construction Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Demonstrates how to construct Val instances from different primitive types, starting with boolean values. ```APIDOC ## Val Construction ### `fn from(bool_val: bool) -> Val` Construct Val from boolean. ```rust let t = Val::from(true); // Tag::True let f = Val::from(false); // Tag::False ``` ``` -------------------------------- ### Example Usage: Invoking a Contract Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/host.md Demonstrates how to invoke a contract's function, including building arguments and handling results. ```APIDOC ## Example Usage: Invoking a Contract ### Description An example demonstrating how to invoke a contract's function, including building arguments and handling results. ### Function Signature ```rust fn invoke_transfer( host: &Host, to: AddressObject, amount: u128, ) -> Result<(), Box>; ``` ### Usage ```rust use soroban_env_host::{Host, Env}; use soroban_env_common::{Symbol, AddressObject, VecObject}; // ... inside a function or method ... // Get current contract let contract = host.get_current_contract_address()?; // Build arguments let args = host.vec_new()?; let args = host.vec_push_back(args, Val::from_u128(amount))?; // Invoke transfer function host.invoke_contract( contract, Symbol::try_from_small_str("transfer")?, args, )?; // ... ``` ``` -------------------------------- ### Example: Verify Ed25519 Signature Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/authentication-and-authorization.md An example function demonstrating how to use the env.ed25519_verify method to validate an Ed25519 signature. It returns Ok(()) if the signature is valid. ```rust fn verify_ed25519( env: &impl Env, pk: BytesObject, msg: BytesObject, sig: BytesObject ) -> Result<(), HostError> { env.ed25519_verify(pk, msg, sig)?; println!("Signature valid!"); Ok(()) } ``` -------------------------------- ### Example: Test Contract Call with Simulation Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/e2e-and-simulation.md Demonstrates how to set up an InvocationSpec and use `simulate_invocation` to test a contract function. Handles success and failure cases, printing relevant simulation details. ```rust use soroban_simulation::{InvocationSpec, simulate_invocation}; fn test_contract_call( contract_id: ContractId, snapshot: &dyn SnapshotSource, ) -> Result<(), Box> { let spec = InvocationSpec { contract_id, function_name: "transfer".to_string(), args: vec![/* args */], auth: vec![], // None initially ledger: current_ledger_info(), }; let result = simulate_invocation(spec, snapshot)?; if result.success { println!("Simulation succeeded!"); println!("Changes: {:?}", result.ledger_changes); println!("Resources: {:?}", result.resources); println!("Auth records: {:?}", result.auth_records); } else { println!("Simulation failed!"); } Ok(()) } ``` -------------------------------- ### Complete Preflight Simulation Example Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/e2e-and-simulation.md This function simulates a contract invocation, discovers authorization requirements, collects necessary signatures, and performs a final validation. It also reports resource usage upon successful validation. Use this for comprehensive preflight checks before deploying or executing transactions. ```rust fn run_preflight( contract_id: ContractId, function: &str, args: Vec, snapshot: &dyn SnapshotSource, signer: impl Signer, ) -> Result> { println!("=== Running Preflight ===\n"); // Step 1: Initial simulation to discover auth requirements println!("[1] Discovering authorization requirements..."); let spec = InvocationSpec { contract_id: contract_id.clone(), function_name: function.to_string(), args: args.clone(), auth: vec![], ledger: current_ledger_info(), }; let initial_result = simulate_invocation(spec.clone(), snapshot)?; if initial_result.success { println!(" ✓ No authorization required"); } else { println!(" ✓ Auth required: {} signatures needed", initial_result.auth_records.len()); } let mut auth_records = initial_result.auth_records; // Step 2: Collect signatures println!("\n[2] Collecting signatures..."); for (i, record) in auth_records.iter_mut().enumerate() { println!(" Signing for address: {:?}", record.address); let signature = signer.sign(&record.signature_payload)?; record.signatures.push(ContractAuthorizationEntry { signer: record.address.clone(), nonce: record.nonce, signature_expiration_ledger: record.signature_expiration_ledger, signature, }); println!(" ✓ Signed ({})", i + 1); } // Step 3: Final validation println!("\n[3] Validating with signatures..."); let mut final_spec = spec; final_spec.auth = auth_records; let final_result = simulate_invocation(final_spec, snapshot)?; if final_result.success { println!(" ✓ Validation successful!\n"); // Step 4: Report resources println!("=== Resource Report ==="); println!("CPU Units: {}", final_result.resources.cpu_units); println!("Memory Units: {}", final_result.resources.mem_units); println!("Ledger Reads: {}", final_result.resources.ledger_read_units); println!("Ledger Writes: {}", final_result.resources.ledger_write_units); println!("Ledger Bytes: {}", final_result.resources.ledger_bytes_written); println!("Keys Accessed: {}", final_result.resources.footprint.0.len()); Ok(final_result) } else { Err("Final validation failed".into()) } } ``` -------------------------------- ### Self-Invocation Example Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/contract-invocation.md Demonstrates how to get the current contract's address and then invoke a function within the same contract. Ensure the target function exists and is accessible. ```rust fn get_my_address(env: &impl Env) -> Result { env.get_current_contract_address() } fn call_myself(env: &impl Env) -> Result { let my_address = env.get_current_contract_address()?; let args = env.vec_new()?; env.invoke_contract( my_address, Symbol::try_from_small_str("helper_function")?, args, ) } ``` -------------------------------- ### Complete Event System Example in Rust Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/events-and-diagnostics.md Demonstrates a complete transfer event system, including authorization, logging, balance updates, and emitting a 'transfer' event with associated topics and data. Use this for implementing core token functionalities. ```rust use soroban_env_common::{Symbol, Env}; fn complete_transfer( env: &impl Env, from: AddressObject, to: AddressObject, amount: u128, ) -> Result<(), HostError> { // Verify authorization env.require_auth(from)?; // Log start env.log_from_slice("transfer starting", &[ Val::from(from), Val::from(to), Val::from(U128Val::from(amount)), ])?; // Update balances (internal) let from_balance = get_balance(env, from)?; require!(from_balance >= amount, "insufficient balance"); set_balance(env, from, from_balance - amount)?; let to_balance = get_balance(env, to)?; set_balance(env, to, to_balance + amount)?; // Emit event (on-chain) let topics = env.vec_new_from_slice(&[ Val::from(Symbol::try_from_small_str("transfer")?), Val::from(from), Val::from(to), ])?; let data = Val::from(U128Val::from(amount)); env.contract_event(topics, data)?; // Log completion env.log_from_slice("transfer completed", &[ Val::from(U128Val::from(amount)) ])?; Ok(()) } ``` -------------------------------- ### Example Usage of obj_cmp Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/conversion-and-compare.md Demonstrates how to use the `env.obj_cmp` method to compare values and convert the `i64` result into the standard `std::cmp::Ordering` enum. Also includes helper functions for checking less than or equal to. ```rust use soroban_env_common::Compare; use std::cmp::Ordering; fn compare_values( env: &impl Env, a: Val, b: Val ) -> Result { let cmp_result = env.obj_cmp(a, b)?; Ok(match cmp_result { -1 => Ordering::Less, 0 => Ordering::Equal, 1 => Ordering::Greater, _ => panic!("invalid comparison result"), }) } fn is_less(env: &impl Env, a: Val, b: Val) -> Result { env.obj_cmp(a, b).map(|c| c < 0) } fn is_equal(env: &impl Env, a: Val, b: Val) -> Result { env.obj_cmp(a, b).map(|c| c == 0) } ``` -------------------------------- ### Constructing Small Integer Types Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/types.md Examples of creating U32Val and I32Val instances using the From trait for Rust primitive integer types. ```rust let u32_val = U32Val::from(42u32); let i32_val = I32Val::from(-100i32); ``` -------------------------------- ### TryFromVal Example: Symbol to String Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/conversion-and-compare.md Shows how to convert a Symbol to a String using the TryFromVal trait. This is useful for processing string-like data from the environment. ```rust use soroban_env_common::{TryFromVal, Env, U32Val, Symbol}; fn symbol_to_string(env: &impl Env, sym: Symbol) -> Result { String::try_from_val(env, &sym) } ``` -------------------------------- ### StringObject Operations via Env Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Provides examples of common operations on StringObject using the Env trait, including creation, length, slicing, and copying. ```rust // Creation env.string_new_from_slice(slice: &[u8]) -> Result // Length env.string_len(obj: StringObject) -> Result // Slicing env.string_slice(obj: StringObject, start: U32Val, end: U32Val) -> Result // Copy env.string_copy_to_slice( obj: StringObject, pos: U32Val, slice: &mut [u8] ) -> Result<(), E::Error> ``` -------------------------------- ### String Conversions Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/conversion-and-compare.md Functions for creating, copying, and getting the length of string objects. ```APIDOC ## String Conversions ### Create from slice ```rust env.string_new_from_slice(slice: &[u8]) -> Result ``` ### Extract to slice ```rust env.string_copy_to_slice( obj: StringObject, pos: U32Val, slice: &mut [u8] ) -> Result<(), Self::Error> ``` ### Get length ```rust env.string_len(obj: StringObject) -> Result ``` ``` -------------------------------- ### Protected Transfer Example Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/authentication-and-authorization.md Demonstrates how to perform a protected transfer operation, ensuring that the 'from' address has authorized the transaction. This includes balance checks and event emission. ```rust use soroban_env_common::{Symbol, AddressObject, Env}; fn transfer( env: &impl Env, from: AddressObject, to: AddressObject, amount: u128, ) -> Result<(), HostError> { // Require that 'from' authorized this operation env.require_auth(from)?; // Get current contract (e.g., a token contract) let contract = env.get_current_contract_address()?; // Proceed with transfer now that authorization is verified let from_balance = get_balance(env, from)?; if from_balance < amount { return Err(insufficient_balance_error()); } set_balance(env, from, from_balance - amount)?; let to_balance = get_balance(env, to)?; set_balance(env, to, to_balance + amount)?; // Emit event let topics = env.vec_new_from_slice(&[ Val::from(Symbol::try_from_small_str("transfer")?), Val::from(from), Val::from(to), ])?; env.contract_event(topics, Val::from(U128Val::from(amount)))?; Ok(()) } ``` -------------------------------- ### Monitoring Crypto Operation Costs Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/cryptography.md Cryptographic operations are metered. This example shows how to hash a large message and includes a placeholder for checking the remaining budget, requiring the 'testutils' feature. ```rust fn monitor_crypto_cost( env: &impl Env, data: BytesObject, ) -> Result<(), HostError> { // Expensive: large message hash let hash = env.sha256(data)?; // Check remaining budget // (testutils feature required) Ok(()) } ``` -------------------------------- ### Filter Events by Topic 1+ (Participant) Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/events-and-diagnostics.md Example SQL-like query to select all 'transfer' events to a specific address, filtering by topics. ```sql SELECT * WHERE topics[0] == Symbol("transfer") AND topics[2] == AddressObject(X) ``` -------------------------------- ### Filter Events by Topic 0 (Event Name) Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/events-and-diagnostics.md Example SQL-like query to select all events where the first topic (event name) is 'transfer'. ```sql SELECT * WHERE topics[0] == Symbol("transfer") ``` -------------------------------- ### Budget-Aware Contract Invocation Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/contract-invocation.md Shows how to invoke a contract while being mindful of the shared budget. This example differentiates between a 'heavy_computation' and a 'light_operation', highlighting potential budget exhaustion with repeated expensive calls. ```rust fn budget_aware_invocation( env: &impl Env, contract: AddressObject, expensive_operation: bool, ) -> Result { if expensive_operation { // This might exceed budget if multiple expensive calls happen env.invoke_contract( contract, Symbol::try_from_small_str("heavy_computation")?, env.vec_new()?, ) } else { env.invoke_contract( contract, Symbol::try_from_small_str("light_operation")?, env.vec_new()?, ) } } ``` -------------------------------- ### TryIntoVal Example: Creating Values Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/conversion-and-compare.md Illustrates using TryIntoVal to convert primitive types and Strings into Soroban Val types like U32Val and Symbol. This is useful for preparing data to be stored or passed within the Soroban environment. ```rust use soroban_env_common::TryIntoVal; fn create_values(env: &impl Env) -> Result<(), ConversionError> { // u32 -> U32Val let val: U32Val = 42u32.try_into_val(env)?; // String -> Symbol let sym: Symbol = "hello".to_string().try_into_val(env)?; Ok(()) } ``` -------------------------------- ### BytesObject Operations via Env Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Provides examples of common operations on BytesObject using the Env trait, including creation, length, access, modification, slicing, and copying. ```rust // Creation env.bytes_new_from_slice(slice: &[u8]) -> Result // Length env.bytes_len(obj: BytesObject) -> Result // Access env.bytes_get(obj: BytesObject, i: U32Val) -> Result // Modification env.bytes_set(obj: BytesObject, i: U32Val, b: U32Val) -> Result // Slicing env.bytes_slice(obj: BytesObject, start: U32Val, end: U32Val) -> Result // Copy env.bytes_copy_from_slice( b: BytesObject, b_pos: U32Val, slice: &[u8] ) -> Result env.bytes_copy_to_slice( b: BytesObject, b_pos: U32Val, slice: &mut [u8] ) -> Result<(), E::Error> ``` -------------------------------- ### TryFromVal Example: Converting Values Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/conversion-and-compare.md Demonstrates converting a vector of Val to a vector of u32 using the TryFromVal trait. Requires explicit casting to U32Val before conversion. ```rust use soroban_env_common::{TryFromVal, Env, U32Val, Symbol}; fn convert_values(env: &impl Env, vals: Vec) -> Result, ConversionError> { vals.iter() .map(|v| u32::try_from_val(env, &U32Val::try_from(*v)?)) .collect() } ``` -------------------------------- ### Pre-hashing Large Messages Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/cryptography.md For large messages, pre-hash them before passing to cryptographic functions to avoid performance issues. This example shows the recommended approach. ```rust env.sha256(large_message)?; ``` ```rust let hash = env.sha256(large_message)?; // Use hash for signature verification ``` -------------------------------- ### Budget Aware Invocation Example Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/contract-invocation.md Illustrates how contract invocations consume budget and how exceeding limits can lead to transaction failure. This function shows conditional invocation based on an `expensive_operation` flag. ```APIDOC ## budget_aware_invocation ### Description Demonstrates invoking a contract, potentially performing an expensive operation, while being mindful of the shared budget. ### Signature ```rust fn budget_aware_invocation( env: &impl Env, contract: AddressObject, expensive_operation: bool, ) -> Result; ``` ### Parameters - `env` (impl Env): The Soroban environment. - `contract` (AddressObject): The address of the contract to invoke. - `expensive_operation` (bool): A flag to determine if an expensive operation should be invoked. ### Usage ```rust if expensive_operation { // This might exceed budget if multiple expensive calls happen env.invoke_contract( contract, Symbol::try_from_small_str("heavy_computation")?, env.vec_new()?, ) } else { env.invoke_contract( contract, Symbol::try_from_small_str("light_operation")?, env.vec_new()?, ) } ``` ``` -------------------------------- ### Enable Benchmarking in Soroban Host Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/configuration.md Include the `bench` feature to enable the benchmarking infrastructure for the Soroban host. ```toml soroban-env-host = { version = "27", features = ["bench"] } ``` -------------------------------- ### VecObject Access Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Retrieve the length of a vector or get an element at a specific index. ```rust env.vec_len(obj: VecObject) -> Result ``` ```rust env.vec_get(obj: VecObject, i: U32Val) -> Result ``` -------------------------------- ### Initialize Default Host Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/configuration.md Creates a Soroban Host instance with default configuration settings. Further configuration is typically done via method calls after initialization. ```rust use soroban_env_host::Host; let host = Host::default(); ``` -------------------------------- ### MeteredOrdMap Get Method Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/budget.md Retrieves a value from MeteredOrdMap, metering the lookup operation. ```rust fn get(&self, k: &Q, budget: &Budget) -> Result, HostError> where K: Borrow + Ord, Q: Ord + ?Sized, ``` -------------------------------- ### Enable Recording Mode in Soroban Host Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/configuration.md Activate the `recording_mode` feature for preflight simulation to record footprints. ```toml [dev-dependencies] soroban-env-host = { version = "27", features = ["recording_mode"] } ``` -------------------------------- ### Convert i64 to/from Object Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Illustrates converting an i64 primitive to an I64Object and back using the environment. ```rust env.obj_from_i64(v: i64) -> Result env.obj_to_i64(obj: I64Object) -> Result ``` -------------------------------- ### Object Conversion Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Convert a Val to an Object if it has an object tag, or get the wrapped Val from an Object. ```rust fn try_from(val: Val) -> Result ``` ```rust fn as_val(&self) -> Val ``` -------------------------------- ### MapObject Access Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Retrieve the length of a map, get a value associated with a key, or check for the existence of a key. ```rust env.map_len(obj: MapObject) -> Result ``` ```rust env.map_get(obj: MapObject, key: Val) -> Result ``` ```rust env.map_has(obj: MapObject, key: Val) -> Result ``` -------------------------------- ### Budget Key Methods Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/host.md Provides essential methods for interacting with the Budget struct, such as retrieving current usage, resetting counters, setting limits, and consuming costs. ```rust fn current_time(&self) -> Result; ``` ```rust fn reset(&mut self); ``` ```rust fn set_limits(&mut self, cpu: u64, mem: u64, ledger: u64); ``` ```rust fn consume(&mut self, cost_type: ContractCostType, inputs: &[u64]) -> Result<(), HostError>; ``` -------------------------------- ### Rust: Get String Length Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/conversion-and-compare.md Retrieves the length of a string object in bytes. Returns a U32Val representing the length. ```rust env.string_len(obj: StringObject) -> Result ``` -------------------------------- ### Get Raw Val Representation Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Retrieves the raw 64-bit unsigned integer representation of the `Val`. This can be useful for low-level inspection or serialization. ```rust let bits: u64 = val.to_constant(); ``` -------------------------------- ### Convert u64 to/from Object Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Shows how to convert a u64 primitive to a U64Object and vice versa using the environment. ```rust env.obj_from_u64(v: u64) -> Result env.obj_to_u64(obj: U64Object) -> Result ``` -------------------------------- ### Create Small Numeric Wrappers Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Demonstrates how to create instances of small numeric wrappers like U32Val and I32Val from primitive types. ```rust use soroban_env_common::U32Val; let u32_val = U32Val::from(42u32); let i32_val = I32Val::from(-100i32); ``` -------------------------------- ### Get Current Contract Address Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/contract-invocation.md Retrieves the address of the contract that is currently being executed. This is useful for self-invocations or when a contract needs to know its own identity. ```APIDOC ## get_current_contract_address ### Description Get the address of the currently executing contract. ### Signature ```rust fn get_current_contract_address(&self) -> Result; ``` ### Returns - `Result`: The address of the current contract. ``` -------------------------------- ### Get Current Contract Address Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/contract-invocation.md Retrieves the address of the contract currently being executed. This is useful for self-invocations or when a contract needs to know its own identity. ```rust fn get_current_contract_address(&self) -> Result; ``` -------------------------------- ### Budget Reset Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/budget.md Resets the budget counters to zero. This is typically called at the start of an invocation to ensure a clean slate for cost tracking. ```APIDOC ## Budget Reset ### Description Resets the budget counters to zero. Used at the start of an invocation. ### Signature `fn reset(&mut self);` ``` -------------------------------- ### Enable Test Utilities in Soroban Host Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/configuration.md Use the `testutils` feature to enable contract registration, authorization inspection, budget introspection, and direct contract invocation for testing purposes. ```rust #[cfg(any(test, feature = "testutils"))] impl Host { pub fn register_test_contract(...) { } pub fn get_previous_authorizations(...) { } } ``` ```toml [dev-dependencies] soroban-env-host = { version = "27", features = ["testutils"] } ``` -------------------------------- ### Host Construction Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/host.md Creates a default Host instance. The Host is a reference-counted wrapper around HostImpl, allowing for efficient cloning and thread-safe sharing. ```APIDOC ## Host Construction ```rust impl Default for Host { fn default() -> Self { Self(Default::default()) } } ``` Create a default Host instance. ```rust let host = Host::default(); ``` ``` -------------------------------- ### Filter Events by Data Content Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/events-and-diagnostics.md Example SQL-like query to select all 'transfer' events where the data payload is greater than a specified U128 value. ```sql SELECT * WHERE data > U128Val(1000) ``` -------------------------------- ### Testing Budget Configuration Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/configuration.md Sets generous budget limits for testing purposes and uses mock ledger information. This allows for more flexibility during development and testing phases. ```rust // Generous budgets budget.set_limits( 1_000_000_000, // 1B CPU 1_000_000_000, // 1B Memory 1_000_000_000, // 1B Ledger ); // Mock ledger info ledger_info = LedgerInfo { protocol_version: 27, sequence_number: 1000000, timestamp: 1704067200, network_id: Vec::from(&[0u8; 32]), base_reserve_in_stroops: 100_000_000, max_tx_set_size: 1000, }; ``` -------------------------------- ### Bool Wrapper Creation Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Demonstrates how to create Bool wrapper types from boolean literals. ```rust let t: Bool = true.into(); let f: Bool = false.into(); ``` -------------------------------- ### MeteredOrdMap Methods Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/budget.md MeteredOrdMap is an ordered map that automatically meters its operations. It provides methods for getting, inserting, and deleting entries while tracking budget usage. ```APIDOC ## MeteredOrdMap Ordered map that automatically meters its operations. **Location**: `soroban-env-host/src/host/metered_map.rs` #### Methods ```rust fn get(&self, k: &Q, budget: &Budget) -> Result, HostError> where K: Borrow + Ord, Q: Ord + ?Sized, ``` Get a value, metering the lookup. ```rust fn insert(self, k: K, v: V, budget: &Budget) -> Result; ``` Insert a key-value pair, metering the operation. ```rust fn delete(self, k: &Q, budget: &Budget) -> Result where K: Borrow + Ord, Q: Ord + ?Sized, ``` Delete an entry, metering the operation. ``` -------------------------------- ### Get Current Cost Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/budget.md Retrieves the current total cost incurred in abstract cost units. This allows for monitoring the accumulated cost during contract execution. ```APIDOC ## Get Current Cost ### Description Gets the current total cost incurred (in abstract cost units). ### Signature `fn current_time(&self) -> Result;` ### Returns `Result` - Total cost units spent ``` -------------------------------- ### Bool Wrapper Usage Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Shows how to attempt conversion of a Val to a Bool wrapper, handling potential errors. ```rust match bool::try_from(val) { Ok(b) => { /* use b */ }, Err(_) => { /* not a boolean */ } } ``` -------------------------------- ### Default Host Instance Construction Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/host.md Provides a default implementation for creating a Host instance using the Default trait. ```rust impl Default for Host { fn default() -> Self { Self(Default::default()) } } ``` ```rust let host = Host::default(); ``` -------------------------------- ### Symbol Wrapper Small String Construction Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Illustrates creating a Symbol wrapper from a string literal that is 9 characters or less. ```rust let sym = Symbol::try_from_small_str("abc")?; ``` -------------------------------- ### Create InstanceStorageMap from XDR Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/storage-and-footprint.md Creates an InstanceStorageMap from an XDR ScContractInstance entry. Requires a Host for validation. ```rust pub(crate) fn from_instance_xdr( instance: &ScContractInstance, host: &Host ) -> Result; ``` -------------------------------- ### Rust: Copy String to Byte Slice Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/conversion-and-compare.md Copies a portion of a string object into a mutable byte slice. Specify the starting position and the slice's capacity. ```rust env.string_copy_to_slice( obj: StringObject, pos: U32Val, slice: &mut [u8] ) -> Result<(), Self::Error> ``` -------------------------------- ### Soroban Environment Source Code Structure Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/README.md Provides an overview of the directory structure for the Soroban environment, detailing the purpose of key files within the common, host, and guest crates. ```text soroban-env-common/ ├── src/ │ ├── lib.rs → Public exports │ ├── val.rs → Val, Tag types │ ├── symbol.rs → Symbol wrapper │ ├── bytes.rs → BytesObject wrapper │ ├── string.rs → StringObject wrapper │ ├── object.rs → Object wrapper │ ├── error.rs → Error type │ ├── env.rs → Env trait definition │ ├── convert.rs → TryFromVal, TryIntoVal │ ├── compare.rs → Compare trait │ ├── storage_type.rs → StorageType enum │ └── num.rs → Numeric types soroban-env-host/ ├── src/ │ ├── lib.rs → Public exports │ ├── host.rs → Host struct (4000+ lines) │ ├── budget.rs → Budget metering │ ├── storage.rs → Storage management │ ├── auth.rs → Authorization (3000+ lines) │ ├── vm.rs → WASM VM integration │ ├── crypto/ → Cryptographic functions │ ├── events/ → Event management │ ├── e2e_invoke.rs → Transaction simulation │ └── fees.rs → Fee computation soroban-env-guest/ └── src/ └── lib.rs → Guest stub ``` -------------------------------- ### Get Current Budget Cost Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/budget.md Retrieves the total accumulated cost in abstract cost units incurred so far during the current invocation. Returns a Result containing the cost or a HostError. ```rust fn current_time(&self) -> Result; ``` -------------------------------- ### Convert u64 to DurationObject Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Demonstrates converting a u64 duration into a DurationObject using the environment. ```rust env.obj_from_duration(d: u64) -> Result ``` -------------------------------- ### Including Domain Context in Signed Data Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/cryptography.md To prevent signature reuse, include domain or context information in the data being signed. This example demonstrates appending domain bytes to the actual message. ```rust let msg_with_context = env.bytes_append( domain_bytes, actual_message )?; env.ed25519_verify(pk, msg_with_context, sig?); ``` -------------------------------- ### Create InstanceStorageMap from Vec Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/storage-and-footprint.md Creates an InstanceStorageMap from a vector of key-value pairs. Requires a Host for validation. ```rust pub(crate) fn from_map( map: Vec<(Val, Val)>, host: &Host ) -> Result; ``` -------------------------------- ### Try From Small String for Symbol Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/types.md Constructs a Symbol from a small string, accepting strings up to 9 characters. Returns a Result indicating success or failure. ```rust fn try_from_small_str(s: &str) -> Result ``` -------------------------------- ### Error Wrapper Construction Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Demonstrates creating an Error wrapper using specific error types and codes. ```rust use soroban_env_common::xdr::{ScErrorType, ScErrorCode}; let err = Error::from_type_and_code( ScErrorType::Contract, ScErrorCode::ExecutionFailure ); ``` -------------------------------- ### Get Total Call Stack Size (Diagnostic Mode) Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/budget.md In diagnostic mode, this function retrieves the current call stack depth in cost units. This is useful for debugging and performance analysis. ```rust #[cfg(any(test, feature = "testutils"))] fn total_call_stack_size(&self) -> Result; ``` -------------------------------- ### Create and Access Soroban Values Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Demonstrates creating various Soroban Val types including Symbols, Bytes, Vectors, and Maps, and accessing elements within a Map. Ensure the `soroban_env_common` crate is imported. ```rust use soroban_env_common::{Val, Symbol, BytesObject, VecObject, MapObject, Env}; fn demo(env: &impl Env) -> Result<(), env::Error> { // Create values let my_sym = Symbol::try_from_small_str("key")?; let my_bytes = env.bytes_new_from_slice(b"hello")?; let my_vec = env.vec_new_from_slice(&[ Val::from(1u32), Val::from(2u32), ])?; // Create map let my_map = env.map_new_from_slices( &["a", "b"], &[Val::from(10u32), Val::from(20u32)] )?; // Access map let key_val = Val::from(my_sym); let _value = env.map_get(my_map, key_val)?; Ok(()) } ``` -------------------------------- ### Get Contract Data Value Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/host.md Retrieves a value from contract storage using a given key and storage type. Throws ScErrorCode::MissingValue if the key is not found or ScErrorCode::ExceededLimit if access is not in the footprint. ```rust fn get_contract_data( &self, k: Val, dtype: StorageType ) -> Result; ``` -------------------------------- ### Production Budget Configuration Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/configuration.md Sets conservative budget limits for CPU, Memory, and Ledger operations in a production environment. Fetches real ledger information from the blockchain. ```rust // Conservative budgets budget.set_limits( 100_000_000, // CPU 100_000_000, // Memory 10_000_000, // Ledger ); // Real ledger info from blockchain ledger_info = fetch_current_ledger_info(); ``` -------------------------------- ### Void Wrapper Creation Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Illustrates the creation of a Void wrapper type from the unit type. ```rust let empty: Void = ().into(); ``` -------------------------------- ### Convert u64 to TimepointObject Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Demonstrates converting a u64 timestamp into a TimepointObject using the environment. ```rust env.obj_from_timepoint(t: u64) -> Result ``` -------------------------------- ### Soroban VM CompilationContext Structure Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/configuration.md Controls settings and limits for WebAssembly compilation, including module parsing and validation. ```rust pub struct CompilationContext { // Limits and settings for WASM compilation } ``` -------------------------------- ### Simulate Invocation (No Auth) Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/e2e-and-simulation.md Performs an initial simulation of a contract invocation to determine authorization requirements. This function should be used when the authorization details are not yet known. ```rust fn get_auth_requirements( contract_id: ContractId, function: &str, args: Vec, snapshot: &dyn SnapshotSource, ) -> Result, SimulationError> { let spec = InvocationSpec { contract_id, function_name: function.to_string(), args, auth: vec![], // Start with no auth ledger: current_ledger(), }; let result = simulate_invocation(spec, snapshot)?; if !result.success { eprintln!("Simulation failed: missing authorizations"); } Ok(result.auth_records) } ``` -------------------------------- ### Symbol Wrapper Conversion Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Shows converting a Symbol wrapper to a String and creating a Symbol from a small string. ```rust let symbol = Symbol::try_from_small_str("hello")?; let s: String = symbol.try_into()?; assert_eq!(s, "hello"); ``` -------------------------------- ### Set Custom Budget Limits Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/configuration.md Configures the per-invocation limits for CPU, memory, and ledger operations on the Soroban host's budget. These limits are specified in abstract cost units. ```rust use soroban_env_host::{Host, budget::Budget}; let mut host = Host::default(); let budget = host.as_budget_mut(); budget.set_limits( 10_000_000, // CPU units 10_000_000, // Memory units 1_000_000, // Ledger units ); ``` -------------------------------- ### Footprint Methods Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/storage-and-footprint.md Methods for recording and enforcing ledger access within a footprint. ```APIDOC ## `Footprint::record_access` ### Description Records a ledger access during preflight execution (recording mode only). ### Method `record_access` ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Parameters - **key** (`&Rc`) - Required - Key being accessed - **ty** (`AccessType`) - Required - Type of access (read or write) - **budget** (`&Budget`) - Required - Budget for metering ### Returns - `Result<(), HostError>` ### Behavior - If key not yet in footprint: insert with given access type - If key exists with `ReadOnly`, upgrade to `ReadWrite` if new access is write - Otherwise, keep existing (more permissive) type ## `Footprint::enforce_access` ### Description Checks that a ledger access is allowed by the footprint (enforcing mode only). ### Method `enforce_access` ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Parameters - **key** (`&Rc`) - Required - Key being accessed - **ty** (`AccessType`) - Required - Type of access being attempted - **budget** (`&Budget`) - Required - Budget for metering ### Returns - `Result<(), HostError>` ### Throws - `ScErrorCode::ExceededLimit` if: - Key not in footprint - Footprint allows read-only but write is attempted ``` -------------------------------- ### Estimate Fees from Simulation Results Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/e2e-and-simulation.md Calculates base and priority fees based on contract execution resources and a network multiplier. Use this to determine transaction costs. ```rust fn estimate_fees( result: &InvocationResult, network_multiplier: f64, ) -> u64 { // Base fee calculation from resources let base_fee = ( result.resources.cpu_units + result.resources.mem_units + result.resources.ledger_read_units + result.resources.ledger_write_units ) as f64; // Apply network multiplier (bid to prioritize) (base_fee * network_multiplier) as u64 } fn example_fee_estimation( result: &InvocationResult, ) { let base_fee = estimate_fees(result, 1.0); let priority_fee = estimate_fees(result, 1.5); // 50% premium println!("Base fee: {} stroops", base_fee); println!("Priority fee: {} stroops", priority_fee); } ``` -------------------------------- ### Rust: Safe Conversion with Error Handling Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/conversion-and-compare.md Demonstrates a safe way to convert a Val to a u32, handling potential conversion errors. Use this pattern for robust type casting. ```rust fn safe_convert(env: &impl Env, val: Val) -> Result { // Try to convert to u32 u32::try_from_val(env, &val) } fn handle_conversion_error(err: ConversionError) { match err { ConversionError::BadVal => eprintln!("Invalid Val tag for target type"), ConversionError::UnknownError => eprintln!("Unexpected conversion error"), } } ``` -------------------------------- ### Convert DurationObject to u64 Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Illustrates converting a DurationObject back into a u64 duration using the environment. ```rust env.obj_to_duration(obj: DurationObject) -> Result ``` -------------------------------- ### Object Conversion and Access Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/val-and-wrappers.md Methods for converting between Val and Object, and accessing the wrapped Val. ```APIDOC ## Object ### Description `Object` is a generic wrapper for any object type, including `U64Object` through `MuxedAddressObject`. ### Creation and Conversion - `fn try_from(val: Val) -> Result`: Attempts to convert a `Val` into an `Object` if it has an object tag. ### Access - `fn as_val(&self) -> Val`: Returns the wrapped `Val`. ``` -------------------------------- ### Usage of AsBudget Trait Source: https://github.com/stellar/rs-soroban-env/blob/main/_autodocs/api-reference/budget.md Demonstrates how to use the AsBudget trait to obtain a budget within a generic function. ```rust use soroban_env_host::budget::AsBudget; fn metered_operation(t: &T) -> Result<(), HostError> { let budget = t.as_budget(); // Can now use budget for metering Ok(()) } ```