This post is from the first CKB. Dev Tea Party. The topic of this issue is: How to implement UDT in CKB.

Tea party scene video:…

The trading and contract model of CKB

Since CKB’s programming model is completely different from Ethereum’s, it’s worth explaining CKB’s transaction and contract model before we begin.

Firstly, the transaction model of CKB is UTXO structure. Each transaction destroys some Cells and generates some new Cells. Cells are the smallest structural unit in CKB network.

The transaction model of CKB is similar to that of Bitcoin, but it has been extended on this basis. The destruction and generation rules on Bitcoin are determined, while the core improvement of CKB is that the scripts on CKB can be customized by users.

For example, the signature algorithm we now use in CKB is SECP256K1, which is the same as the signature algorithm used in Bitcoin and Ethereum. However, in Bitcoin and Ethereum, the signature algorithm is written in the node and cannot be changed, while in CKB, there is no original signature algorithm. If you want to implement another signature algorithm, SECP256R1, on CKB, all you need to do is write your own Script for SECP256R1 and then write a Lock Script to do it, whereas on Ethereum you have to go through a hard fork to do it. The signature algorithm is always replaceable on CKB.

Another big improvement of CKB is that the balance before and after the transfer on Bitcoin must be the same. This equation is solidified in the node, so there is only native BTC on Bitcoin, and other UDT cannot be realized. This point is also customizable in CKB, namely the Type Script in CKB, which means users can develop additional transfer rules on this basis. For example, the user can define that the balance of a field in the Type Script must be the same before and after the transfer. In fact, a new UDT can be implemented on CKB, because the object specified in the Type Script can no longer be limited to the native CKB Token. It could be any newly created UDT.

In addition, CKB and Ethereum have completely different design patterns. On Ethereum, contracts focus on the intent of the action, not the outcome of the action, whereas on CKB, we focus on the outcome of the action. Contract interaction on Ethereum is interface to interface, while CKB Script interaction is state to state.

ERC20 review and analysis

Here we review the content of ERC20. After analyzing it, we can see that ERC20 has a lot of problems:

Methods and events provided by common ERC20 contracts

  • ERC20 only defines an interface, not a unified implementation. Each time you create a new ERC20, you deploy a new contract, and it’s difficult for users to understand each contract individually. In addition, because each new contract is recreated by the developer, many ERC20 contracts have intentionally or unintentionally caused security issues.
  • The user behavior in the ERC20 interface is coupled. For example, TotalSupply, Mint and Burn are administrator actions. While balanceOf, approve and transfer are the actions of ordinary users, while allowance and transfer from are the actions of authorized users. As we can see, this one ERC20 contract has at least three user behaviors coupled to it, which is relatively messy.
  • Logic and data in ERC20 are coupled. The implementation logic of the contract and the amount data held under the user’s address are all in this contract, and because of this coupling, the unified implementation cannot be carried out on Ethereum.

Design idea of implementing UDT on CKB:

  • Separate logic from state and use the same business code. Security will be greatly guaranteed.
  • Separation of user behavior, administrator behavior, and authorization behavior.
  • Provides only the most core UDT functionality. Refers to providing the most core UDT functionality to ensure the flexibility of the UDT needs of developers.
  • A state-oriented, result-oriented design pattern is used to define UDT behavior.

Minimized UDT

The two core functions of minimization UDT are: one is coin issuing, where the basic information of UDT needs to be defined and the UDT needs to be unique; The other is to transfer money to ensure consistency before and after UDT.

Create Action

Input Cells: Fill the Cells to destroy the state of this CKB. It could be the CKB that you’re currently holding, it could be the CKB that you’re currently using, and so on.

Output Cells: There are two parts, one is the UDT_ID_CELL, which describes the logic rules, basic information, and uniqueness of the UDT. The other is UDT_BALANCE_CELL, which describes the balance of the UDT and guarantees consistency before and after the transfer.

The UDT_ID_CELL side contains several main contents:

  • Type Script: used to store the logical rules of UDT creation, and UUID used to describe the uniqueness of this UDT;
  • Lock Script: simply a signature algorithm that explains who can unlock the Cell;
  • Data: The defined Data used to hold the UDT. Creator information, number of UDTs created, number of decimal points, etc.

The UDT_BALANCE_CELL side mainly contains several contents:

  • Type Script: the logical rules used to store UDT transfers, and the UUID used to describe the uniqueness of this UDT;
  • Lock Script: simply a signature algorithm that explains who can unlock the Cell;
  • Data: Used to represent the balance of the UDT.

Transfer: Transfer Action

The transfer of UDT will be relatively easy, and part of UDT will be destroyed and part of new UDT will be generated to realize the transfer.

Input Cells: Place a portion of UDT_BALANCE_CELL(s) as Input.

Output Cells: Put a portion of UDT_BALANCE_CELL(s) into the Output.

Extend the Minimal UDT

What we have achieved above is to minimize UDT and only design the two most basic functions of issuing currency and transferring money. What about other complex functions?

3. The new issue/destroy: Mint/Burn Action

For the UDT administrator, he may need to do some additional issue and destroy operations on the UDT. This is where we need to make some changes to the UDT_ID_CELL we created above.

The Input Cells:

  • Enter UDT_ID_CELL, of course, only the previous UDT_ID_CELL Lock Script specified by the administrator can do this operation, not everyone can do this operation.
  • (optional) UDT_BALANCE_CELL: If it is destructed, enter the address and number of UDTs to destroy here.

The Output Cells:

  • Output the new UDT_ID_CELL, which is the newly generated UDT_ID_CELL after the rule was changed;
  • (Optional) UDT_BALANCE_CELL: If the additional issue is optional, enter the address to which the additional issue should be sent and the number of UDTs here.

Authorization: the Approve/Transfer_from

So how do you implement the authorization behavior? Again, we can extend the minimum UDT scheme.

Action Approve

Input Cells: Enter UDT_BALANCE_CELL

Output Cells: outputs the new UDT_BALANCE_CELL_WITH_APPROVE, which is the intermediate state and indicates that the Cell is in an authorized state.

  • Lock: UDT_APPROVE_LOCK: This is a Script that writes the logical rules for the authorization

    • Licensor information: Licensor’s public key
    • Licensee information: The public key of the licensee
    • Authorized amount

The UDT_Approve_lock here can implement two logics.One is that the licensee can unlock the Cell with its own private key and use the UDT amount within it. The other is that the licensee can use the licensee’s private key to unlock the Cell and use the UDT amount within the authorized amount.

Action Transfer_from

The licensee can call Transfer_from, using the UDT within the authorized amount range.


Output Cells: outputs a new UDT_BALANCE_CELL_WITH_APPROVE.Perhaps the authorized amount is not fully used. This is change. Output UDT_BALANCE_CELL, which is the part of UDT rolled out by the authorized party.

Note: The licensee information in UDT_BALANCE_CELL_WITH_APPROVE can be either a LOCK Script or a TYPE Script. So the licensee here could be one address, or it could be N addresses, or it could be another contract.

At the end of the share, Cipher also introduces an example of Token Swap.

Join Nervos Community

The Nervos Community is committed to being the best Nervos Community. We will continue to promote and popularize Nervos technology, explore the intrinsic value of Nervos, and explore the infinite possibilities of Nervos. To provide an excellent platform for everyone who wants to know more about Nervos Network.

Add WeChat ID: BitcoinDog to join the Nervos Community. If you are a programmer, please comment and it will pull you into the developer group.