RFC: Info Cell for sUDT Draft Spec

Updates

  • 2021.11.29 Add Rule 3 and Rule 4 for info_cell od single owner sUDT, add Rule 3 for info_cell of script-drive sUDT.

1. Overview

sUDT is a very simple udt standard. With the udt deployed by this standard, we can only get the balance from the chain, but not the token name, token symbol, decimals and other parameters.
In order to extend the existing sUDT standard, it is necessary to design a scheme to store token information and bind it to the corresponding sUDT, but does not destroy any compatibility with the existing sUDT.

There is a proposal here[A SUDT Information Storage Meta Cell Design Proposal], but need improvement.

2. sUDT Info Cell

In info_cell, the most basic information that must be included is token_name, token_symbol and decimals. As for total supply and balance, they can all be obtained by indexing the cell.

A SUDT Info cell in specification looks like following:

data:
    decimals: uint8
    name: Common knowledge Byte
    symbol: CKB
    extra: {website:"https://nervos.org"} // optional
type:
    code_hash: sudt_info type script
    args: sudt type script hash or type_ID
lock:
    sUDT creator defined

The format of the data field encoding can be determined as a certain serialization scheme, such as molecule or json, we need to be clear which one to use in order to standardize. It is recommended to use json, but using other formats may reduce the occupation of CKB, so suggestions can be made.

Data:

  • decimals: (uint8 type) the number of decimal digits used by the token, if decimals is 8 it means that the token can be divided to 0.00000001 at least.
  • tokenname: name of token
  • symbol: identifier of the token, such as “HIX”
  • extra: Anything you want to write, such as the website, the hash value of a certain picture, etc.

The first three items are parameters that must be filled in, and information can be added as required.

3. For Single Owner sUDT

The issuance of sUDT on CKB is controlled by lockscript, so the simplest sUDT is issued by an individual or organization using a lockscript controlled by a private key, such as USDC and other stable coins.

For this type of UDT, you can construct an info_cell while minting sUDT, whose type code_hash is Info_cell type, its args is sUDT’s type_script hash. Info_cell will check whether the transaction meets the conditions.

// Issue new SUDT/SUDT_Info
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>
    SUDT_Info_Cell:
        Data:
            decimals: uint8
            tokenname: xxxx
            symbol: xxx
        Type:
            code_hash: sudt_info type script
            args: sudt type script hash
        Lock:
           <user defined>

The following rules should be met in a SUDT Info Cell (typescript):

  • Rule 1: In this transaction, at least one sUDT cell must exist in the output cell, and the hash of its typescript matches the args of Info_cell.
  • Rule 2: In this transaction, at least one cell must exist in the input cell, and its lockscript is the owner lockscript of sUDT.
  • Rule 3: the lockscript of info_cell should be set to dead lock by default, in some cases, developers can choose other lockscript.
  • Rule 4: If there are multiple Info_cells, choose the info_cell with the smallest block height at the time of generation. If it is at the same block height, choose the info_cell with the smallest transaction index. The same transaction cannot generate two info_cells.

4. For Script-drive sUDT

However, there is another type of sUDT on CKB, which is not issued by a lockscript controlled by a private key, but follows a specific script logic. Such as NexisDAO’s dCKB and Tai, and the previous Info_cell design is no longer suitable for this situation.

Since anyone can mint sUDT while following the script logic, if we continue to use the previous logic, anyone can generate the corresponding info_cell. So we need to add new logic on the basis of the previous design.

// Issue new SUDT/SUDT_Info
Inputs:
    <any cell>
Outputs:
    SUDT_Info_Cell:
        Data:
            decimals: uint8
            tokenname: xxxx
            symbol: xxx
        Type:
            code_hash: sudt_info type script
            args: type_id
        Lock:
           <user defined>

The following rules should be met in a SUDT Info Cell (typescript):

  • Rule1: the cell data conforms to the format.
  • Rule2: args conform to the rules of type id.
  • Rule 3: the lockscript of info_cell should be set to dead lock by default, in some cases, developers can choose other lockscript.

The type script of the info cell checks whether the transaction satisfies one of the two logics(single-owner or script-driven) above.

