当前位置:主页 > 查看内容

区块链的简单实现

发布时间:2021-10-03 00:00| 位朋友查看

简介:区块链的简单实现 什么是区块链 块结构 创世区块 hash 验证块的有效性 记录数据 从其他节点接收一个块 编写测试代码 测试结果 完整代码 什么是区块链 一个维护着一个持续增长的有序数据记录列表的这么一个分布式数据库 下面我将简单用nodejs实现一个简单的区……

什么是区块链

一个维护着一个持续增长的有序数据记录列表的这么一个分布式数据库

下面我将简单用nodejs实现一个简单的区块链,它具有区块链的基本特性,但没有涉及PoS of PoW。

块结构

在这里插入图片描述
一个块Block一般有:

  • index 块号
  • previousHash 上一个区块的hash值
  • timestamp 时间戳
  • data 存放的数据
  • hash 区块的hash值
class Block {
    constructor(index, previousHash, timestamp, data, hash) {
        this.index = index;
        this.previousHash = previousHash;
        this.timestamp = timestamp;
        this.data = data;
        this.hash = hash.toString();
    }
    toString(){
        return "\n{\nindex:"+this.index+",\npreviousHash:'"+this.previousHash+"',\ntimestamp:"+this.timestamp+",\ndata:'"+this.data+"',\nhash:'"+this.hash+"'\n}\n"
    }
}

我们每生成一个区块,我们都会给这个区块按照特定的hash算法,来得到一个hash值,一般来说,只要这个区块的index,previoushash,timestamp,data有改动,那么它所算出的hash值也会改变,所以当你想要篡改某个区块的数据时,你需要将后面所有的区块的previoushash都进行篡改。

创世区块

第一个区块是没有前置hash的,是特殊的一个区块,我们用代码将这个区块写死

const genesisBlock = new Block.Block(
    0, null, 1619079309.946, "genesis block", '80dea37cccca5fb56b9b78dbe2733fb19e8ee2aa7bb03d4ac1e361fe3fad7b51'
);

hash

本文采用sha256来求得hash值

exports.caHash=function (index, previousHash, timestamp, data){
   	return sha256(index + previousHash + timestamp + data).toString();
}

验证块的有效性

下面是验证单个块是否有效,可以根据下面遍历整个链是否有效。

vaildBlock(block,lastBlock) {
        if (!Block.isValidBlockStructure(block))
            return false;
        if (
            (block.index==lastBlock.index+1)
            &&(block.previousHash==lastBlock.previousHash)
            &&Block.caHash(block.index,block.previousHash,block.timestamp,block.data)
        )
            return true;
        return false;
    }

记录数据

creatBlock(data){
        var lastBlock=this.getLastBlock();
        var newIndex=lastBlock.index+1;
        var newTime=new Date().getTime()/1000;
        var newPreHash=lastBlock.hash;
        var newhash=Block.caHash(newIndex,newPreHash,newTime,data.toString());
        return this.blocks[this.blocks.length]= new Block.Block(
            newIndex, newPreHash, newTime, data, newhash
        );

    }

从其他节点接收一个块

addBlock(block){
        if (validBlock(block,this.getLastBlock())){
            blocks.push(block);
            return true;
        }
        return false;
    }

编写测试代码

var Chain=require("./Chain");
var BlockChain=new Chain.BlockChain();
var http=require('http');
var fs=require('fs');
var querystring=require('querystring');

var server=http.createServer(function (req,res) {
    var url=req.url;
    if (url=="/get"){
        res.writeHead(200,{'content-type':'text/plain'+'charset=UTF8'});
        var str=BlockChain.blocks;
        res.end(str.toString());
    }else if (url=="/creat"){
        var data=[];
        req.on('data',function (chunk) {
            data.push(chunk);
        })
        req.on('end',function (chunk){
            var dataObj=querystring.parse(data.toString())
            BlockChain.creatBlock(dataObj["data"]);
            var lastblock=BlockChain.getLastBlock();
            res.setHeader('content-type','text/plain;charset=UTF8');
            res.write(lastblock.toString());
            res.end("生成区块"+lastblock.index+"号成功!");
        })

    }else {
        res.setHeader('content-type','text/html;charset=UTF8');
        fs.readFile('./client.html',function (err,data) {
            res.write(data);
            res.end();
        })
    }

});
server.listen(2345);

测试结果

在这里插入图片描述
输入一些数据,然后点击生成区块:
在这里插入图片描述
点击获取区块链:
在这里插入图片描述

完整代码

你可以从仓库里获取完整代码:

github: https://github.com/Lixingwei0623/ablockchain.
gitee: https://gitee.com/li-xingwei/simple-block-chain.

;原文链接:https://blog.csdn.net/qq_43289711/article/details/116082281
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!
上一篇:ASP 中使用 HTTP 协议发送参数详解 下一篇:没有了

推荐图文


随机推荐