Skip to main content

JSON-RPC

CKB exposes a set of RPCs in JSON-RPC 2.0 protocols for interactions.

Here are some initial tips:

  • The RPCs exposed by CKB are only designed for internal usage. Please limit the access to the CKB RPCs strictly to trusted machines (by using rpc.listen_address configuration option). Exposing CKB RPCs to the public Internet is dangerous and strongly discouraged.
  • CKB JSON-RPC only supports HTTP now. If you need SSL support, please setup a reverse proxy via nginx or other HTTPS servers.
  • Subscriptions require a full duplex connection. CKB offers such connections in the form of tcp (enable with rpc.tcp_listen_address configuration option) and websockets (enable with rpc.ws_listen_address), plain HTTP connection does not support subscriptions. See below for examples on this.

Basic Usage

Here we try to provide a starting point for interacting with CKB's RPCs. For more details, please refer to CKB JSON RPC Protocols Documentation.

To use CKB JSON-RPC, you must first have a node running, please refer to existing guides on how to run a CKB Mainnet node, a CKB Testnet node, or a development-only CKB blockchain. The commands below also assumes you are exposing CKB JSON-RPC on the default 8114 port. If you are starting CKB JSON-RPC on a different port, please make changes accordingly.

The following commands uses get_tip_block_number RPC to fetch the tip block number, of the latest block number in the longest blockchain:

echo '{
"id": 2,
"jsonrpc": "2.0",
"method": "get_tip_block_number",
"params": []
}' \
| tr -d '\n' \
| curl -H 'content-type: application/json' -d @- \
http://localhost:8114
(click here to view response)
{"jsonrpc":"2.0","result":"0x2cb4","id":2}

The following commands uses send_transaction RPC send transactions to the ckb network:

echo '{
"id": 3,
"jsonrpc": "2.0",
"method": "send_transaction",
"params": [
{
"cell_deps": [
{
"dep_type": "code",
"out_point": {
"index": "0x0",
"tx_hash": "0xa4037a893eb48e18ed4ef61034ce26eba9c585f15c9cee102ae58505565eccc3"
}
}
],
"header_deps": [
"0x7978ec7ce5b507cfb52e149e36b1a23f6062ed150503c85bbf825da3599095ed"
],
"inputs": [
{
"previous_output": {
"index": "0x0",
"tx_hash": "0x365698b50ca0da75dca2c87f9e7b563811d3b5813736b8cc62cc3b106faceb17"
},
"since": "0x0"
}
],
"outputs": [
{
"capacity": "0x2540be400",
"lock": {
"code_hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5",
"hash_type": "data",
"args": "0x"
},
"type": null
}
],
"outputs_data": [
"0x"
],
"version": "0x0",
"witnesses": []
}
]
}'\
| tr -d '\n' \
| curl -H 'content-type: application/json' -d @- \
http://localhost:8114
(click here to view response)
{
"id": 3,
"jsonrpc": "2.0",
"result": "0xa0ef4eb5f4ceeb08a4c8524d84c5da95dce2f608e0ca2ec8091191b0f330c6e3"
}

It should be noted that send_transaction is asynchronous, that is, the return of the transaction hash, does not mean that the transaction is fully verified, if you need to follow up on the status of the transaction, it is recommended to use the following get_transaction rpc:

echo '{
"id": 4,
"jsonrpc": "2.0",
"method": "get_transaction",
"params": ["0xa0ef4eb5f4ceeb08a4c8524d84c5da95dce2f608e0ca2ec8091191b0f330c6e3"]
}' \
| tr -d '\n' \
| curl -H 'content-type: application/json' -d @- \
http://localhost:8114
(click here to view response)
{
"id": 4,
"jsonrpc": "2.0",
"result": {
"transaction": {
"cell_deps": [
{
"dep_type": "code",
"out_point": {
"index": "0x0",
"tx_hash": "0xa4037a893eb48e18ed4ef61034ce26eba9c585f15c9cee102ae58505565eccc3"
}
}
],
"hash": "0xa0ef4eb5f4ceeb08a4c8524d84c5da95dce2f608e0ca2ec8091191b0f330c6e3",
"header_deps": [
"0x7978ec7ce5b507cfb52e149e36b1a23f6062ed150503c85bbf825da3599095ed"
],
"inputs": [
{
"previous_output": {
"index": "0x0",
"tx_hash": "0x365698b50ca0da75dca2c87f9e7b563811d3b5813736b8cc62cc3b106faceb17"
},
"since": "0x0"
}
],
"outputs": [
{
"capacity": "0x2540be400",
"lock": {
"code_hash": "0x28e83a1277d48add8e72fadaa9248559e1b632bab2bd60b27955ebc4c03800a5",
"hash_type": "data",
"args": "0x"
},
"type": null
}
],
"outputs_data": [
"0x"
],
"version": "0x0",
"witnesses": []
},
"cycles": "0x219",
"time_added_to_pool" : "0x187b3d137a1",
"tx_status": {
"block_hash": null,
"status": "pending",
"reason": null
}
}
}

