在 CKB 上如何用最簡單的方法構造驗證交易

買賣虛擬貨幣
你知道如何在 CKB 上構建驗證交易嗎?今天,CKB 開發者 luochao 就來和大家聊一聊如何用最常見最簡單的方式在 CKB 上構建驗證交易,快來檢視吧。1. Cell Collet在 CKB,任何交易必須包含至少一條 input 和一條 output。為了構造交易,首先需要定位 input,我們將其稱為「cell collect」。我們知道 CKB 與 UTXO 模型非常類似,這意味著如果沒有任何預快取,就無法得知任何地址的當前狀態。組成當前狀態的資訊可能分散在鏈上不同的 cell 中。可參考 Cell model 瞭解 CKB 的資料模型。有兩種方法可進行 cell collect:a.使用 ckb indexer 服務這裡介紹一種標識指定地址的資訊(如 live_cell 數量、交易數量、總容量)的簡單方法,而不需要任何其他操作。請注意,由於基於 CKB 節點的 indexer 函式,此方法只適用於基礎用法。另外此方法也不支援查詢更詳細的資訊(例如,無法定位合約 cell),而且還將消耗 CKB 節點本身的資源。
不過拋開這些缺點,讓我們從這個方法開始,以更好地理解單元收集是如何工作的。CKB 節點中預設關閉此功能。要開啟它,請按如下所示手動更改配置檔案並重新啟動 CKB 節點:在 mckb.toml 中更改以下配置:[rpc]...# List of API modules: ["Net", "Pool", "Miner", "Chain", "Stats", "Subscription", "Indexer", "Experiment"]modules = ["Net", "Pool", "Miner", "Chain", "Stats", "Subscription", "Experiment"]
可看出 indexer 服務預設沒有啟動。要開啟該功能,請向陣列 modules 中新增「Indexer」。modules = ["Net", "Pool", "Miner", "Chain", "Stats", "Subscription", "Experiment", "Indexer"]使用 ckb run -C<path>  重啟 CKB 節點後,透過 RPC 方法 index_lock_hash 註冊需索引的地址。請注意:index_from 引數控制索引的起始點,null 值從 chain tip(當前塊)開始索引,而 0 值從 genesis 塊開始索引。現在,等待重新構建 index 服務,然後使用 index 服務的 RPC 介面來檢視相應地址的 live_cell/transaction/capacity 值。如果不再需要 index 服務,可以透過 RPC 登出監視列表,關閉服務,並從 ckb.toml 中的陣列中刪除「Indexer」。b.建立你自己的 Cell 收集服務
建立你自己的 Cell 收集服務有什麼好處?我們都知道,交易包括建立和銷燬任意數量的 cell,這是交易的最簡單定義。由於 cell 使用的靈活性,任何有意義的資料都可以儲存在 cell 的 data 欄位中,各種型別的合約都可以用 type script 表示。因此,每個使用者或用例可能對 cell 收集有不同的需求。實際上有許多問題有待探索,每個問題根據不同的用例都可能有不同的答案:· cell 收集的順序是什麼?先進先出,按大小順序,最佳模型等等· 可以使用哪種 cell?特定的幸運數字或任意的· 是否有任何 cell data 或 type 需要特殊處理?
· 選擇 cell 後是否需要過濾/確認?CKB 包含的 index 服務不能很好地滿足這些需求,並且它不能靈活適配未來可能增加的額外需求。最有效的方法是自己構建 cell 收集功能。如何做?當一個新的區塊上鍊時,區塊中作為 input 的 cell 必須從 live cell 集中移除,而區塊中的 output 必須新增到 live cell 集中。由於在 PoW 區塊鏈中經常發生短分叉,當分叉使以前接收的區塊無效時,必須回滾該塊的 input 和 output 以更改。快取設計可有助於加速同步,例如,快取鏈中的最後 N 個塊並刪除這些塊中使用的 live cell。2. 構造交易現在我們可以開始構建交易了。開始之前你需要了解一些背景知識,包括構建witness,交易費的計算和一些小技巧。
構造交易所有型別都基於 molecule(一個序列化系統)進行序列化,核心結構體是:table RawTransaction {  version:        Uint32,  cell_deps:      CellDepVec,  header_deps:    Byte32Vec,
  inputs:         CellInputVec,  outputs:        CellOutputVec,  outputs_data:   BytesVec,}table Transaction {  raw:            RawTransaction,
  witnesses:      BytesVec,}cell_deps 和 input 是一系列指向鏈上 live cell 的指標。不同之處在於,dep 是一個引用(只讀),在交易中使用 input。index 結構為:struct OutPoint {  tx_hash:        Byte32,  index:          Uint32,
}struct CellDep {  out_point:      OutPoint,  dep_type:       byte,}tx_hash 和 outputs_index 用於定位 cell。 dep 有一個額外的 dep_type 欄位,用於表示 cell 中的 data 是 code 還是 dep_group。(請注意,可以使用 dep_group 功能組合多個 cell 中的程式碼)
· 用 0 表示 code ,這意味著可以直接使用cell data· 用 1 表示 dep group,這意味著這個 cell 中的 data 是一個重定向欄位,需要解析 n 個 cell(此處不允許遞迴),dep group data 用 dVector OutPointVec <OutPoint> 列出所有需要的要點。例如:你可以檢視預設的 lock cell,並使用 dep group 功能將 secp256k1 庫分成兩個 cell 來儲存乘法表和程式碼。區塊大小是有限的,如果資料太大不能放入一個塊中,它可以儲存在單獨的 cell 中並在執行時一起載入。outputs 和 outputs_data 是兩個一對一的列表。output 中只有容量和 type/lock script。輸出資料放在與索引對應的 outputs_data 中。header_dep 是過去區塊頭雜湊的列表,這些區塊頭的頭資料可以透過 CKB scripts 訪問。既然已經解釋了交易的簡單結構,現在讓我們探索稍微複雜一點的結構:
scripttable Script {  code_hash:      Byte32,  hash_type:      byte,  args:           Bytes,}
code_hash 和 hash_type 用於指定 lock cell,args 是 lock script 所需的引數。hash_type 有兩個值:· 「data」用 0 表示,code_hash 意味著,lock cell的 data hash· 「type」用 1 表示,code_hash 意味著 lock cell 的 type script hash很容易將 hash_type 理解為 code,但是 type 有什麼用呢?CKB 的預設 lock 是按 type 索引的。這對合約開發者意味著什麼?你可以看到的第 0 個區塊的第二個輸出的 type script,這是一個 TypeID script,這意味著,如果您釋出的庫也繫結這個 typeid script,它將生成一個唯一的 id(code hash)用於索引資料,你可以持續更新這個庫的內容而不改變typeid。引用庫的合約不會因庫更改而無效。這是更新鏈上庫的解決方案。witness
現在,所有 RawTransacion 欄位已經設定完成,來看 witness 欄位。這個欄位是為了確保交易不能篡改其他交易,並且這個欄位還允許包含一些合約可能需要的臨時變數。它由一系列的 witness 組成:table WitnessArgs {  lock:                   BytesOpt,          // Lock args  input_type:             BytesOpt,          // Type args for input  output_type:            BytesOpt,          // Type args for output}
最初,input 需要一個 witness 來驗證,但這是低效的,所以當 VM 驗證交易時,使用 script group,將交易指令碼中一致的 input/output  cell 合併到一個 script group 中,並且只執行一次驗證。script group 的優點是提高了驗證速度,減少了驗證的消耗,減小了 witness 的大小。相應的缺點是生成 witness 的規則要複雜得多。witness 是所有東西的簽名:包括 tx_hash、長度和 witness 值、input_group中其他定位的 witness的長度和值。當 witness 尚未生成時,如何簽名 witness?ckb lock 的方案是設定所有 0 的簽名進行簽名,然後覆蓋witness。因為簽名訊息的長度只能是 65 個字元,所以我們首先對要簽名的內容進行 blake2b-hash,然後對 hash 進行簽名。具體的簽名過程和關於如何安排不同指令碼組的見證的約定可參考:如何對交易簽名 url.cn/5yfunBR
樣式和交易費透過以上過程,我們得到了一個完整的交易結構。此時,如果需要接受最低費用的交易,我們需要對現有的交易做一些迴歸測試和修改。如何估算交易費?交易費是序列化交易(molecule)的大小和執行的指令的消耗的總和。預設的大小單位是 1,000 shannons / KB(千位元組)。(Shannon 是 1/100,000,000 CKByte)然而,礦工可以修改這個預設單元。如果需要檢視實時事務費用估計,可以使用 hestimate_fee_rate 透過 RPC 進行檢視。如果需要花費最低的費用,可以不斷地調整 input capacity 和 output capacity之間的差異,然後使用二分查詢方法重新生成交易,直到滿意為止。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;