rs-soroban-sdk
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSoroban SDK Skill
Soroban SDK 技能指南
Soroban SDK is the Rust SDK for building smart contracts on the Stellar blockchain's Wasm-powered Soroban runtime.
Soroban SDK 是用于在Stellar区块链的Wasm驱动Soroban运行时上构建智能合约的Rust SDK。
Prerequisites
前置要求
- Rust: v1.84.0 or higher
- Target: Install with
rustup target add wasm32v1-none - Stellar CLI: v25.1.0+ (recommended for building and testing)
- Install:
curl -fsSL https://github.com/stellar/stellar-cli/raw/main/install.sh | sh - Or:
brew install stellar-cli
- Install:
- Rust:v1.84.0 或更高版本
- Target:通过安装
rustup target add wasm32v1-none - Stellar CLI:v25.1.0+(推荐用于构建和测试)
- 安装方式:
curl -fsSL https://github.com/stellar/stellar-cli/raw/main/install.sh | sh - 或:
brew install stellar-cli
- 安装方式:
⚠️ Security First
⚠️ 安全优先
Smart contracts handle valuable assets. Follow these rules to prevent vulnerabilities:
Do:
- ✅ Call before any state changes
require_auth() - ✅ Validate all inputs (amounts, addresses, array lengths)
- ✅ Use checked arithmetic (,
.checked_add()).checked_mul() - ✅ Extend TTL on all persistent/instance storage writes
- ✅ Initialize contract only once with a guard flag
- ✅ Test authorization, overflow, and edge cases
Don't:
- ❌ Skip authorization checks
- ❌ Use unchecked arithmetic (can overflow/underflow)
- ❌ Allow reinitialization
- ❌ Forget to extend TTL on storage writes
- ❌ Trust external addresses without validation
See references/security.md for complete security guidance.
智能合约会处理高价值资产,请遵循以下规则以预防漏洞:
需要做到:
- ✅ 在任何状态变更之前调用
require_auth() - ✅ 验证所有输入(金额、地址、数组长度)
- ✅ 使用带检查的算术运算(、
.checked_add()).checked_mul() - ✅ 在所有Persistent/Instance存储写入操作时延长TTL
- ✅ 使用防护标志确保合约仅初始化一次
- ✅ 测试授权、溢出和边缘场景
切勿:
- ❌ 跳过授权检查
- ❌ 使用无检查的算术运算(可能导致溢出/下溢)
- ❌ 允许重初始化
- ❌ 忘记在存储写入时延长TTL
- ❌ 未验证就信任外部地址
完整的安全指南请参考references/security.md。
Core Contract Structure
核心合约结构
Every Soroban contract follows this pattern:
rust
#![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
}
}Key requirements:
- - Must be first line (standard library not available)
#![no_std] - All contracts export as a single contract when compiled to WASM
- Function names max 32 characters
- Contract inputs must not be references
Key attributes:
- - Marks the struct as a contract type
#[contract] - - Exports public functions as contract functions
#[contractimpl] - - Converts custom types to/from
#[contracttype]for storageVal - - Defines error enums with
#[contracterror]repr(u32) - - Marks structs as publishable events
#[contractevent]
所有Soroban合约均遵循以下模式:
rust
#![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] - 所有合约编译为WASM后会导出为单个合约
- 函数名最长32个字符
- 合约输入不能是引用类型
核心属性:
- - 将结构体标记为合约类型
#[contract] - - 将公共函数导出为合约函数
#[contractimpl] - - 将自定义类型与
#[contracttype]相互转换以用于存储Val - - 定义带有
#[contracterror]的错误枚举repr(u32) - - 将结构体标记为可发布的事件
#[contractevent]
Environment (Env)
执行环境(Env)
The type provides access to the contract execution environment. It's always the first parameter in contract functions.
Envrust
pub 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();
}Envrust
pub 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();
}Storage Types
存储类型
Soroban provides three storage types with different lifetimes and costs. See references/storage.md for detailed patterns.
Quick reference:
- - Long-lived data (user balances, state)
Persistent - - Short-lived data (caching, temporary locks)
Temporary - - Contract-wide configuration/metadata
Instance
Soroban提供三种具有不同生命周期和成本的存储类型。详细的实现模式请参考references/storage.md。
速查:
- - 长期存储数据(用户余额、状态)
Persistent - - 短期存储数据(缓存、临时锁)
Temporary - - 合约级配置/元数据
Instance
Data Types
数据类型
Core Types
核心类型
- - Universal identifier (contracts or accounts)
Address - - Short strings with limited charset (max 32 chars)
Symbol - - Growable array type
Vec<T> - - Ordered key-value dictionary
Map<K, V> - - Growable byte array
Bytes - - Fixed-size byte array
BytesN<N> - - UTF-8 string type
String - ,
U256- 256-bit integersI256
- - 通用标识符(合约或账户)
Address - - 字符集受限的短字符串(最多32个字符)
Symbol - - 可增长数组类型
Vec<T> - - 有序键值字典
Map<K, V> - - 可增长字节数组
Bytes - - 固定大小字节数组
BytesN<N> - - UTF-8字符串类型
String - ,
U256- 256位整数I256
Type Macros
类型宏
- - Create Vec
vec![&env, item1, item2] - - Create Map
map![&env, (key1, val1), (key2, val2)] - - Create Symbol constant
symbol_short!("text") - - Create Bytes
bytes!(&env, 0x010203) - - Create BytesN
bytesn!(&env, 0x010203)
- - 创建Vec
vec![&env, item1, item2] - - 创建Map
map![&env, (key1, val1), (key2, val2)] - - 创建Symbol常量
symbol_short!("text") - - 创建Bytes
bytes!(&env, 0x010203) - - 创建BytesN
bytesn!(&env, 0x010203)
Authorization
授权机制
⚠️ Critical: Authorization vulnerabilities are the #1 cause of smart contract exploits. Always call before any state changes.
require_auth()When a function requires authorization, use :
Address::require_auth()rust
pub fn transfer(env: Env, from: Address, to: Address, amount: i128) {
from.require_auth(); // ✅ ALWAYS FIRST
// Now authorized to proceed
}Common mistake: Authorizing the wrong address
rust
// ❌ 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
}For custom auth logic, see references/auth.md.
⚠️ 关键提示:授权漏洞是智能合约被攻击的首要原因。请始终在任何状态变更之前调用。
require_auth()当函数需要授权时,使用:
Address::require_auth()rust
pub fn transfer(env: Env, from: Address, to: Address, amount: i128) {
from.require_auth(); // ✅ ALWAYS FIRST
// Now authorized to proceed
}常见错误:授权错误的地址
rust
// ❌ 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
}自定义授权逻辑请参考references/auth.md。
Testing
测试
Use feature for testing. Tests use and register contracts:
testutilsEnv::default()rust
#[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);
}For advanced testing patterns, see references/testing.md.
使用特性进行测试。测试使用并注册合约:
testutilsEnv::default()rust
#[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);
}高级测试模式请参考references/testing.md。
Tokens
代币处理
Work with tokens using the module:
tokenrust
use 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);
}See references/tokens.md for token integration patterns.
使用模块处理代币:
tokenrust
use 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);
}代币集成模式请参考references/tokens.md。
Events and Logging
事件与日志
Publish events for off-chain tracking:
rust
env.events().publish((symbol_short!("transfer"), from, to), amount);During development, use logging:
rust
use soroban_sdk::log;
log!(&env, "Debug message: {}", value);发布事件以用于链下追踪:
rust
env.events().publish((symbol_short!("transfer"), from, to), amount);开发过程中可使用日志功能:
rust
use soroban_sdk::log;
log!(&env, "Debug message: {}", value);Error Handling
错误处理
Define custom errors with :
#[contracterror]rust
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u32)]
pub enum Error {
InvalidAmount = 1,
Unauthorized = 2,
InsufficientBalance = 3,
}Use with or :
panic_with_error!assert_with_error!rust
// 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);
}⚠️ Security: Always validate inputs to prevent:
- Integer overflow/underflow (use checked arithmetic)
- Invalid addresses or amounts
- Array length mismatches
- Division by zero
使用定义自定义错误:
#[contracterror]rust
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u32)]
pub enum Error {
InvalidAmount = 1,
Unauthorized = 2,
InsufficientBalance = 3,
}结合或使用:
panic_with_error!assert_with_error!rust
// 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);
}⚠️ 安全提示:请始终验证输入以预防:
- 整数溢出/下溢(使用带检查的算术运算)
- 无效地址或金额
- 数组长度不匹配
- 除零错误
Deployment
合约部署
Contracts can deploy other contracts:
rust
use soroban_sdk::deploy::{Deployer, ContractIdPreimage};
let deployer = env.deployer();
let contract_id = deployer.deploy_wasm(&wasm_hash, &salt);合约可以部署其他合约:
rust
use soroban_sdk::deploy::{Deployer, ContractIdPreimage};
let deployer = env.deployer();
let contract_id = deployer.deploy_wasm(&wasm_hash, &salt);Common Patterns
常见实现模式
State Management
状态管理
Store contract state in Instance storage for contract-wide config:
rust
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()
}将合约状态存储在Instance存储中以用于合约级配置:
rust
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()
}Iterating Over Collections
集合遍历
Use iterator methods on Vec and Map:
rust
let total: i128 = amounts
.iter()
.map(|x| x.unwrap())
.sum();对Vec和Map使用迭代器方法:
rust
let total: i128 = amounts
.iter()
.map(|x| x.unwrap())
.sum();Cross-Contract Calls
跨合约调用
Import contracts with or create manual clients:
contractimport!rust
let other_contract = OtherContractClient::new(&env, &contract_address);
let result = other_contract.function(&args);使用导入合约或手动创建客户端:
contractimport!rust
let other_contract = OtherContractClient::new(&env, &contract_address);
let result = other_contract.function(&args);Project Setup
项目配置
Requirements
要求
- Rust toolchain v1.84.0 or higher (required for target)
wasm32v1-none - Stellar CLI v25.1.0 or higher
- Install target:
rustup target add wasm32v1-none
- Rust工具链v1.84.0或更高版本(目标所需)
wasm32v1-none - Stellar CLI v25.1.0或更高版本
- 安装目标:
rustup target add wasm32v1-none
Cargo.toml Configuration
Cargo.toml配置
Workspace-level Cargo.toml:
toml
[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 = trueContract-level Cargo.toml:
toml
[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"] }工作区级别的Cargo.toml:
toml
[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合约级别的Cargo.toml:
toml
[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"] }Building Contracts
构建合约
Recommended: Use Stellar CLI (automatically sets correct target and profile):
bash
stellar contract buildEquivalent manual command:
bash
cargo build --target wasm32v1-none --releaseOutput:
target/wasm32v1-none/release/contract_name.wasmOptimize for production:
bash
stellar contract optimize --wasm target/wasm32v1-none/release/contract_name.wasmProduces:
contract_name.optimized.wasm推荐方式:使用Stellar CLI(自动设置正确的目标和配置文件):
bash
stellar contract build等效手动命令:
bash
cargo build --target wasm32v1-none --release输出文件:
target/wasm32v1-none/release/contract_name.wasm生产环境优化:
bash
stellar contract optimize --wasm target/wasm32v1-none/release/contract_name.wasm生成文件:
contract_name.optimized.wasmAdditional Resources
额外资源
For detailed information on specific topics, see:
- Storage patterns and TTL management
- Authorization and auth context
- Testing strategies and utilities
- Token integration and Stellar Asset Contracts
- Common contract patterns and examples
- Security best practices and vulnerabilities ⚠️ CRITICAL
Official documentation: https://developers.stellar.org/docs/build/smart-contracts
如需特定主题的详细信息,请参考:
- 存储模式与TTL管理
- 授权机制与认证上下文
- 测试策略与工具
- 代币集成与Stellar Asset Contracts
- 常见合约模式与示例
- 安全最佳实践与漏洞预防 ⚠️ 至关重要
Security Quick Reference
安全速查指南
Critical rules to prevent vulnerabilities:
- ✅ Always authorize first: Call before any state changes
require_auth() - ✅ Validate all inputs: Check amounts, addresses, array lengths
- ✅ Prevent overflow: Use checked arithmetic for all math operations
- ✅ Initialize once: Use initialization flag to prevent reinitialization
- ✅ Extend TTL: Always extend TTL on persistent/instance storage writes
- ✅ Choose storage wisely: Persistent for critical data, Temporary for cache
- ✅ Test thoroughly: Cover authorization, overflows, edge cases
See references/security.md for complete security guidance.
预防漏洞的关键规则:
- ✅ 始终先授权:在任何状态变更之前调用
require_auth() - ✅ 验证所有输入:检查金额、地址、数组长度
- ✅ 预防溢出:所有数学运算使用带检查的算术
- ✅ 仅初始化一次:使用初始化标志防止重初始化
- ✅ 延长TTL:在Persistent/Instance存储写入时始终延长TTL
- ✅ 合理选择存储类型:Persistent用于关键数据,Temporary用于缓存
- ✅ 全面测试:覆盖授权、溢出、边缘场景
完整的安全指南请参考references/security.md。