簡單Javascript製作區塊鏈(教學一)

近年區塊鏈技術十分火,很多人都研究區塊鏈如何應用在不同行業上,為了要走在這個科技時代的尖端,學習區塊鏈是必須的。今天看了一個視頻影片,用簡單的Javascript實作了區塊鏈的基本原理,讓大家容易明白區塊鏈是如何運作的,同時也講解了區塊鏈是怎樣保證到每一個區塊都不會被篡改。

以下範例實作了區塊鏈內每一個區塊是如何關聯,驗証區塊鏈內的所有區塊資料是否正確,沒有被篡改。

const SHA256 = require('crypto-js/sha256');

/*
 * 區塊
 */
class Block {
    constructor(index, timestamp, data, previousHash = '') {
        this.index = index;
        this.timestamp = timestamp;
        this.data = data;
        this.previousHash = previousHash;
        this.hash = this.calculateHash();
    }

    /*
     * 計算區塊的hash
     */
    calculateHash() {
        return SHA256(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data)).toString();
    }
}

/*
 * 區塊鏈
 */
class Blockchain {
    constructor() {
        this.chain = [this.createGenesisBlock()];
    }

    /*
     * 建立第一個區塊
     */
    createGenesisBlock() {
        return new Block(0, "2018-03-19", "Genesis block", "0");
    }

    /*
     * 取得最新的一個區塊
     */
    getLatestBlock() {
        return this.chain[this.chain.length - 1];
    }

    /*
     * 加入一個區塊
     */
    addBlock(newBlock) {
        newBlock.previousHash = this.getLatestBlock().hash;
        newBlock.hash = newBlock.calculateHash();
        this.chain.push(newBlock);
    }

    /*
     * 驗証區塊鏈內的所有區塊資料是否正確,沒有被篡改
     */
    isChainValid() {
        for(let i = 1; i < this.chain.length; i++) {
            const currentBlock = this.chain[i]; // 取得目前區塊
            const previousBlock = this.chain[i-1]; // 取得上一個區塊

            // 檢查目前區塊的hash是否和計算出來的hash不一樣
            if(currentBlock.hash !== currentBlock.calculateHash()) {
                return false;
            }

            // 檢查目前區塊的上一個區塊hash是否和上一個區塊hash不一樣
            if(currentBlock.previousHash !== previousBlock.hash) {
                return false;
            }
        }

        return true;
    }
}

let testCoin = new Blockchain();
testCoin.addBlock(new Block(1, "2018-03-19", { id: 1 }));
testCoin.addBlock(new Block(2, "2018-03-20", { id: 2 }));

console.log('區塊鏈是否正確? ' + testCoin.isChainValid());

 

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *

*

驗證碼 * Time limit is exhausted. Please reload CAPTCHA.