摘要
本教程将逐步介绍在 Bittensor 上构建的实用部分:通过 RPC 连接到 Subtensor 链、读取元图和子网状态,以及使用 Python SDK 提交外部交易。它侧重于大多数教程跳过的连接层,以便您的脚本在从本地实验过渡到持续运行的过程中保持可靠。
您将了解如何配置 WebSocket 端点、运行 JSON-RPC 和 SDK 调用,并决定何时共享公共端点足够,何时专用节点更合适。目标是建立一个可扩展的工作设置,可用于矿工、验证者、仪表板或子网工具。
Bittensor 是一个由机器学习子网组成的去中心化网络,而协调所有子网的链是 Subtensor。如果您搜索 Bittensor 教程,您可能想做一些具体的事情:读取子网数据、注册热键、运行矿工或构建仪表板。几乎所有任务都始于同一步骤——获得与 Subtensor 的可靠连接。
本教程围绕该连接层构建。它不仅解释 Bittensor 是什么,还展示如何连接、首先进行哪些调用,以及如何决定共享公共端点或专用节点是否适合您的工作负载。您可以使用 Python SDK 或原始 JSON-RPC 跟随学习。
从这里开始:选择您的连接路径
在编写代码之前,决定如何与 Subtensor 通信。正确的选择取决于您是在探索、运行长期进程还是为其他用户服务。
| 您的情况 | 推荐的连接 | 原因 |
|---|---|---|
| 学习、一次性脚本、读取少量值 | 共享公共 RPC 端点 | 设置快速,无需管理基础设施 |
| 持续运行的矿工或验证者 | 专用节点或具有稳定容量的提供商计划 | 长期 WebSocket 会话和一致的吞吐量很重要 |
| 为许多用户提供服务的仪表板或应用 | 带监控和故障转移的提供商 RPC | 您需要可预测的容量和回退路径 |
| 索引历史链数据 | 支持归档的节点 | 回填需要完整历史 |
如果您刚开始学习本教程,请使用公共端点并继续。一旦您的脚本需要保持在线,请重新查看此表。
Subtensor 究竟是什么
Subtensor 是一个基于 Substrate 的区块链。这很重要,因为它决定了您与它交互的方式。您不会像在 EVM 链上那样调用智能合约。相反,您通过存储查询读取链状态,并提交映射到特定 pallet 的外部交易(交易)。
您最常接触的部分:
- 子网 — 由矿工和验证者组成的独立网络,每个子网由 netuid 标识。
- 元图 — 每个子网中神经元、其质押、激励和排名的快照。
- 热键和冷键 — 热键签署操作活动,冷键持有质押并控制注册。
- TAO — 用于质押、注册和激励的原生代币。
由于 Subtensor 基于 Substrate,大多数工具使用 Polkadot 风格的堆栈:substrate-interface 或 bittensor Python 包,或 JavaScript 中的 polkadot-js。底层的 RPC 层是标准的 Substrate JSON-RPC。
通过 RPC 连接到 Subtensor
OnFinality 通过 HTTP 和 WebSocket 公开 Bittensor Finney 主网。公共端点是:
- HTTP:
https://bittensor-finney.api.onfinality.io/public - WebSocket:
wss://bittensor-finney.api.onfinality.io/public-ws
对于大多数 Bittensor 工作,您需要 WebSocket 端点,因为 SDK 和订阅依赖它。快速检查节点是否可达并返回链元数据:
curl -s https://bittensor-finney.api.onfinality.io/public \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"system_chain","params":[]}'
健康的响应会返回链名称。如果出现连接错误,首先检查端点或您的网络。如果出现 JSON-RPC 错误,可能是方法名或参数问题。
对于任何交互式操作,请切换到 WebSocket。在 Python 中使用 Bittensor SDK:
import bittensor as bt
subtensor = bt.subtensor(network="wss://bittensor-finney.api.onfinality.io/public-ws")
print(subtensor.get_current_block())
print(subtensor.get_total_stake())
如果您更喜欢底层的 Substrate 接口,同样的端点也适用:
from substrateinterface import SubstrateInterface
substrate = SubstrateInterface(
url="wss://bittensor-finney.api.onfinality.io/public-ws"
)
print(substrate.get_chain_head())
两种方法连接到同一个节点;SDK 只是为您包装了常见的 Bittensor 调用。
读取子网和元图数据
大多数教程做的第一件有用的事情是读取子网的状态。元图为您提供子网中每个神经元的快照,包括质押、激励和共识。这是矿工和验证者用来做决策的数据。
使用 Bittensor SDK:
import bittensor as bt
subtensor = bt.subtensor(network="wss://bittensor-finney.api.onfinality.io/public-ws")
metagraph = subtensor.metagraph(netuid=1)
print("neurons:", metagraph.n)
print("top incentive:", metagraph.incentive.max())
print("total stake:", metagraph.total_stake)
元图是时间点视图。如果您正在构建仪表板或对变化做出反应的矿工,您需要按间隔刷新它或订阅新块。这就是连接质量开始重要的地方:在繁忙的子网上刷新元图会拉取大量数据,而在不稳定的连接上每个块都这样做会产生间隙。
一个简单的轮询循环如下所示:
import time
import bittensor as bt
subtensor = bt.subtensor(network="wss://bittensor-finney.api.onfinality.io/public-ws")
last_block = 0
while True:
block = subtensor.get_current_block()
if block != last_block:
metagraph = subtensor.metagraph(netuid=1)
print(block, metagraph.n, float(metagraph.total_stake))
last_block = block
time.sleep(6)
根据您的需求调整睡眠间隔。对于单个子网,每个块轮询是可以的;同时轮询多个子网是更重的工作负载,也是转向专用节点的好理由。
提交外部交易而不破坏东西
读取数据是安全的。写入链是错误会花钱的地方,因此请将本节视为检查清单,而不是复制粘贴脚本。
- 首先使用测试网或低价值热键。 在接触真实质押之前,确认您的外部交易构建并提交。
- 在提交前检查当前块和账户余额,以便知道交易在那一刻是有效的。
- 设置合理的 era 和 tip。 短的 era 可以防止交易滞留;tip 可以在拥堵时帮助包含。
- 等待最终确认,而不仅仅是提交。 已提交的外部交易仍可能失败。
使用 SDK 的最小转账式外部交易:
import bittensor as bt
wallet = bt.wallet(name="my_coldkey", hotkey="my_hotkey")
subtensor = bt.subtensor(network="wss://bittensor-finney.api.onfinality.io/public-ws")
result = subtensor.transfer(
wallet=wallet,
dest_ss58="5F...destination...",
amount=bt.Balance.from_tao(0.1),
)
print(result)
将目标和金额替换为您自己的值。重要的习惯是记录外部交易哈希并检查其状态,而不是假设成功。
常见故障模式及如何调试
大多数 Bittensor 连接问题属于少数几类。此表将症状映射到可能的原因。
| 症状 | 可能原因 | 尝试方法 |
|---|---|---|
| WebSocket 一段时间后断开 | 空闲超时或端点不稳定 | 使用退避重连;对于长会话使用专用节点 |
Method not found | 方法名错误或端点类型错误 | 确认您在 Substrate JSON-RPC 端点上,而不是 EVM 端点 |
| 元图返回过时数据 | 缓存或滞后的节点 | 查询当前块并比较;切换端点 |
| 外部交易已提交但从未最终确认 | Era 过期或费用太低 | 使用新的 era 和足够的 tip 重新提交 |
| 高峰活动期间响应缓慢 | 共享端点负载过高 | 将繁重或连续的工作负载移至专用节点 |
模式是一致的:只读、偶尔的调用可以容忍共享端点,而连续或高容量的工作则受益于专用容量。
当共享端点不够时
公共端点适合学习和轻量脚本。当您的进程需要保持连接数小时、跨多个子网刷新元图或为其他用户服务时,它就会成为问题。那时您不再调试代码——而是在调试基础设施。
OnFinality 通过共享 API 端点和专用节点提供 Bittensor RPC。专用节点为您的工作负载提供自己的容量,这在您运行矿工、验证者或无法承受连接间隙的仪表板时很有帮助。您可以查看 RPC 定价 和 Bittensor 网络页面 以了解适合您工作负载的内容,如果您跨链操作,可以与其他 支持的 RPC 网络 进行比较。
如果您正在评估提供商,同样的标准适用:传输支持(HTTP 和 WebSocket)、如果需要历史记录则归档可用性,以及如何处理故障转移。关于 选择 RPC 提供商 的简短检查清单更详细地涵盖了这些权衡。
一个实用的第一个项目
如果您想为本教程设定一个具体目标,请构建一个小型子网监视器。它应该:
- 通过 WebSocket 连接到 Subtensor。
- 按间隔轮询当前块。
- 每个块刷新一个或两个子网的元图。
- 打印或存储神经元数量、总质押和最高激励。
- 如果 WebSocket 断开,自动重连。
该项目练习了您以后将重用的连接层的每个部分:端点选择、块跟踪、状态查询和重连逻辑。一旦它可靠运行一天,您就拥有了矿工或验证者工具的基础。
关键要点
- Subtensor 是一个基于 Substrate 的链,因此您通过存储查询和外部交易进行交互,而不是 EVM 合约。
- 对于 SDK 工作和订阅,使用 WebSocket 端点;HTTP 适合快速 JSON-RPC 检查。
- 元图是一个快照——如果您的逻辑依赖于当前状态,请按间隔或每个块刷新它。
- 将外部交易提交视为检查清单:先测试,检查余额和块,等待最终确认。
- 共享公共端点适合学习和轻量脚本;专用节点适合连续矿工、验证者和仪表板。
常见问题
我需要一个节点来跟随这个 Bittensor 教程吗?
不需要。您可以使用共享公共 RPC 端点完成本教程。当您的进程需要持续连接或处理更高容量时,专用节点会变得有用。
我应该使用哪个端点,HTTP 还是 WebSocket?
对于 SDK 工作、订阅和任何长期运行的操作,使用 WebSocket。对于快速 JSON-RPC 调用和健康检查,使用 HTTP。
为什么我的元图看起来过时了?
您可能正在从滞后或缓存的节点读取。比较端点之间的当前块,如果值不同则切换。
我可以对测试网运行这个吗?
可以。工作流程相同;只是端点改变。在接触真实质押之前,在测试网上或使用低价值热键测试外部交易。
如何保持矿工或验证者在线?
针对稳定端点运行它,添加带退避的重连逻辑,并考虑使用专用节点,这样您的连接就不依赖于共享容量。
下一步
一旦您的监视器可靠运行,请扩展它:当子网的激励分布发生变化时添加警报,存储历史元图快照,或将其连接到根据实时状态调整的矿工。每一步都会增加您对稳定连接的依赖,因此在扩展之前规划您的端点策略。从 Bittensor 网络页面 开始了解端点详细信息,当您准备脱离共享容量时,查看 专用节点。