Subscription

To use subscription feature, you need to configure CKB to enable such features. In this section, we assume you use the following configuration in ckb.toml section:

[rpc]
listen_address = "127.0.0.1:8114"
tcp_listen_address = "127.0.0.1:18114"
ws_listen_address = "127.0.0.1:18115"

# ... more configs

This above config ensures CKB listens at 8114 port for normal HTTP connections, 18114 port for TCP duplex connections, and 18115 port for WebSocket duplex connections.

TCP Based RPC

The following command uses netcat to connect via TCP to CKB, then fire the same get_tip_block_number RPC as shown above to fetch the block number in the longest chain:

echo '{
"id": 2,
"jsonrpc": "2.0",
"method": "get_tip_block_number",
"params": []
}' \
| tr -d '\n' \
| sed -e "s/$/\n/"
| nc localhost 18114 -q 1
{"jsonrpc":"2.0","result":"0xdc90","id":2}

The following command uses netcat to connect to CKB, make a subscription request to monitor the latest committed block:

cat <(echo '{
"id": 2,
"jsonrpc": "2.0",
"method": "get_tip_block_number",
"params": []
}' \
| tr -d '\n' \
| sed -e "s/$/\n/") -
| nc localhost 18114
{"jsonrpc":"2.0","result":"0xa","id":2}
{"jsonrpc":"2.0","method":"subscribe","params":{"result":"{\"version\":\"0x0\",\"compact_target\":\"0x1a2810cf\",\"timestamp\":\"0x16ee81d0d5f\",\"number\":\"0x30673\",\"epoch\":\"0x5f102b400007a\",\"parent_hash\":\"0xc9020c79d4f19797022af3631eb9e76c57933bd608fe81a137b834975616c991\",\"transactions_root\":\"0x7d8e3c102a5c52598cdbe7d208deb986eb2f0af189bc4655e6dd1a71564c2b25\",\"proposals_hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"uncles_hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"dao\":\"0x15b9ae7648400f2fb61d57e0379b2300fc641b7e8db5160000060394d5580007\",\"nonce\":\"0x1f86f056000002460000000053170600\",\"hash\":\"0xa3c8feda83d7e184f09cb4f05e535bccd4c159e2cc0ac7a06ea7d457e0051a08\"}","subscription":"0xa"}}
{"jsonrpc":"2.0","method":"subscribe","params":{"result":"{\"version\":\"0x0\",\"compact_target\":\"0x1a2810cf\",\"timestamp\":\"0x16ee81d1dfd\",\"number\":\"0x30674\",\"epoch\":\"0x5f102b500007a\",\"parent_hash\":\"0xa3c8feda83d7e184f09cb4f05e535bccd4c159e2cc0ac7a06ea7d457e0051a08\",\"transactions_root\":\"0x6d2dfc88bd8dda743b5bae14453f5f405a2a29a3cf6fff00c60f0f5c60a84fbe\",\"proposals_hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"uncles_hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"dao\":\"0xb4e019376f400f2f34c172e7379b230031d1417d95b5160000a399ffd6580007\",\"nonce\":\"0xded8ffa1000000000000040a90000000\",\"hash\":\"0x7d10fd1fb459630aa2f87ee4de699b7466a5da6efc0aee6ff459ff17b6cc5904\"}","subscription":"0xa"}}
// ... more data

Use Ctrl-C to exit netcat here.

WebSocket Based RPC

To play with WebSocket based RPC, please make sure to install wscat first:

npm install -g wscat

You can use the following command to start wscat and connect to CKB:

wscat -c ws://localhost:18115
Connected (press CTRL+C to quit)
>

Now we can run the same get_tip_block_number request as above:

> {"id": 2, "jsonrpc": "2.0", "method": "get_tip_block_number", "params": []}
< {"jsonrpc":"2.0","result":"0x76887","id":2}

You can also create subscriptions for new blocks:

