1. 程式人生 > >驚奇!用Java也能實現比特幣系統

驚奇!用Java也能實現比特幣系統

代碼 ring str 之間 lin 再次 action 入門 rev

最近區塊鏈技術突然爆火,身邊做技術的朋友茶余飯後不談點區塊鏈什麽的都被認為是跟不上時代了,為啥會這樣了?

這其實跟比特幣價格去年的突飛猛進是分不開的,比特幣價格從去年初不到一千美金到今年初最高接近兩萬美金,賺錢效應已經足夠博取大家眼球了,吃瓜群眾對比特幣價格一年上漲20倍早已目瞪狗呆,個個備足錢袋,躍躍欲試。

可是,細問一下這些朋友比特幣到底是個什麽東西,它是如何構造出來的,還真沒幾個能答得上來的,作為技術出身的我們今天就來帶大家用Java語言實現一個簡單比特幣系統,以期讓大家能對區塊鏈與比特幣的底層實現技術有一個入門性的認識。(上海尚學堂java培訓

一、區塊鏈

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


public class Block {
/**
* 區塊索引號
*/
private int index;
/**
* 當前區塊的hash值,區塊唯一標識
*/
private String hash;
/**
* 生成區塊的時間戳
*/
private long timestamp;
/**
* 當前區塊的交易集合
*/
private List transactions;
/**
* 工作量證明,計算正確hash值的次數
*/private int nonce;
/**
* 前一個區塊的hash值
*/
private String previousHash;
}

二、轉賬交易

轉賬交易即比特幣的擁有方之間進行的相互轉賬行為,我們把這些比特幣的擁有方暫時假設為比特幣的錢包,錢包有對應的錢包地址,那這些轉賬交易實際上就是錢包地址之間的轉賬交易(類似於支付寶用戶之間的轉賬,其實就是支付寶用戶名之間的轉賬),這些轉賬交易需要被記錄到賬本裏才算真正的生效。

由於比特幣的轉賬交易設計比較復雜,我們今天暫時不深入討論,所以這裏我設計了一個簡單的交易模型如下:


public class Transaction {
/**
* 交易唯一標識
*/
private String id;
/**
* 交易發送方錢包地址
*/
private String sender;
/**
* 交易接收方錢包地址
*/
private String recipient;
/**
* 交易金額
*/
private int amount;
}

三、挖礦

技術分享圖片

挖礦到底是怎麽回事?

為什麽那麽多人吵著要去挖礦,夢想著一夜暴富?

我們可以簡單的把挖礦比喻成礦工解一道數學難題的過程,只要解對了就能獲取比特幣系統獎勵的一筆比特幣,同時獲取了區塊鏈賬本新區塊的交易記賬權,礦工會把比特幣系統近期發生的轉賬交易記錄到賬本新的一頁上,並獲取交易的手續費,一旦交易被記錄進了賬本,交易就算完成了,接收方才能真正收到發送方轉賬的比特幣。

那這道數學難題到底長什麽樣了?

我們看下這個數學難題的公式:

Hash = SHA-256(區塊鏈的最後一個區塊的Hash + 需記賬交易記錄信息 + 隨機數)

這個公式已經很明白了,SHA-256是一種哈希加密算法,被加密的前兩部分是固定不變的,我們只有依賴於隨機數的不斷變化計算出不同的hash結果,系統要求hash結果必須要以10個0開頭,這個幾率實在是太小太小,我們做測試可以簡單一點。

比如:只要hash結果滿足以4個0開頭,我們就認為解題成功,即挖礦成功了,這時礦工就可以生成一個新的區塊把需記賬的交易記錄全部記錄進區塊裏去,同時再構造一筆系統獎勵給自己的比特幣的交易(發起方為系統,接收方為礦工,比特幣金額假設為10個),將其也記錄進賬本,這樣通過賬本裏的交易記錄就會發現礦工的余額多了10個比特幣了。

我們看下挖礦的代碼:


/**
* 挖礦
* @param blockchain 整個區塊鏈
* @param txs 需記賬交易記錄,包含
* @param address 礦工錢包地址
* @return
*/
private static void mineBlock(List blockchain, List txs, String address) {
//加入系統獎勵的交易
Transaction sysTx = new Transaction(CryptoUtil.UUID(), "", address, 10);
txs.add(sysTx);
//獲取當前區塊鏈裏的最後一個區塊
Block latestBlock = blockchain.get(blockchain.size() - 1);
//隨機數
int nonce = 1;
String hash = "";
while(true){
hash = CryptoUtil.SHA256(latestBlock.getHash() + JSON.toJSONString(txs) + nonce);
if (hash.startsWith("0000")) {
System.out.println("=====計算結果正確,計算次數為:" +nonce+ ",hash:" + hash);
break;
}
nonce++;
System.out.println("計算錯誤,hash:" + hash);
}
//解出難題,可以構造新區塊並加入進區塊鏈裏
Block newBlock = new Block(latestBlock.getIndex() + 1, System.currentTimeMillis(), txs, nonce, latestBlock.getHash(), hash);
blockchain.add(newBlock);
System.out.println("挖礦後的區塊鏈:" + JSON.toJSONString(blockchain));
}

四、余額

計算某個錢包地址的余額其實就是從區塊鏈賬本裏找出所有該地址作為接收方的交易記錄,將這些交易記錄的發生金額累加就得到該地址收到的所有比特幣金額了,然後找出所有該地址作為發送方的交易記錄再次累加則得到該地址發送出去的所有比特幣金額了,用收到的比特幣金額之和減去發送出去的比特幣金額之和就得到該地址真正的比特幣余額了。

具體我們看下代碼:
上海java培訓


/**
* 查詢余額
* @param blockchain
* @param address
* @return
*/
public static int getWalletBalance(Listblockchain, String address) {
int balance = 0;
for (Block block : blockchain) {
Listtransactions = block.getTransactions();
for (Transaction transaction : transactions) {
if (address.equals(transaction.getRecipient())) {
balance += transaction.getAmount();
}
if (address.equals(transaction.getSender())) {
balance -= transaction.getAmount();
}
}
}
return balance;
}

至此,我們就用java基於區塊鏈賬本技術實現了一個簡單的比特幣系統了,包含區塊鏈功能,挖礦產生新比特幣功能,轉賬交易功能,查詢余額功能,完整的代碼找小助手領取。

運行結果如下圖所示:
技術分享圖片

歡迎大家評論留言,想獲取更多內容或資料支持請點擊 上海java培訓

驚奇!用Java也能實現比特幣系統