成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

基于Java語(yǔ)言構(gòu)建區(qū)塊鏈(二)—— 工作量證明

abson / 2874人閱讀

摘要:在比特幣中,這種工作的目標(biāo)是找到滿足某個(gè)特定要求的區(qū)塊哈希值。這個(gè)區(qū)塊哈希值就是工作結(jié)果的一個(gè)證明。因此,計(jì)算工作的目的就是為了尋找到這個(gè)證明值。例如哈希算法被廣泛用于驗(yàn)證文件的一致性上。在區(qū)塊鏈中,哈希值用于保證區(qū)塊的一致性。

最終內(nèi)容請(qǐng)以原文為準(zhǔn): https://wangwei.one/posts/789...
引言

在 上一篇 文章中,我們實(shí)現(xiàn)了區(qū)塊鏈最基本的數(shù)據(jù)結(jié)構(gòu)模型,添加區(qū)塊以及和前一個(gè)區(qū)塊連接在一起。但是,我們的實(shí)現(xiàn)方式非常簡(jiǎn)單,而真實(shí)的比特幣區(qū)塊鏈中,每一個(gè)區(qū)塊的添加都是需要經(jīng)過大量的計(jì)算才可以完成,這個(gè)過程就是我們熟知的挖礦。

工作量證明機(jī)制

區(qū)塊鏈最關(guān)鍵的一個(gè)思想就是,必須進(jìn)行大量且困難的計(jì)算工作才能將交易數(shù)據(jù)存放到區(qū)塊鏈上。這種工作機(jī)制才能保證整個(gè)區(qū)塊鏈數(shù)據(jù)的安全性和一致性。同時(shí),完成這個(gè)計(jì)算工作的礦工會(huì)得到相應(yīng)的Token獎(jiǎng)勵(lì)。

這套機(jī)制和我們的現(xiàn)實(shí)生活非常相似:我們必須努力工作來(lái)賺取報(bào)酬用以維持我們的生活。在區(qū)塊鏈中,網(wǎng)絡(luò)中的礦工們努力工作來(lái)維持區(qū)塊鏈網(wǎng)絡(luò),為其添加區(qū)塊,并且獲得一定的Token獎(jiǎng)勵(lì)。作為他們工作的成果,一個(gè)區(qū)塊以安全的方式被組合進(jìn)了區(qū)塊鏈中,這樣就保證了整個(gè)區(qū)塊鏈數(shù)據(jù)庫(kù)的穩(wěn)定性。還有一個(gè)必須要注意的是,某個(gè)礦工完成了計(jì)算工作的結(jié)果,還必須得到其他所有礦工的認(rèn)同(證明是正確的),這樣才算完成。

這一整套的計(jì)算和證明機(jī)制,就稱為Proof-of-Work(工作量證明)。計(jì)算工作是非常非常困難的,因?yàn)樗枰拇罅康挠?jì)算機(jī)算力資源,即使是性能非常高的計(jì)算機(jī)都不能非??斓赜?jì)算出正確的結(jié)果。此外,隨著時(shí)間的推移,這項(xiàng)計(jì)算工作的難度也會(huì)隨之增加,目的是為了保證每小時(shí)6個(gè)新區(qū)塊的出塊率。在比特幣中,這種工作的目標(biāo)是找到滿足某個(gè)特定要求的區(qū)塊Hash(哈希值)。這個(gè)區(qū)塊哈希值就是工作結(jié)果的一個(gè)證明。因此,計(jì)算工作的目的就是為了尋找到這個(gè)證明值。

最后要注意的是,計(jì)算出這個(gè)特定的Hash(哈希值)是非常困難的,但是別人來(lái)驗(yàn)證這個(gè)Hash值是否正確的時(shí)候,是非常簡(jiǎn)單的,一下子就能完成。

Hashing
Hash:哈希 | 散列

我們來(lái)討論一下Hashing(哈希),對(duì)這一塊非常熟悉的朋友可以直接跳過這一段內(nèi)容。

哈希是一種計(jì)算機(jī)算法,該算法能夠計(jì)算出任意大小數(shù)據(jù)的哈希值,并且這個(gè)哈希值的長(zhǎng)度是固定的,256bit。這個(gè)被計(jì)算出來(lái)的哈希值能夠作為這個(gè)數(shù)據(jù)的唯一代表。哈希算法有幾個(gè)關(guān)鍵的特性:

