Intro to CKB Script Programming 1: Validation Model

Nervos Network
Nervos Network
Published in
6 min readAug 3, 2019

July 2019 · 6 minute read

by Xuejie Xiao, a blockchain engineer working on Nervos CKB and the main developer on CKB VM.

As of now, the cell validation model in CKB has been more or less stabilized, so I’m starting a series of articles introducing CKB script programming. My goal is to fill in all the missing implementation details one needs to write CKB scripts after reading the whitepaper, so you can start exploring CKB.

You may have noticed that I refer to the code running on CKB as ascript, not asmart contract. This is because I want to differentiate and highlight CKB’s unique programmability. A script in CKB’s sense need not be just a script— we see in scripting languages such as Ruby, JS— it actually refers to the RISC-V format binary you run on CKB VM.

This first article is dedicated to the new verification model introduced in CKB v0.14.0. [I promise you this is the last post without actual examples to play with :P]

Note: CKB development is still happening, so there will likely be updates. I will try my best to make sure this post is updated, but for reference, this post is describing CKB as of this commit.

Overview

Below illustrates a real transaction on CKB:

There are a lot of things going on in this graph, and we refer to this graph again in later posts. To start, we will just focus on 2 entities in the cell data structure: lock and type.

pub struct CellOutput {
pub capacity: Capacity,
pub data: Bytes,
pub lock: Script,
#[serde(rename = "type")]
pub type_: Option<Script>,
}

From the data structure we can see that lock and type shared the same structure, later we can show that they are also executed in the same environment, the differences between them are just in a few tiny bits:

  • lock is required, while type is optional
  • Mentally, they are used to capture different use cases.

We will first start with type script here.

Type script

Note: the name here is just a coincidence, it is not related to the much loved programming language.

If you think about it, a transaction on CKB (or most UTXO-based blockchains) just transforms one set of cells (or UTXOs) to another set of cells. What’s interesting, is the actual transformation. That’s where we start to design CKB’s verification model— how can we build a model to better validate the cell transformations?

That’s where a type script comes in play: a type script is used to validate certain rules in the cell transformation phase. A few examples:

  • Validating UDT(user defined token) balances to ensure no new token is invalidly issued.
  • Ensuring a unique name is assigned to a cell that might be mutated. This is a fun one, please expect a future article dedicated entirely to this topic.
  • Implementing economic constructs. In fact NervosDAO is completely implemented as a type script with minimal support from the consensus layer.
  • A Bitcoin VM can be compiled to RISC-V binary, which can transform CKB into an alternative Bitcoin implementation :)
  • Keep in mind that in addition to data, cells can be used to store code, hence a type script can also be used to run tests on the code in cells to ensure certain behavior.

In a nutshell, type script can be used to capture any validation logic you need in the cell transformation. Combined with CKB’s flexible virtual machine, this has endless potential.

Lock script

Type script captures the cell transformation logic, but there’s another important component— how can I guard my own cell from someone else? In other words, how can I ensure my tokens stay mine?

This is why we designed the always required lock script. A cell can only be consumed when the lock script can be executed successfully. This is different from type script, which may be optional. A lock script is always there to guard the security of a cell.

Typically, you would expect that a lock script contains a signature verification phase, like all the other blockchains do, but there are also brand new use cases unlocked by CKB:

  • The actual signature algorithm is totally determined by the lock script, and you are free to use any lock script. That means you are free to incorporate any signature algorithms that suit your need. In the official CKB distribution we are including secp256k1 algorithm as the default lock script. But you don’t have to use this. For example, if someone implements a lock script using schnorr signature, that can be used.
  • In addition to signature verification, a lock script can also include other rules to unlock the cell as well. I can configure my lock script to pass if the transaction contains an output cell that uses my lock script, but has more capacity than my consumed cell. This way when someone sends me capacity, they can consume my existing cell and create a new cell for me.

The best part of CKB is that a lock script created by the community is treated exactly the same way as the official default one. No privilege is granted to the official scripts. Unlike some other blockchains, CKB provides the freedom to develop CKB scripts that are shared back to the whole community.

Execution model

Back to the Example

Here’s the transaction used earlier:

The execution flow is as follows:

  1. Lock Script 1 is executed once.
  2. Lock Script 2 is executed once.
  3. Type Script 1 is executed once.
  4. Type Script 2 is executed once.

In later posts we will see that both lock and type scripts are executed in the same environment, and both have access to the whole transaction. If any of the script fails, the whole transaction fails. Only when all the scripts succeed, the transaction is considered validated.

There’re few of points worth mentioning:

  • Even though there are 2 input cells with Lock Script 1, it is only executed once, it’s up to the actual lock script to locate all the input cells with the same lock script and validate both signatures.
  • Only lock scripts in input cells are executed in this transaction, for example, Lock Script 3 is not executed here.
  • Even though an input cell and an output cell both contain Type Script 1, it is only executed once.
  • Type scripts in both input and output cells are executed, which includes Type Script 1 and Type Script 2.
  • Some cells do not have type scripts,and in this case we just omit the execution.

Rules

To summarize the rules:

  • Lock scripts in input cells are collected and deduped—each unique lock script is executed and only executed once.
  • Type scripts in input and output cells (if they exist) are collected together and deduped—each unique type script is executed and only executed once.
  • If any script fails, the whole transaction validation fails.

What’s next

Now that the cell model is covered, we will look at how to write a CKB VM script in the next post. The default secp256k1 lock script will be examined to show the life of a CKB VM script.

Stay updated on Nervos: Forum, Twitter, Reddit, Youtube, Telegram, Github

--

--