區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

前段時間,Gavin Wood要求我研究基於Substrate實施UTXO鏈的可能性,Substrate是目前最有前景的區塊鏈技術底層架構,而且目前Polkadot是基於substrate進行開發的。

我們想知道Substrate的靈活性,而UTXO鏈似乎是進行測試的一個不錯的選擇,因為它與我們過去在實施Substrate時所考慮的完全不同。如果可行,則表明Substrate確實非常靈活且通用。我們可以更有信心,把Substrate應該到不同領域的區塊鏈項目中。

與以太坊類似,Substrate保留一定數量的可用資金。從某種意義上講,它類似於普通的銀行系統,其中帳戶餘額用數字表示,並存儲在數據庫或計算機內存中的某個位置。

從歷史上看,第一個成功的加密貨幣是比特幣,它使用完全不同的方法。在比特幣中,本身沒有賬戶,餘額也不是作為一個數字存儲的。取而代之的是,可用資金是根據一組所謂的未用交易輸出來定義的,簡稱為UTXO,這是一個非常簡單的主意。

簡而言之是UTXO

簡而言之,UTXO非常類似於現金,或者更確切地說,是旅行支票。

當你用現金支付某人時,你通常會想到要支付的總價值,但是你用一組獨特的、不可分割的單位(代幣或鈔票)來表示這個價值。例如如果Alice希望付給Bob$250美元,她可以給Bob2張價值$100美元的鈔票和1張價值50美元的鈔票,或五張面值$50的鈔票,或總計為所需值的任何其他組合。

每一張鈔票都是獨一無二的。儘管有數百萬張鈔票具有相同的價值,但是每張鈔票在物理上都是唯一的,並在其表面印有序列號。通常情況下,我們不太注意它,只是在支付東西的時候,把兩張100美元的鈔票視為相等,但這個數字對於銀行控制資金流動和真偽檢查是必不可少的。

因此每張鈔票代表著具有預定和固定價值的獨特且不可分割的資產,這些資產只能整體使用,即您不能將100美元的鈔票撕成兩張50美元的鈔票。當然你可以要求某人找零,將價值分成較小的單位,但是您仍然需要花100美元的原始鈔票。同樣,購買咖啡時,您會花掉10美元的鈔票,作為回報,您會得到咖啡和一些零錢。

UTXO的工作方式與此類似。要使用比特幣付款,您的錢包中應該已經有一些未使用的資產。與法定貨幣一樣,您可以結合使用多個UTXO以獲得更大的價值。

與現金不同,每個UTXO都有自己的所有者。從這個意義上說,它類似於旅行支票,因為只有支票所有人才可以使用它。這是通過所有者簽名增加單位來完成的。不同之處在於,旅行支票由所有者的手簽名,而UTXO使用非對稱加密,並且包含收件人而非發件人的公鑰。而是鈔票由政府印刷,UTXO由發起人創建。

目標

在我們的研究中,我們將嘗試建立一個區塊鏈模型,使用與比特幣相同的原理將資金從一個所有者轉移到另一個所有者。

當閱讀文章時,請記住我們的主要目標是評估Substrate的靈活性,而不是比特幣移植時使用端口的詳細解釋。在某些情況下,其實現幾乎與Parity比特幣的實現相同,而在其他情況下則不是。例如當前的實現不支持挖掘和coinbase事務;它只是重新分配在genesis塊中初始化的“預先定義”UTXO集的值。

另外,請注意,所提供的實現還不能完全投入生產。它尚未經過正式驗證,並且可能存在一些安全性或穩定性問題,因此,我不建議您在沒有適當研究的情況下,將其用於任何關鍵基礎架構。但是如果有人將這個原型製作成可行的解決方案,我會非常高興。

話雖如此,讓我們繼續進行代碼。

首先讓我們談談Substrate如何允許您對其進行自定義。作為應用程序員,您應該提供一個runtime的運行邏輯,這些邏輯告訴Substrate如何處理鏈以及應採用的業務邏輯。所有這些都圍繞著狀態轉換函數(簡稱STF)的概念。但現在我們只需說,每個區塊鏈都可以表示為一個函數,接受當前狀態和一個掛起的事務,然後生成另一個狀態,反映在應用事務後所做的更改。

