作者:Ash Li, Noah Ho

隨著Ordinals協議的誕生,其為比特幣提供了編號和銘文的功能,從而拓寬了比特幣生態系統的產品範圍,並為比特幣生態帶來了新的活力。在本文中,我們將深入探討Ordinal協議的細節,包括如何對每個比特幣進行編號和追踪,以及銘文與編號之間的關係。但在深入探討這個主題之前,我們需要首先了解一些比特幣的基本背景,以幫助我們更好地理解後續內容。

完成本文的閱讀後,你將掌握比特幣的交易機制和支付模型,了解Ordinals如何為每個聰實現編號和追踪,以及銘文是如何創建和交易的。此外,你還將了解不同類型的錢包之間的差異。

一、比特币背景

比特幣採用了一個類似於現金的交易模型(cash system),其支付方式基於一種稱為UTXO的模型,這與傳統的基於賬戶餘額的模型有所不同。舉例而言:在銀行的賬戶記賬模型流程中,當A向B轉賬100元時,銀行會記錄三個步驟,這三個步驟構成了一個交易過程。第一步是從A的賬戶中扣除100元,這個步驟的記錄ID為tid1。第二步是將100元存入B的賬戶中,這個步驟的記錄ID為tid2。第三步是記錄一筆轉賬記錄,該記錄將tid1和tid2關聯起來,表示A賬戶減少100元,B賬戶增加100元。這樣,A和B之間的轉賬關係就被記錄下來,並且可以在未來查詢與追踪。現在,我們將通過對於UTXO和支付模型的介紹,講解比特幣的支付方式。

UTXO

在比特幣區塊鏈中,所有的餘額都是存儲在一個名為“未花費交易輸出”(Unspent Transaction Output, UTXO)的列表中。每個UTXO都包含一定數量的比特幣,以及這些比特幣的所有者信息,並標明是否可用。可以將其想像成一張署有持有人姓名的現金支票,只要持有人在上面簽名,就可以將使用權轉讓給他人。對於特定的地址,其所有的UTXO金額加起來即為該地址錢包的餘額。通過遍歷所有的UTXO,我們可以獲取每個地址的當前餘額。將所有的UTXO金額加總,則為當前全部流通的比特幣。

在比特幣的交易結構中,每筆交易都包括若干個輸入和輸出,其中每個輸入是對一個已有的UTXO的引用,而每個輸出則指定了新的資金接收地址及相應的金額。一旦一筆交易被發起,其輸入部分所引用的UTXO便會被暫時鎖定,以防止在交易完成前被重複使用。只有當這筆交易成功地被礦工打包到一個區塊(Block)並獲得網絡確認後,相關的UTXO狀態才會發生變化。具體來說,用於交易輸入的UTXO將從UTXO列表中移除,表示它們已經被消費,而交易的輸出則會生成新的UTXO,並添加到UTXO列表中。可以理解為,舊的現金支票被使用後失效,產生了新的現金支票,其所有權屬於新的持有人。

值得強調的是,每個UTXO只能在一筆交易中被使用一次。一旦它作為輸入被消費,它就會永久地從UTXO列表中移除。同時,新生成的輸出作為新的UTXO加入到列表中。 UTXO列表是不斷變化的,隨著每個新區塊的創建,它會相應地進行更新。並且,通過分析區塊鏈中的交易歷史,我們能夠重建在任何給定時間點的UTXO列表狀態。

此外,一筆交易的總輸入金額通常會略微超過其總輸出金額。這個差額,稱為交易費用(Transaction fee)或網絡費(Network fee),是作為激勵給予負責將交易打包到區塊的礦工的。網絡費的大小與交易的複雜性成正比,因此,一筆包含更多輸入和輸出的交易通常需要支付更高的網絡費。

現在,為了更加形像地理解比特幣的交易結構,我們將通過一個具體的示例進行深入分析。比特幣的交易結構如下,其中vin和vout這兩個變量分別代表著比特幣交易的 “輸入” 與 “輸出”。比特幣的交易並不像傳統的賬戶餘額模型記錄賬戶形的數據變化,而是通過輸入和輸出來表示。

const std::vector<CTxIn> vin;
const std::vector<CTxOut> vout;
const int32_t nVersion;
const uint32_t nLockTime;

来源:https://github.com/bitcoin/bitcoin/blob/v22.0/src/primitives/transaction.h#L270