Skip to content

Commit 1ad2f7c

Browse files
feat: implement Soroban contract example library
- Add token-example with initialize, balance, and transfer - Add access-control-example with role-based admin/user system - Add upgradeable-example with admin-gated WASM upgrade mechanism - Register all three crates in workspace Cargo.toml
1 parent 54f8995 commit 1ad2f7c

7 files changed

Lines changed: 155 additions & 1 deletion

File tree

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ members = [
1313
"libs/plugin-system",
1414
"libs/auto-fix",
1515
"apps/api",
16-
"tests/mutation"
16+
"tests/mutation",
17+
"packages/examples/stellar/token-example",
18+
"packages/examples/stellar/access-control-example",
19+
"packages/examples/stellar/upgradeable-example"
1720
]
1821

1922
[workspace.package]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "access-control-example"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["cdylib"]
8+
9+
[dependencies]
10+
soroban-sdk = { version = "21.0.0", features = ["alloc"] }
11+
12+
[dev-dependencies]
13+
soroban-sdk = { version = "21.0.0", features = ["testutils", "alloc"] }
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#![no_std]
2+
use soroban_sdk::{contract, contractimpl, contracttype, Address, Env};
3+
4+
#[contracttype]
5+
pub enum DataKey {
6+
Admin,
7+
Role(Address),
8+
}
9+
10+
#[contracttype]
11+
#[derive(Clone, PartialEq)]
12+
pub enum Role {
13+
Admin,
14+
User,
15+
None,
16+
}
17+
18+
#[contract]
19+
pub struct AccessControlContract;
20+
21+
#[contractimpl]
22+
impl AccessControlContract {
23+
pub fn initialize(env: Env, admin: Address) {
24+
env.storage().instance().set(&DataKey::Admin, &admin);
25+
env.storage().instance().set(&DataKey::Role(admin), &Role::Admin);
26+
}
27+
28+
pub fn grant_role(env: Env, caller: Address, account: Address) {
29+
caller.require_auth();
30+
let stored_admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap();
31+
assert!(caller == stored_admin, "Only admin can grant roles");
32+
env.storage().instance().set(&DataKey::Role(account), &Role::User);
33+
}
34+
35+
pub fn get_role(env: Env, account: Address) -> Role {
36+
env.storage().instance().get(&DataKey::Role(account)).unwrap_or(Role::None)
37+
}
38+
39+
pub fn restricted_action(env: Env, caller: Address) {
40+
caller.require_auth();
41+
let role: Role = env.storage().instance().get(&DataKey::Role(caller)).unwrap_or(Role::None);
42+
assert!(role != Role::None, "Access denied: no role assigned");
43+
}
44+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "token-example"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["cdylib"]
8+
9+
[dependencies]
10+
soroban-sdk = { version = "21.0.0", features = ["alloc"] }
11+
12+
[dev-dependencies]
13+
soroban-sdk = { version = "21.0.0", features = ["testutils", "alloc"] }
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#![no_std]
2+
use soroban_sdk::{contract, contractimpl, contracttype, Address, Env};
3+
4+
#[contracttype]
5+
pub enum DataKey {
6+
Admin,
7+
Balance(Address),
8+
}
9+
10+
#[contract]
11+
pub struct TokenContract;
12+
13+
#[contractimpl]
14+
impl TokenContract {
15+
pub fn initialize(env: Env, admin: Address, amount: i128) {
16+
env.storage().instance().set(&DataKey::Admin, &admin);
17+
env.storage().instance().set(&DataKey::Balance(admin.clone()), &amount);
18+
}
19+
20+
pub fn balance(env: Env, account: Address) -> i128 {
21+
env.storage().instance().get(&DataKey::Balance(account)).unwrap_or(0)
22+
}
23+
24+
pub fn transfer(env: Env, from: Address, to: Address, amount: i128) {
25+
from.require_auth();
26+
let from_balance: i128 = env.storage().instance().get(&DataKey::Balance(from.clone())).unwrap_or(0);
27+
assert!(from_balance >= amount, "Insufficient balance");
28+
env.storage().instance().set(&DataKey::Balance(from.clone()), &(from_balance - amount));
29+
let to_balance: i128 = env.storage().instance().get(&DataKey::Balance(to.clone())).unwrap_or(0);
30+
env.storage().instance().set(&DataKey::Balance(to.clone()), &(to_balance + amount));
31+
}
32+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "upgradeable-example"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["cdylib"]
8+
9+
[dependencies]
10+
soroban-sdk = { version = "21.0.0", features = ["alloc"] }
11+
12+
[dev-dependencies]
13+
soroban-sdk = { version = "21.0.0", features = ["testutils", "alloc"] }
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![no_std]
2+
use soroban_sdk::{contract, contractimpl, contracttype, Address, BytesN, Env};
3+
4+
#[contracttype]
5+
pub enum DataKey {
6+
Admin,
7+
Version,
8+
}
9+
10+
#[contract]
11+
pub struct UpgradeableContract;
12+
13+
#[contractimpl]
14+
impl UpgradeableContract {
15+
pub fn initialize(env: Env, admin: Address) {
16+
env.storage().instance().set(&DataKey::Admin, &admin);
17+
env.storage().instance().set(&DataKey::Version, &1u32);
18+
}
19+
20+
pub fn upgrade(env: Env, caller: Address, new_wasm_hash: BytesN<32>) {
21+
caller.require_auth();
22+
let admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap();
23+
assert!(caller == admin, "Only admin can upgrade");
24+
env.deployer().update_current_contract_wasm(new_wasm_hash);
25+
let version: u32 = env.storage().instance().get(&DataKey::Version).unwrap_or(1);
26+
env.storage().instance().set(&DataKey::Version, &(version + 1));
27+
}
28+
29+
pub fn version(env: Env) -> u32 {
30+
env.storage().instance().get(&DataKey::Version).unwrap_or(1)
31+
}
32+
33+
pub fn admin(env: Env) -> Address {
34+
env.storage().instance().get(&DataKey::Admin).unwrap()
35+
}
36+
}

0 commit comments

Comments
 (0)