> {"id": 2, "jsonrpc": "2.0", "method": "subscribe", "params": ["new_tip_header"]}                                                                                                        < {"jsonrpc":"2.0","result":"0x2","id":2}                                                                                                                                                 < {"jsonrpc":"2.0","method":"subscribe","params":{"result":"{\"version\":\"0x0\",\"compact_target\":\"0x1a216e17\",\"timestamp\":\"0x16f886b2223\",\"number\":\"0x77e2a\",\"epoch\":\"0x6c$01a9000135\",\"parent_hash\":\"0x2662c8056c638408d8f018a53785d68f633bd1edfa06b82d7c29ddcac1d98927\",\"transactions_root\":\"0xa6488b15373521ec0b1bc9dff1f117cc1cad7d3579e8a6c38cc6e35166dad9bd\",\"proposals_hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"uncles_hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"dao\":\"0x1a1aab41ad3eb72fa260f4eedeb9230092c4510af45b390000547d684fc40007\",\"nonce\":\"0xce1aaca681000089001d0003cb2d0500\",\"hash\":\"0x993e593921024167c1779146348fe2d82864ecd3f657b3bd2b14fbdfa87c4f06\"}","subscription":"0x2"}}
< {"jsonrpc":"2.0","method":"subscribe","params":{"result":"{\"version\":\"0x0\",\"compact_target\":\"0x1a216e17\",\"timestamp\":\"0x16f886b29e3\",\"number\":\"0x77e2b\",\"epoch\":\"0x6c601aa000135\",\"parent_hash\":\"0x993e593921024167c1779146348fe2d82864ecd3f657b3bd2b14fbdfa87c4f06\",\"transactions_root\":\"0xe64cb6afb57e92a2af1da34d8a1d547fcd8b833e187697ae28a9dfadaaeba247\",\"proposals_hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"uncles_hash\":\"0xa807c9cbb16a5af7cf36fd5c20b29535f6db4de52062138ad21ea6790ba9529c\",\"dao\":\"0xba227d3fcf3eb72fc8d61ff5deb92300402b3f12fb5b390000f113d450c40007\",\"nonce\":\"0xfb68521601000000000000503c9e2338\",\"hash\":\"0xf55d0f7ae1d9b106eee96139d86313e46b109ec8fa0d92f9eb6eb8bc81c294ec\"}","subscription":"0x2"}}
< {"jsonrpc":"2.0","method":"subscribe","params":{"result":"{\"version\":\"0x0\",\"compact_target\":\"0x1a216e17\",\"timestamp\":\"0x16f886b40a3\",\"number\":\"0x77e2c\",\"epoch\":\"0x6c601ab000135\",\"parent_hash\":\"0xf55d0f7ae1d9b106eee96139d86313e46b109ec8fa0d92f9eb6eb8bc81c294ec\",\"transactions_root\":\"0xad2c9e1eabc586c8e38cc1eaca61eba5e320bbf4655c510c5be5de9eaafea96f\",\"proposals_hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"uncles_hash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"dao\":\"0x5a2b4f3df13eb72feb4c4bfbdeb923008c922c1a025c3900008eaa3f52c40007\",\"nonce\":\"0x7b5ad85601000000000000005b340000\",\"hash\":\"0x2077e0c022514fe07844411436cfbf50e413694858a3d4775e0c836e787ce7ab\"}","subscription":"0x2"}}
<< // ... more data.

Serialization

CKB's RPCs returns data in JSON format. While most fields are self-explanatory, CKB has special handling for numbers and binary data:

Numbers

All numbers used in CKB's RPCs, including request parameters and return values, use hex encoding, the number is encoded first in hexadecimal in the most compact format(meaning useless leading zeros should be striped), and then prefixed with 0x. Here are some examples:

  • 0 is encoded as 0x0, we cannot remove the remaining 0 since otherwise it won't be a proper number
  • 4 is encoded as 0x4
  • 15 is encoded as 0xf
  • 42 is encoded as 0x2a
  • 291 is encoded as 0x123
  • 3984 is encoded as 0xf90

Binary data

All binary data, including all the hashes, args in script, outputs_data items, are represented as hex string with 0x prefix. Some examples include:

  • 0x65b253cdcb6226e7f8cffec5c47c959b3d74af2caf7970a1eb1500e9b92aa200
  • 0x927f3e74dceb87c81ba65a19da4f098b4de75a0d
  • 0x40420f00000000000000000000000000
  • 0x (empty data)

Unlike numbers, binary data should always have a even numbered length.