假設Alice和Bob都有10個代幣,然後Alice向Bob發送了5個代幣。應用此交易後,我們預計Alice現在將有5個代幣,而Bob將有15個代幣。如果Bob隨後嘗試向Claire支付20個代幣,則該交易必須視為無效,因為根據最新的鏈條狀態,Bob只有15個代幣。

這正是runtime的意圖-它定義了所有實體及其關係,驗證了傳入的事務並相應地更改了狀態。

讓我們從指定將用於定義UTXO鏈的業務邏輯的數據類型開始。首先是Transaction 類型。它表示要調度的單個UTXO事務:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

這裡沒有什麼特別的,只是一個簡單的定義,即Transaction只是一堆輸入和輸出。如果您好奇,可以將其與Parity Bitcoin的版本進行比較,以瞭解相似之處。上面所有#[...]怪異都稱為屬性,它告訴Rust編譯器為我們實現各種操作,例如比較運算符,哈希函數和序列化例程。您現在可以放心地忽略它們。

我留下了所有註釋和屬性,以表明即使將它們包括在內,代碼仍會保持緊湊。我認為,即使與在成千上萬行中做“同一件事”的Parity Bitcoin相比,這也是Substrate的可觀成就。就像在用JavaScript為網絡編寫代碼時一樣,您並沒有考慮過瀏覽器引擎或任何底層操作系統(包括操作系統)的複雜性。相反,您只是以高級形式制定業務邏輯,然後讓系統完成其餘工作。

好的,但是TransactionInput呢?

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

TransactionInput彙總花費一個UTXO所需的所有數據。首先我們需要一種方法來引用一些現有的UTXO。最簡單的方法是使用其哈希作為標識符。這是分佈式系統世界中的一種普遍做法,並且只要哈希衝突的可能性可以忽略不計,它就可以很好地工作。為此我們使用256位Blake2。parent_output字段包含此類哈希。

如前所述,要使用UTXO,所有者必須使用與存儲在該特定UTXO中的公鑰匹配的秘密密鑰對其進行簽名。只要知道密鑰的唯一人是所有者,這就是安全的。這種證明存儲在簽名字段中。

我們的實現與比特幣之間的區別在於,我們直接通過其哈希值引用parent_output,而比特幣則使用產生了UTXO的交易的哈希值以及一個索引來從交易輸出列表中選擇特定條目。原因是比特幣是根據交易和區塊定義的,而我們是根據業務邏輯和狀態轉換來定義的。在我們的例子中,Substrate事務只是輔助實體,它們促進了流程,並且大部分都超出了業務邏輯的範圍。稍後再談。

接下來是定義UTXO的TransactionOutput結構:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

value和pubkey字段的用途應該已經清楚。唯一值得解釋的是salt。此字段提供了額外的熵,以使每個UTXO及其哈希真正唯一。想象一下這樣的情況,我們有一個機器人每天向同一個收件人發送10個代幣。為了簡單起見,它可以使用相同的目的地地址,即接收者的公鑰。因為value和pubkey字段都包含相同的數據,所以bot創建的所有UTXO看起來都完全相同,因此具有相同的散列。

沒有salt,攻擊者將能夠記住所有者所用的第一個UTXO的簽名,然後在所有者甚至沒有注意到之前就花費所有後續的UTXO來竊取金錢,這稱為重放攻擊。同樣還有另一種在源代碼中尚未解決的重放攻擊的可能性。

請注意,由於比特幣實現依賴於交易哈希來精確定位UTXO,因此它不會遭受此問題的困擾,因此不需要salt。然而,這並不意味著比特幣不可能進行重放攻擊。這就是為什麼為每一筆交易生成一個新的比特幣地址是至關重要的。

狀態

到目前為止,我們已經定義了表示內存中單個事務所需的所有數據結構。但是我們還需要告訴Substrate通過在一段時間內保留此信息,在狀態數據庫中存儲什麼以支持鏈的業務邏輯。

這是通過使用decl_storage定義模塊存儲來完成的!marco:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

