The add example demonstrates how to write a simple contract, with a single function that takes two i32
inputs and returns their sum as an output.
To run a contract, you must first install the official stellar-cli:
cargo install --locked stellar-cli
Then, to run the example, navigate it's directory and install the SDK. Then build the contract:
cd add
npm install
npm run asbuild:release
You can find the generated .wasm
(WebAssembly) file in the build
folder. You can also find the .wat
file there (text format of the .wasm
).
Run the example contract:
To run the contract, we first need to deploy it:
stellar contract deploy \
--wasm build/release.wasm \
--source SAIPPNG3AGHSK2CLHIYQMVBPHISOOPT64MMW2PQGER47SDCN6C6XFWQM \
--rpc-url https://soroban-testnet.stellar.org \
--network-passphrase "Test SDF Network ; September 2015"
This returns the ID of the contract, starting with a C. Next let's invoke:
stellar -q contract invoke \
--source SAIPPNG3AGHSK2CLHIYQMVBPHISOOPT64MMW2PQGER47SDCN6C6XFWQM \
--rpc-url https://soroban-testnet.stellar.org \
--network-passphrase "Test SDF Network ; September 2015" \
--id <your contract id here> \
-- add --a 1 --b 5
You should see the output:
6
You can find the code in:
add/assembly/index.ts
import { I32Val, toI32, fromI32 } from 'as-soroban-sdk/lib/value';
export function add(a: I32Val, b: I32Val): I32Val {
// decode arguments from host values to i32 primitives
let ai:i32 = toI32(a);
let bi:i32 = toI32(b);
// add
let sum = ai + bi;
// encode to host value
let result = fromI32(sum);
// return host value
return result;
}
When calling a contract function the host will only pass so called host values. The SDK can encode and decode host values. A host value is a 64-bit integer carrying a bit-packed disjoint union of several cases, each identified by a different tag value (e.g. i32
, u32
, symbol
, timestamp
, bool
etc. or object handles
such as references to vectors, maps, bytes, strings that live in the host).
You can read more about host values and their types in CAP-0046.
The contract function add
defined in our contract has 2 arguments of type I32Val
, and returns a I32Val
. I32Val
representing the host values passed by and to the host.
The concrete types must also be defined in the contract spec: contract.json
file:
{
"functions": [
{
"name" : "add",
"arguments": [
{"name": "a", "type": "i32"},
{"name": "b", "type": "i32"}
],
"returns" : "i32"
}
],
"meta": [
{
"key" : "name",
"value" : "add"
},
{
"key" : "version",
"value" : "1.1.0"
},
{
"key" : "description",
"value" : "soroban contract example adding 2 integers"
}
]
}
Because the host calls our function with I32Val
(host value), we need to decode them first into i32
primitives. To do so, we use the SDKs function toI32
which decodes the I32Val
(host value) into a i32
(primitive).
let ai:i32 = toI32(a);
let bi:i32 = toI32(b);
Next, we can apply the + operation to our integers and return the result to the host. Because the host expects I32Val
(host value) as a return value, we must encode the result into a such a host value containing our i32
sum.
// add
let sum = ai + bi;
// encode to host value
let result = fromI32(sum);
// return host value
return result;