本文详细阐述了 Stellar 链上 Soroban 智能合约的验证工作流,解释了如何通过比对源码编译后的 WASM 字节码哈希与链上数据来建立技术信任。内容涵盖了从验证步骤、常见错误分析、构建可复现性要求到 CLI 和 CI/CD 自动化集成的全方位指南。
合约验证证明你声称的源代码与部署在 Stellar 区块链上的字节码相匹配。这通过允许用户在交互前审计合约行为来建立信任。
当前实现现在在 API 路径中强制执行验证:
POST /api/contracts/verify 先创建一条 pending 验证记录。contracts.wasm_hash 进行比较。verified,失败时为 failed,并附带 error_message。contracts.is_verified 仅在验证成功时设置为 true。┌─────────────────┐
│ 用户提交 │
│ 源代码 + │──┐
│ 合约 ID │ │
└─────────────────┘ │
│
▼
┌─────────────────────────────────────┐
│ 1. 验证 │
│ ✓ 合约 ID 在链上存在 │
│ ✓ 源代码格式有效 │
│ ✓ 没有之前的验证 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 2. 编译 │
│ • 解析源代码 │
│ • 设置构建环境 │
│ • 使用 soroban-sdk 编译 │
│ • 生成 WASM 字节码 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 3. 字节码比较 │
│ • 对编译后的 WASM 进行哈希 │
│ • 获取链上字节码哈希 │
│ • 比较哈希 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 4. ABI 验证(可选) │
│ • 提取合约接口 │
│ • 与声明的 ABI 比较 │
│ • 验证方法签名 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 5. 存储结果 │
│ • 保存验证状态 │
│ • 存储源代码 │
│ • 更新合约元数据 │
│ • 发出验证事件 │
└─────────────────────────────────────┘
│
▼
┌──────┴──────┐
│ │
成功 失败
│ │
▼ ▼
合约上的徽章 带详细信息的
错误报告
核心验证确保编译你的源代码生成的 WASM 字节码与链上部署的字节码 完全相同。
流程:
hash(compiled_wasm) == on_chain_hash成功标准: 哈希完全匹配(逐字节一致)。
验证合约接口是否符合预期。
检查项:
成功标准: 源代码中的所有公开函数都与从字节码中提取的 ABI 匹配。
确保源代码完整且可构建。
检查项:
Cargo.toml 中指定了所有依赖成功标准: 代码可无错误编译。
提交完整源代码进行编译和比较。
API 端点:
POST /api/contracts/verify
Content-Type: application/json
{
"contract_id": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"source_code": "base64_encoded_source",
"compiler_version": "21.0.0",
"optimization_level": "z"
}
响应(成功):
{
"verified": true,
"status": "verified",
"verification_id": "ver_abc123",
"contract_id": "f7da1d3a-31f2-40f8-9b6f-ec63fe4a60b7",
"compiled_wasm_hash": "a3f2b8c9d1e4...",
"deployed_wasm_hash": "a3f2b8c9d1e4..."
}
响应(失败):
{
"error": "VerificationFailed",
"message": "Bytecode mismatch: compiled hash 9f1a2b3c4d5e... does not match deployed hash a3f2b8c9d1e4...",
"code": 422
}
通过直接提供 WASM 字节码哈希进行验证(适用于预编译合约)。
API 端点:
POST /api/contracts/verify-hash
Content-Type: application/json
{
"contract_id": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"bytecode_hash": "a3f2b8c9d1e4..."
}
使用场景: 当源代码无法公开,但你想验证字节码哈希是否正确时。
当以下 所有 条件都成立时,验证成功:
| 错误代码 | 原因 | 如何修复 |
|---|---|---|
CONTRACT_NOT_FOUND |
链上不存在该合约 ID | 验证合约 ID,检查网络 |
BYTECODE_MISMATCH |
编译字节码 ≠ 链上字节码 | 检查 compiler 版本、优化设置 |
COMPILATION_FAILED |
源代码无法编译 | 修复语法错误,确保依赖正确 |
ABI_MISMATCH |
函数签名不匹配 | 确保源代码与已部署版本一致 |
INVALID_SOURCE_FORMAT |
源代码编码/格式问题 | 检查文件编码(UTF-8)、正确的 base64 |
COMPILER_VERSION_MISMATCH |
使用了错误的 soroban-sdk 版本 | 使用最初部署时的精确版本 |
OPTIMIZATION_MISMATCH |
错误的优化级别 | 尝试不同的 -C opt-level 设置 |
MISSING_DEPENDENCIES |
Cargo.toml 缺少依赖 | 包含完整的依赖树 |
BUILD_TIMEOUT |
编译耗时过长 | 简化合约或联系支持 |
如果验证因瞬态问题(RPC 超时、网络错误)失败,系统会自动重试:
重试策略:
第 1 次尝试:立即
第 2 次尝试:+2 秒
第 3 次尝试:+4 秒
第 4 次尝试:+8 秒
第 5 次尝试:+16 秒(最终)
可重试错误:
不可重试错误:
soroban-registry verify \
--contract-id CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC \
--source ./src \
--network mainnet
soroban-registry verify \
--contract-id CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC \
--source ./src \
--compiler-version 21.0.0 \
--optimization-level z \
--network mainnet \
--wait-for-confirmation \
--verbose
标志:
--source:合约源代码目录路径--compiler-version:指定 soroban-sdk 版本--optimization-level:Rust 优化(0、1、2、3、s、z)--wait-for-confirmation:等待验证完成--verbose:显示详细编译输出soroban-registry info CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC
输出:
Contract: CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC
Status: Verified ✓
Verified at: 2026-02-24 12:34:56 UTC
Compiler: soroban-sdk 21.0.0
Source available: Yes
前往:https://registry.soroban.example/contracts/{contract_id}
选项 A - 上传 ZIP:
.zip 文件Cargo.toml 和 src/ 目录选项 B - 粘贴源代码:
Cargo.toml 依赖选项 C - GitHub 集成:
21.0.0)z,用于减小体积)为了使验证成功,构建必须是可重现的——相同的源代码编译两次应生成相同的字节码。
在 Cargo.toml 中固定 soroban-sdk 版本:
[dependencies]
soroban-sdk = "=21.0.0" # 使用精确版本
固定所有依赖:
[dependencies]
some-crate = "=1.2.3" # 不是 "^1.2" 或 "~1.2"
使用 Cargo.lock:
Cargo.lock 提交到仓库显式指定 target:
[build]
target = "wasm32-unknown-unknown"
在构建中禁用时间戳:
[profile.release]
opt-level = "z"
debug = false
## 构建两次并比较
cargo build --release --target wasm32-unknown-unknown
mv target/wasm32-unknown-unknown/release/my_contract.wasm build1.wasm
cargo clean
cargo build --release --target wasm32-unknown-unknown
mv target/wasm32-unknown-unknown/release/my_contract.wasm build2.wasm
## 比较字节码
sha256sum build1.wasm build2.wasm
## 哈希应该相同
| 阶段 | 典型时长 | 最大时长 |
|---|---|---|
| 验证 | < 1 秒 | 5 秒 |
| 编译 | 10-60 秒 | 300 秒(5 分钟) |
| 字节码获取 | 1-5 秒 | 30 秒 |
| 哈希比较 | < 1 秒 | 1 秒 |
| 存储 | 1-2 秒 | 10 秒 |
| 总计 | 15-90 秒 | 5 分钟 |
注意: 依赖较多的复杂合约可能需要更长时间编译。
成功验证的合约会显示徽章:
✓ 已于 2026-02-24 验证
源代码与链上字节码匹配
徽章包含:
name: Verify Contract
on:
push:
tags:
- 'v*'
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Soroban CLI
run: |
cargo install soroban-cli
cargo install soroban-registry-cli
- name: Build Contract
run: |
cd contracts/my-contract
cargo build --release --target wasm32-unknown-unknown
- name: Deploy to Mainnet
run: |
soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/my_contract.wasm \
--network mainnet \
--source deployer
env:
SOROBAN_SECRET_KEY: ${{ secrets.DEPLOYER_SECRET }}
- name: Verify Contract
run: |
soroban-registry verify \
--contract-id ${{ env.CONTRACT_ID }} \
--source ./src \
--network mainnet \
--wait-for-confirmation
跟踪验证健康状况:
## 验证成功率
rate(soroban_verification_total{result="success"}[10m]) /
rate(soroban_verification_total[10m])
## P99 验证延迟
histogram_quantile(0.99,
sum(rate(soroban_verification_latency_seconds_bucket[5m])) by (le))
## 队列深度
soroban_verification_queue_depth
A: 通常 15-90 秒。复杂合约可能需要长达 5 分钟。
A: 可以!任何人都可以提交源代码来验证任何合约。
A: 已验证源代码是公开的。如果你不能公开源代码,请使用基于哈希的验证,或者不验证。
A: 最常见原因是错误的 compiler 版本或优化设置。请参见 故障排查指南。
A: 不可以。验证绑定到特定的链上字节码。如果你升级合约,必须单独验证新版本。
A: 需要。Mainnet、Testnet 和 Futurenet 是分开的,因此需要在合约部署的每个网络上分别验证。
A: 从 20.0.0 版本开始的所有稳定 soroban-sdk 发布版。
如遇验证问题:
verification、contracts
- 原文链接: github.com/ALIPHATICHYD/...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!