上面的代碼實際上它僅定義了三件事:未使用的輸出列表,當前剩餘值量以及已鎖定且除非解鎖就無法使用的輸出列表。除此之外,它還定義了在引導過程中如何使用一組初始的UTXO填充鏈。

需要要注意的是,狀態存儲與區塊存儲有很大不同。

區塊存儲是每個區塊鏈節點的重要組成部分,用於存儲該鏈中的區塊。如今只有專用的存檔節點將整個鏈存儲在本地,而普通節點僅管理最近區塊的臨時子集。

另一方面,狀態存儲與業務邏輯有關。它包含反映業務實體及其關係的當前狀態所需的所有數據。為了驗證傳入交易,您唯一需要知道的是所有受影響方的狀態及其資金額。這就是為什麼即使是輕度客戶也能夠驗證交易的原因。

設計邏輯

當我們說Alice從Bob那裡得到一些資金時,我們的意思是根據規則,Bob用來支付Alice的一組UTXO必須標記為已用(以防止Bob以後重複使用)。然後Bob為Alice創建的一組新UTXO現在必須被記住是有效的,這樣Alice就可以在之後使用它們了。

這些規則是業務邏輯的本質,在驗證和調度傳入事務時需要考慮這些規則。

讓我們看一下整個UTXO模塊的入口點:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

我們定義了兩個函數:execute和on_finalize

execute函數是整個UTXO邏輯的關鍵。它接受單個事務,對其進行檢查,如果有效,則通過更新存儲應用該事務。最後它存儲一個事件,表示一個事務剛剛被處理。

當剛剛形成一個充滿交易的單個塊時,將調用on_finalize事件處理程序。通過觸發該事件處理程序,Substrate允許運行時根據需要採取一些措施。我們使用此處理程序從參與創建此塊的驗證程序之間的所有事務中重新分配合並的剩餘價值,作為對其工作的獎勵。

交易檢查

為了驗證傳入事務,我們需要確保以下內容:

  1. 輸入和輸出不為空。
  2. 所有輸入與現有的、未使用的和未鎖定的輸出匹配。
  3. 每個輸入只使用一次。
  4. 每個輸出只定義一次,並且有一個非零值。
  5. 總產值不得超過總產值。
  6. 新的輸出不能與現有的衝突。
  7. 輸入和輸出值之和不能溢出。
  8. 提供的簽名有效。

違反任何一項檢查都可能導致連鎖安全性問題,因此正確實施它們至關重要。幸運的是,邏輯非常簡單明瞭:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

您可能注意到,除了事務檢查之外,此函數還收集一些信息。讓我們看看它的定義:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

稍後將顯示,我們使用總的 inputs和outputs來計算交易的優先級,並將剩餘價值的一部分作為塊式獎勵在驗證者之間重新分配。

但是如果交易未通過驗證,談論這些價值絕對沒有任何意義。否則攻擊者將能夠通過淹沒交易池並阻止正常交易被派發,從而故意製作具有最高優先級的交易並對鏈進行DoS。或者,它可能會“憑空產生”大量剩餘價值以利用獎勵系統。

通過將數據組織為Rust枚舉,可以防止意外誤用,因為只有在交易有效時值才可用。反之亦然,只有在發現事務引用狀態數據庫中不存在的某個UTXO時,才可以使用缺少輸入的列表。這樣一來,就不會濫用API,這有利於提高可讀性和鏈安全性。

狀態更新

如果交易經過驗證並證明是正確的,那麼我們要做的就是更改鏈狀態以反映該交易所做的更改:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

基本上,我們刪除所有現在認為已用完的輸入,並添加所有新輸出以將其標記為可用。我們還將剩餘的值累積在臨時存儲變量LeftoverTotal中,該變量將在區塊確定期間使用。

區塊獎勵

區塊完成後,就該獎勵創作該區塊的節點了。這是通過重新分配從此區塊中包括的所有事務中收集的剩餘價值來完成的:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

邏輯非常簡單:我們接受一個權限列表,然後將剩餘的總值除以權限數平均得出一個share_value。然後,我們為每個作者創建一個UTXO,並將其插入UnspentOutputs中。我們將當前區塊號用作salt值,以防止上述潛在的重放攻擊。

