Hi there! Welcome to my first post on Dev.to. This is the beginning 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 first post of the series, I'll be covering one of the most fundamental concepts in the programming world - "Hello World". Traditionally, it's the first program developers use to test a system. This will introduce you to Soroban Contracts, give you an idea of what Soroban Contracts are and how they work.
The Contract Code
#![no_std]
use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec};
pub struct HelloContract;
#[contractimpl]
impl HelloContract {
pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
vec![&env, symbol!("Hello"), to]
}
}
The #![no_std]
directive at the beginning of the code indicates that the Rust standard library is not included in the build to keep the code lightweight and efficient.
The code imports the necessary modules from the Soroban SDK using the use
keyword. These modules include contractimpl
, symbol
, vec
, Env
, Symbol
, and Vec
.
The HelloContract zero-sized struct is used as a placeholder to specify the name of the contract.
The #[contractimpl]
attribute indicates that the following code block is a Soroban Contract implementation. The hello()
function is the main part of the contract, which takes two arguments: env
of type Env
and to
of type Symbol
. The Env
type provides access to the contract's environment, while Symbol
represents an encoded string with maximum length of 10.
The function returns a vector of Symbols containing the env, "Hello", and to
values that will be supplied when function invoked.
The Test Code
#[test]
fn test() {
let env = Env::default();
let contract_id = env.register_contract(None, HelloContract);
let client = HelloContractClient::new(&env, &contract_id);
let words = client.hello(&symbol!("SourBun"));
assert_eq!(words, vec![&env, symbol!("Hello"), symbol!("Dev"),]);
}
This code is a test module for the "Hello World" Soroban Contract. It uses the #[cfg(test)]
attribute to denote that this code is only meant to run during testing.
The code imports the super::*
module, which allows the test module to access the contract implementation in the parent module. It also imports modules from the soroban_sdk library, including symbol
, vec
, and Env
.
The test()
function is the main part of the test module. It begins by creating a default Env
object, which represents the contract's environment. It then registers the HelloContract
without a name, which is represented by None
, and returns its unique contract ID. The HelloContractClient
is then created using the Env
object and the contract ID.
The client.hello()
function is called with the argument symbol!("Dev")
, which represents an encoded string. The hello()
function returns a vector of Symbol
s containing the Env
, "Hello"
, and "Dev"
values.
Lastly, the code uses the assert_eq!()
macro to compare the expected output of the hello()
function with the actual output. If the two are not equal, the test fails. This ensures that the hello()
function is working as expected.
Testing contract code is an essential step in the development process to ensure that our contract is working correctly before deploying it to the blockchain.
Running Contract Tests
To ensure that the contract functions as intended, you can run the contract tests using the following command:
cargo test
If the tests are successful, you should see an output similar to:
running 1 test
test test::test ... ok
Building The Contract
To build the contract, use the following command:
cargo build --target wasm32-unknown-unknown --release
This should output a .wasm file in the ../target directory:
../target/wasm32-unknown-unknown/release/soroban_hello_world_contract.wasm
Invoking The Contract
To invoke the hello
function of the contract with a to
value supplied as a string, use the following command with Soroban-CLI:
soroban contract invoke \
--wasm ../target/wasm32-unknown-unknown/release/soroban_hello_world_contract.wasm \
--id 1 \
-- \
hello \
--to World
You should see the following output:
["Hello", "World"]
Therefore, the output ["Hello", "World"] indicates that the hello function was successfully invoked with the specified to
value, and that the function executed as intended, returning the expected array of strings.
Conclusion
In this first post of the series, we introduced you to Soroban Contracts by explaining "Hello World" contract. We hope this article has given you an idea of what Soroban Contracts are and how they work. 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)