After constructing this Info Cell, use the hash of its type_script as the first 32 bytes of the args of the Owner lockscript of sUDT. Then the Info cell is bound to the sUDT, and the owner of the info_cell can continue to change the information of the Info_cell.

Because Info Cell will be generated before sUDT is created, it is recommended to set it to a recognized format standard, otherwise it will be troublesome to upgrade UDT in order to meet the parsing standard later.

Maybe we can refer to the script design, that is, use 33Byte to specify an Info_cell. When theflag byte is 0, the 32Bytes of args is the hash of a certain cell data. When the flag byte is 1, look for a cell whose type_hash conforms to args.

1 Like

更新

  • 2021.11.29 给单独控制sUDT的Info_cell添加规则三和规则四,给脚本驱动sUDT的info_cell添加规则三。

1. 概述

sUDT 是一个非常简单的 udt 标准。 使用这个标准部署的udt,我们只能从链上得到余额,而不能得到代币名称、代币符号、小数等参数。
为了扩展现有的 sUDT 标准,需要设计一个方案来存储UDT信息并将其绑定到相应的 sUDT,但不破坏与现有 sUDT 的任何兼容性。

这里有一个针对本议题的提议[A SUDT Information Storage Meta Cell Design Proposal],但是该提议需要改进。

2. sUDT Info cell

在 info_cell 中,必须包含的最基本信息是 token_name、token_symbol和精度。 至于总供应量和余额,它们都可以通过对Cell索引来获得。

规范中的 SUDT 信息单元如下所示:

data:
    decimals: uint8
    name: Common knowledge Byte
    symbol: CKB
    extra: {website:"https://nervos.org"} // optional
type:
    code_hash: sudt_info type script
    args: sudt type script hash or type_ID
lock:
    sUDT creator defined

数据字段编码的格式可以确定为某种序列化方案,例如moleculejson,我们需要明确使用哪一种以便标准化。 建议使用json,使用其他格式也许可以减少CKB的用量,可以提出建议。

数据:

  • decimals:(uint8 类型)token 使用的小数位数,如果decimals 为8 表示token 至少可以被整除为0.00000001。
  • tokenname: 令牌名称
  • symbol: 令牌的标识符,例如“HIX”
  • extra:你想写的任何东西,比如网站,某张图片的哈希值等。

前三项是必须填写的参数,extra可以根据需要添加信息。

3. 单独控制的sUDT

CKB 上 sUDT 的发行是由 lockscript 控制的,所以最简单的 sUDT 是由个人或组织使用由私钥控制的 lockscript 发行的,例如 USDC 和其他稳定币。

对于这种类型的UDT,你可以在铸造sUDT的同时构造一个info_cell,它的type的code_hash是Info_cell类型,它的args是sUDT的type_script hash。 Info_cell 会检查交易是否满足条件。

// Issue new SUDT/SUDT_Info
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>
    SUDT_Info_Cell:
        Data:
            decimals: uint8
            tokenname: xxxx
            symbol: xxx
        Type:
            code_hash: sudt_info type script
            args: sudt type script hash
        Lock:
           <user defined>

sUDT info cell(type script)应满足以下规则:

  • 规则 一: 在本次交易中,输出单元中必须至少存在一个 sUDT cell,并且其type script的哈希与 Info_cell 的 args 匹配。
  • 规则二: 在本次交易中,输入单元格中必须至少存在一个cell,其lock script为sUDT的Owner的lock script。
  • 规则三: info_cell的lockscript默认采用无法解锁的死锁,但某些时候开发者可以选择其他lock_script。
  • 规则四: 如果存在多个info_cell,选择产生时区块高度最小的info_cell,如果同一高度有多个info_cell,选择交易索引最小的,info_cell的type应该规定同一交易不能生成多个info_cell。

4. 脚本驱动的sUDT

但是CKB 上还有一种 sUDT,它不是由私钥控制的lockscript发行,而是遵循特定的脚本逻辑。 比如NexisDAO的dCKB和Tai,之前的Info_cell设计就不适合这种情况。

由于任何人都可以在遵循脚本逻辑的同时生成 sUDT,如果我们继续使用之前的逻辑,任何人都可以生成相应的 info_cell。 所以我们需要在之前的设计基础上增加新的逻辑。

