亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何用JS構建你自己的區塊鏈

發布時間:2021-12-13 21:39:02 來源:億速云 閱讀:141 作者:柒染 欄目:互聯網科技

如何用JS構建你自己的區塊鏈,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

前言

區塊鏈太復雜,那我們就講點簡單的。用JS來構建你自己的區塊鏈系統,寥寥幾行代碼就可以說明區塊鏈的底層數據結構、POW挖礦思想和交易過程等。當然了,真實的場景遠遠遠比這復雜。小編的目的僅限于讓大家初步了解、初步認識區塊鏈。

認識區塊鏈

區塊鏈顧名思義是由區塊連接而成的鏈,因此最基本的數據結構是Block。每個Block都含有timestamp、data、hash、previousHash等信息。其中data用來存儲數據,previousHash是前一個區塊的hash值。示意如下:

如何用JS構建你自己的區塊鏈

hash是對區塊信息的摘要存儲,hash的好處是任意長度的信息經過hash都可以映射成固定長度的字符串,如可用sha256:

calculateHash() {
    return SHA256(this.previousHash + this.timestamp + JSON.stringify(this.data)).toString();
}

Block的數據結構

Block的最基本數據結構如下:

class Block {
    constructor(timestamp, data, previousHash = '') {
        this.timestamp = timestamp;
        this.data = data;
        this.previousHash = previousHash;
        //對hash的計算必須放在最后,保證所有數據賦值正確后再計算
        this.hash = this.calculateHash(); 
    }

    calculateHash() {
        return SHA256(this.previousHash + this.timestamp + JSON.stringify(this.data)).toString();
    }
}

BlockChain的數據結構

多個Block鏈接而成BlockChain,顯然可用用數組或鏈表來表示,如:

class BlockChain {
    constructor() {
        this.chain = [];
    }
}

創世區塊

正所謂萬物始于一,區塊鏈的第一個區塊總是需要人為來手動創建,這個區塊的previousHash為空,如:

createGenesisBlock() {
    return new Block("2018-11-11 00:00:00", "Genesis block of simple chain", "");
}

區塊鏈的構造方法也應改為:

class BlockChain {
    constructor() {
        this.chain = [this.createGenesisBlock()];
    }
}

添加區塊

每新加一個區塊,必須保證與原有區塊鏈連接起來,即:

class BlockChain {
    getLatestBlock() {
        return this.chain[this.chain.length - 1];
    }
    
    addBlock(newBlock) {
        //新區塊的前一個hash值是現有區塊鏈的最后一個區塊的hash值;
        newBlock.previousHash = this.getLatestBlock().hash;
        //重新計算新區塊的hash值(因為指定了previousHash);
        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值對不上,說明該區塊有數據被篡改,hash值未重新計算
        if (currentBlock.hash !== currentBlock.calculateHash()) {
            console.error("hash not equal: " + JSON.stringify(currentBlock));
            return false;
        }
        //判斷當前區塊的previousHash是否真的等于前一個區塊的hash,若不等,說明前一個區塊被篡改,雖然hash值被重新計算正確,但是后續區塊的hash值并未重新計算,導致整個鏈斷裂
        if (currentBlock.previousHash !== previousBlock.calculateHash) {
            console.error("previous hash not right: " + JSON.stringify(currentBlock));
            return false;
        }
    }
    return true;
}

Just run it

跑起來看看,即:

let simpleChain = new BlockChain();
simpleChain.addBlock(new Block("2018-11-11 00:00:01", {amount: 10}));
simpleChain.addBlock(new Block("2018-11-11 00:00:02", {amount: 20}));


console.log(JSON.stringify(simpleChain, null, 4));

console.log("is the chain valid? " + simpleChain.isChainValid());

結果如下:

ali-186590cc4a7f:simple-chain shanyao$ node main_1.js 
{
    "chain": [
        {
            "timestamp": "2018-11-11 00:00:00",
            "data": "Genesis block of simple chain",
            "previousHash": "",
            "hash": "fd56967ff621a4090ff71ce88fdd456547d1c92d2e93766b7e8791f7a5f91f89"
        },
        {
            "timestamp": "2018-11-11 00:00:01",
            "data": {
                "amount": 10
            },
            "previousHash": "fd56967ff621a4090ff71ce88fdd456547d1c92d2e93766b7e8791f7a5f91f89",
            "hash": "150b196268a0152e9f0e719ac131a722472a809f49bd507965029a78c7400529"
        },
        {
            "timestamp": "2018-11-11 00:00:02",
            "data": {
                "amount": 20
            },
            "previousHash": "150b196268a0152e9f0e719ac131a722472a809f49bd507965029a78c7400529",
            "hash": "274a7a13ed20118e8cb745654934a7e24a4d59333ba17dfbf5d4cfe0fa8a6e34"
        }
    ]
}
is the chain valid? true

注意看其中的previousHash與hash,確實是當前區塊的previousHash指向前一個區塊的hash。

篡改下試試

都說區塊鏈不可篡改,是真的嗎?讓我們篡改第2個區塊試試,如:

let simpleChain = new BlockChain();
simpleChain.addBlock(new Block("2018-11-11 00:00:01", {amount: 10}));
simpleChain.addBlock(new Block("2018-11-11 00:00:02", {amount: 20}));

console.log("is the chain valid? " + simpleChain.isChainValid());

//將第2個區塊的數據,由10改為15
simpleChain.chain[1].data = {amount: 15};

console.log("is the chain still valid? " + simpleChain.isChainValid());
console.log(JSON.stringify(simpleChain, null, 4));