不可逆性。不能根據(jù)一個(gè)哈希值推導(dǎo)出原始數(shù)據(jù)。所以,哈希不是加密。

唯一性。每個(gè)數(shù)據(jù)有且僅有一個(gè)唯一的哈希值。

迥異性。原始數(shù)據(jù)一丁點(diǎn)的變化都將得到完全不一樣的哈希值。

例如:

SHA256("wangwei1") ——> 1e898b7c9adaad86c20139a302ccd5277f81040cab68dc2aecfc684773532652
SHA256("wangwei2") ——> c9cc7417c17318c8aab448cc8ace24c53b6dcf350f5c5fd8e91cbc3b011a179d

哈希算法被廣泛用于驗(yàn)證文件的一致性上。比如軟件提供商通常會(huì)在安裝包上附加一個(gè)檢驗(yàn)碼(checksums),當(dāng)我們下載完一個(gè)軟件安裝包后,可以用哈希函數(shù)計(jì)算一下這個(gè)軟件安裝包的哈希值,然后再和軟件安裝包的檢驗(yàn)碼做個(gè)對(duì)比,就可以知道下載的安裝包是否完整、是否有數(shù)據(jù)丟失。

在區(qū)塊鏈中,哈希值用于保證區(qū)塊的一致性。每一個(gè)區(qū)塊被用于進(jìn)行哈希計(jì)算的數(shù)據(jù),都包含前一個(gè)區(qū)塊鏈的哈希值,因此任何人想要修改區(qū)塊的數(shù)據(jù)幾乎是不可能的,他必須要把整個(gè)區(qū)塊鏈中從創(chuàng)世區(qū)塊到最新的區(qū)塊的所有哈希值全部重新計(jì)算一遍。

你可以腦補(bǔ)一下這個(gè)工作量有多大,按照目前計(jì)算機(jī)的算力來(lái)看,幾乎不可能
Hashcash

比特幣的工作量證明是使用的是Hashcash算法,一種最初被用于反垃圾郵件的算法,它可以被拆解為以下幾步:

獲取某種公開可知的數(shù)據(jù)data(在郵件案例中,指的是收件人郵件地址;比特幣案例中,指的是區(qū)塊頭)

添加一個(gè)計(jì)數(shù)器counter,初始值設(shè)置為0;

計(jì)算 data 與 counter拼接字符串的哈希值;

檢查上一步的哈希值是否滿足某個(gè)條件,滿足則停止計(jì)算,不滿足則 counter 加1,然后重復(fù)第3步和第4步,直到滿足這個(gè)特定的條件為止。

這是一種粗暴的算法:你改變計(jì)數(shù)器,計(jì)算一個(gè)新的哈希值,檢查它,增加計(jì)數(shù)器,計(jì)算一個(gè)新的哈希值,循環(huán)往復(fù),這就是為什么它需要花費(fèi)大量計(jì)算機(jī)算力資源的原因所在。

讓我們來(lái)近距離看一下這個(gè)特定的條件指的是什么。在原始的Hashcash算法中,這個(gè)特殊的要求指的是計(jì)算出來(lái)的哈希值的前20bit必須全是零,

在比特幣種,這種要求哈希值前面有多少個(gè)零打頭的要求是隨著時(shí)間的推移而不斷調(diào)整的,這是出于設(shè)計(jì)的目的,盡管在計(jì)算機(jī)的算力會(huì)不斷的提升和越來(lái)越多的礦工加入這個(gè)網(wǎng)絡(luò)中的情況下,都要保證每10min生產(chǎn)一個(gè)區(qū)塊。

我們演示一下這個(gè)算法,

# 計(jì)算字符串"I like donuts"的哈希值
SHA256("I like donuts") 
——> f80867f6efd4484c23b0e7184e53fe4af6ab49b97f5293fcd50d5b2bfa73a4d0

# 拼接一個(gè)計(jì)數(shù)器值(ca07ca),再次進(jìn)行Hash計(jì)算
SHA256("I like donutsca07ca") 
——> 0000002f7c1fe31cb82acdc082cfec47620b7e4ab94f2bf9e096c436fc8cee06

這里的ca07ca是計(jì)數(shù)器值的十六進(jìn)制,他表示的十進(jìn)制值為13240266

即,從0開始,總共計(jì)算了13240266次,才計(jì)算出I like donuts這個(gè)數(shù)據(jù)的Hash值,滿足前6位(3字節(jié))全是零。
代碼實(shí)現(xiàn)
思路:

