国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

區(qū)塊鏈筆記(4)用JS寫個(gè)簡(jiǎn)單的區(qū)塊鏈原型

W_BinaryTree / 753人閱讀

摘要:介紹了一些關(guān)于比特幣的概念與機(jī)制,為了加深理解,本文基于來實(shí)現(xiàn)一個(gè)簡(jiǎn)單的區(qū)塊鏈原型,后續(xù)再對(duì)其進(jìn)行不斷豐富。概述如前所述區(qū)塊鏈模型的組成部分,包括區(qū)塊,區(qū)塊構(gòu)成的區(qū)塊鏈,以及保存區(qū)塊鏈的數(shù)據(jù)持久層等。

介紹了一些關(guān)于比特幣的概念與機(jī)制,為了加深理解,本文基于JavaScript來實(shí)現(xiàn)一個(gè)簡(jiǎn)單的區(qū)塊鏈原型,后續(xù)再對(duì)其進(jìn)行不斷豐富。
1. 概述

如前所述區(qū)塊鏈模型的組成部分,包括區(qū)塊,區(qū)塊構(gòu)成的區(qū)塊鏈,以及保存區(qū)塊鏈的數(shù)據(jù)持久層等。一個(gè)超簡(jiǎn)單的UML類圖如下:

由于我是前端的,業(yè)余看了這么久區(qū)塊鏈的理論,還是手癢癢謝謝代碼,把這個(gè)類用JavaScript實(shí)現(xiàn)一下。寫完之后發(fā)現(xiàn)目前階段,對(duì)于區(qū)塊鏈原型來說還是太過簡(jiǎn)單,不過如果說用來做前端面試題,考察下面向?qū)ο蠛蚉romise等知識(shí)點(diǎn)倒是挺接洽。

2. 定義區(qū)塊數(shù)據(jù)模型

摘取比特幣區(qū)塊的詳情進(jìn)行修改,去除所有多余信息,只留下能描述區(qū)塊最基本的信息,聲明區(qū)塊類如下:

class Block {
    constructor(data) {
        // 區(qū)塊的屬性值
        this.hash = "";
        this.height = 0;
        this.body = data;
        this.time = 0;
        this.previousBlockHash = "";
    }
}

module.exports.Block = Block;
3. 數(shù)據(jù)持久層

其實(shí)用數(shù)組實(shí)現(xiàn)區(qū)塊鏈?zhǔn)亲詈?jiǎn)單的原型方案,但每次重啟數(shù)組都會(huì)被清空,數(shù)據(jù)并不持久。所以這里引入levelDB數(shù)據(jù)庫作為持久層來保存數(shù)據(jù),相關(guān)操作可參考level。由于直接調(diào)用API,對(duì)于應(yīng)用層來說過于麻煩,所以在此聲明一個(gè)數(shù)據(jù)操作類LevelSandbox,該類不像傳統(tǒng)的關(guān)系型數(shù)據(jù)庫具有增、刪、改、查等全部功能,由于區(qū)塊鏈上數(shù)據(jù)的不可更改性,此類只包含增和查的操作。

3.1 根據(jù)key從數(shù)據(jù)庫中獲取數(shù)據(jù)

本文如下相關(guān)異步實(shí)現(xiàn),都采用Promise的方式而非回調(diào),其中好處作為前端工程師此處就不多介紹了,有需要了解的可異步Promise介紹,自行擴(kuò)展閱讀。

getLevelDBData(key) {
    let self = this;
    return new Promise(function(resolve, reject) {
        self.db.get(key)
            .then(value => {
                console.log("Value = " + value);
                resolve(value)
            })
            .catch(err => {
                console.log("Not found!");
                reject(err)
            })
    });
}
3.2 將key/value數(shù)據(jù)插入數(shù)據(jù)庫中

key/value的方式在數(shù)據(jù)庫中存儲(chǔ),其key值得選取,這里考慮使用區(qū)塊類中聲明的height字段,該字段標(biāo)識(shí)一個(gè)區(qū)塊在鏈中的位序,同時(shí)也具有唯一性,非常合適。

addLevelDBData(key, value) {
    let self = this;
    return new Promise(function(resolve, reject) {
        self.db.put(key, value)
            .then(() => resolve())
            .catch((err) => {
                console.log("Block " + key + " submission failed");
                reject(err)
            })
    });
}
3.3 獲取數(shù)據(jù)庫中區(qū)塊總數(shù)

createReadStream()方法創(chuàng)建一個(gè)讀取數(shù)據(jù)庫的流,這里的作用是為了遍歷整庫以獲取存儲(chǔ)的區(qū)塊總數(shù),另外此方法還可通過傳參,設(shè)置遍歷次序,詳情可參閱文檔。

