RFC: Simple UDT Draft Spec

Simple UDT Proposal

This document defines the Simple User Defined Tokens(Simple UDT or SUDT) specification. Simple UDT provides a way for dapp developers to issue custom tokens on Nervos CKB. The simple part in Simple UDT means we are defining a minimal standard that contains what’s absolutely needed, more sophisticated actions are left to CKB’s flexibility to achieve.

Data Structure

SUDT Cell

A SUDT cell in Simple SUDT specification looks like following:

data:
    amount: uint128
type:
    code_hash: simple_udt type script
    args: owner lock script hash (...)
lock:
    <user_defined>

The following rules should be met in a SUDT Cell:

  • Simple UDT Rule 1: a SUDT cell must store SUDT amount in the first 16 bytes of cell data segment, the amount should be stored as little endian, 128-bit unsigned integer format. In the case of composable scripts, the SUDT amount must still be located at the initial 16 bytes in the data segment which corresponds to the composed SUDT script
  • Simple UDT Rule 2: the first 32 bytes of the SUDT cell’s type script args must store the lock script hash of owner lock. Owner lock will be explained below
  • Simple UDT Rule 3: each SUDT must have unique type script, in other words, 2 SUDT cells using the same type script are considered to be the same SUDT.

User shall use any lock script as they wish in the SUDT Cell.

Owner lock script

Owner lock shall be used for governance purposes, such as issurance, mint, burn as well as other operations. The SUDT specification does not enforce specific rules on the behavior of owner lock script. It is expected that owner lock script should at least provide enough security to ensure only token owners can perform governance operations.

Operations

This section describes operations that must be supported in Simple UDT implementation

Transfer

Transfer operation transfers SUDTs from one or more SUDT holders to other SUDT holders.

// Transfer
Inputs:
    <vec> SUDT_Cell
        Data:
            amount: uint128
        Type:
            code_hash: simple_udt type script
            args: owner lock script hash (...)
        Lock:
            <user defined>
    <...>
Outputs:
    <vec> SUDT_Cell
        Data:
            amount: uint128
        Type:
            code_hash: simple_udt type script
            args: owner lock script hash (...)
        Lock:
            <user defined>
    <...>

Transfer operation must satisfy the following rule:

  • Simple UDT Rule 4: in a transfer transaction, the sum of all SUDT tokens from all input cells must be larger or equal to the sum of all SUDT tokens from all output cells. Allowing more input SUDTs than output SUDTs enables burning tokens.

Governance Operations

This section describes governance operations that should be supported by Simple UDT Implementation. All goverance operations must satisfy the following rule:

  • Simple UDT Rule 5: in a governance operation, at least one input cell in the transaction should use owner lock specified by the SUDT as its cell lock.

Issue New SUDT

This operation enables issuing new SUDTs.

// Issue new SUDT
Inputs:
    <... one of the input cell must have owner lock script as lock>
Outputs:
    SUDT_Cell:
        Data:
            amount: uint128
        Type:
            code_hash: simple_udt type script
            args: owner lock script hash (...)
        Lock:
            <user defined>
12 Likes

An implementation for the spec is already provided at here expect for one minor difference: the draft spec requires the input tokens to be larger or equalled to output tokens. While the implementation requires the input tokens to be the same as output tokens.

6 Likes

Why the request for implementation is just that output needs to be the same as input?
Is transaction fee not necessary for sudt transfer on testnet ?

The transaction fee is paid by CKB instead of sUDT by default. And to follow the protocol, the output of sUDT amount should be equal to or less than that of input. I think the code has been modified to fit the protocol.

2 Likes

the transfer which’s output is greater than the input can be understood as burn function.
But for token, the burn function should only be called by the Owner || issuer || governance instead of User
So I think the RFC0025 protocol should be changed to require the input tokens to be the same as output tokens.

from a standard perspective why would you want to prevent a user from burning their tokens?

There are use cases, one example that quickly comes to mind is in a decentralized cross-chain bridge. A user would have to burn their wrapped tokens to unlock them on the other side of the bridge.

1 Like

You’re right.