Hi there! Welcome to my sixth post of my series called "Soroban Contracts 101", where I'll be explaining the basics of Soroban contracts, such as data storage, authentication, custom types, and more. All the code that we're gonna explain throughout this series will mostly come from soroban-contracts-101 github repository.
In this sixth post of the series, I'll be covering soroban contract logging. Logging is a useful tool for both development and transparency/reactivity in blockchain contracts.
The Soroban SDK provides the log!
macro for easy logging from contracts. The log!
macro allows logging a string from a contract. For example:
log!(&env, "Count is: {}", count);
This would log a string including the count variable.
Some key points about logging in Soroban:
- Logs are only output if a contract is built with
debug assertions
enabled (release builds omit logs) - Logs are only output in test environments and the soroban-cli (not in actual contract deployments)
- Logs are output to stdout in the soroban-cli
- Logs can be asserted on/printed in tests to verify/debug contract behavior
The Contract Code
#![no_std]
use soroban_sdk::{contractimpl, log, Env, Symbol};
pub struct Contract;
#[contractimpl]
impl Contract {
pub fn hello(env: Env, value: Symbol) {
log!(&env, "Hello {}", value);
}
}
This minimal contract
Uses the no_std
attribute, indicating it uses no Rust standard library. Imports essential parts of the Soroban SDK : Env
, Symbol
and the log
macro. Defines a Contract
struct and Implements a contractimpl
on Contract
.
The main code is the hello
function,it will :
- Takes an Env and a Symbol parameter
- Logs a "Hello" greeting and the passed in value
The Test Code
extern crate std;
#[test]
fn test() {
let env = Env::default();
let contract_id = env.register_contract(None, Contract);
let client = ContractClient::new(&env, &contract_id);
client.hello(&symbol!("Dev"));
let logs = env.logger().all();
assert_eq!(logs, std::vec!["Hello Symbol(Dev)"]);
std::println!("{}", logs.join("\n"));
}
This code is a unit test for our contract. It does the following:
- Imports the standard library (for testing)
- Creates a test function
- Creates an
Env
and registers the Contract - Creates a client to call the contract
- Calls the client's
hello
function with a "Dev" symbol (to be logged) - Gets all logs from the
Env
and asserts that the expected "Hello Symbol(Dev)" log occurred - Also prints out the logs
So this test verifies that logging the passed in symbol parameter works as expected. It's a good practice to include basic logging tests like this in development to ensure your logging is working correctly.
Running Contract Tests
To ensure that the contract functions as intended, you can run the contract tests using the following command:
cargo test -- --nocapture
If the tests are successful, you should see an output similar to:
running 1 test
Hello Symbol(Dev)
test test::test ... ok
Building The Contract
Before we build the contract, we need to change cargo.toml
profile in the contract directory,because earlier in this post i mentioned logs are only output if a contract is built with debug assertions
enabled. So change the cargo.toml
profile into :
[profile.release-with-logs]
inherits = "release"
debug-assertions = true
To build the contract, use the following command:
cargo build --target wasm32-unknown-unknown --profile release-with-logs
This should output a .wasm file in the ../target directory:
../target/wasm32-unknown-unknown/release-with-logs/soroban_logging_contract.wasm
Invoking The Contract
To invoke the hello
function of the contract, use the following command with Soroban-CLI:
soroban contract invoke \
--wasm ../target/wasm32-unknown-unknown/release-with-logs/soroban_logging_contract.wasm \
--id 1 \
-- \
hello \
--to world
You should see the following output:
null
#0: debug: Hello Symbol(world)
Conclusion
So logging is a useful development/testing tool, and leaving appropriate log statements in contracts can provide transparency, but logs do not impact actual contract deployments. The log!
macro provides a simple way to log information from your Soroban contracts. Stay tuned for more post in this "Soroban Contracts 101" Series where we will dive deeper into Soroban Contracts and their functionalities.
Top comments (0)