我們還通過將獎勵UTXO插入UnspentOutputs來進行檢查,以確保我們不會意外覆蓋一些恰好具有相同哈希值的現有UTXO。這種情況在實踐中極為罕見,但是不幸的是,如果有人因為常規獎勵UTXO覆蓋了他或她的UTXO而損失了數百萬美元的UTXO,那將是不幸的。

乍一看,我們似乎是憑空創造價值,但仔細想想,人們可能會意識到,全局價值不會增加,因為交易所有者明確放棄了部分資金,以換取優先權。

最後,由於每個區塊發起人都知道所有詳細信息,例如區塊編號,該特定時代使用的會話密鑰,當然還有與該會話密鑰匹配的秘密密鑰,因此區塊發起人將始終能夠重構UTXO,計算其哈希值,即使沒有將UTXO存儲在任何地方也可以要求其獎勵。

UTXO鎖定

這就是與比特幣不同的地方。

據我所知,比特幣規範並沒有規定哪些信息需要存儲在磁盤上以及如何存儲。唯一重要的是比特幣協議本身,它是根據交易和區塊來制定的。因此,每個節點必須建立自己的理解,在區塊鏈歷史的任何給定點上,哪些UTXO是有效的。

相反,根據定義,我們的UTXO實現具有所有參與節點都同意的全局狀態數據庫。眾所周知,它用於存儲UTXO狀態和剩餘的臨時值。由於狀態數據庫是共識的一部分,因此我們可以在業務邏輯中依賴狀態數據庫的內容,並確保所有其他節點都將這樣做。

但沒有什麼能阻止我們儲存額外的東西。例如我們可以將現有UTXO的哈希映射映射到定義該UTXO的鎖定狀態的結構。如果UTXO被鎖定,則不允許以通常的方式使用它:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

很像鎖在保險箱裡的現金:你可以最終使用它,但不早於你打開保險箱的時候。它是可用的,只是鎖上了。

你可能在想,為什麼一個人會需要這個?您會發現,在加密貨幣的世界中,有一種趨勢是用貪婪程度更低,更有效的方法來代替舊的廢物證明算法(proof-of-waste)。一種可能是將資金本身用作保證同peer行為正常的保證。

基本上,有人會說:“我發誓要遵守規則。這是我的錢。請把它鎖在安全的地方。如果有人證明我的行為不當,那麼我的錢就必須削減或在誠實的參與者之間分配。”當然,如果這樣的人隨後希望取回他或她的資金,則網絡將檢查是否沒有惡意行為。在最後期限內提取,然後解鎖資金。通常,鎖定的資金越多,您獲得的能力,投票權重或收入就越多。此類系統通常簡稱為權益證明或PoS。

只要網絡中三分之二以上的節點沒有惡意,並且按照協議操作,這就可以正常工作。除了執行常規任務外,這些節點還將支持PoS。

在類似以太坊的區塊鏈中,在調度交易時,對可用資金的推論可能非常複雜:每個節點必須確保有足夠的可用資金,尤其是因為可能存在與時間相關的複雜合約。

有趣的是,我們的UTXO實現以幾行代碼來完成。與以太坊式的鏈相反,類比特幣的鏈的資金已經以自然的方式分配。我們可以輕鬆地鎖定單個UTXO,並在滿足某些解鎖條件之前防止其被花費。

由於狀態數據庫不是其原始規範的一部分,因此在比特幣中很難做到這一點。因此,很難在任何給定的時間點推斷哪個UTXO被鎖定,更不用說客戶端兼容性問題了。

交易排序

在談到鏈的業務邏輯時,我們提到Substrate為我們完成了所有骯髒的工作,例如處理塊存儲,執行網絡交互和進行共識投票。但這並非總是如此。我們已經說過,我們的runtime原子性一次調度一個事務。因此如果該交易有效,則狀態將相應更改。

但是如果兩個從屬事務在短時間內到達同一節點會發生什麼呢?真實的網絡是複雜且不可預測的。連接性問題和突然的拓撲更改可能會對傳輸的數據造成各種影響。值得注意的是,消息可能會丟失,延遲或重新排序。後一個事實對我們尤為重要。

