术语表 /节点与软件
RPC
又称 JSON-RPC、远程过程调用、比特币节点接口。
- RPC 是什么?
- RPC 是比特币节点向其他程序开放的命令接口,钱包、交易所后端或您自己的终端都可以通过它向节点提问并下达指令。
所有实现比特币自动化的程序,都是通过这种方式与节点通信的。Bitcoin Core 在端口8332上监听携带 JSON 的 HTTP 请求,一次只应答一个调用,并且默认只接受来自其所在机器的连接。如果有服务曾向您报出手续费估算,或告知某笔提币已确认,那么这个答复就是由某个 RPC 调用产生的。
运作方式
RPC 调用是一个 HTTP POST 请求,请求体中写明方法名并列出其参数。
调用 getblockchaininfo,返回的是链名称、当前区块高度、验证进度和磁盘占用大小。调用 listunspent 或 sendtoaddress,就是在操作节点的钱包。调用 getrawtransaction,得到的是字节数据。随附的 bitcoin-cli 程序只是一层很薄的封装:构造 JSON、发送并打印返回结果,因此任何您能在命令行中输入的操作,程序都可以通过套接字完成。
身份验证的演变过程值得了解。Bitcoin Core 在版本0.12.0中移除了内置的 SSL 支持,因此该接口只使用未加密的 HTTP,别无其他。同一版本还引入了 cookie 文件,这是启动时写入数据目录的随机凭据,每次重启都会更换,所以 bitcoin-cli 在您自己的机器上无需设置任何密码即可工作。对于远程调用方,可以使用 rpcauth,它在配置文件中保存的是加盐哈希,而不是明文密钥。传输层依然没有加密,因此要通过网络访问节点,只能使用 SSH 隧道、VPN 或 Tor 隐藏服务,其他方式都不可行。
每个网络都有各自的端口,以便多个守护进程共用一台机器:主网为8332,testnet3 为18332,testnet4 为48332,signet 为38332,regtest 为18443。主网的 RPC 端口正好比点对点端口8333小1,把两者混淆是初学者常犯的错误。
其接口规范的变化一直很缓慢。Bitcoin Core 在十多年里一直使用 JSON-RPC 1.0的一种宽松变体来应答,而版本28.0让服务器学会识别 JSON-RPC 2.0请求,并严格按照该规范应答,同时仍接受旧风格的请求。钱包专属的调用按路径寻址,因此持有多个钱包的节点通过 /wallet/ 加钱包名称来路由这些调用。
在哪里会遇到它
RPC 是比特币本身与所有构建在其上的产品之间的衔接点。
闪电网络实现会向节点索取区块,并通过节点广播关闭通道的交易。区块浏览器、内存池面板和 BTCPay Server 等支付处理程序都运行在 bitcoind 实例之上,并在其外层封装出更友好的界面。交易所的提币系统,在最底层就是一个由 sendrawtransaction 调用组成的队列。本站的交易所评测指出某平台会批量处理提币时,这种批量处理就发生在最终落到这里的代码中。
自托管部署被攻破的情况也出在这里。端口8332会被持续扫描,一个暴露在公网上、密码容易被猜到且加载了钱包的节点,其钱包终将被盗空。请将该接口限定在本机,需要从其他地方访问时,请通过隧道连接。
RPC vs RPC 字节序
RPC 和 RPC 字节序只是缩写相同,别无其他共同点,却造成了实际的错误。RPC 是接口。RPC 字节序是一种显示约定:区块哈希和交易哈希以一个方向计算和传输,而 RPC 层以相反方向打印,因此从区块浏览器复制的交易 ID,与原始交易内部的同样32个字节相比,读起来是倒着的。把复制的交易 ID 不经反转直接送入字节级解析器,查询将始终无法匹配。