RFC:可擴展的 UDT(Extensible UDT)

可擴展的 UDT(Extensible UDT,本文統一稱爲 xUDT)是基於 Simple UDT 的擴展,可用於定義更多 UDT 可能須要的行爲。sUDT 爲在 Nervos CKB 上發行 UDT 提供了一個最基本的核心,xUDT 則能夠創建在 sUDT 的基礎上,知足更多的潛在需求,例如監管。git

數據結構

xUDT Cell

xUDT cell 向後兼容於 sUDT,全部 sUDT 規範中定義的既存規則仍然適用於 xUDT cell。在 sUDT 的基礎上,xUDT 擴展的 cell 以下:github

data:
    <amount: uint128> <xudt data>
type:
    code_hash: extensible_udt type script
    args: <owner lock script hash> <xudt args>
lock:
    <user_defined>

這個被加上去的 xudt args 和 xudt data 部分提供了全部 xUDT 所需的新功能,咱們將會在下文闡述這些細節的架構。數據結構

xUDT Args

xUDT args 的架構以下:架構

  • 4 個字節的 xUDT 標記
  • 可變長度擴展數據

依賴於 flags 的內容,可能會附加不一樣的擴展數據:函數

  • 若是 flags 所有爲 0,咱們不須要任何擴展數據。值得注意的是,向後兼容的查看方式是,一個空白的 sUDT cell 也等於有一個所有爲 0 的隱藏 flags 字段。
  • 若是 flags 是 0x1,那麼擴展數據將包含一個以 ScriptVec 結構進行序列化的 molecule (https://github.com/nervosnetw...
table Script {
    code_hash:      Byte32,
    hash_type:      byte,
    args:           Bytes,
}

vector ScriptVec <Script>;

ScriptVec 結構中包含的每一個條目,都被解釋爲具備附加行爲的擴展腳本的 CKB 腳本哈希。當一個 xUDT 腳本被執行時,它將運行這裏所包含的每一個擴展腳本。只有當全部擴展腳本都經過驗證時,xUDT 纔會認爲該驗證是成功的。區塊鏈

一個擴展的腳本能夠被下列的任一種方式加載:ui

  • 有些擴展的邏輯可能已經有預約義的哈希,例如,咱們可使用 0x0000 ... 0001 來表示監管的擴展。這些腳本的實際代碼已經被鑲嵌在 xUDT 自身的腳本中了。
  • Owner lock (全部者的鎖)可拿來使用:若是當前交易中的一個 input cell 使用了與當前擴展腳本相同腳本哈希的 lock script,咱們能夠認爲該擴展腳本已經被驗證。
  • 若是一個擴展腳本不匹配任何上述標準,xUDT 將使用包含在擴展腳本中的 code_hash 和 hash_type 以調用 ckb_dlopen2(https://github.com/nervosnetw... 的功能,從當前交易的 cell deps 中加載動態連接的腳本。若是腳本能夠成功定位,xUDT 將尋找一個帶有如下簽名的導出函數:
int validate(int is_owner_mode, size_t extension_index, const uint8_t* args, size_t args_length);

is_owner_mode 表示當前 xUDT 是否經過全部者模式解鎖(如 sUDT 所述),extension_index 指的是當前的擴展在 ScriptVec 結構中的索引。args 和 args_length 被設置爲當前擴展腳本的 Script 結構中所包含的 script args。spa

若是該函數返回 0,則認爲對當前擴展腳本的驗證是成功的。code

  • 若是 flags 是 0x2,擴展數據將包含前一節解釋的 ScriptVec 結構的 blake160 哈希。實際的 ScriptVec 結構數據將包含在當前交易中的 witness 中。咱們將在下面解釋這一部分。

xUDT Data

xUDT 數據是一個以 XUDTData 結構來進行序列化的模組:索引

vector Bytes <byte>;
vector BytesVec <Bytes>;

table XUDTData {
  lock: Bytes;
  data: BytesVec;
}

包含在 XUDTData 中的 data 字段,必須與包含在 xUDT args 中的 ScriptVec 結構的長度相同。一些擴展可能須要在每一個 xUDT cell 中存儲特定於用戶的數據。xUDT 數據爲此類數據提供了一個放置的位子。

XUDTData 中包含的 lock 字段不會被 xUDT 腳本使用,它被保留用於當前 cell 的鎖定腳本特定數據。

擴展腳本首先須要找到它定位在 xUDT args 中的索引,而後在 XUDTData 結構的 data 字段的同一個索引處,查找當前擴展腳本的數據。

操做

xUDT 採用與 sUDT 相同的治理操做:全部者鎖控制全部治理行爲,如代幣鑄造等。

然而,xUDT 的正常調用操做不一樣於 sUDT。根據所用的 flags,可能會有兩種使用模式:

原始擴展腳本

當 flags 設置爲 0x1 時,原始擴展數據將直接包含在 xUDT args 中。

Inputs:
    <vec> xUDT_Cell
        Data:
            <amount: uint128> <xudt data>
        Type:
            code_hash: extensible_udt type script
            args: <owner lock script hash> <xudt args>
        Lock:
            <user defined>
    <...>
Outputs:
    <vec> xUDT_Cell
        Data:
            <amount: uint128> <xudt data>
        Type:
            code_hash: extensible_udt type script
            args: <owner lock script hash> <xudt args>
        Lock:
            <user defined>
    <...>
Witnesses:
    WitnessArgs structure:
      Lock: <user defined>
      Input Type: <BytesVec structure>

與第一個輸入 xUDT cell 相同的索引的 witness 是由 xUDT 腳本定位的。它首先被解析爲 WitnessArgs 結構,所以 WitnessArgs 的 input_type 字段被視爲 BytesVec 結構。這個結構也必須與 xUDT args 和 xUDT data 部分的長度相同。擴展腳本可能還須要特定交易的數據,以便進行驗證。Witness 在此爲這種數據需求提供了一個放置的位置。

注意,每一個擴展腳本在交易中只執行一次。擴展腳本負責檢查當前類型的全部 xUDT cell,確保當前擴展腳本的每一個 cell 數據和 witness 均可以根據擴展腳本的規則進行驗證。

P2SH Style Extension Script

當 flags 設置爲 0x2 時,xUDT args 只包含擴展數據的 blake160 哈希。用戶會被要求直接提供在 Witness 中的擴展數據:

Inputs:
    <vec> xUDT_Cell
        Data:
            <amount: uint128> <xudt data>
        Type:
            code_hash: extensible_udt type script
            args: <owner lock script hash> <xudt args>
        Lock:
            <user defined>
    <...>
Outputs:
    <vec> xUDT_Cell
        Data:
            <amount: uint128> <xudt data>
        Type:
            code_hash: extensible_udt type script
            args: <owner lock script hash> <xudt args>
        Lock:
            <user defined>
    <...>
Witnesses:
    WitnessArgs structure:
      Lock: <user defined>
      Input Type: <Raw Extension Data> <BytesVec structure>

這裏惟一的區別是,在相應的 WitnessArgs 結構中的 input_type 字段包含在 ScriptVec 數據結構中的原始擴展數據,xUDT 腳本必須首先驗證這裏提供的原始擴展數據的哈希,是否與 xUDT args 中包含的 blake160 哈希相同。在此以後,它將使用與前面工做流中相同的邏輯。

區塊鏈抽象和互操做性 2.0_1.gif

相關文章
相關標籤/搜索