getBlocksCount() {
    let self = this;
    return new Promise(function(resolve, reject){
        let height = 0;
        self.db.createReadStream()
            .on("data", function () {
                height++;
            })
            .on("error", function (error) {
                reject("Unable to read data stream!", error);
            })
            .on("close", function () {
                resolve(height);
            });
    });
}
4. 區(qū)塊鏈類

該類主要負(fù)責(zé)將新創(chuàng)建的區(qū)塊添加進(jìn)區(qū)塊鏈,并驗(yàn)證鏈中各個(gè)區(qū)塊的數(shù)據(jù)完整性。這個(gè)過程中少不了對(duì)區(qū)塊數(shù)據(jù)的哈希處理,為方便起見,采用第三方庫crypto-js實(shí)現(xiàn)的SHA256方法。

構(gòu)想該類中的主要方法包括:

createGenesisBlock():生成起始區(qū)塊

getBlockHeight():獲取區(qū)塊鏈長度

getBlock(height):獲取指定區(qū)塊

addBlock(block):將一個(gè)新區(qū)塊加入?yún)^(qū)塊鏈中

validateBlock(block):驗(yàn)證某個(gè)區(qū)塊

validateChain():驗(yàn)證區(qū)塊鏈

如下便實(shí)現(xiàn)其中主要的幾個(gè)方法:

4.1 增加新區(qū)塊

各個(gè)區(qū)塊通過previousBlockHash屬性,依次指向前一個(gè)區(qū)塊來連接成鏈的,除首區(qū)塊該屬性為空外。

addBlock(block) {
    return this.getBlockHeight()
        .then(height => {
            區(qū)塊高度
            block.height = height;
            // UTC 時(shí)間戳
            block.time = new Date().getTime().toString().slice(0, -3);
            if (height > 0) {
                this.getBlock(height - 1)
                    .then(preBlock => {
                        // 前一個(gè)區(qū)塊的哈希值
                        block.previousBlockHash = preBlock.hash;
                        // 對(duì)區(qū)塊進(jìn)行哈希處理
                        block.hash = SHA256(JSON.stringify(block)).toString();
                        // 將新區(qū)快存入庫中
                        this.bd.addLevelDBData(height, JSON.stringify(block));
                    })
                    .catch(error => console.log(error));
            } else {
                block.hash = SHA256(JSON.stringify(block)).toString();
                this.bd.addLevelDBData(height, JSON.stringify(block));
            }
        })
        .catch( error => console.log(error));
}
4.2 驗(yàn)證單個(gè)區(qū)塊完整性

驗(yàn)證方法就是應(yīng)用了hash算法的性質(zhì):相同的數(shù)據(jù)經(jīng)過hash后會(huì)生成相同的hash值。

