diff --git a/ContractExamples/contracts/setter/README.md b/ContractExamples/contracts/setter/README.md new file mode 100644 index 00000000..fe85a976 --- /dev/null +++ b/ContractExamples/contracts/setter/README.md @@ -0,0 +1,37 @@ +`Setter` is a simple Soroban contract that contains setters and getters for the +built-in [Soroban types][]. We are using this contract to debug the transaction +fetcher. + +## How to use + + 1. Make sure that you have installed Soroban by following the [Getting Started] + guide. + + 1. Deploy the setter contract: + + ```sh + $ cd ContractExamples + $ soroban build + $ soroban contract deploy --wasm target/wasm32-unknown-unknown/release/setter.wasm \ + --source alice --network testnet | tee >setter.id + ``` + + 1. Invoke a setter function. For example: + + ```sh + $ soroban contract invoke --id $(cat setter.id) --source alice --network testnet \ + -- set_i32 --v 42 + 0 + ``` + + 1. Invoke a getter function. For example: + + ```sh + $ soroban contract invoke --id $(cat setter.id) --source alice --network testnet \ + -- get_i32 + 42 + ``` + + +[Soroban types]: https://developers.stellar.org/docs/learn/smart-contract-internals/types/built-in-types +[Getting Started]: https://developers.stellar.org/docs/smart-contracts/getting-started/setup diff --git a/ContractExamples/contracts/setter/src/lib.rs b/ContractExamples/contracts/setter/src/lib.rs index 93c7ade6..8101cd4e 100644 --- a/ContractExamples/contracts/setter/src/lib.rs +++ b/ContractExamples/contracts/setter/src/lib.rs @@ -1,11 +1,54 @@ #![no_std] -use soroban_sdk::{contract, contractimpl, log, symbol_short, Env, Symbol}; +use soroban_sdk::{contract, contractimpl, contracttype, log, symbol_short, vec, Address, Bytes, BytesN, Env, Map, Symbol, Vec}; + +// scalar types const MY_BOOL: Symbol = symbol_short!("MY_BOOL"); +const MY_U32: Symbol = symbol_short!("MY_U32"); +const MY_I32: Symbol = symbol_short!("MY_I32"); +const MY_U64: Symbol = symbol_short!("MY_U64"); +const MY_I64: Symbol = symbol_short!("MY_I64"); +const MY_U128: Symbol = symbol_short!("MY_U128"); +const MY_I128: Symbol = symbol_short!("MY_I128"); +const MY_SYM: Symbol = symbol_short!("MY_SYM"); + +// aggregate types +const MY_BYTES: Symbol = symbol_short!("MY_BYTES"); +const MY_BYTES32: Symbol = symbol_short!("MY_BTES32"); +const MY_VEC: Symbol = symbol_short!("MY_VEC"); +const MY_MAP: Symbol = symbol_short!("MY_MAP"); +const MY_ADDR: Symbol = symbol_short!("MY_ADDR"); +const MY_STRUCT: Symbol = symbol_short!("MY_STRUCT"); +const MY_ENUM: Symbol = symbol_short!("MY_ENUM"); + +/** + * A simple two-field structure. + */ +#[contracttype] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MyStruct { + pub a: u32, + pub b: i128, +} + +/** + * A simple enum. + */ +#[contracttype] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum MyEnum { + A, + B(u32), +} #[contract] pub struct SetterContract; +/** + * A test contract to try all kinds of types enumerated in: + * + * https://developers.stellar.org/docs/learn/smart-contract-internals/types/built-in-types + */ #[contractimpl] impl SetterContract { pub fn set_bool(env: Env, v: bool) -> bool { @@ -19,7 +62,186 @@ impl SetterContract { } pub fn get_bool(env: Env) -> bool { - return env.storage().instance().get(&MY_BOOL).unwrap_or(false); + env.storage().instance().get(&MY_BOOL).unwrap_or(false) + } + + pub fn set_u32(env: Env, v: u32) -> u32 { + let old: u32 = env.storage().instance().get(&MY_U32).unwrap_or(0); + env.storage().instance().set(&MY_U32, &v); + log!(&env, "myU32: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100); + // return the old value to the caller + old + } + + pub fn get_u32(env: Env) -> u32 { + env.storage().instance().get(&MY_U32).unwrap_or(0) + } + + pub fn set_i32(env: Env, v: i32) -> i32 { + let old: i32 = env.storage().instance().get(&MY_I32).unwrap_or(0); + env.storage().instance().set(&MY_I32, &v); + log!(&env, "myI32: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100); + // return the old value to the caller + old + } + + pub fn get_i32(env: Env) -> i32 { + env.storage().instance().get(&MY_I32).unwrap_or(0) + } + + pub fn set_u64(env: Env, v: u64) -> u64 { + let old: u64 = env.storage().instance().get(&MY_U64).unwrap_or(0); + env.storage().instance().set(&MY_U64, &v); + log!(&env, "myU64: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100); + // return the old value to the caller + old + } + + pub fn get_u64(env: Env) -> u64 { + env.storage().instance().get(&MY_U64).unwrap_or(0) + } + + pub fn set_i64(env: Env, v: i64) -> i64 { + let old: i64 = env.storage().instance().get(&MY_I64).unwrap_or(0); + env.storage().instance().set(&MY_I64, &v); + log!(&env, "myi64: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100); + // return the old value to the caller + old + } + + pub fn get_i64(env: Env) -> i64 { + env.storage().instance().get(&MY_I64).unwrap_or(0) + } + + pub fn set_u128(env: Env, v: u128) -> u128 { + let old: u128 = env.storage().instance().get(&MY_U128).unwrap_or(0); + env.storage().instance().set(&MY_U128, &v); + log!(&env, "myU128: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100); + // return the old value to the caller + old + } + + pub fn get_u128(env: Env) -> u128 { + env.storage().instance().get(&MY_U128).unwrap_or(0) + } + + pub fn set_i128(env: Env, v: i128) -> i128 { + let old: i128 = env.storage().instance().get(&MY_I128).unwrap_or(0); + env.storage().instance().set(&MY_I128, &v); + log!(&env, "myi128: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100); + // return the old value to the caller + old + } + + pub fn get_i128(env: Env) -> i128 { + env.storage().instance().get(&MY_I128).unwrap_or(0) + } + + pub fn set_sym(env: Env, v: Symbol) -> Symbol { + let old: Symbol = env.storage().instance().get(&MY_SYM).unwrap_or(symbol_short!("NONE")); + env.storage().instance().set(&MY_SYM, &v); + log!(&env, "mySym: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100); + // return the old value to the caller + old + } + + pub fn get_sym(env: Env) -> Symbol { + env.storage().instance().get(&MY_SYM).unwrap_or(symbol_short!("NONE")) + } + + pub fn set_bytes(env: Env, v: Bytes) -> () { + env.storage().instance().set(&MY_BYTES, &v); + log!(&env, "myBytes: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100) + } + + pub fn get_bytes(env: Env) -> Bytes { + env.storage().instance().get(&MY_BYTES).unwrap_or(Bytes::new(&env)) + } + + pub fn set_bytes32(env: Env, v: BytesN<32>) -> () { + env.storage().instance().set(&MY_BYTES32, &v); + log!(&env, "myBytes32: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100) + } + + pub fn get_bytes32(env: Env) -> BytesN<32> { + env.storage().instance().get(&MY_BYTES32) + .unwrap_or(BytesN::from_array(&env, &[0u8; 32])) + } + + pub fn set_vec(env: Env, v: Vec) -> () { + env.storage().instance().set(&MY_VEC, &v); + log!(&env, "myVec: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100) + } + + pub fn get_vec(env: Env) -> Vec { + env.storage().instance().get(&MY_VEC).unwrap_or(vec![&env]) + } + + pub fn set_map(env: Env, v: Map) -> () { + env.storage().instance().set(&MY_MAP, &v); + log!(&env, "myMap: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100) + } + + pub fn get_map(env: Env) -> Map { + env.storage().instance().get(&MY_MAP).unwrap_or(Map::from_array(&env, [(0, 0); 0])) + } + + pub fn set_address(env: Env, v: Address) -> () { + env.storage().instance().set(&MY_ADDR, &v); + log!(&env, "myAddress: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100) + } + + pub fn get_address(env: Env) -> Option
{ + env.storage().instance().get(&MY_VEC) + } + + pub fn set_my_struct(env: Env, v: MyStruct) -> () { + env.storage().instance().set(&MY_STRUCT, &v); + log!(&env, "myStruct: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100) + } + + pub fn get_my_struct(env: Env) -> MyStruct { + env.storage().instance().get(&MY_STRUCT) + .unwrap_or(MyStruct { + a: 0u32, b: 0i128 + }) + } + + pub fn set_my_enum(env: Env, v: MyEnum) -> () { + env.storage().instance().set(&MY_ENUM, &v); + log!(&env, "myEnum: {}", v); + // bump the lifetime + env.storage().instance().extend_ttl(50, 100) + } + + pub fn get_my_enum(env: Env) -> MyEnum { + env.storage().instance().get(&MY_ENUM).unwrap_or(MyEnum::A) } }