3.1 比特幣的交易

讓我們先一起看一下比特幣的交易,比特幣交易的過程其實就是不停地創造區塊的過程,爲了理解上的方便,我們先看一個簡單模式的賬簿,在這個賬簿裏,每一筆交易依次被添加到賬簿裏。

那我們如何使用這個賬簿來創造一種貨幣呢?首先你可能想到(也是許多人誤認作比特幣使用的方式):建立一個 以賬戶爲核心的系統,可以創造新的幣並且放入某人的賬號,然後就可以轉給其他人了。一筆交易的信息就像這樣:「把愛麗絲賬戶裏17個幣轉給鮑勃」,然後由 愛麗絲簽名。我們從圖3.1可以看到,愛麗絲在第一筆交易裏收到25個幣,然後轉了17個幣給鮑勃,她的賬戶裏應該還有8個幣。

image.png

圖3.1 基於賬戶的賬簿

這麼做的不便之處在於,任何人如果想要確認一筆交易是否真實,就必須跟蹤每一個賬戶的餘額。讓我們再看一 下圖3.1,當愛麗絲想要轉給戴維15個幣的時候她是否真的有15個幣呢?爲了搞清楚這個問題,我們必須回過頭去看和愛麗絲有關的所有交易,並加總來確認 當時的餘額。當然,我們可以有一些更有效的辦法,比如另外增加一個數據字段,用來更新每次交易後的賬戶餘額,但這也增加了記賬的工作量。

所以,比特幣並沒有用這種記賬方式,而是用了我們在第1章1.5節裏提到的「財奴幣」相類似的方法來記錄交易。

這種方式就像財奴幣裏的付幣,每個交易中都有一個輸入值和輸出值。輸入值可以看成是將被消費掉的幣(這些幣 是前一個交易創造出來的),把輸出看成是在本次交易中創造出來的幣。鑄造新幣時,只會創造新幣,而不會消費舊幣(就像財奴幣裏的造幣,只有輸出,沒有輸 入)。每筆交易都有一個獨一無二的ID。每筆交易中可能有多個輸出,輸出的索引從0開始,所以我們稱第一個輸出爲「輸出0」。

我們現在來看圖3.2。交易1是鑄造新幣的交易,因此沒有輸入,也沒有簽名;交易1的輸出是向愛麗絲轉移 25個幣。現在,愛麗絲想把一些幣轉給鮑勃,她就創造了一條新的交易,這就是圖3.2中的交易2。在交易裏,她必須明確指出要轉出的幣的來源(引用之前的 某筆交易)。愛麗絲指出本次交易的幣來自交易1中的輸出0(也是交易1中的唯一輸出),即向愛麗絲轉移25個幣。交易中,愛麗絲還要明確收款人——也就是 輸出的地址,在這個例子裏,有兩個輸出,一個是轉17個幣給鮑勃,另一個是轉8個幣給愛麗絲自己。當然,整個交易由愛麗絲簽名,這樣,大家就知道這筆交易 愛麗絲是確實授權了的。

image.png

圖3.2 與比特幣類似的基於交易的賬本

地址轉換。在這個例子裏,爲什麼愛麗絲要把幣轉給自 己呢?事實上比特幣就像財奴幣中描述的幣一樣,一個交易中輸出的幣,要麼在另一個交易中被完全消費掉,要麼就一個都不被消費,不存在只消費部分的情況。愛 麗絲只需付給鮑勃17個幣,但愛麗絲在上一交易中實際獲得了25個幣,爲了把這些幣全部消費掉,她必須再轉給自己8個幣。這8個幣可以轉到另外一個地址 (不同於交易1中獲得25個幣的地址),但前提是該地址爲愛麗絲所有,這就叫地址轉換。

有效驗證。當一個新的交易被加入總賬,它的有效性是否 容易被驗證?在這個例子裏,我們要覈查一下愛麗絲引用的交易輸出,確認她確實有25個幣沒有被花費掉。因爲我們使用了哈希指針,所以覈查很快。爲了確認這 25個幣沒有被花掉,我們只需從愛麗絲所引用的交易開始,一直覈查到賬本上最新記錄的交易爲止即可——而不需要從賬本建立之初的交易開始覈查。而且,這種 方法也不需要增加額外的數據結構(當然,我們將會看到,加入新的數據結構將進一步提高速度)。

資金合併。和財奴幣一樣,比特幣交易可能有許多輸入與 輸出,資金分隔與合併也很容易。假如鮑勃在兩筆不同的交易中分別收到17個幣和2個幣,現在他想把這兩筆錢合併起來花掉,這很容易,他只需發起一個交易, 交易裏有兩個輸入和一個輸出,輸出的地址是他自己的地址,這樣,鮑勃就把兩個交易合二爲一了。

共同支付。同樣地,共同支付也很容易做到。如果卡羅爾和鮑勃想要共同支付給戴維,他們可以發起一個交易,交易裏也有兩個輸入和一個輸出,唯一不同在於,兩個輸入所引用的「上一筆交易」的輸出地址不同,因此,這筆交易需要兩個簽名:卡羅爾的和鮑勃的。

交易語法。比特幣交易涉及的概念就是上面這些。我們再來看看比特幣交易在底層是如何實現的。實際上,比特幣在網絡上傳輸的數據結構都是一串字符,圖3.3顯示了一個真實的程序,經過編譯就會變成供機器執行的二進制代碼了。

image.png

圖3.3 一個真實的比特幣交易程序段

從圖3.3可以看到,一個比特幣交易分成三部分:元數據、一系列的輸入和一系列的輸出。

● 元數據。這裏存放一些內部處理的信息:包含這筆交易的規模、輸入的數量、輸出的數量,還有此筆交易的哈希值,也就是這個交易獨一無二的ID。我們可以用哈希指針指向這個ID。最後還有一個「鎖定時間」(lock_time),我們後面會談到。

● 輸入。所有輸入排成一個序列,每個輸入的格式都是一樣的。輸入需要明確說明之前一筆交易的某個輸出,因此它包括之前那筆交易的哈希值,使其成爲指向那個特 定交易的哈希指針。這個輸入部分同時包括之前交易輸出的索引和一個簽名:我們必須有簽名來證明我們有資格去支配這筆比特幣。

● 輸出。所有輸出也排成一個序列。每個輸出的內容分成兩部分。所有輸出的金額之和必須小於或等於輸入的金額之和。當輸出的總金額小於輸入總金額時,輸出的總金額與輸入的總金額的差額部分,就作爲交易費支付給爲這筆交易記賬的礦工。

一長串怪怪的(funny)字符看上去像是接收地址。實際上,每個輸出都要和一個特定的公鑰(地址)對應,所以這一長串字符裏面確實有一部分看上去是公鑰的哈希值,但裏面還有一部分看上去像指令集合的東西,它其實是一個比特幣的腳本,下文展開介紹。

來源:我是碼農,轉載請保留出處和鏈接!

本文鏈接:http://www.54manong.com/?id=416

'); (window.slotbydup = window.slotbydup || []).push({ id: "u3646208", container: s }); })(); '); (window.slotbydup = window.slotbydup || []).push({ id: "u3646147", container: s }); })();