API 高级功能
该文档详细介绍了 Soroban Registry API 的高级功能,包括批量操作、复杂过滤与排序、基于游标的分页、全文检索、数据聚合以及关联资源包含。此外,还提供了 API 性能优化建议、针对不同场景的代码示例(Python/JS)以及详细的限额说明,旨在帮助开发者高效地检索和管理 Stellar 网络上的智能合约数据。
API 高级功能
概览
本文档介绍了 Soroban Registry API 的高级功能,包括批量操作、高级过滤、排序、分页、搜索、聚合以及嵌套关系。这些功能能够实现高效的数据检索和批量处理。
目录
计划中的端点 (返回 501)
以下端点已配置路由,但在完整功能发布前会故意返回 501 Not Implemented:
GET /api/contracts/:id/state/:keyPUT /api/contracts/:id/state/:keyGET /api/contracts/:id/trust-scoreGET /api/contracts/:id/deployment-statusPOST /api/contracts/:id/deploy-green
响应结构:
{
"error": "not_implemented",
"message": "This endpoint is planned but not yet functional"
}
网络元数据
使用 networks 端点发现支持的环境并填充客户端的网络选择器。
GET /networks
返回所有受支持的部署网络,包括 RPC URL、浏览器链接和当前状态指示器。
响应:
{
"cached_at": "2026-03-25T10:15:00Z",
"networks": [
{
"id": "mainnet",
"name": "Stellar Mainnet",
"network_type": "mainnet",
"status": "online",
"endpoints": {
"rpc_url": "https://rpc-mainnet.stellar.org",
"health_url": "https://rpc-mainnet.stellar.org/health",
"explorer_url": "https://stellar.expert/explorer/public"
},
"last_checked_at": "2026-03-25T10:15:00Z",
"last_indexed_ledger_height": 52345678,
"consecutive_failures": 0
}
]
}
状态值:
online- RPC 健康检查通过,且索引器没有已知问题degraded- RPC 可访问,但索引数据过时或报告故障offline- RPC 健康检查失败或网络处于持续故障状态
用例:
- 动态填充前端网络选择器
- 显示特定环境的浏览器链接
- 在网络降级或离线时限制功能使用
批量操作
批量操作允许你在单个 API 调用中执行多个动作,从而减少网络开销并提高性能。
POST /api/contracts/batch-verify
一次性验证多个合约。
请求:
POST /api/contracts/batch-verify
Content-Type: application/json
{
"contracts": [
{
"contract_id": "CDLZFC3...",
"source_code": "base64_encoded_source",
"compiler_version": "21.0.0"
},
{
"contract_id": "CAFX2Y7...",
"source_code": "base64_encoded_source",
"compiler_version": "21.0.0"
}
],
"options": {
"fail_fast": false,
"parallel": true
}
}
请求字段:
| 字段 | 类型 | 描述 |
|---|---|---|
contracts |
array | 待验证的合约数组(最多 100 个) |
options.fail_fast |
boolean | 遇首个失败即停止(默认:false) |
options.parallel |
boolean | 并行执行验证(默认:true) |
响应:
{
"batch_id": "batch_abc123",
"total": 2,
"successful": 1,
"failed": 1,
"results": [
{
"contract_id": "CDLZFC3...",
"status": "verified",
"verification_id": "ver_xyz789"
},
{
"contract_id": "CAFX2Y7...",
"status": "failed",
"error": {
"code": "BYTECODE_MISMATCH",
"message": "Compiled bytecode does not match"
}
}
]
}
限制:
- 每个批次最多 100 个合约
- 每次验证遵循正常的速率限制
- 超时时间:整个批次 10 分钟
用例: 部署后验证多个合约版本。
POST /api/contracts/batch-fetch
在单个请求中获取多个合约。
请求:
POST /api/contracts/batch-fetch
Content-Type: application/json
{
"contract_ids": [
"CDLZFC3...",
"CAFX2Y7...",
"CBGTX43..."
],
"include": ["publisher", "verification_status"]
}
响应:
{
"contracts": [
{
"contract_id": "CDLZFC3...",
"name": "Token Contract",
"verification_status": "verified",
"publisher": {
"id": "pub_abc123",
"name": "Acme Corp"
}
},
{
"contract_id": "CAFX2Y7...",
"name": "DEX Contract",
"verification_status": "pending",
"publisher": {
"id": "pub_def456",
"name": "DeFi Labs"
}
}
],
"not_found": ["CBGTX43..."]
}
限制:
- 每个批次最多 50 个合约
- 不存在的合约在
not_found数组中返回
使用 CLI 进行批量操作
批量清单 (YAML):
version: "1.0"
batch:
- contract: "CDLZFC3..."
operation: verify
params:
source: "./contracts/token/src"
compiler_version: "21.0.0"
- contract: "CAFX2Y7..."
operation: verify
params:
source: "./contracts/dex/src"
compiler_version: "21.0.0"
- contract: "CBGTX43..."
operation: update-metadata
params:
name: "Updated Token Contract"
description: "A better description"
执行批次:
## 空运行(只验证不执行)
soroban-batch run --manifest batch.yaml --dry-run
## 执行批次
soroban-batch run --manifest batch.yaml
## 以 JSON 格式输出
soroban-batch run --manifest batch.yaml --format json > report.json
批量报告:
{
"batch_id": "batch_abc123",
"total": 3,
"successful": 2,
"failed": 1,
"results": [
{
"contract": "CDLZFC3...",
"operation": "verify",
"status": "success"
},
{
"contract": "CAFX2Y7...",
"operation": "verify",
"status": "failed",
"error": "Compilation failed"
},
{
"contract": "CBGTX43...",
"operation": "update-metadata",
"status": "success"
}
]
}
支持的操作:
publish- 发布合约verify- 验证源代码update-metadata- 更新合约元数据set-network- 更改网络指定retire- 将合约标记为已退役
高级过滤
应用复杂的过滤器来缩小结果范围。
基础过滤
GET /api/contracts?network=mainnet&verified=true
多字段过滤
GET /api/contracts?network=mainnet&verified=true&publisher=pub_abc123&category=defi
范围过滤器
## 获取指定日期之间创建的合约
GET /api/contracts?created_from=2026-01-01T00:00:00Z&created_to=2026-02-01T00:00:00Z
## 获取过去 7 天内修改过的合约
GET /api/contracts?updated_from=2026-03-18T00:00:00Z
## 获取在特定时间窗口内验证的合约
GET /api/contracts?verified_from=2026-03-01T00:00:00Z&verified_to=2026-03-25T23:59:59Z
## 获取交互次数在范围内的合约
GET /api/contracts?interactions_min=1000&interactions_max=10000
运算符
使用运算符进行更复杂的查询:
可用运算符:
| 运算符 | 语法 | 描述 | 示例 |
|---|---|---|---|
| 等于 | field=value |
精确匹配 | network=mainnet |
| 不等于 | field_ne=value |
排除特定值 | network_ne=testnet |
| 大于 | field_gt=value |
数值比较 | interactions_gt=1000 |
| 小于 | field_lt=value |
数值比较 | interactions_lt=10000 |
| 包含于 | field_in=val1,val2 |
匹配任一值 | category_in=defi,nft |
| 包含 | field_contains=value |
字符串包含 | name_contains=token |
| 以...开头 | field_starts=value |
字符串前缀 | name_starts=Stellar |
示例:
## 不在测试网上的合约
GET /api/contracts?network_ne=testnet
## 交互次数较高的合约
GET /api/contracts?interactions_gt=5000
## 属于多个类别的合约
GET /api/contracts?category_in=defi,token,nft
## 名称中包含 "token" 的合约
GET /api/contracts?name_contains=token
复杂过滤 (Query DSL)
对于非常复杂的查询,请使用查询 DSL:
POST /api/contracts/search
Content-Type: application/json
{
"query": {
"bool": {
"must": [
{ "term": { "network": "mainnet" } },
{ "term": { "verified": true } }
],
"should": [
{ "range": { "interactions": { "gte": 1000 } } },
{ "term": { "featured": true } }
],
"must_not": [
{ "term": { "deprecated": true } }
]
}
}
}
查询类型:
term- 精确匹配range- 数值/日期范围match- 全文搜索wildcard- 通配符匹配bool- 布尔逻辑(must, should, must_not)
排序
按一个或多个字段对结果进行排序。
单字段排序
## 按创建日期排序(最新的在前)
GET /api/contracts?sort_by=createdat&sort_order=desc
## 按最近更新排序
GET /api/contracts?sort_by=updatedat&sort_order=desc
## 按最新验证时间戳排序
GET /api/contracts?sort_by=verifiedat&sort_order=desc
## 按最近合约查看次数排序
GET /api/contracts?sort_by=lastaccessedat&sort_order=desc
排序顺序:
asc- 升序(A-Z, 0-9, 从旧到新)desc- 降序(Z-A, 9-0, 从新到旧)
多字段排序
## 先按验证状态排序,再按交互次数排序
GET /api/contracts?sort_by=verified,interactions&sort_order=desc,desc
可用排序字段:
| 字段 | 类型 | 描述 |
|---|---|---|
createdat |
datetime | 合约创建时间戳 |
updatedat |
datetime | 最后更新时间戳 |
verifiedat |
datetime | 最近一次成功验证的时间戳 |
lastaccessedat |
datetime | 最近一次查看合约详情的时间戳 |
interactions |
integer | 总交互次数 |
popularity |
integer | 交互驱动的流行度排序 |
deployments |
integer | 版本/部署数量排序 |
relevance |
integer | 存在 query 时的搜索相关性排序 |
相关性排序(搜索)
使用全文搜索时,结果默认按相关性排序:
POST /api/contracts/search
Content-Type: application/json
{
"query": "token transfer",
"sort": {
"by": "_score",
"order": "desc"
}
}
分页
使用分页高效地检索大型数据集。
基于偏移量的分页
使用 limit 和 offset 的传统分页方式:
## 第一页(20 条项目)
GET /api/contracts?limit=20&offset=0
## 第二页
GET /api/contracts?limit=20&offset=20
## 第三页
GET /api/contracts?limit=20&offset=40
响应:
{
"contracts": [...],
"pagination": {
"limit": 20,
"offset": 40,
"total": 1543,
"has_more": true
}
}
限制:
limit必须在1到1000之间(默认:50)offset必须为非负整数- 无效的分页值将返回
400 Bad Request
性能: 对于大偏移量(offset > 1000)速度较慢。
验证示例:
GET /api/contracts?limit=5001
返回 400 Bad Request,并附带说明 limit 必须在 1 到 1000 之间的消息。
GET /api/contracts?offset=-1
返回 400 Bad Request,并附带说明 offset 必须为非负数的消息。
最适用于: 小型数据集、页面的随机访问。
基于游标的分页(推荐)
对于大型数据集更高效:
## 第一页
GET /api/contracts?limit=50
## 下一页(使用前一次响应中的 cursor)
GET /api/contracts?limit=50&cursor=eyJpZCI6MTIzNDU...
响应:
{
"contracts": [...],
"pagination": {
"limit": 50,
"next_cursor": "eyJpZCI6MTI4OTA...",
"has_more": true
}
}
优点:
- 无论位置如何,性能保持恒定
- 正确处理实时更新
- 无最大偏移限制
缺点:
- 无法跳转到任意页面
- 仅支持向前迭代
最适用于: 大型数据集、流式传输、实时更新。
分页示例 (Python)
import requests
def fetch_all_contracts(api_url, limit=100):
"""使用基于游标的分页获取所有合约"""
contracts = []
cursor = None
while True:
params = {'limit': limit}
if cursor:
params['cursor'] = cursor
response = requests.get(f'{api_url}/api/contracts', params=params)
data = response.json()
contracts.extend(data['contracts'])
if not data['pagination']['has_more']:
break
cursor = data['pagination']['next_cursor']
return contracts
## 使用示例
all_contracts = fetch_all_contracts('https://registry.soroban.example')
print(f'Fetched {len(all_contracts)} contracts')
全文搜索
合约搜索由基于 name、category 和 description 的 PostgreSQL 全文索引提供支持。
基础搜索
GET /api/contracts?query=token transfer
高级搜索语法
query 参数支持通过 PostgreSQL 网页风格搜索进行运算符感知的解析:
## 精确短语
GET /api/contracts?query="token factory"
## 必要词和排除词
GET /api/contracts?query=token -deprecated
## 包含额外必要词的短语
GET /api/contracts?query="liquidity pool" soroban
支持的模式:
| 模式 | 描述 | 示例 |
|---|---|---|
| 短语 | 精确词序 | "token contract" |
| 必要词 | 必须出现的词 | stellar token |
| 排除词 | 不得出现的词 | token -legacy |
| 前缀词 | Token 的前缀匹配 | token* |
相关性排名
当 sort_by=relevance 或在没有明确排序且存在 query 时,匹配项将按以下标准排名:
- 在
name、category和description上的加权全文评分 - 精确的合约名称匹配权重高于部分匹配
- 前缀名称匹配权重高于通用的正文匹配
搜索建议
使用 suggestions 端点为自动完成 UI 提供支持:
GET /api/contracts/suggestions?q=tok&limit=8
响应:
{
"items": [
{ "text": "Token Factory", "kind": "contract", "score": 1.0 },
{ "text": "Token", "kind": "category", "score": 0.82 }
]
}
性能与监控
- 搜索使用生成的
tsvector列加上 GIN 索引,以实现低延迟排名 - 自动完成对合约名称和类别使用前缀和三元组(trigram)索引
- 慢于 200ms 的搜索请求会被记录并计入 Prometheus 指标
- 建议响应会进行短暂缓存,以保持选择器/自动完成的低延迟
聚合
计算统计数据并对数据进行分组。
GET /api/contracts/stats
获取汇总统计数据:
GET /api/contracts/stats?network=mainnet
响应:
{
"total_contracts": 1543,
"verified_contracts": 987,
"total_interactions": 1234567,
"by_network": {
"mainnet": 1200,
"testnet": 300,
"futurenet": 43
},
"by_category": {
"defi": 450,
"nft": 320,
"token": 280,
"other": 493
},
"by_publisher": [
{ "publisher": "Acme Corp", "count": 23 },
{ "publisher": "DeFi Labs", "count": 18 },
{ "publisher": "Token Inc", "count": 15 }
]
}
POST /api/contracts/aggregate
自定义聚合:
POST /api/contracts/aggregate
Content-Type: application/json
{
"aggregations": {
"by_month": {
"type": "date_histogram",
"field": "published_at",
"interval": "month"
},
"avg_interactions": {
"type": "avg",
"field": "interactions"
},
"top_publishers": {
"type": "terms",
"field": "publisher",
"size": 10
}
},
"filters": {
"network": "mainnet",
"verified": true
}
}
响应:
{
"aggregations": {
"by_month": {
"buckets": [
{ "key": "2026-01", "count": 123 },
{ "key": "2026-02", "count": 156 }
]
},
"avg_interactions": {
"value": 456.7
},
"top_publishers": {
"buckets": [
{ "key": "pub_abc123", "name": "Acme Corp", "count": 23 }
]
}
}
}
聚合类型:
| 类型 | 描述 | 用例 |
|---|---|---|
count |
计算匹配文档数 | 合约总数 |
sum |
对数值字段求和 | 总交互次数 |
avg |
平均值 | 平均流行度 |
min/max |
最小值/最大值 | 数值范围 |
terms |
按字段分组 | 顶尖发布者 |
date_histogram |
基于时间的桶 | 每月合约数 |
range |
数值范围 | 交互层级 |
嵌套资源与包含项
高效地加载相关资源。
默认响应(最小化)
GET /api/contracts/CDLZFC3...
响应:
{
"contract_id": "CDLZFC3...",
"name": "Token Contract",
"publisher_id": "pub_abc123",
"verified": true
}
使用包含项 (Includes)
GET /api/contracts/CDLZFC3...?include=publisher,verification,interactions
响应:
{
"contract_id": "CDLZFC3...",
"name": "Token Contract",
"publisher": {
"id": "pub_abc123",
"name": "Acme Corp",
"verified_publisher": true,
"total_contracts": 12
},
"verification": {
"verified": true,
"verified_at": "2026-02-15T10:30:00Z",
"compiler_version": "21.0.0",
"source_url": "https://registry.../source/..."
},
"interactions": {
"total": 12345,
"last_24h": 234,
"last_7d": 1890,
"last_30d": 7654
}
}
可用包含项:
| 包含项 | 描述 | 性能影响 |
|---|---|---|
publisher |
发布者详情 | 低 |
verification |
验证信息 | 低 |
interactions |
交互统计 | 中 |
dependencies |
合约依赖项 | 中 |
versions |
版本历史 | 高 |
similar |
相似合约 | 高 |
性能提示:
- 仅包含你需要的内容
- 多个包含项会产生累加成本
- 考虑缓存带有包含项的响应
性能特征
了解性能有助于你高效地使用 API。
操作性能
| 操作 | 平均延迟 | 吞吐量 | 速率限制 |
|---|---|---|---|
| 获取单个合约 | 10-30ms | 高 | 100/min |
| 获取列表 (50 条) | 50-100ms | 中 | 100/min |
| POST 搜索 | 30-200ms | 中 | 100/min |
| POST 批量验证 (10) | 10-60s | 低 | 20/min |
| POST 聚合 | 100-500ms | 低 | 100/min |
查询复杂度
快速查询 (< 50ms):
- 简单过滤器:
?network=mainnet&verified=true - 获取单个合约
- 基础分页 (offset < 1000)
中等查询 (50-200ms):
- 全文搜索
- 带排序的多重过滤
- 包含项 (1-2 个关系)
- 游标分页
- 聚合(简单)
慢速查询 (> 200ms):
- 复杂的布尔搜索
- 多个包含项 (3+)
- 大型聚合
- 深分页 (offset > 5000)
优化建议
- 对于大型数据集,使用游标分页
- 仅包含你需要的内容
- 在客户端缓存响应(设置 TTL)
- 使用批量端点而不是多个请求
- 尽早过滤以减少结果集大小
- 对经常查询的字段建立索引(联系支持人员)
- 避免深分页(改用游标)
缓存建议
| 端点 | 缓存 TTL | 理由 |
|---|---|---|
| GET /contracts/{id} | 5 分钟 | 合约元数据很少变动 |
| GET /contracts (列表) | 1 分钟 | 列表变动频繁 |
| POST /search | 30 秒 | 预期实时搜索 |
| GET /stats | 1 小时 | 聚合数据更新缓慢 |
用例与方案
方案 1:查找热门合约
获取近期活动频繁的合约:
POST /api/contracts/search
Content-Type: application/json
{
"filters": {
"network": "mainnet",
"verified": true
},
"sort": {
"by": "interactions_7d",
"order": "desc"
},
"limit": 20,
"include": ["publisher", "interactions"]
}
方案 2:监控合约更新
轮询特定合约的更改:
import requests
import time
def monitor_contract(contract_id, callback, poll_interval=60):
"""监控合约更新"""
last_updated = None
while True:
response = requests.get(f'https://api.example/contracts/{contract_id}')
contract = response.json()
if last_updated and contract['updated_at'] != last_updated:
callback(contract)
last_updated = contract['updated_at']
time.sleep(poll_interval)
## 使用示例
def on_update(contract):
print(f"Contract {contract['name']} updated!")
monitor_contract('CDLZFC3...', on_update)
方案 3:批量发布合约
高效发布多个合约:
## publish-batch.yaml
version: "1.0"
batch:
- contract: "token-v1"
operation: publish
params:
source: "./contracts/token/v1"
name: "Token Contract v1"
category: "token"
- contract: "token-v2"
operation: publish
params:
source: "./contracts/token/v2"
name: "Token Contract v2"
category: "token"
soroban-batch run --manifest publish-batch.yaml
方案 4:导出所有合约(备份)
import requests
import json
def export_all_contracts(output_file):
"""将所有合约导出为 JSON"""
contracts = []
cursor = None
while True:
params = {'limit': 100, 'include': 'publisher,verification'}
if cursor:
params['cursor'] = cursor
response = requests.get('https://api.example/contracts', params=params)
data = response.json()
contracts.extend(data['contracts'])
if not data['pagination']['has_more']:
break
cursor = data['pagination']['next_cursor']
print(f"Fetched {len(contracts)} contracts...")
with open(output_file, 'w') as f:
json.dump(contracts, f, indent=2)
print(f"Exported {len(contracts)} contracts to {output_file}")
## 使用示例
export_all_contracts('contracts_backup.json')
方案 5:合约健康仪表板
async function getContractHealth(contractId) {
const response = await fetch(
`https://api.example/contracts/${contractId}?include=interactions,health_score`
);
const contract = await response.json();
return {
name: contract.name,
health_score: contract.health_score,
verified: contract.verified,
last_interaction: contract.interactions.last_interaction_at,
interactions_7d: contract.interactions.last_7d,
status: getStatus(contract)
};
}
function getStatus(contract) {
if (contract.health_score >= 80) return 'healthy';
if (contract.health_score >= 60) return 'warning';
return 'critical';
}
限制与约束
| 限制项 | 对应值 | 升级途径 |
|---|---|---|
| 最大批次大小 | 100 个项目 | 联系支持人员 |
| 最大查询结果数 | 10,000 | 使用游标分页 |
| 最大包含项 (includes) | 5 | N/A |
| 最大搜索查询长度 | 1,000 字符 | N/A |
| 最大聚合桶数 | 1,000 | 联系支持人员 |
| 速率限制(标准版) | 100 req/min | 升级至企业版 |
| 批次超时时间 | 10 分钟 | 联系支持人员 |
相关文档
支持
针对高级 API 功能:
- GitHub Issues: https://github.com/ALIPHATICHYD/Soroban-Registry/issues
- 标签注明:
api,advanced-features
- 原文链接: github.com/ALIPHATICHYD/...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~