想象一個情況,我們有兩個事務,A和B,B依賴於A。在UTXO的情況下,這意味著B消耗了A創建的UTXO。如果B在A之前到達,我們可能會遇到這樣的情況節點運行時將無法檢查事務的有效性,因為它引用了看似不存在的UTXO。當然,我們確實知道它存在,但尚未交付,但是節點不知道。本質上,它有兩個選擇:

  1. 只需將交易B視為無效即可。如果原始發送人重新廣播該交易,它仍將有機會被應用,但不會早於A被調度。此解決方案可能有效,但它是骯髒且無效的。此外,一些嚴重的網絡問題可能導致無法分配B的情況,從而使整個系統無用。我們可以做得更好。
  2. 將事務B的分派推遲到有意義的時候。在我們的情況下,我們需要以某種方式等待A的發送。

第二種選擇似乎更有趣,但是在實踐中我們該如何做呢?通過其本身的設計,Substrate對運行時內部或鏈的業務邏輯一無所知。實際上,從其角度來看,Substrate就像不透明的字節數組一樣“看到”我們的交易。

這裡的解決方案是“解釋” Substrate如何處理我們的交易以及如何正確排序它們。這是通過使用事務池向運行時公開的專用TaggedTransactionQueue API完成的。

在Substrate中,每個事務都與兩組標籤相關聯:require和Provides。標籤只是代表某個唯一值的任意字節向量。第一組描述此事務需要哪些標籤,而第二組定義此事務提供的標籤。

在上述情況下,我們需要通過聲明A提供一些標籤而B消耗與其要求相同的標籤來將事務A和B鏈接在一起。為了簡單起見,我們可以使用UTXO哈希作為標籤。

通過遍歷事務並查詢其標記,事務池以一種順序組織它們,以使每個事務都可以滿足其要求。那些熟悉計算機科學的人可能會意識到這類似於拓撲順序。

有時兩個事務不相互依賴,但又依賴於第三次事務。例如我們可能有交易A產生兩個輸出,交易B和C分別花費這兩個輸出。這將導致B和C都依賴於A。拓撲排序狀態規定必須在B和C之前調度A,但是未定義分發B和C的順序。在這種情況下,事務池使用其他條件來確定事務的優先級。

經典解決方案是將剩餘值的數量用作優先級。交易所有者有意留給當局的資金越多,交易優先級就越高,雙贏。

讓我們看看它如何在我們的鏈中實現:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

TaggedTransactionQueue API處理所有傳入的外部消息,而不僅僅是我們的自定義UTXO事務。這為runtime提供了對外部驗證過程的細粒度控制。例如runtime可能會執行其他檢查,分配自定義優先級或簡單地丟棄不需要的外部組件。

完成後,validate_transaction函數將產生TransactionValidity結構,該結構包含對事務池進行排序和優先考慮外部事務的提示:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

為了實現我們的邏輯,我們只需要選擇與UTXO交易相對應的外部性。這是通過對模塊名稱為utxo :: Module <runtime>參數化的IsSubType :: is_aux_sub_type(&tx.function)函數的“魔術”調用來完成的。成功完成後,此函數將返回一個類型,該類型包含對我們的execute方法的反序列化調用以及一個Transaction實例-我們需要就事務標記和優先級進行推理的所有內容。/<runtime>

剩下的只是根據check_transaction結果分配標籤和優先級的邏輯:

1. 如果交易經過了充分驗證,即在存儲中找到了所有傳入的UTXO,並且所有簽名均被證明是正確的,那麼我們僅填充提供標籤,而將要求列表保留為空。通過這種方式,我們告訴事務池該事務不依賴任何內容,並且可以立即分派,優先級的計算方式是其輸入值與輸出值之差。2. 如果交易經過驗證,但是缺少一些輸入,那麼我們將填充需求並提供列表,從而允許交易池對交易進行排序。稍後交易池將在滿足需求時再次致電我們以重新驗證交易。3. 如果驗證失敗(例如如果其中一個簽名恰巧是無效的),那麼我們將通過返回TransactionValidity :: Invalid來中止事務調度。事務池將丟棄外部變量,並記住我們的決定,以便所有可能從其他對等方收到的後續副本也將被丟棄。