1)每次區(qū)塊被添加到區(qū)塊鏈之前,先要進(jìn)行挖礦(Pow)

2)挖礦過程中,產(chǎn)生的 Hash 值,如果小于難度目標(biāo)值則添加進(jìn)區(qū)塊,否則繼續(xù)挖礦,直到找到正確的Hash為止

3)最后,驗(yàn)證區(qū)塊Hash是否有效

定義Pow類
/**
 * 工作量證明
 *
 * @author wangwei
 * @date 2018/02/04
 */
@Data
public class ProofOfWork {

    /**
     * 難度目標(biāo)位
     */
    public static final int TARGET_BITS = 20;

    /**
     * 區(qū)塊
     */
    private Block block;
    /**
     * 難度目標(biāo)值
     */
    private BigInteger target;

    private ProofOfWork(Block block, BigInteger target) {
        this.block = block;
        this.target = target;
    }
  
    /**
     * 創(chuàng)建新的工作量證明,設(shè)定難度目標(biāo)值
     * 

* 對(duì)1進(jìn)行移位運(yùn)算,將1向左移動(dòng) (256 - TARGET_BITS) 位,得到我們的難度目標(biāo)值 * * @param block * @return */ public static ProofOfWork newProofOfWork(Block block) { BigInteger targetValue = BigInteger.valueOf(1).shiftLeft((256 - TARGET_BITS)); return new ProofOfWork(block, targetValue); } }

設(shè)定一個(gè)難度目標(biāo)位TARGET_BITS,表示最終挖礦挖出來(lái)Hash值,轉(zhuǎn)化為二進(jìn)制后,與256相比,長(zhǎng)度少了多少bit,也即二進(jìn)制前面有多少bit是零.

TARGET_BITS 越大,最終targetValue就越小,要求計(jì)算出來(lái)的Hash越來(lái)越小,也就是挖礦的難度越來(lái)越大。

我們這里的TARGET_BITS是固定的,但是在真實(shí)的比特幣中,難度目標(biāo)是隨著時(shí)間的推推,會(huì)動(dòng)態(tài)調(diào)整的。詳見:《精通比特幣 (第二版)》第10章

由于數(shù)值比較大,這里要使用BitInteger類型。

準(zhǔn)備數(shù)據(jù)
/**
 * 準(zhǔn)備數(shù)據(jù)
 * 

* 注意:在準(zhǔn)備區(qū)塊數(shù)據(jù)時(shí),一定要從原始數(shù)據(jù)類型轉(zhuǎn)化為byte[],不能直接從字符串進(jìn)行轉(zhuǎn)換 * @param nonce * @return */ private String prepareData(long nonce) { byte[] prevBlockHashBytes = {}; if (StringUtils.isNoneBlank(this.getBlock().getPrevBlockHash())) { prevBlockHashBytes = new BigInteger(this.getBlock().getPrevBlockHash(), 16).toByteArray(); } return ByteUtils.merge( prevBlockHashBytes, this.getBlock().getData().getBytes(), ByteUtils.toBytes(this.getBlock().getTimeStamp()), ByteUtils.toBytes(TARGET_BITS), ByteUtils.toBytes(nonce) ); }

參與Hash運(yùn)算的如下幾個(gè)信息:

前一個(gè)區(qū)塊(父區(qū)塊)的Hash值;

區(qū)塊中的交易數(shù)據(jù);

區(qū)塊生成的時(shí)間;

難度目標(biāo);

用于工作量證明算法的計(jì)數(shù)器

詳見:《精通比特幣 (第二版)》第09章
Pow算法
/**
 * 運(yùn)行工作量證明,開始挖礦,找到小于難度目標(biāo)值的Hash
 *
 * @return
 */