// Issue new SUDT/SUDT_Info
Inputs:
    <any cell>
Outputs:
    SUDT_Info_Cell:
        Data:
            decimals: uint8
            tokenname: xxxx
            symbol: xxx
        Type:
            code_hash: sudt_info type script
            args: type_id
        Lock:
           <user defined>

sUDT Info cell (type script)应满足以下规则:

  • 规则一:Cell data符合格式。
  • 规则二: args 符合type id 的规则。
  • 规则三: info_cell的lockscript默认采用无法解锁的死锁,但某些时候开发者可以选择其他lock_script。

info cell的type script会检查交易,是否满足上面的两个逻辑(单独控制或者脚本驱动)之一。

构造完这个Info Cell后,使用它的type_script的hash作为sUDT的owner lockscript的args的前32个字节,由此就将Info cell绑定到sUDT上了,并且info_cell的拥有者可以继续修改Info_cell的信息。

因为Info Cell在sUDT创建之前就会生成,所以推荐将其设置为一个公认的格式标准,否则之后为了满足解析标准而升级UDT会比较麻烦。

也许我们可以参考脚本设计,即使用33Byte指定一个Info_cell。 当flag字节为0时,args的32Bytes就是某个cell数据的hash,即sUDT info是不允许更改的。当标志字节为1时,查找 type_hash 符合 args 的单元格,即sUDT Info是允许更改的。

Hi @orange-xc What is the purpose of Rule 2?

Rule 2 ensures that the transaction to create the Info cell is indeed sent by the owner of sUDT, and other people cannot create the Info cell.

Thanks for your reply.

Well, I am still confused:

Why is it necessary to enforce that the transaction creator must be the sUDT issuer?

What might happen if other people are allowed to create the info cell?

If anyone can generate info_cell for a specific sUDT, then I can generate an info_cell for USDC sUDT and name it ETH. This will lead to a very confusing situation. You can’t determine which info_cell is correct, and info_cell will It becomes meaningless.

  1. For a single owner, because the owner is fully responsible for this sUDT, if he wants to create multiple info_cells, the consequences are also borne by him. When parsing Info_cell, we can simply choose the one with the earliest block height.
  2. Setting info_cell to be variable is to take into account that UDT may be renamed and split, although this is a special case.
  3. Compact UDT should be directly supported because it is an extension of sUDT. As for xUDT, a new design needs to be added.

I think the ease of operation should match its nature: is the operation “light” that we agree the issuer should feel free to do, or it’s “heavy” that the issuer should only take at 100% discretion? A well accepted token name is the result of social consensus, and changing it has consequences not only to the issuer but to 3rd parties in the ecosystem.

Ideally, the token rename operation should be governed by its community. If it’s too much for a simple/initial spec I’d rather not make it a cheap operation that the issuer can make any time with barely no cost.

This spec should be compatible with xUDT: it needs some wording. Currently I can’t find any conflict with xUDT.

But in implementation, it should be mentioned to support xUDT. For example, length of args and cell data is greater than sUDT.

Then we can set info_cell to be unchangeable. For Single Owner UDT, only the first info_cell is recognized as the standard to meet the requirements.

I think the lockscript of info_cell can be set to dead lock by default, but if the issuer thinks that the changeability of info_cell is important, they can also use other lockscript themselves, and this information can be known by the udt holder.

@orange-xc thanks for putting this together. If there’s no further feedback by the end of this week I think we can turn this spec into a RFC proposal on standards track and begin adding support in tools/dapps.

Hey @orange-xc, congratulations on this spec ideation!! :hugs:

If you are so gentle to entertain my curiosity, I was wondering a couple of details:

In the case of a Script-driven UDT whose owner script is referenced by data, is there any way to adopt this standard?

Ideally I’d like to adopt this standard for iCKB xUDT, but iCKB Logic (the owner type of iCKB xUDT) is referenced by data1, so I don’t really see a way to achieve this :thinking:

Is there any publicly available implementation?

I’m aware of a couple projects that adopted this standard for token metadata, but I was not able to find a public reference implementation.

Love & Peace, Phroi

This standard is not recommended now, as no wallet or explorer support it, use utxostack/unique-cell: Unique cell on CKB instead.

1 Like