区块链基础

内容纲要

这里讨论区块链的基本原理和实现,更多技术可与我联系🏸

技术等级
高级

Server

首先是服务搭建,建议使用ES草案(即将发布为推荐标准),将高级ES编译为二进制低级ES,性能和C/C++一样,就不用担心各种性能问题了。

为了简化步骤,我使用Express,所有代码均为演示,不建议实际项目使用。

启动服务

/*
 * @Author: indeex
 * @Date: 2018-06-24 15:21:53
 * @LastEditors: indeex
 * @LastEditTime: 2018-06-25 15:50:39
 * @Description: This is blockchain base with indeex.
 * @WebSite: http://www.indeex.cc
 * @Email: indeex@qq.com
 */

import express from 'express';
import bodyParser from 'body-parser';

const app: express.Application = express();

const port: number = 3000;

app.use(bodyParser.json());

app.listen(port, () => {
    console.log('server start...');
});

设置路由

import { Router, Request, Response} from 'express';

const router: Router = Router();

router.get('/', (req: Request, res: Response) => {
    res.json({
        index: 'index'
    });
});

export const HomeControllerRouter: Router = router;

使用路由

import {HomeControllerRouter} from './router/homeController';

//...

app.use('/', HomeControllerRouter);

基本服务搭建就绪。

为了简化,这里不再对路由进行拆分。

路由分配

router.get('/', (req: Request, res: Response) => {
    console.log(req.params);
});

router.get('/blockchain/transactions', (req: Request, res: Response) => {
    console.log(req.params);
});

router.get('/blockchain/mine', (req: Request, res: Response) => {
    console.log(req.params);
});

router.get('/blockchain/blocks', (req: Request, res: Response) => {
    console.log(req.params);
});

这里只做了路由访问的演示,以便简化。

Transaction

交易接口及实现

首先是交易接口:

interface TransactionData{
    from: string;
    to: string;
    amount: number;
    timestamp: number;
}

只需要实现接口即可:

class Transaction implements TransactionData{
    constructor(
        public from: string,
        public to: string,
        public amount: number,
        public timestamp:number
    ){
    }
}

Block

交易块接口:

interface BlockData{
    index: number;
    hash: string;
    previousHash: string;
    nonce: number;//临时匹配
    transactions: TransactionData[];
    key: string;
}

接口实现:

class Block implements BlockData{
    constructor(
        public index: number = 0,
        public hash: string = '',
        public previousHash: string = '',
        public nonce: number = 0,
        public transactions: TransactionData[] = []
    ){
    }
}

接着需要在Block中获取需要的key,这里使用getter

get key():string{
        return JSON.stringify(this.transactions) + this.index + this.previousHash + this.nonce;
}

接着创建增加交易的方法:

public addTransaction(transaction: TransactionData) :void{
    this.transactions = [...this.transactions, transaction];
}

将每次交易添加到交易链中。

Blockchain

接下来,处理所有链,首先是链接口和基本类实现:

接口;

interface BlockChainData{
     blocks: BlockData[];
 }

接口实现:

class BlockChain implements BlockChainData{
    public blocks: BlockData[];
    public difficulty: number;
    constructor(genesisBlock: BlockData){
        this.blocks = [];
        this.difficulty = 2;
    }
}

在类初始化时,需要创建交易块,并创世块处理:

constructor(genesisBlock: BlockData){
    this.addBlock(genesisBlock);
}

//...


public addBlock(block: BlockData) :void{
    if(this.blocks.length === 0){
        block.previousHash = '00000000';
        block.hash = null;
    }
    this.blocks = [...this.blocks, block];
}

然后生成交易块的hash,这里简化处理:

 public generateHash(block: BlockData):string{
    let hash = sha256(block.key);
    while(!hash.startsWith("7a7")){
        block.nonce += 1;
        hash = sha256(block.key);
    }
    return hash;
}

获取前一个交易块:

public getPreviousBlock():BlockData{
    return this.blocks[this.blocks.length - 1];
}

获取后一个交易块:

public getNextBlock(transactions: TransactionData[]): BlockData{
    let block = new Block();
    transactions.map((t: TransactionData) => {
        block.addTransaction(t);
    });
    let previousBlock = this.getPreviousBlock();
    block.index = this.blocks.length;
    block.previousHash = previousBlock.hash;
    block.hash = this.generateHash(block);
    return block;
}

然后开始验证交易块,这里建议当交易块不是最新时取最长交易链。

Valid

交易链验证略。

Publish

验证后就可以发布了:

发布后可以查看所有交易链:

router.get('/blockchain/blocks', (req: Request, res: Response) => {
    let timestamp = new Date();
    let transaction = new Transaction('me', 'you', 100, Number(timestamp));
    let newBlock = blockchain.getNextBlock([transaction]);
    blockchain.addBlock(newBlock);
    res.json(blockchain.blocks);
});

接下来将所有交易写入数据库,可以选用目前主流的Oracle,Mysql,或者mongo,由于所有编程语言对数据库的操作速度、性能、效率基本一致,需要哪种数据库以项目及技术方向为主。

code enjoy! ÒܫÓ

作者:indeex

链接:http://indeex.cc

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


发表评论

您的电子邮箱地址不会被公开。