Loading...
Loading...
Compare original and translation side by side
rustup target add wasm32v1-nonecurl -fsSL https://github.com/stellar/stellar-cli/raw/main/install.sh | shbrew install stellar-clirustup target add wasm32v1-nonecurl -fsSL https://github.com/stellar/stellar-cli/raw/main/install.sh | shbrew install stellar-clirequire_auth().checked_add().checked_mul()require_auth().checked_add().checked_mul()#![no_std] // Required: excludes Rust std library (too large for contracts)
use soroban_sdk::{contract, contractimpl, Env};
#[contract]
pub struct MyContract;
#[contractimpl]
impl MyContract {
pub fn function_name(env: Env, param: Type) -> ReturnType {
// Implementation
}
}#![no_std]#[contract]#[contractimpl]#[contracttype]Val#[contracterror]repr(u32)#[contractevent]#![no_std] // Required: excludes Rust std library (too large for contracts)
use soroban_sdk::{contract, contractimpl, Env};
#[contract]
pub struct MyContract;
#[contractimpl]
impl MyContract {
pub fn function_name(env: Env, param: Type) -> ReturnType {
// Implementation
}
}#![no_std]#[contract]#[contractimpl]#[contracttype]Val#[contracterror]repr(u32)#[contractevent]Envpub fn my_function(env: Env) {
// Access storage
env.storage().persistent();
env.storage().temporary();
env.storage().instance();
// Get contract address
let contract_id = env.current_contract_address();
// Get ledger info
let ledger = env.ledger().sequence();
let timestamp = env.ledger().timestamp();
}Envpub fn my_function(env: Env) {
// Access storage
env.storage().persistent();
env.storage().temporary();
env.storage().instance();
// Get contract address
let contract_id = env.current_contract_address();
// Get ledger info
let ledger = env.ledger().sequence();
let timestamp = env.ledger().timestamp();
}PersistentTemporaryInstancePersistentTemporaryInstanceAddressSymbolVec<T>Map<K, V>BytesBytesN<N>StringU256I256AddressSymbolVec<T>Map<K, V>BytesBytesN<N>StringU256I256vec![&env, item1, item2]map![&env, (key1, val1), (key2, val2)]symbol_short!("text")bytes!(&env, 0x010203)bytesn!(&env, 0x010203)vec![&env, item1, item2]map![&env, (key1, val1), (key2, val2)]symbol_short!("text")bytes!(&env, 0x010203)bytesn!(&env, 0x010203)require_auth()Address::require_auth()pub fn transfer(env: Env, from: Address, to: Address, amount: i128) {
from.require_auth(); // ✅ ALWAYS FIRST
// Now authorized to proceed
}// ❌ WRONG: Authorizing recipient
pub fn transfer(env: Env, from: Address, to: Address, amount: i128) {
to.require_auth(); // Anyone can receive!
}
// ✅ CORRECT: Authorize sender
pub fn transfer(env: Env, from: Address, to: Address, amount: i128) {
from.require_auth(); // Sender must approve
}require_auth()Address::require_auth()pub fn transfer(env: Env, from: Address, to: Address, amount: i128) {
from.require_auth(); // ✅ ALWAYS FIRST
// Now authorized to proceed
}// ❌ WRONG: Authorizing recipient
pub fn transfer(env: Env, from: Address, to: Address, amount: i128) {
to.require_auth(); // Anyone can receive!
}
// ✅ CORRECT: Authorize sender
pub fn transfer(env: Env, from: Address, to: Address, amount: i128) {
from.require_auth(); // Sender must approve
}testutilsEnv::default()#[test]
fn test() {
let env = Env::default();
let contract_id = env.register(MyContract, ());
let client = MyContractClient::new(&env, &contract_id);
let result = client.my_function(¶m);
assert_eq!(result, expected);
}testutilsEnv::default()#[test]
fn test() {
let env = Env::default();
let contract_id = env.register(MyContract, ());
let client = MyContractClient::new(&env, &contract_id);
let result = client.my_function(¶m);
assert_eq!(result, expected);
}tokenuse soroban_sdk::token::{TokenClient, StellarAssetClient};
pub fn use_token(env: Env, token_address: Address, amount: i128) {
let token = TokenClient::new(&env, &token_address);
token.transfer(&from, &to, &amount);
}tokenuse soroban_sdk::token::{TokenClient, StellarAssetClient};
pub fn use_token(env: Env, token_address: Address, amount: i128) {
let token = TokenClient::new(&env, &token_address);
token.transfer(&from, &to, &amount);
}env.events().publish((symbol_short!("transfer"), from, to), amount);use soroban_sdk::log;
log!(&env, "Debug message: {}", value);env.events().publish((symbol_short!("transfer"), from, to), amount);use soroban_sdk::log;
log!(&env, "Debug message: {}", value);#[contracterror]#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u32)]
pub enum Error {
InvalidAmount = 1,
Unauthorized = 2,
InsufficientBalance = 3,
}panic_with_error!assert_with_error!// Validate before operations
assert_with_error!(&env, amount > 0, Error::InvalidAmount);
assert_with_error!(&env, balance >= amount, Error::InsufficientBalance);
// Or panic directly
if amount == 0 {
panic_with_error!(&env, Error::InvalidAmount);
}#[contracterror]#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u32)]
pub enum Error {
InvalidAmount = 1,
Unauthorized = 2,
InsufficientBalance = 3,
}panic_with_error!assert_with_error!// Validate before operations
assert_with_error!(&env, amount > 0, Error::InvalidAmount);
assert_with_error!(&env, balance >= amount, Error::InsufficientBalance);
// Or panic directly
if amount == 0 {
panic_with_error!(&env, Error::InvalidAmount);
}use soroban_sdk::deploy::{Deployer, ContractIdPreimage};
let deployer = env.deployer();
let contract_id = deployer.deploy_wasm(&wasm_hash, &salt);use soroban_sdk::deploy::{Deployer, ContractIdPreimage};
let deployer = env.deployer();
let contract_id = deployer.deploy_wasm(&wasm_hash, &salt);const STATE_KEY: Symbol = symbol_short!("STATE");
pub fn init(env: Env, admin: Address) {
env.storage().instance().set(&STATE_KEY, &admin);
}
pub fn get_admin(env: Env) -> Address {
env.storage().instance().get(&STATE_KEY).unwrap()
}const STATE_KEY: Symbol = symbol_short!("STATE");
pub fn init(env: Env, admin: Address) {
env.storage().instance().set(&STATE_KEY, &admin);
}
pub fn get_admin(env: Env) -> Address {
env.storage().instance().get(&STATE_KEY).unwrap()
}let total: i128 = amounts
.iter()
.map(|x| x.unwrap())
.sum();let total: i128 = amounts
.iter()
.map(|x| x.unwrap())
.sum();contractimport!let other_contract = OtherContractClient::new(&env, &contract_address);
let result = other_contract.function(&args);contractimport!let other_contract = OtherContractClient::new(&env, &contract_address);
let result = other_contract.function(&args);wasm32v1-nonerustup target add wasm32v1-nonewasm32v1-nonerustup target add wasm32v1-none[workspace]
resolver = "2"
members = ["contracts/*"]
[workspace.dependencies]
soroban-sdk = "25"
[profile.release]
opt-level = "z"
overflow-checks = true
debug = 0
strip = "symbols"
debug-assertions = false
panic = "abort"
codegen-units = 1
lto = true
[profile.release-with-logs]
inherits = "release"
debug-assertions = true[package]
name = "my-contract"
version = "0.0.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
doctest = false
[dependencies]
soroban-sdk = { workspace = true }
[dev-dependencies]
soroban-sdk = { workspace = true, features = ["testutils"] }[workspace]
resolver = "2"
members = ["contracts/*"]
[workspace.dependencies]
soroban-sdk = "25"
[profile.release]
opt-level = "z"
overflow-checks = true
debug = 0
strip = "symbols"
debug-assertions = false
panic = "abort"
codegen-units = 1
lto = true
[profile.release-with-logs]
inherits = "release"
debug-assertions = true[package]
name = "my-contract"
version = "0.0.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
doctest = false
[dependencies]
soroban-sdk = { workspace = true }
[dev-dependencies]
soroban-sdk = { workspace = true, features = ["testutils"] }stellar contract buildcargo build --target wasm32v1-none --releasetarget/wasm32v1-none/release/contract_name.wasmstellar contract optimize --wasm target/wasm32v1-none/release/contract_name.wasmcontract_name.optimized.wasmstellar contract buildcargo build --target wasm32v1-none --releasetarget/wasm32v1-none/release/contract_name.wasmstellar contract optimize --wasm target/wasm32v1-none/release/contract_name.wasmcontract_name.optimized.wasmrequire_auth()require_auth()