赞
踩
本文使用JavaScript实现一个简单的区块链,主要在node.js环境中运行。使用crypto-js来为区块链中的块创建哈希加密,使用express.js来创建用于与区块链交互的API。
以下是实现区块链的步骤:
首先初始化一个node项目:
npm init
在package.json文件中,添加type字段:
"type": "module"
安装crypto-js和express:
- npm install crypto-js
- npm install express
- npm install body-parser
在index.js中写入:
- import express from "express";
- import bodyParser from "body-parser";
-
- const app = express();
- const port = 3000;
-
- app.listen(port, () => {
- console.log(`Example app listening on port ${port}`);
- });
在terminal中输入:
node index.js
你将看到:
Server running on port 3000.
到这里,基本的node.js设置搞定。
新建blockchain.js
文件,定义我们的区块结构:
import crypto from "crypto-js"; class Block { constructor(index, timestamp, transactions = [], previousHash = "") { this.index = index; this.timestamp = timestamp; this.transactions = transactions; this.previousHash = previousHash; this.hash = ""; this.nonce = 0; } calcHash() { return crypto .SHA256( this.index + this.timestamp + JSON.stringify(this.transactions).toString() + this.previousHash + this.nonce, ) .toString(); } mineBlock(difficulty) { while (!this.hash.startsWith("0".repeat(difficulty))) { this.nonce++; this.hash = crypto .SHA256( this.index + this.timestamp + JSON.stringify(this.transactions).toString() + this.previousHash + this.nonce, ) .toString(); } } }
Block
类包含6个属性,2个方法。
index
:数字,区块的索引。timestamp
:数字,时间戳。transactions
:数组,储存每一笔交易信息。previousHash
:哈希值,记录上一个区块的哈希值。hash
:哈希值,记录当前区块的哈希值。nonce
:数字,用于找到满足特定条件的哈希值的随机数,pow相关。calcHash
:函数,计算哈希值,将index
, timestamp
, transactions
, previousHash
, nonce
拼接在一起输出哈希值。mineBlock
:函数,用于工作量证明的方法,接受一个代表复杂度的数字。本文对于工作量证明的计算条件为:寻找前4位为0的哈希值。同样在blockchain.js
文件中,定义一个区块链类:
export class Blockchain { constructor() { this.difficulty = 4; this.pendingTrasactions = []; this.chain = [this.createGenesisBlock()]; } createGenesisBlock() { const genesisPreviousHash = "0".repeat(64); const genesisBlock = new Block(0, Date.now(), [], genesisPreviousHash); genesisBlock.mineBlock(this.difficulty); genesisBlock.transactions.push({ sender: "", recipient: genesisBlock.hash, amount: 50, }); return genesisBlock; } createBlock() { const minerReward = { sender: "", recipient: "miner_adress", amount: 50, }; this.pendingTrasactions.push(minerReward); const block = new Block( this.getLatestBlock().index + 1, Date.now(), this.pendingTrasactions, this.getLatestBlock().hash, ); block.mineBlock(this.difficulty); this.chain.push(block); this.pendingTrasactions = []; } getLatestBlock() { return this.chain[this.chain.length - 1]; } createTransaction(transaction) { this.pendingTrasactions.push(transaction); return this.chain[this.chain.length - 1].index + 1; } }
Blockchain
类包含3个属性,4个方法。
difficulty
:数字,代表复杂度的数字。pendingTrasactions
:数组,资源池,用于存储每一笔交易。当新的区块产生时,会将资源池中的交易信息存入新区块中。chain
:数组,储存每一个区块。createGenesisBlock
:函数,创建第一个区块(创世块)。createBlock
:函数,创建新区块。getLatestBlock
:函数,返回最后一个区块。createTransaction
:函数,创建一笔交易,返回将被写入区块的索引值。接下来需要实现三个api,分别是:
- GET /chain //查看区块链
- GET /mine //执行挖矿,成功后增加一个区块
- POST /transactions/new //添加一笔交易
回到index.js中,导入blockchain.js,并添加route:
import express from "express"; import bodyParser from "body-parser"; import { Blockchain } from "./blockchain.js"; const app = express(); const port = 3000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); }); app.use(express.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); const blockchain = new Blockchain(); app.get("/mine", (req, res) => { blockchain.createBlock(); res.status(200).send(blockchain.chain[blockchain.chain.length - 1]); }); app.post("/transactions/new", (req, res) => { // const transaction = { // sender: "sender_adress", // recipient: "recipient_adress", // amount: 50, // }; const transaction = req.body; const blockNumber = blockchain.createTransaction(transaction); res.status(200).send(`will be added to block ${blockNumber}`); }); app.get("/chain", (req, res) => { res.status(200).send(blockchain.chain); });
测试 GET http://localhost:3000/chain:
测试 GET http://localhost:3000/mine:
测试 POST http://localhost:3000/transactions/new:
文章不断跟新,欢迎长期关注,同时如有错误请评论区或私信纠正互相研究学习!
VX:LALAKO_2
免责声明:我们研究和内容中提供的信息仅供参考,不应被视为财务或投资建议。投资或参与金融活动的任何决定完全由你负责。我们不认可或推荐任何特定的投资策略,个人在做出任何投资决策之前应进行自己的研究并寻求专业建议。我们不对因将我们的内容用于投资目的而导致的任何财务损失、损害或不便承担责任。请始终注意与金融市场相关的风险,并在做出任何投资选择之前仔细考虑你的财务状况和风险承受能力。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。