本文档介绍了Bitcoin Core的JSON-RPC接口,包括可用端点、参数传递方式、版本控制、JSON-RPC协议版本(1.1 vs 2.0)、安全注意事项、RPC一致性保证以及一些限制。强调了通过RPC接口控制Bitcoin Core的风险,并提供了安全配置建议,以减少潜在的滥用风险。
默认情况下,无头守护进程 bitcoind
启用了 JSON-RPC API,而 GUI bitcoin-qt
默认情况下禁用了它。这可以通过 -server
选项进行更改。在 GUI 中,可以在调试控制台对话框中执行 RPC 方法。
服务器上有两个 JSON-RPC 终端节点:
/
/wallet/<walletname>/
/
终端节点此终端节点始终处于活动状态。 它始终可以处理非钱包请求,并且在仅加载一个钱包时可以处理钱包请求。
/wallet/<walletname>/
终端节点仅当钱包组件已编译到其中时,此终端节点才会被激活。 它可以处理钱包和非钱包请求。 当加载两个或多个钱包时,必须将其用于钱包请求。
这是 bitcoin-cli 在传入 -rpcwallet=
参数时使用的终端节点。
最佳实践是,当使用多个钱包时,对所有请求使用 /wallet/<walletname>/
终端节点。
## 从 / 终端节点获取区块计数,当 rpcuser=alice 且 rpcport=38332
$ curl --user alice --data-binary '{"jsonrpc": "2.0", "id": "0", "method": "getblockcount", "params": []}' -H 'content-type: application/json' localhost:38332/
## 从 /wallet/walletname 终端节点获取余额,当 rpcuser=alice, rpcport=38332 且 rpcwallet=desc-wallet
$ curl --user alice --data-binary '{"jsonrpc": "2.0", "id": "0", "method": "getbalance", "params": []}' -H 'content-type: application/json' localhost:38332/wallet/desc-wallet
JSON-RPC 服务器支持 按位置 和 按名称 参数结构,该结构在 JSON-RPC 规范中进行了描述。为了更加方便,为了避免命名每个参数值的需要,所有 RPC 方法都接受一个名为 args
的命名参数,该参数可以设置为初始位置值的数组,这些值与命名值组合在一起。
例子:
## "params": ["mywallet", false, false, "", false, false, true]
bitcoin-cli createwallet mywallet false false "" false false true
## "params": {"wallet_name": "mywallet", "load_on_startup": true}
bitcoin-cli -named createwallet wallet_name=mywallet load_on_startup=true
## "params": {"args": ["mywallet"], "load_on_startup": true}
bitcoin-cli -named createwallet mywallet load_on_startup=true
bitcoin rpc
也可以代替 bitcoin-cli -named
,并且是一种较新的替代方案。
RPC 接口可能会从 Bitcoin Core 的一个主要版本更改为下一个主要版本。这使得 RPC 接口在主要版本上隐式地进行版本控制。版本元组可以通过例如 getnetworkinfo
RPC 中的 version
来检索。
通常,不推荐使用的功能可以在一个主要版本的宽限期内通过 -deprecatedrpc=
命令行选项重新启用。新主要版本的发行说明中包含有关哪些 RPC 功能已弃用以及如何临时重新启用它们的详细说明。
服务器识别 JSON-RPC v2.0 请求并相应地响应。2.0 请求通过请求正文中是否存在 "jsonrpc": "2.0"
来识别。如果该键+值未出现在请求中,则遵循旧的 JSON-RPC v1.1 协议,该协议是 v27.0 及更早版本中唯一可用的协议。
1.1 | 2.0 | |
---|---|---|
请求标记 | "version": "1.1" (或无) |
"jsonrpc": "2.0" |
响应标记 | (无) | "jsonrpc": "2.0" |
响应中的 "error" 和 "result" 字段 |
两者都存在 | 仅存在一个 |
响应中的 HTTP 代码 | 200 ,除非存在任何类型的 RPC 错误(无效参数、未找到方法等) |
始终 200 ,除非存在实际的 HTTP 服务器错误(请求解析错误、未找到端点等) |
通知:未收到回复的请求 | (不支持) | 支持排除 "id" 字段的请求。返回 HTTP 状态 204 "无内容" |
RPC 接口允许其他程序控制 Bitcoin Core,包括从你的钱包中花费资金、影响共识验证、读取私有数据以及执行可能导致金钱、数据或隐私损失的其他操作。本节建议你应如何使用和配置 Bitcoin Core,以降低其 RPC 接口被滥用的风险。
保护可执行文件: 任何有权访问运行 Bitcoin Core 的计算机、容器或虚拟机的物理或远程访问权限的人都可以破坏整个程序或仅破坏 RPC 接口。这包括能够记录你输入的用于解锁加密钱包的任何密码短语,或更改设置,以便你的 Bitcoin Core 程序告诉你某些交易已获得多次确认,即使它们不是最佳区块链的一部分。因此,你不应在你不完全控制的系统(例如共享计算机或虚拟专用服务器)上使用 Bitcoin Core 进行安全敏感的操作。
保护本地网络访问: 默认情况下,RPC 接口只能由在同一台计算机上运行的客户端访问,并且只能在客户端提供有效的身份验证凭据(用户名和密码短语)后才能访问。你计算机上任何有权访问文件系统和本地网络的程序都可以获得此级别的访问权限。此外,你计算机上的其他程序可以尝试在与 Bitcoin Core 相同的端口上提供 RPC 接口,以诱骗你透露你的身份验证凭据。因此,重要的是仅在你信任其其他程序的计算机上使用 Bitcoin Core 进行安全敏感的操作。
保护远程网络访问: 你可以选择允许其他计算机通过设置 rpcallowip
和 rpcbind
配置参数来远程控制 Bitcoin Core。这些设置仅用于通过安全专用网络或已以其他方式保护的连接(例如,使用 VPN 或通过 SSH 或 stunnel 进行端口转发)来启用连接。不要通过公共互联网启用 RPC 连接。 尽管 Bitcoin Core 的 RPC 接口确实使用身份验证,但它不使用加密,因此你的登录凭据以明文形式发送,网络路径上的任何人都可以读取。此外,RPC 接口尚未加强以承受任意 Internet 流量,因此更改上述设置以将其暴露于 Internet(即使使用像 Tor onion 服务之类的东西)可能会使你面临未考虑到的漏洞。有关这些设置和本文档中描述的其他设置的更多信息,请参见 bitcoind -help
。
相关地,如果你在 Docker 容器中使用 Bitcoin Core,则可能需要将 RPC 端口暴露给主机系统。在 Docker 中执行此操作的默认方式也会将端口暴露给公共 Internet。相反,仅在主机系统的 localhost 上暴露它,例如:-p 127.0.0.1:8332:8332
安全身份验证: 默认情况下,当未指定 rpcpassword
时,Bitcoin Core 每次重新启动时都会生成唯一的登录凭据,并将它们放入只有启动 Bitcoin Core 的用户才能读取的文件中,从而允许该用户的任何 RPC 客户端在具有对该文件的读取访问权限的情况下自动登录。该文件是 Bitcoin Core 配置目录中的 .cookie
,并且使用这些凭据是首选的 RPC 身份验证方法。如果你需要为程序生成静态登录凭据,可以使用 Bitcoin Core 源代码树中 share/rpcauth
目录中的脚本。作为最后的后备方案,你可以直接使用手动选择的 rpcuser
和 rpcpassword
配置参数---但你必须确保选择一个强而唯一的密码短语(并且仍然不要使用不安全的网络,如上所述)。
安全字符串处理: RPC 接口不保证数据的任何转义,超出将其编码为 JSON 所需的范围,尽管它通常使用字节的十六进制表示形式提供序列化数据。如果在程序中使用 RPC 数据或将其数据提供给其他程序,则必须确保正确转义任何问题字符串。例如,createwallet
RPC 接受诸如 wallet_name
之类的参数,该参数是一个字符串,可以在没有应用程序级别检查的情况下用于路径遍历攻击。多个网站已被操纵,因为它们显示了解码后的十六进制字符串,其中包括 HTML <script>
标签。因此,以及其他原因,建议仅以十六进制形式显示所有序列化数据。
可以通过 RPC 查询的状态保证至少与调用执行之前的链状态保持同步。但是,通过反映 交易池 的 RPC 返回的状态可能不是最新的 交易池 状态。
通过 RPC 返回的 交易池 状态与自身以及调用时的链状态一致。因此,交易池 状态仅包含节点在 RPC 调用时认为可挖掘的交易。
通过 RPC 返回的 交易池 状态反映了在此调用之前返回的与 交易池 和链状态相关的 RPC 的所有影响。
通过 RPC 返回的钱包状态与自身以及调用时的链状态一致。
钱包 RPC 将返回与先前的非钱包 RPC 一致的最新链状态。调用时所有区块(和区块中的交易)的影响都反映在所有钱包交易的状态中。例如,如果一个区块包含与 交易池 交易冲突的交易,则钱包将反映在状态下删除这些 交易池 交易。
但是,钱包可能不是最新的当前 交易池 状态,或者在 RPC 之前返回的 RPC 的 交易池 状态。例如,在此 RPC 之前在 交易池 中 BIP-125 替换的钱包交易可能尚未在此 RPC 响应中反映出来。
JSON-RPC 接口中存在一个已知问题,如果同时打开太多的 http 连接,由于系统耗尽了可用的文件描述符,可能会导致节点崩溃。为了防止这种情况发生,你可能需要增加系统中允许的最大文件描述符数量,并尝试防止同时打开太多与 JSON-RPC 接口的连接(如果这在你的控制之下)。很难给出一般的建议,因为这取决于你的系统,但是如果你一次发出数百个请求,那么你绝对有遇到此问题的风险。
- 原文链接: github.com/bitcoin/bitco...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!