远程过程调用 RPC
RPC
是 Remote Procedure Call 的缩写,即远程过程调用,它是一种计算机通信协议,用于在计算机网络中的不同系统之间进行通信和调用远程服务。它允许一个程序调用另一个计算机上的程序,并且就像调用本地程序一样,使得远程服务的使用者无需了解底层的网络细节。
在区块链领域,RPC
是一种常见的通信协议,用于与区块链节点进行交互和调用节点上的方法或功能。
Solana RPC
就是 Solana
区块链提供的一种远程过程调用协议,允许开发者通过 RPC
接口与 Solana
主网或测试网的节点进行通信,并执行一系列操作,如获取区块信息、查询交易状态、部署智能合约等。它是用户界面和区块链之间的桥梁,是开发者构建 Solana DApps
的重要工具之一。
通过 Solana RPC
,开发者可以使用各种编程语言(如 JavaScript、Python、Go 等)编写应用程序或脚本,与 Solana
区块链进行交互并访问其功能。例如,开发者可以使用 Solana RPC
获取最新的区块高度、查询某个地址的余额、发送交易等操作,从而构建各种类型的去中心化应用或工具。
Solana
提供的 RPC
分为:主动请求的 HTTP 接口 和 消息推送的 Websocket 接口。
单次查询一般使用 HTTP
接口,如发送交易,查询用户余额,而对于链上数据的监控则通过 Websocket
接口,如监控合约执行的日志。
HTTP 接口
HTTP
接口是通过 JSON RPC
的格式对外提供服务。
JSON RPC
是一种以 JSON
作为序列化工具,HTTP
作为传输协议的 RPC
模,当前使用的是 v2 版本。
请求格式为:
{ "jsonrpc": "2.0", "id": 1, "method": "getBalance", "params": [ "83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri" ] }
数据结构中的 Key
是固定的,其中:
jsonrpc
表示协议办法本号;id
表示序号;method
表示RPC
的函数方法名;params
表示该函数的参数。
对应的请求结果为:
{ "jsonrpc": "2.0", "result": { }, "id": 1 }
这里的 Key
也是固定的,其中:
- result 表示请求的结果;
- id 与请求里面的 id 对应,表示的是哪个请求的结果。
在请求查询的时候,对查询的结果有三种状态选择:
- 'finalized' - 节点将查询由超过集群中超多数确认为达到最大封锁期的最新区块,表示集群已将此区块确认为已完成。
- 'confirmed' - 节点将查询由集群的超多数投票的最新区块。
- 'processed' - 节点将查询最新的区块。注意,该区块可能被集群跳过。
状态参数可以在 "params" 数组的最后,以字典的形式带入进去。
同时 Solana
也对常用的结果做了人为可读的优化。
当传递 "encoding":"jsonParsed" 会讲结果尽量以 JSON
的方式返回。
encoding
和上面的状态放在同一个位置。
例如:
{ "commitment":"processed", "encoding":"jsonParsed" }
Websocket 接口
Websocket
是 HTTP
为了补充长链接,而增加一个特性,概括来说就可以认为这个是一条 TCP
长连接。Solana
通过这条连接来给客户端推送消息。
只是这里的消息的内容也是采用了 JSONRPC
的格式,如:
{ "jsonrpc": "2.0", "id": 1, "method": "accountSubscribe", "params": [ "CM78CPUeXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNH12", { "encoding": "jsonParsed", "commitment": "finalized" } ] }
这样的消息订阅了 Account("CM78CPUeXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNH12") 的变化消息。
当有变化时,也是将结果打包成一个 JSONRPC
的格式推送给客户端:
{ "jsonrpc": "2.0", "method": "accountNotification", "params": { "result": { "context": { "slot": 5199307 }, "value": { "data": { "program": "nonce", "parsed": { "type": "initialized", "info": { "authority": "Bbqg1M4YVVfbhEzwA9SpC9FhsaG83YMTYoR4a8oTDLX", "blockhash": "LUaQTmM7WbMRiATdMMHaRGakPtCkc2GHtH57STKXs6k", "feeCalculator": { "lamportsPerSignature": 5000 } } } }, "executable": false, "lamports": 33594, "owner": "11111111111111111111111111111111", "rentEpoch": 635, "space": 80 } }, "subscription": 23784 } }
每个 Subscribe
方法,都对应的有一个 Unsubscribe
方法,当发送改方法时,服务器后续不再推送消息。