> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Hello World

> Create your first smart contract on Stellar with this Hello World guide. Learn how to write, deploy, and test your contract using Rust and the Stellar CLI.

Once you've [set up](/docs/build/smart-contracts/getting-started/setup.md) your development environment, you're ready to create your first smart contract.

## Create a New Project

Create a new project using the `init` command to create a `soroban-hello-world` project.

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract init soroban-hello-world
```

The `init` command will create a Rust workspace project, using the recommended structure for including Soroban contracts. Let’s take a look at the project structure:

```
.
├── AGENTS.md
├── Cargo.toml
├── README.md
└── contracts
    ├── hello-world
    │   ├── Cargo.toml
    │   ├── Makefile
    │   ├── src
    │   │   ├── lib.rs
    │   │   └── test.rs
```

### Cargo.toml

The `Cargo.toml` file at the root of the project is set up as Rust Workspace, which allows us to include multiple smart contracts in one project.

#### Rust Workspace

The `Cargo.toml` file sets the workspace’s members as all contents of the `contracts` directory and sets the workspace’s `soroban-sdk` dependency version including the `testutils` feature, which will allow test utilities to be generated for calling the contract in tests.

```toml title="Cargo.toml" theme={"theme":{"light":"github-light","dark":"github-dark"}}
[workspace]
resolver = "2"
members = [
  "contracts/*",
]

[workspace.dependencies]
soroban-sdk = "28"
```

> [!NOTE]
>
> The `testutils` are automatically enabled inside \[Rust unit tests] inside the same crate as your contract. If you write tests from another crate, you'll need to require the `testutils` feature for those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities.

#### `release` Profile

Configuring the `release` profile to optimize the contract build is critical. The network enforces a maximum contract size (currently 128KB on Mainnet, a value that can change with network configuration). Rust programs, even small ones, without these configurations almost always exceed this size.

The `Cargo.toml` file has the following release profile configured.

```toml theme={"theme":{"light":"github-light","dark":"github-dark"}}
[profile.release]
opt-level = "z"
overflow-checks = true
debug = 0
strip = "symbols"
debug-assertions = false
panic = "abort"
codegen-units = 1
lto = true
```

#### `release-with-logs` Profile

Configuring a `release-with-logs` profile can be useful if you need to build a `.wasm` file that has logs enabled for printing debug logs when using the [`stellar-cli`]. Note that this is not necessary to access debug logs in tests or to use a step-through-debugger.

```toml theme={"theme":{"light":"github-light","dark":"github-dark"}}
[profile.release-with-logs]
inherits = "release"
debug-assertions = true
```

See the [logging example] for more information about how to log.

[logging example]: /docs/build/smart-contracts/example-contracts/logging.md

### Contracts Directory

The `contracts` directory is where Soroban contracts will live, each in their own directory. There is already a `hello-world` contract in there to get you started.

#### Contract-specific Cargo.toml file

Each contract should have its own `Cargo.toml` file, which relies on the top-level `Cargo.toml` that we just discussed.

This is where we can specify contract-specific package information.

```toml title="contracts/hello-world/Cargo.toml" theme={"theme":{"light":"github-light","dark":"github-dark"}}
[package]
name = "hello-world"
version = "0.0.0"
edition = "2021"
publish = false
```

The `crate-type` includes `cdylib`, which is required for building contracts. It also includes `lib`, so other crates, such as a [fuzz target](/docs/build/guides/testing/fuzzing.md), can import the contract as a Rust library.

```toml theme={"theme":{"light":"github-light","dark":"github-dark"}}
[lib]
crate-type = ["lib", "cdylib"]
doctest = false
```

We also have included the soroban-sdk dependency, configured to use the version from the workspace Cargo.toml.

```toml theme={"theme":{"light":"github-light","dark":"github-dark"}}
[dependencies]
soroban-sdk = { workspace = true }

[dev-dependencies]
soroban-sdk = { workspace = true, features = ["testutils"] }
```

#### Contract Source Code

Creating a Soroban contract involves writing Rust code in the project’s `lib.rs` file.

All contracts should begin with `#![no_std]` to ensure that the Rust standard library is not included in the build. The Rust standard library is large and not well suited to being deployed into small programs like those deployed to blockchains.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#![no_std]
```

The contract imports the types and macros that it needs from the `soroban-sdk` crate.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
use soroban_sdk::{contract, contractimpl, vec, Env, String, Vec};
```

Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts by default (the SDK does provide an opt-in allocator through its `alloc` feature — see the [alloc example](/docs/build/smart-contracts/example-contracts/alloc.md)). The `soroban-sdk` provides a variety of types like `Vec`, `Map`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory and native capabilities. Primitive values like `u128`, `i128`, `u64`, `i64`, `u32`, `i32`, and `bool` can also be used. Floats and floating point math are not supported.

Contract inputs must not be references.