public PowResult run() {
    long nonce = 0;
    String shaHex = "";
    System.out.printf("Mining the block containing:%s 
", this.getBlock().getData());

    long startTime = System.currentTimeMillis();
    while (nonce < Long.MAX_VALUE) {
        String data = this.prepareData(nonce);
        shaHex = DigestUtils.sha256Hex(data);
        if (new BigInteger(shaHex, 16).compareTo(this.target) == -1) {
            System.out.printf("Elapsed Time: %s seconds 
", (float) (System.currentTimeMillis() - startTime) / 1000);
            System.out.printf("correct hash Hex: %s 

", shaHex);
            break;
         } else {
            nonce++;
         }
     }
     return new PowResult(nonce, shaHex);
}

循環(huán)體里面主要以下四步:

準(zhǔn)備數(shù)據(jù)

進(jìn)行sha256運(yùn)算

轉(zhuǎn)化為BigInter類型

與target進(jìn)行比較

最后,返回正確的Hash值以及運(yùn)算計(jì)數(shù)器nonce

驗(yàn)證區(qū)塊Hash有效性
/**
 * 驗(yàn)證區(qū)塊是否有效
 *
 * @return
 */
public boolean validate() {
    String data = this.prepareData(this.getBlock().getNonce());
    return new BigInteger(DigestUtils.sha256Hex(data), 16).compareTo(this.target) == -1;
}
修改區(qū)塊添加邏輯
/**
 * 

創(chuàng)建新區(qū)塊

* * @param previousHash * @param data * @return */ public static Block newBlock(String previousHash, String data) { Block block = new Block("", previousHash, data, Instant.now().getEpochSecond(), 0); ProofOfWork pow = ProofOfWork.newProofOfWork(block); PowResult powResult = pow.run(); block.setHash(powResult.getHash()); block.setNonce(powResult.getNonce()); return block; }

創(chuàng)建區(qū)塊

創(chuàng)建Pow算法對(duì)象

執(zhí)行Pow算法

保存返回的Hash以及運(yùn)算計(jì)數(shù)器

測(cè)試運(yùn)行
/**
 * 測(cè)試
 *
 * @author wangwei
 * @date 2018/02/05
 */
public class BlockchainTest {

    public static void main(String[] args) {

        Blockchain blockchain = Blockchain.newBlockchain();

        blockchain.addBlock("Send 1 BTC to Ivan");
        blockchain.addBlock("Send 2 more BTC to Ivan");

        for (Block block : blockchain.getBlockList()) {
            System.out.println("Prev.hash: " + block.getPrevBlockHash());
            System.out.println("Data: " + block.getData());
            System.out.println("Hash: " + block.getHash());
            System.out.println("Nonce: " + block.getNonce());

            ProofOfWork pow = ProofOfWork.newProofOfWork(block);
            System.out.println("Pow valid: " +  pow.validate() + "
");
        }
    }
}

/**
 * 設(shè)定TARGET_BITS = 20,得到如下結(jié)果:
 */
Mining the block containing:Genesis Block 
Elapsed Time: 2.118 seconds 
correct hash Hex: 00000828ee8289ef6381f297585ef8c952fde93fc2b673ff7cc655f699bb2442 

Mining the block containing:Send 1 BTC to Ivan 
Elapsed Time: 1.069 seconds 
correct hash Hex: 00000a38c0d7f2ebbd20773e93770298aa8bc0cc6d85fca8756fe0646ae7fea5 

Mining the block containing:Send 2 more BTC to Ivan 
Elapsed Time: 4.258 seconds 
correct hash Hex: 00000777f93efe91d9aabcba14ab3d8ab8e0255b89818cdb9b93cfa844ad0c7f 

Prev.hash: 
Data: Genesis Block
Hash: 00000828ee8289ef6381f297585ef8c952fde93fc2b673ff7cc655f699bb2442
Nonce: 522163
Pow valid: true

Prev.hash: 00000828ee8289ef6381f297585ef8c952fde93fc2b673ff7cc655f699bb2442
Data: Send 1 BTC to Ivan
Hash: 00000a38c0d7f2ebbd20773e93770298aa8bc0cc6d85fca8756fe0646ae7fea5
Nonce: 474758
Pow valid: true

Prev.hash: 00000a38c0d7f2ebbd20773e93770298aa8bc0cc6d85fca8756fe0646ae7fea5
Data: Send 2 more BTC to Ivan
Hash: 00000777f93efe91d9aabcba14ab3d8ab8e0255b89818cdb9b93cfa844ad0c7f
Nonce: 1853839
Pow valid: true
總結(jié)

我們正在一步一步接近真實(shí)的區(qū)塊鏈架構(gòu),本篇我們實(shí)現(xiàn)了挖礦機(jī)制,但是我們還有很多關(guān)鍵性的功能沒有實(shí)現(xiàn):區(qū)塊鏈數(shù)據(jù)庫(kù)的持久性、錢包、地址、交易、共識(shí)機(jī)制,這些我們后面一步一步來(lái)實(shí)現(xiàn)

資料

源代碼:https://github.com/wangweiX/b...

https://jeiwan.cc/posts/build...

《精通比特幣(第二版)》

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/23989.html

相關(guān)文章

  • 基于Java語(yǔ)言構(gòu)建區(qū)塊)—— 作量證明

    摘要:在比特幣中,這種工作的目標(biāo)是找到滿足某個(gè)特定要求的區(qū)塊哈希值。這個(gè)區(qū)塊哈希值就是工作結(jié)果的一個(gè)證明。因此,計(jì)算工作的目的就是為了尋找到這個(gè)證明值。例如哈希算法被廣泛用于驗(yàn)證文件的一致性上。在區(qū)塊鏈中,哈希值用于保證區(qū)塊的一致性。 showImg(https://segmentfault.com/img/remote/1460000013923267?w=3500&h=2090); 最終...

    RaoMeng 評(píng)論0 收藏0
  • 基于Java語(yǔ)言構(gòu)建區(qū)塊(一)—— 基本原型

    摘要:本文將基于語(yǔ)言構(gòu)建簡(jiǎn)化版的,來(lái)實(shí)現(xiàn)數(shù)字貨幣。值用于確保的安全。計(jì)算是計(jì)算敏感的操作,即使在高性能電腦也需要花費(fèi)一段時(shí)間來(lái)完成計(jì)算這也就是為什么人們購(gòu)買高性能進(jìn)行比特幣挖礦的原因。資料源代碼精通比特幣第二版 showImg(https://segmentfault.com/img/remote/1460000013923206?w=1600&h=900); 最終內(nèi)容請(qǐng)以原文為準(zhǔn):http...

    PiscesYE 評(píng)論0 收藏0
  • 基于Java語(yǔ)言構(gòu)建區(qū)塊(一)—— 基本原型

    摘要:本文將基于語(yǔ)言構(gòu)建簡(jiǎn)化版的,來(lái)實(shí)現(xiàn)數(shù)字貨幣。值用于確保的安全。計(jì)算是計(jì)算敏感的操作,即使在高性能電腦也需要花費(fèi)一段時(shí)間來(lái)完成計(jì)算這也就是為什么人們購(gòu)買高性能進(jìn)行比特幣挖礦的原因。資料源代碼精通比特幣第二版 showImg(https://segmentfault.com/img/remote/1460000013923206?w=1600&h=900); 最終內(nèi)容請(qǐng)以原文為準(zhǔn):http...

    Flink_China 評(píng)論0 收藏0
  • 以太坊、EOS和Hyperledger等不同區(qū)塊的比較

    摘要:以太坊背后的主要人物是。以太坊通過在區(qū)塊鏈上引入智能合約,徹底改變了加密世界。以太坊使用名為以太坊虛擬機(jī)的虛擬機(jī)執(zhí)行其智能合約。以太坊最終將利用協(xié)議轉(zhuǎn)向權(quán)益證明。截至目前,以太坊在可擴(kuò)展性方面都失敗了。 不同的區(qū)塊鏈智能合約和區(qū)塊鏈技術(shù)現(xiàn)在風(fēng)靡一時(shí)。越來(lái)越多的人出于某種原因試圖進(jìn)入這個(gè)神奇的世界。如果你是這項(xiàng)技術(shù)的新手并正在尋找基于區(qū)塊鏈的開發(fā)平臺(tái)的快速入門,那么本指南非常適合你。我們...

    harriszh 評(píng)論0 收藏0
  • 以太坊DApp開發(fā)入門教程——Node.js和truffle框架打造區(qū)塊投票系統(tǒng)

    摘要:第一節(jié)課程概述本課程面向初學(xué)者,內(nèi)容涵蓋以太坊開發(fā)相關(guān)的基本概念,并將手把手地教大家如何構(gòu)建一個(gè)基于以太坊的完整去中心化應(yīng)用區(qū)塊鏈投票系統(tǒng)。第七節(jié)以太坊世界計(jì)算機(jī)以太坊是一種區(qū)塊鏈的實(shí)現(xiàn)。交易數(shù)據(jù)以太坊中每筆交易都存儲(chǔ)在區(qū)塊鏈上。 第一節(jié) 課程概述 本課程面向初學(xué)者,內(nèi)容涵蓋以太坊開發(fā)相關(guān)的基本概念,并將手把手地教大家如何構(gòu)建一個(gè) 基于以太坊的完整去中心化應(yīng)用 —— 區(qū)塊鏈投票系統(tǒng)。 ...

    zebrayoung 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<