validateBlock(height) {
        // 獲取區(qū)塊的值
        return this.getBlock(height)
            .then(block => {
                const objBlock = JSON.parse(block);
                let blockHash = objBlock.hash;
                objBlock.hash = "";
                // 重新生成區(qū)塊的哈希值
                let validBlockHash = SHA256(JSON.stringify(objBlock)).toString();
                objBlock.hash = blockHash;
                // 比較以驗(yàn)證完整性
                if (blockHash === validBlockHash) {
                    return Promise.resolve({isValidBlock: true, block: objBlock});
                } else {
                    console.log("Block #"+blockHeight+" invalid hash:
"+blockHash+"<>"+validBlockHash);
                    return Promise.resolve({isValidBlock: false, block: objBlock});
                }
            })
    }
4.3 驗(yàn)證整個(gè)區(qū)塊鏈

通過依次校驗(yàn)每個(gè)區(qū)塊以驗(yàn)證整條鏈的完整性。

validateChain() {
    let errorLog = [];
    let previousHash = "";
    this.getBlockHeight()
        .then(height => {
            for (let i = 0; i < height; i++) {
                this.getBlock(i)
                    .then(block => this.validateBlock(block.height))
                    .then(({isValidBlock, block}) => {
                        if (!isValidBlock) errorLog.push(i);
                        if (block.previousBlockHash !== previousHash) errorLog.push(i);
                        previousHash = block.hash;
                        if (i === height - 1) {
                            if (errorLog.length > 0) {
                                console.log(`Block errors = ${errorLog.length}`)
                                console.log(`Blocks: ${errorLog}`)
                            } else {
                                console.log("No errors detected")
                            }
                        }
                    })
            }
        })
}
5. 生成測(cè)試數(shù)據(jù)
(function theLoop (i) {
    setTimeout(function () {
        let blockTest = new Block.Block("Test Block - " + (i + 1));
        myBlockChain.addBlock(blockTest).then((result) => {
            console.log(result);
            i++;
            if (i < 10) theLoop(i);
        });
    }, 10000);
})(0);

作為一個(gè)區(qū)塊鏈原型的樣子算是初見端倪,但就目前的功能來說還非常簡(jiǎn)陋,說是原型都算抬舉了,不過后面慢慢再豐富吧。這里也只算是對(duì)之前的一個(gè)實(shí)踐性的小節(jié)。

文中以列出主要代碼片段,整體實(shí)現(xiàn)其實(shí)不難,沒貼出所有代碼主要是為了表述思路更清晰些,若有朋友實(shí)現(xiàn)過程中有問題,可文下留言交流。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/109909.html

相關(guān)文章

  • 區(qū)塊筆記4JS寫個(gè)簡(jiǎn)單區(qū)塊原型

    摘要:介紹了一些關(guān)于比特幣的概念與機(jī)制,為了加深理解,本文基于來實(shí)現(xiàn)一個(gè)簡(jiǎn)單的區(qū)塊鏈原型,后續(xù)再對(duì)其進(jìn)行不斷豐富。概述如前所述區(qū)塊鏈模型的組成部分,包括區(qū)塊,區(qū)塊構(gòu)成的區(qū)塊鏈,以及保存區(qū)塊鏈的數(shù)據(jù)持久層等。 介紹了一些關(guān)于比特幣的概念與機(jī)制,為了加深理解,本文基于JavaScript來實(shí)現(xiàn)一個(gè)簡(jiǎn)單的區(qū)塊鏈原型,后續(xù)再對(duì)其進(jìn)行不斷豐富。 1. 概述 如前所述區(qū)塊鏈模型的組成部分,包括區(qū)塊,區(qū)塊...

    binaryTree 評(píng)論0 收藏0
  • 區(qū)塊上編程:DApp 開發(fā)實(shí)戰(zhàn)——來寫個(gè)競(jìng)猜游戲吧

    摘要:合約編寫可以看出合約需要實(shí)現(xiàn)用戶投注生成隨機(jī)數(shù)發(fā)放獎(jiǎng)勵(lì)獎(jiǎng)池余額查詢的功能,接下來編寫我們的合約代碼??偨Y(jié)當(dāng)前隨機(jī)數(shù)的實(shí)現(xiàn)通過鏈上信息生成,這種生成隨機(jī)數(shù)的方式容易受到不誠實(shí)的節(jié)點(diǎn)攻擊。 導(dǎo)讀:本文旨在引導(dǎo)對(duì) DApp 開發(fā)感興趣的開發(fā)者,構(gòu)建一個(gè)基于以太坊去中心化應(yīng)用,通過開發(fā)一款功能完備的競(jìng)猜游戲,邁出 DApp 開發(fā)的第一步,通過實(shí)例講解 Solidity 語言的常用語法,以及前端...

    codecook 評(píng)論0 收藏0
  • 300行ABAP代碼實(shí)現(xiàn)一個(gè)最簡(jiǎn)單區(qū)塊原型

    摘要:我的這篇文章沒有任何高大上的術(shù)語,就是行代碼,實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的區(qū)塊鏈原型。檢查該區(qū)塊鏈?zhǔn)欠裼行?。而通過在循環(huán)里不斷嘗試最終得到一個(gè)合法的哈希值的這一過程,就是區(qū)塊鏈圈內(nèi)俗稱的挖礦。 不知從什么時(shí)候起,區(qū)塊鏈在網(wǎng)上一下子就火了。 showImg(https://segmentfault.com/img/remote/1460000014744826); 這里Jerry就不班門弄斧了,網(wǎng)上...

    cikenerd 評(píng)論0 收藏0
  • 300行ABAP代碼實(shí)現(xiàn)一個(gè)最簡(jiǎn)單區(qū)塊原型

    摘要:我的這篇文章沒有任何高大上的術(shù)語,就是行代碼,實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的區(qū)塊鏈原型。檢查該區(qū)塊鏈?zhǔn)欠裼行?。而通過在循環(huán)里不斷嘗試最終得到一個(gè)合法的哈希值的這一過程,就是區(qū)塊鏈圈內(nèi)俗稱的挖礦。 不知從什么時(shí)候起,區(qū)塊鏈在網(wǎng)上一下子就火了。 showImg(https://segmentfault.com/img/remote/1460000014744826); 這里Jerry就不班門弄斧了,網(wǎng)上...

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

    摘要:本文將基于語言構(gòu)建簡(jiǎn)化版的,來實(shí)現(xiàn)數(shù)字貨幣。值用于確保的安全。計(jì)算是計(jì)算敏感的操作,即使在高性能電腦也需要花費(fèi)一段時(shí)間來完成計(jì)算這也就是為什么人們購買高性能進(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

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

0條評(píng)論

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