注意:當前的實現將最大值分配給longevity 字段。這樣事務池將無限期地將未決事務保存在其隊列中。對於概念驗證的實現這是可以的,但是正確的解決方案必須分配一些更聰明的東西。

例如我們可能要等待幾個區塊週期才能滿足交易要求。如果在所有時間之後仍未調度交易,則我們將其視為格式錯誤且無效的交易,並照常丟棄。

如果沒有這種超時,惡意人員可能會利用依賴於隨機不存在的輸入的交易來充斥我們的節點。由於我們沒有明智的方式儘早丟棄此類事務,因此可以通過在事務池中填充垃圾來有效地對節點進行DoS處理。

實操

本文已經過長,無法涵蓋與初始鏈配置和引導過程有關的所有內容。

所以讓我們看看,如果我們嘗試執行我們的鏈會發生什麼。

如果願意,您可以嘗試自己實現UTXO鏈。基於我的原型實現,Nicole Zhu和Amar Singh一起準備了一個UTXO研討會資料庫,您可以在其中找到所需的一切,從代碼存根到詳細的說明。https://github.com/substrate-developer-hub/utxo-workshop

首先,我們需要使用UTXO運行時來構建Substrate節點。我假設您已經熟悉Rust生態系統並且知道如何構建東西。

接下來,我們需要配置UI以連接到local node而不是默認節點。我們還需要告訴UI如何讀入我們的自定義UTXO類型。這是通過提供一個JSON文件完成的,該文件具有從我們的自定義類型到UI已經熟悉的核心類型的映射:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

開發鏈已嵌入其創世塊。在我們的案例中,它包含唯一給Alice提供大量0xff ... f令牌的UTXO。

讓我們檢查一下Alice是否確實擁有這筆資金。為此我們需要計算UTXO的哈希值,恰好是0xf414d3…2393b2。如果鏈初始化正確,我們應該看到類似以下內容:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

現在,讓Alice花掉一部分價值,然後向Bob發送100個代幣。我們通過UI提交Inherent的外部變量來做到這一點:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

我們通過提供序列化的十六進制編碼版本來提交外部信息。準備就緒後,我們點擊“Submit Inherent”按鈕,並驗證它是否已被系統正確解析:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

注意交易內容。 我們看到該事務將0xf414d3…2393b2作為其parent_output並根據需要提及100個代幣。

如果一切順利,我們應該會在右上角看到彈出窗口,這些彈出窗口將通知我們有關交易進度的信息:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

最後,我們可以檢查該事務確實包含在該區塊中:

區塊鏈研究實驗室|基於Substrate實現比特幣UTXO支付模型

顯然它起作用了!

請注意,在我們的研究中,我們沒有談論如何找到對等點和進行網絡通信,如何編寫和存儲數據區塊,如何與其他對等點達成共識等。我們只是說了我們想要的業務邏輯 。其餘的工作由Substrate自動完成。

結論

在軟件工程的世界裡,庫和框架是有區別的。

庫是處理有限問題集的相當獨立的代碼,通常不足以單獨支持解決方案。作為開發人員,通常需要組合幾個庫並編寫自己的粘合代碼才能使工作正常進行。

另一方面,框架要複雜得多,並且通常涵蓋從頭到尾的軟件開發過程的所有方面。通過提供現成的解決方案並提出有效的設計模式,框架使您能夠以最少的時間投入來交付項目。

框架可以為您提供強大的功能,但是如果您的項目不再適合框架的理念,那麼框架可能會變得很繁重。您可以通過查看框架“規則彎曲”並執行似乎“超出範圍”的工作來測試框架設計的質量和靈活性。通常解決方案範圍越廣,匹配框架的“流程”就越難。

從這個意義上說,Substrate看起來非常有前途。正如我們在使用UTXO實施方案中看到的那樣,我們能夠使用Substrate來實現最初不是Substrate設計期望的解決方案。但是仍然可以實現無縫連接,這是一個好兆頭。


分享到:


相關文章: