Skip to main content

Quick Start

Once you've Setup your development environment, you're ready to create your first Soroban contract.

Create New Project

Start by creating a new Rust library using the cargo new command.

cargo new --lib first-project

Open the Cargo.toml, it should look something like this:

Cargo.toml
[package]
name = "first-project"
version = "0.1.0"
edition = "2021"

Add soroban-sdk Dependency

Add the following sections to the Cargo.toml that will import the soroban-sdk.

caution

The soroban-sdk is in early development. Report issues here.

[lib]
crate-type = ["cdylib", "rlib"]

[features]
testutils = ["soroban-sdk/testutils"]

[dependencies]
soroban-sdk = "0.0.4"

[dev_dependencies]
soroban-sdk = { version = "0.0.4", features = ["testutils"] }

[profile.release]
opt-level = "z"
overflow-checks = true
debug = 0
strip = "symbols"
debug-assertions = false
panic = "abort"
codegen-units = 1
lto = true

The features list includes a testutils feature, which will cause additional test utilities to be generated for calling the contract in tests.

info

The testutils test utilities are automatically enabled inside Rust unit tests inside the same crate as your contract. If you write Rust integration tests, or write tests from another crate, you'll need to add #[cfg(feature = "testutils")] to those tests and enable the testutils feature when running your tests with cargo test --features testutils to be able to use those test utilities.

The config for the release profile configures the Rust toolchain to produce smaller contracts.

Write the Code

Open the src/lib.rs file, and copy-paste the following code.

#![no_std]
use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec};

pub struct Contract;

#[contractimpl]
impl Contract {
pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
vec![&env, symbol!("Hello"), to]
}
}

#[cfg(test)]
mod test {
use super::{Contract, ContractClient};
use soroban_sdk::{symbol, vec, BytesN, Env};

#[test]
fn test() {
let env = Env::default();
let contract_id = BytesN::from_array(&env, &[0; 32]);
env.register_contract(&contract_id, Contract);
let client = ContractClient::new(&env, &contract_id);

let words = client.hello(&symbol!("Dev"));
assert_eq!(
words,
vec![&env, symbol!("Hello"), symbol!("Dev"),]
);
}
}

Run the Tests

Run cargo test and watch the contract run. You should see the following output:

cargo test
running 1 test
test test::test ... ok

Try changing the values in the test to see how it works.

Build the Contract

To build the contract into a .wasm file, use the cargo build command.

cargo build --target wasm32-unknown-unknown --release

A .wasm file should be outputted in the target directory:

target/wasm32-unknown-unknown/release/first_project.wasm
info

Hyphens in Rust crate names are replaced by underscores in code and generated file names, so first-project is outputted as first_project.wasm.

Run the Contract

If you have soroban-cli installed, you can invoke contract functions in the contract.

soroban-cli invoke \
--wasm target/wasm32-unknown-unknown/release/first_project.wasm \
--id 1 \
--fn hello \
--arg friend

You should see the following output:

["Hello","friend"]