程式設計小白模擬簡易位元幣系統(五)

2021-10-03 11:59:53 字數 3825 閱讀 2363

相關**

程式設計小白模擬簡易位元幣系統(四)中,我們有了自己的錢包,明確了交易輸入中的簽名屬性,那麼如何把這些知識運用到交易中呢?

那麼請大家繼續往下看?

我們再考慮下交易的過程,在這個系統中,每個人都有可能進行交易,就像之前提到的abc一樣,可能還有defgh…的存在,交易就類似於上篇文章中的傳送訊息一樣,他們不希望大家都知道具體的細節,所以需要使用密碼學的手段進行加密,我們的交易是通過數字簽名的方式進行加密和驗證。

需要加密的資料就是:傳送者和接收者的公鑰雜湊以及整個交易,由於hash是不可逆的運算,考慮到安全性問題,因此對公鑰進行hash之後再簽名。另外,系統的交易(coinbase交易)沒有輸入,因此我們不必驗證。

還需要解釋的一點,不知道大家有沒有注意到,交易模型中,輸入中有個屬性是傳送方的公鑰,輸出中有個屬性是接收方的公鑰雜湊,為什麼這樣設計而不統一呢?就是因為這個簽名的過程,給大家打個**更清晰一些。

簽名的資料

驗證簽名

傳送方公鑰

需要傳送方公鑰雜湊

需要接收方公鑰

接收方公鑰雜湊

需要接收方的公鑰我們簽名中用不到,因此,傳送方的公鑰接收方的公鑰雜湊我們需要存在交易中。

前面我們提到,在區塊鏈中,都有指標指向前乙個區塊,每個區塊都依賴於前乙個區塊,那麼追溯到起源,我們建立了乙個創世區塊。交易也類似,交易中包含了交易的輸入輸出,輸入是未花費的交易輸出(utxo)使用者的每一筆交易都有自己所依賴的交易(前一筆或幾筆交易),是不是也類似於區塊鏈中的依賴前乙個的概念?

那麼追溯到起源來看,最初始錢包中的球球幣是**來的呢?機智的大家可能會想到,在我們之前提到過的挖礦過程中,系統獎勵給了礦工一筆球球幣。事實上,這也是一筆交易,由於這個獎勵是系統給予的,因此不存在依賴的交易,這也就是第一筆球球幣的**,我們稱之為coinbase交易

在coinbase交易中,不存在交易的輸入只有輸出,考慮到交易模型,我們在實現過程中作為系統的設計者自己寫定了交易的輸入中的屬性

一對公私鑰,由於生成的公鑰太長,因此引入了錢包位址的概念,想必誰都不希望轉賬的時候,填寫的收款方是一大長串無厘頭的字串吧。因此,錢包位址的存在就是為了簡化公鑰,方便轉賬。

交易簽名

public

void

sign

(string privatekey, transaction prevtx)if(

!prevtx.

getid()

.equals

(gettxin()

.gettxid()

))transaction txclone =

clonetx()

;// 前一筆交易的輸出,就是這一筆交易的輸入

// 對傳送方和接受方的公鑰雜湊以及這個交易做簽名

txclone.

gettxin()

.setpublickey

(prevtx.

gettxout()

.getpublichashkey()

);// 接收方的公鑰hash在txout中,已經被複製到clone中

string sign ="";

trycatch

(nosuchalgorithmexception e)

catch

(invalidkeyspecexception e)

catch

(ioexception e)

catch

(invalidkeyexception e)

catch

(signatureexception e)

txin.

setsignature

(sign)

;}

coinbase交易

/**

* 生成區塊的交易獎勵(建立coinbase交易)

* @param toaddress 挖礦人的錢包位址

* @return

*/public transaction newreward

(string toaddress)

獲取的錢包位址

/**

* 獲取錢包位址

* @return

*/@override

public string getwalletaddress

(string pubkey)

**中的幾點說明:

交易簽名中的變數mywalletmap,是錢包的集合,暫且當作所有人的錢包集合來理解就好,節點的概念我們之後提到(與p2p網路相關)

/**

* 當前節點錢包集合

*/private map

mywalletmap =

newhashmap

<

>()

;

交易簽名中的coinbase方法,是transaction物件中的方法,用來判定交易是否為coinbase交易

public

boolean

coinbasetx()

交易簽名中的clonetx方法,是transaction物件中的方法,用來新建乙個transaction物件,這個物件用來收集要進行簽名的資料,之後使用其進行簽名。

private transaction clonetx()

**中的rsacoder.sign就是前一篇文章所提到的sign方法,我只是把密碼學相關方法進行了封裝,類名為rsacoder

獲取錢包位址中的cryptoutil.md5,使用的為md5資訊摘要演算法,給出如下,會使用就好。

public

static string md5

(string str)

catch

(exception e)

return encodestr;

}

至此,我們搞清楚了整個交易的收付款方(錢包位址),以及交易的所有屬性(輸入:簽名、傳送方公鑰、交易金額、前一筆交易id,輸出:接收方公鑰雜湊、交易輸出金額),接下來就讓我們一起建立一筆真正的球球幣交易吧!

實戰位元幣指令碼程式設計(2)困局

在前一篇可以想到3種分割完整指令碼的辦法。但現實因為要考慮安全因素,位元幣不允許在解鎖指令碼中放入op add這樣的操作符 也就是下面的形式不允許。第一段解鎖指令碼 不允許 op 2 op 3 op add第二段鎖定指令碼 op 5 op equalop 2和op 3將2和3推入棧中,而op add...

驚奇!用Java也能實現位元幣系統

位元幣是構建在區塊鏈技術之上的乙個加密數字貨幣,區塊鏈顧名思義即由很多區塊組成的鏈條,可以把區塊鏈簡單比喻為一本賬本,把區塊比喻為賬本的一頁記錄,賬本的每一頁裡都記錄了很多位元幣的轉賬交易,那根據這個賬本裡的所有交易記錄應該是能算出任何乙個交易者的餘額,我們先來構造乙個區塊的結構 public cl...

位元幣系統中的全節點和輕節點

在本地硬碟上維護完整的區塊鏈資訊 在記憶體裡維護utxo集合,以便快速檢驗交易的正確性 監聽位元幣網路上的交易資訊,驗證每個交易的合法性 決定哪些交易會被打包到區塊裡 監聽別的礦工挖出來的區塊,驗證其合法性 挖礦 不用儲存整個區塊鏈,只要儲存每個區塊的塊頭 不用儲存全部交易,只儲存與自己相關的交易 ...