区块链基础
内容纲要
这里讨论区块链的基本原理和实现,更多技术可与我联系🏸
技术等级
高级
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
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。