区块链入门学习(2)

区块链入门学习(2)--pow

  • 什么是pow
    • 上一篇的思考
    • 挖矿!

什么是pow

上一篇的思考

经过上一篇简单的介绍后,我们对于区块链有了简单的成链及基本校验。但,细心的小伙伴们发现,我们依然可以篡改数据,(我们只要把异常数据节点后面的数据块hash都修改好,就可已成功篡改)所以,我们这一次来讲下pow,更加有效的抵制攻击。
我们在上一篇可以发现,创建区块毫不费力,不仅在创建新区块的同时,也有大量的消息充斥。易造成区块链过载。另外,区块链是依据谁的链长,判断谁是合法且有效的,所以,这样数据将会出现混乱。
好的,说了一通,我们这期的主角pow终于出场了。

为了加大算法难度和成本,以减少垃圾和负载,引入了对应的共识机制,只有开头连续出现对应次数0的hash值才为有效hash,例如:

0000000asdsada1231231   //有效hash
asdasd0000asdqwhwqdk   //无效hash

由于hash是我们区块中的信息产生的,要改变hash的且同时不改变信息,我们额外引入一个参数,随机数nonce,该值会不断改变以求改变hash直到出现适合规则的hash。那么我们的区块类里需要引入一个参数nonce。

class EasyBlock {
    constructor(index, timestamp, data,prevHash = '') {
        this.index = index;
        this.prevHash = prevHash;
        this.timestamp = timestamp;
        this.data = data;
        this.hash = this.calHash();
        this.nonce = 0;
    }

    calHash() {
        return crypto
            .createHash('sha256')
            .update(this.index +this.nonce + this.timestamp + this.data + this.prevHash)
            .digest('hex')
    }
}

那么,问题又来了,需要连续多少个“0”呢,需要一个维度的变量。我们就加一个在EasyChain这个类里加上difficulty这个维度,来控制0 的个数来实现控制新区块产生的速度。

挖矿!

上述我们的不断去试着计算符合规则的hash值的过程,就是挖矿!
首先,我们需要在EasyBlock这个类里加一个挖矿的方法。

class EasyBlock {
    constructor(index, timestamp, data, prevHash = '') {
        this.index = index;
        this.prevHash = prevHash;
        this.timestamp = timestamp;
        this.data = data;
        this.hash = this.calHash();
        this.nonce = 0;
    }

    calHash() {
        return crypto
            .createHash('sha256')
            .update(this.index + this.timestamp + this.data + this.prevHash + this.nonce)
            .digest('hex')
    }
	//difficulty为挖矿难度,hash前面连续0的个数
    mine(difficulty) {
        while (this.hash.slice(0, difficulty) !== '0'.repeat(difficulty)) {
            this.nonce++;
            this.hash = this.calHash()
        }
        console.log('挖矿成功!共挖矿次数为:' + this.nonce + '---hash值为:' + this.hash)
    }
}

对应的EasyChain里,addBlock这个方法就需要修改一下,把挖矿mine带上,

	addBlock(newblock) {
        newblock.prevHash = this.getLastBlock().hash;
        newblock.mine(this.difficulty)
        if (this.isValid()) {
            this.blockchain.push(newblock)
        } else {
            console.log('区块链出现异常')
        }
    }

最后我们输出一下,看看效果。

let easyChain = new EasyChain();
// console.log(easyChain.calHash(firstBlock))
// console.log('prevhash', easyChain.getLastBlock())
easyChain.addBlock(new EasyBlock(1, new Date().getTime(), 'firstMineBlock'))
easyChain.addBlock(new EasyBlock(2, new Date().getTime(), 'secondMineBlock'))

控制台输出:

挖矿成功!共挖矿次数为:38872---hash值为:00001e38c87007836ffaf3fd70c28217eb569bf7b7a90284f4818937200e7adf
挖矿成功!共挖矿次数为:6123---hash值为:000052965a670653d4610004beb5be82e6733d7825f3caaafb99bd4d5ec722e0

今天就先到这儿咯,简单的pow挖矿原理及代码实现,下次会给大家分享下区块链间的p2p通信!

你可能感兴趣的:(前端学习,区块链)