The `#[contract]` attribute designates the `Contract` struct as the type to which contract functions are associated. This implies that the struct will have contract functions implemented for it.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#[contract]
pub struct Contract;
```

Contract functions are defined within an `impl` block for the struct, which is annotated with `#[contractimpl]`. It is important to note that contract functions should have names with a maximum length of 32 characters. Additionally, if a function is intended to be invoked from outside the contract, it should be marked with the `pub` visibility modifier. It is common for the first argument of a contract function to be of type `Env`, allowing access to a copy of the Soroban environment, which is typically necessary for various operations within the contract.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#[contractimpl]
impl Contract {
    pub fn hello(env: Env, to: String) -> Vec<String> {
        vec![&env, String::from_str(&env, "Hello"), to]
    }
}
```

Putting those pieces together a simple contract looks like this.

```rust title="contracts/hello-world/src/lib.rs" theme={"theme":{"light":"github-light","dark":"github-dark"}}
#![no_std]
use soroban_sdk::{contract, contractimpl, vec, Env, String, Vec};

#[contract]
pub struct Contract;

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

mod test;
```

Note the `mod test` line at the bottom, this will tell Rust to compile and run the test code, which we’ll take a look at next.

#### Contract Unit Tests

Writing tests for Soroban contracts involves writing Rust code using the test facilities and toolchain that you'd use for testing any Rust code.

Given our `Contract`, a simple test will look like this.

**contracts/hello-world/src/lib.rs**

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#![no_std]
use soroban_sdk::{contract, contractimpl, vec, Env, String, Vec};

#[contract]
pub struct Contract;

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

mod test;
```

**contracts/hello-world/src/test.rs**

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#![cfg(test)]

use super::*;
use soroban_sdk::{vec, Env, String};

#[test]
fn test() {
    let env = Env::default();
    let contract_id = env.register(Contract, ());
    let client = ContractClient::new(&env, &contract_id);

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

In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let env = Env::default();
```

The contract is registered with the environment using the contract type. Contracts can specify a fixed contract ID as the first argument, or provide `None` and one will be generated.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let contract_id = env.register(Contract, ());
```

All public functions within an `impl` block that is annotated with the `#[contractimpl]` attribute have a corresponding function generated in a generated client type. The client type will be named the same as the contract type with `Client` appended. For example, in our contract the contract type is `Contract`, and the client is named `ContractClient`.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let client = ContractClient::new(&env, &contract_id);
let words = client.hello(&String::from_str(&env, "Dev"));
```

The values returned by functions can be asserted on:

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
    assert_eq!(
        words,
        vec![
            &env,
            String::from_str(&env, "Hello"),
            String::from_str(&env, "Dev"),
        ]
    );
```

## Run the Tests

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

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
cargo test
```

```
running 1 test
test test::test ... ok
```

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

> [!NOTE]
>
> The first time you run the tests you may see output in the terminal of cargo compiling all the dependencies before running the tests.

## Build the contract

To build a smart contract to deploy or run, use the `stellar contract build` command.

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract build
```

> [!TIP]
>
> If you get an error like `can't find crate for 'core'`, it means you didn't install the wasm32 target during the [setup step](/docs/build/smart-contracts/getting-started/setup.md#install-the-target). You can do so by running `rustup target add wasm32v1-none` (reminder, this requires Rust `v1.84.0` or higher).

This is a small wrapper around `cargo build` that sets the target to `wasm32v1-none` and the profile to `release` (it also [optimizes](#optimizing-builds) the resulting `.wasm` file by default). You can think of it as a shortcut for the following command:

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
cargo build --target wasm32v1-none --release
```

A `.wasm` file will be outputted in the `target` directory, at `target/wasm32v1-none/release/hello_world.wasm`. The `.wasm` file is the built contract.

The `.wasm` file contains the logic of the contract, as well as the contract's [specification / interface types](/docs/learn/fundamentals/contract-development/types/fully-typed-contracts.md), which can be imported into other contracts who wish to call it. This is the only artifact needed to deploy the contract, share the interface with others, or integration test against the contract.

## Optimizing Builds

The `stellar contract build` command optimizes the generated `.wasm` by default, so there's no extra step needed to minimize the size of your contract. If you'd like to skip that optimization (during quick, iterative development, for example), you can disable it:

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract build --optimize=false
```

> [!TIP]
>
> Optimized contract builds are only necessary when deploying to a network with fees or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, un-optimized builds will work just fine.

> [!NOTE]
>
> Older versions of the Stellar CLI provided a standalone `stellar contract optimize` command. That command is now deprecated in favor of the (default) `--optimize` flag on `stellar contract build`.

## Summary

In this section, we wrote a simple contract that can be deployed to a Soroban network.

Next we'll learn to deploy the HelloWorld contract to Stellar's Testnet network and interact with it over RPC using the CLI.

[rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html

[`stellar-cli`]: setup#install-the-stellar-cli