結果如下:

ali-186590cc4a7f:simple-chain shanyao$ node main_1.js 
is the chain valid? true
hash not equal: {"timestamp":"2018-11-11 00:00:01","data":{"amount":15},"previousHash":"fd56967ff621a4090ff71ce88fdd456547d1c92d2e93766b7e8791f7a5f91f89","hash":"150b196268a0152e9f0e719ac131a722472a809f49bd507965029a78c7400529"}
is the chain still valid? false
{
    "chain": [
        {
            "timestamp": "2018-11-11 00:00:00",
            "data": "Genesis block of simple chain",
            "previousHash": "",
            "hash": "fd56967ff621a4090ff71ce88fdd456547d1c92d2e93766b7e8791f7a5f91f89"
        },
        {
            "timestamp": "2018-11-11 00:00:01",
            "data": {
                "amount": 15
            },
            "previousHash": "fd56967ff621a4090ff71ce88fdd456547d1c92d2e93766b7e8791f7a5f91f89",
            "hash": "150b196268a0152e9f0e719ac131a722472a809f49bd507965029a78c7400529"
        },
        {
            "timestamp": "2018-11-11 00:00:02",
            "data": {
                "amount": 20
            },
            "previousHash": "150b196268a0152e9f0e719ac131a722472a809f49bd507965029a78c7400529",
            "hash": "274a7a13ed20118e8cb745654934a7e24a4d59333ba17dfbf5d4cfe0fa8a6e34"
        }
    ]
}

顯然,篡改了數據之后,hash值并未重新計算,導致該區塊的hash值對不上。

再篡改下試試

那么,如果我們聰明點,篡改后把hash值也重新計算會如何?

let simpleChain = new BlockChain();
simpleChain.addBlock(new Block("2018-11-11 00:00:01", {amount: 10}));
simpleChain.addBlock(new Block("2018-11-11 00:00:02", {amount: 20}));

console.log("is the chain valid? " + simpleChain.isChainValid());
//篡改后重新計算hash值
simpleChain.chain[1].data = {amount: 15};
simpleChain.chain[1].hash = simpleChain.chain[1].calculateHash();
console.log("is the chain still valid? " + simpleChain.isChainValid());
console.log(JSON.stringify(simpleChain, null, 4));

結果如下:

ali-186590cc4a7f:simple-chain shanyao$ node main_1.js 
is the chain valid? true
previous hash not right: {"timestamp":"2018-11-11 00:00:02","data":{"amount":20},"previousHash":"150b196268a0152e9f0e719ac131a722472a809f49bd507965029a78c7400529","hash":"274a7a13ed20118e8cb745654934a7e24a4d59333ba17dfbf5d4cfe0fa8a6e34"}
is the chain still valid? false
{
    "chain": [
        {
            "timestamp": "2018-11-11 00:00:00",
            "data": "Genesis block of simple chain",
            "previousHash": "",
            "hash": "fd56967ff621a4090ff71ce88fdd456547d1c92d2e93766b7e8791f7a5f91f89"
        },
        {
            "timestamp": "2018-11-11 00:00:01",
            "data": {
                "amount": 15
            },
            "previousHash": "fd56967ff621a4090ff71ce88fdd456547d1c92d2e93766b7e8791f7a5f91f89",
            "hash": "74d139274fb692495b7c805dd5822faa0c5b5e6058b6beef96e87e18ab83a6b1"
        },
        {
            "timestamp": "2018-11-11 00:00:02",
            "data": {
                "amount": 20
            },
            "previousHash": "150b196268a0152e9f0e719ac131a722472a809f49bd507965029a78c7400529",
            "hash": "274a7a13ed20118e8cb745654934a7e24a4d59333ba17dfbf5d4cfe0fa8a6e34"
        }
    ]
}

顯然,第3個區塊的previousHash并未指向第2個區塊的hash。

是真的無法篡改嗎

其實并不是,如果我們再聰明一點,把后續區塊的hash值也重新計算一下,不就OK了嗎? 確實如此,如:

let simpleChain = new BlockChain();
simpleChain.addBlock(new Block("2018-11-11 00:00:01", {amount: 10}));
simpleChain.addBlock(new Block("2018-11-11 00:00:02", {amount: 20}));

console.log("is the chain valid? " + simpleChain.isChainValid());
//篡改第2個區塊
simpleChain.chain[1].data = {amount: 15};
simpleChain.chain[1].hash = simpleChain.chain[1].calculateHash();
//并把第3個區塊也重新計算
simpleChain.chain[2].previousHash = simpleChain.chain[1].hash;
simpleChain.chain[2].hash = simpleChain.chain[2].calculateHash();
console.log("is the chain still valid? " + simpleChain.isChainValid());
console.log(JSON.stringify(simpleChain, null, 4

關于如何用JS構建你自己的區塊鏈問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

上思县| 永福县| 巫溪县| 永泰县| 长垣县| 肥城市| 湘乡市| 阿荣旗| 应用必备| 咸阳市| 湖南省| 鄂尔多斯市| 昌都县| 武汉市| 阜平县| 尖扎县| 攀枝花市| 昆山市| 芒康县| 达拉特旗| 普兰县| 莆田市| 泰顺县| 儋州市| 富蕴县| 商都县| 临城县| 本溪市| 乌鲁木齐县| 依安县| 大名县| 若羌县| 绥阳县| 江油市| 淳安县| 邓州市| 正镶白旗| 伊金霍洛旗| 玛纳斯县| 营山县| 天津市|