Adding the increment contract
In addition to creating a new project, thestellar contract init command also allows us to initialize a new contract workspace within an existing project. In this example, we’re going to initialize a new contract and use the --name flag to specify the name of our new contract, increment.
This command will not overwrite existing files unless we explicitly pass in the --overwrite flag. From within our soroban-hello-world directory, run:
contracts/increment directory with placeholder code in src/lib.rs and src/test.rs, which we’ll replace with our new increment contract and corresponding tests.
contracts/increment/src/lib.rs with the following.
Imports
This contract begins similarly to our Hello World contract, with an annotation to exclude the Rust standard library, and imports of the types and macros we need from thesoroban-sdk crate.
contracts/increment/src/lib.rs
Contract Data Keys
Symbol is a short (up to 32 characters long) string type with limited character space (only a-zA-Z0-9_ characters are allowed). Identifiers like contract function names and contract data keys are represented by Symbols.
The symbol_short!() macro is a convenient way to pre-compute short symbols up to 9 characters in length at compile time using Symbol::short. It generates a compile-time constant that adheres to the valid character set of letters (a-zA-Z), numbers (0-9), and underscores (_). If a symbol exceeds the 9-character limit, Symbol::new should be utilized for creating symbols at runtime.
Contract Data Access
Env.storage() function is used to access and update contract data. The executing contract is the only contract that can query or modify contract data that it has stored. The data stored is viewable on ledger anywhere the ledger is viewable, but contracts executing within the Soroban environment are restricted to their own data.
The get() function gets the current value associated with the counter key.
If no value is currently stored, the value given to unwrap_or(...) is returned instead.
Values stored as contract data and retrieved are transmitted from the environment and expanded into the type specified. In this case a u32. If the value can be expanded, the type returned will be a u32. Otherwise, if a developer cast it to be some other type, a panic would occur at the unwrap.
set() function stores the new count value against the key, replacing the existing value.
Managing Contract Data TTLs with extend_ttl()
Persistent, Temporary, and Instance. This contract only uses Instance storage: env.storage().instance(). Every time the counter is incremented, this storage’s TTL gets extended by 100 ledgers, or about 500 seconds.
Build the contract
From insidesoroban-hello-world, run:
hello_world.wasm and increment.wasm.
Tests
Replace the placeholder code incontracts/increment/src/test.rs with the following increment test code.
contracts/increment/src/test.rs
log! call, run the tests with --nocapture:
Take it further
Can you figure out how to addget_current_value function to the contract? What about decrement or reset functions?