Nervos: transactions with ckb-sdk

At Rather Labs we exploring how to interact with Nervos blockchain, this is a third-generation…

At Rather Labs we exploring how to interact with Nervos blockchain, this is a third-generation blockchain that deploys multiple layers which combines security and decentralization on layer one and scalability on the sub-layers.

ckb-sdk is a JavaScript library that allows to sign and send transactions within the Nervos blockchain. Nervos is based on the concept of “cells” which is analog to the (unspent transactions output) UTXO system of Bitcoin. The “living cells” are used to generate transactions and to produce new cells. The cells can be employed generally by only one owner. The cells in the inputs of the transactions cannot be transferred anymore and they become “dead cells”. A Nervos node run two main programs:

  • CKB: This is the main CKB blockchain program that does the synchronization with the others nodes on the blockchain and can perform transaction validations and mine new blocks.
  • CKB-indexer: This acts as a database allowing the users to fetch the living cells from the blockchain quicker.

To create a transaction on the CKB blockchain, we need to:

  1. Fetch the living cells of a CKB account, from where we are going to transact the CKBs, using the CKB-indexer. It is required to have an access point to a public indexer or even to run a Testnet node locally.
  2. Transfer the tokens using the living cells from the account gotten from the previous step. For this, we are going to use the ckb-sdk library which enables us to sign and send the transactions.

To transfer CKBs create two accounts, one for sending CKBs and the other for receiving. Then use the CKB Testnet faucet to fill one of them with some CKBs. Check this page for generating new CKB addresses.

For fetching the living cells information from the blockchain we need the lock script that identifies the CKB accounts. Each CKB account has a unique lock script that can be obtained using the ckb-sdk-utils (part of ckb-sdk-core) package:

<pre><code>const ckbSdkUtils = require("@nervosnetwork/ckb-sdk-utils");
let address = "ckt1qyqycgdq0d5fpe9nqpf7j0l2n53lxmceqpas2shhaz";
let lockScript = ckbSdkUtils.addressToScript(address)

The lock script looks like this:

    codeHash: '0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8',  
    hashType: 'type',  
    args: '0x4c21a07b6890e4b30053e93fea9d23f36f19007b'

The first step is to fetch the living cells by doing an HTTP request to the indexer. In our case, we are running the ckb-indexer in our private node and it accepts the request with the “get_cells” method. The following code snippet prepares the data to send as an HTTP request and uses Axios to perform the request:

const indexerUrl = "http://localhost:3000"

let post_data = {
jsonrpc: "2.0", method: "get_cells",
params: [
"script": {
"code_hash": lockScript.codeHash,
"hash_type": lockScript.hashType,
"args": lockScript.args
"script_type": "lock"

let post_options = {headers: {'Content-Type': 'application/json'}};

let cells;, post_data, post_options)
.then((response) => {
cells = => {
return {
lock: {
codeHash: value.output.lock.code_hash,
hashType: value.output.lock.hash_type,
args: value.output.lock.args,
outPoint: {
txHash: value.out_point.tx_hash,
index: value.out_point.index,
capacity: value.output.capacity,
data: value.output_data,
.catch((error) => {
console.log("error:", error);

You will need to adapt the URL of the indexer indexerUrl to a public URL or the http://localhost:port if you are running a node locally.

Once the cells related to the sending CKB account have been fetched, it is time to sign and send the transaction. The most important parameters to consider in this part would be:

  • Sending address:fromAddress
  • Sending private key: addressPrivate
  • Receiving address: toAddress
  • Amount to send:capacity
  • Fee for the transaction: fee

const CKB = require('@nervosnetwork/ckb-sdk-core').default;

const signAndSend = async () => {
const ckb = new CKB(nodeUrl);
await ckb.loadDeps();
const rawTransaction = await ckb.generateRawTransaction({
fromAddress: address,
capacity: BigInt(99 * 1E8),//1E8 shannons = 1CKB, min 61E8 shannon = 61CKB
fee: BigInt(0.001 * 1E8),
safeMode: true,
deps: ckb.config.secp256k1Dep,

const signedTx = ckb.signTransaction(addressPrivate)(rawTransaction);
const realTxHash = await ckb.rpc.sendTransaction(signedTx)


These are the basic steps to perform a transaction, more advanced things like checking how many nodes confirm the transaction and checking the balances are also going to be covered in new articles.

Please check the full source code use for this article at the Rather Labs Github. Don’t miss the next articles coming where we are going to explain how to deploy and interact with User Defined Tokens (UDT) and how to work with Non-Fungible Tokens (NFT) on the Nervos Blockchain.

For this articled we have used the following NPM packages:

Thanks to Federico Caccia and Franco Scucchiero

About Rather Labs.

Rather Labs is a Blockchain Technical partner who provides the blockchain expertise along with the partner intensity founders need.

Rather Labs is committed to work alongside our clients as a technical partner, providing insights, technical design, engineering team management, recommendations, maintenance and technology projection.

The company is led by co-founders which have been involved in blockchain projects in finance, real state, gaming, and other industries for years.

For more information, visit or follow the company on Medium and

Nervos: transactions with ckb-sdk
Guido Giuntoli
Article checked for relevance
We respect your privacy
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Talk to Our Experts to Find Out

  • The Rather Labs Way for developing impactful applications, fast
  • How can we get started on your project right now
  • How we helped founders and startups to design, develop and launch their projects globally
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Schedule a Meeting

linkedin logogithub logo