API 高级功能

该文档详细介绍了 Soroban Registry API 的高级功能,包括批量操作、复杂过滤与排序、基于游标的分页、全文检索、数据聚合以及关联资源包含。此外,还提供了 API 性能优化建议、针对不同场景的代码示例(Python/JS)以及详细的限额说明,旨在帮助开发者高效地检索和管理 Stellar 网络上的智能合约数据。

API 高级功能

概览

本文档介绍了 Soroban Registry API 的高级功能,包括批量操作、高级过滤、排序、分页、搜索、聚合以及嵌套关系。这些功能能够实现高效的数据检索和批量处理。

目录

  1. 批量操作
  2. 高级过滤
  3. 排序
  4. 分页
  5. 全文搜索
  6. 聚合
  7. 嵌套资源与包含项
  8. 性能特征
  9. 用例与方案

计划中的端点 (返回 501)

以下端点已配置路由,但在完整功能发布前会故意返回 501 Not Implemented

  • GET /api/contracts/:id/state/:key
  • PUT /api/contracts/:id/state/:key
  • GET /api/contracts/:id/trust-score
  • GET /api/contracts/:id/deployment-status
  • POST /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"
  }
}

分页

使用分页高效地检索大型数据集。

基于偏移量的分页

使用 limitoffset 的传统分页方式:

## 第一页(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 必须在 11000 之间(默认:50
  • offset 必须为非负整数
  • 无效的分页值将返回 400 Bad Request

性能: 对于大偏移量(offset > 1000)速度较慢。

验证示例:

GET /api/contracts?limit=5001

返回 400 Bad Request,并附带说明 limit 必须在 11000 之间的消息。

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')

全文搜索

合约搜索由基于 namecategorydescription 的 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 时,匹配项将按以下标准排名:

  • namecategorydescription 上的加权全文评分
  • 精确的合约名称匹配权重高于部分匹配
  • 前缀名称匹配权重高于通用的正文匹配

搜索建议

使用 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)

优化建议

  1. 对于大型数据集,使用游标分页
  2. 仅包含你需要的内容
  3. 在客户端缓存响应(设置 TTL)
  4. 使用批量端点而不是多个请求
  5. 尽早过滤以减少结果集大小
  6. 对经常查询的字段建立索引(联系支持人员)
  7. 避免深分页(改用游标)

缓存建议

端点 缓存 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.com/ALIPHATICHYD/...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
ALIPHATICHYD
ALIPHATICHYD
江湖只有他的大名,没有他的介绍。