当前位置:   article > 正文

尝试使用JavaScript实现一个简单的区块链_js 区块链

js 区块链

本文使用JavaScript实现一个简单的区块链,主要在node.js环境中运行。使用crypto-js来为区块链中的块创建哈希加密,使用express.js来创建用于与区块链交互的API。

以下是实现区块链的步骤:

  1. 创建一个新的Node.js项目并安装必要的库:crypto-js、express。
  2. 定义区块链中的区块结构。每个块应该包含唯一的索引、时间戳和想要存储在块中的数据。
  3. 创建一个区块链类,包含一些操作区块的方法,例如向链中添加新块。
  4. 使用 express.js 创建api,可以使用postman查询区块链,添加交易,以及执行挖矿操作。
  5. 使用 postman 测试区块链。

1. 创建一个新的Node.js项目并安装必要的库:crypto-js、express。

首先初始化一个node项目:

npm init

在package.json文件中,添加type字段:

"type": "module"

安装crypto-js和express:

  1. npm install crypto-js
  2. npm install express
  3. npm install body-parser

在index.js中写入:

  1. import express from "express";
  2. import bodyParser from "body-parser";
  3. const app = express();
  4. const port = 3000;
  5. app.listen(port, () => {
  6. console.log(`Example app listening on port ${port}`);
  7. });

在terminal中输入:

node index.js

你将看到:

Server running on port 3000.

到这里,基本的node.js设置搞定。

2. 定义区块链中的区块结构。每个块应该包含唯一的索引、时间戳和想要存储在块中的数据。

新建blockchain.js文件,定义我们的区块结构:

  1. import crypto from "crypto-js";
  2. class Block {
  3. constructor(index, timestamp, transactions = [], previousHash = "") {
  4. this.index = index;
  5. this.timestamp = timestamp;
  6. this.transactions = transactions;
  7. this.previousHash = previousHash;
  8. this.hash = "";
  9. this.nonce = 0;
  10. }
  11. calcHash() {
  12. return crypto
  13. .SHA256(
  14. this.index +
  15. this.timestamp +
  16. JSON.stringify(this.transactions).toString() +
  17. this.previousHash +
  18. this.nonce,
  19. )
  20. .toString();
  21. }
  22. mineBlock(difficulty) {
  23. while (!this.hash.startsWith("0".repeat(difficulty))) {
  24. this.nonce++;
  25. this.hash = crypto
  26. .SHA256(
  27. this.index +
  28. this.timestamp +
  29. JSON.stringify(this.transactions).toString() +
  30. this.previousHash +
  31. this.nonce,
  32. )
  33. .toString();
  34. }
  35. }
  36. }

Block类包含6个属性,2个方法。

  • index:数字,区块的索引。
  • timestamp:数字,时间戳。
  • transactions:数组,储存每一笔交易信息。
  • previousHash:哈希值,记录上一个区块的哈希值。
  • hash:哈希值,记录当前区块的哈希值。
  • nonce:数字,用于找到满足特定条件的哈希值的随机数,pow相关。
  • calcHash:函数,计算哈希值,将indextimestamptransactionspreviousHashnonce拼接在一起输出哈希值。
  • mineBlock:函数,用于工作量证明的方法,接受一个代表复杂度的数字。本文对于工作量证明的计算条件为:寻找前4位为0的哈希值。

3. 创建一个区块链类,包含一些操作区块的方法,例如向链中添加新块。

同样在blockchain.js文件中,定义一个区块链类:

  1. export class Blockchain {
  2. constructor() {
  3. this.difficulty = 4;
  4. this.pendingTrasactions = [];
  5. this.chain = [this.createGenesisBlock()];
  6. }
  7. createGenesisBlock() {
  8. const genesisPreviousHash = "0".repeat(64);
  9. const genesisBlock = new Block(0, Date.now(), [], genesisPreviousHash);
  10. genesisBlock.mineBlock(this.difficulty);
  11. genesisBlock.transactions.push({
  12. sender: "",
  13. recipient: genesisBlock.hash,
  14. amount: 50,
  15. });
  16. return genesisBlock;
  17. }
  18. createBlock() {
  19. const minerReward = {
  20. sender: "",
  21. recipient: "miner_adress",
  22. amount: 50,
  23. };
  24. this.pendingTrasactions.push(minerReward);
  25. const block = new Block(
  26. this.getLatestBlock().index + 1,
  27. Date.now(),
  28. this.pendingTrasactions,
  29. this.getLatestBlock().hash,
  30. );
  31. block.mineBlock(this.difficulty);
  32. this.chain.push(block);
  33. this.pendingTrasactions = [];
  34. }
  35. getLatestBlock() {
  36. return this.chain[this.chain.length - 1];
  37. }
  38. createTransaction(transaction) {
  39. this.pendingTrasactions.push(transaction);
  40. return this.chain[this.chain.length - 1].index + 1;
  41. }
  42. }

Blockchain类包含3个属性,4个方法。

  • difficulty:数字,代表复杂度的数字。
  • pendingTrasactions:数组,资源池,用于存储每一笔交易。当新的区块产生时,会将资源池中的交易信息存入新区块中。
  • chain:数组,储存每一个区块。
  • createGenesisBlock:函数,创建第一个区块(创世块)。
  • createBlock:函数,创建新区块。
  • getLatestBlock:函数,返回最后一个区块。
  • createTransaction:函数,创建一笔交易,返回将被写入区块的索引值。

4. 使用 express.js 创建api,可以使用postman查询区块链,添加交易,以及执行挖矿操作。

接下来需要实现三个api,分别是:

  1. GET /chain //查看区块链
  2. GET /mine //执行挖矿,成功后增加一个区块
  3. POST /transactions/new //添加一笔交易

回到index.js中,导入blockchain.js,并添加route: 

  1. import express from "express";
  2. import bodyParser from "body-parser";
  3. import { Blockchain } from "./blockchain.js";
  4. const app = express();
  5. const port = 3000;
  6. app.listen(port, () => {
  7. console.log(`Example app listening on port ${port}`);
  8. });
  9. app.use(express.json());
  10. app.use(bodyParser.urlencoded({ extended: false }));
  11. app.use(bodyParser.json());
  12. const blockchain = new Blockchain();
  13. app.get("/mine", (req, res) => {
  14. blockchain.createBlock();
  15. res.status(200).send(blockchain.chain[blockchain.chain.length - 1]);
  16. });
  17. app.post("/transactions/new", (req, res) => {
  18. // const transaction = {
  19. // sender: "sender_adress",
  20. // recipient: "recipient_adress",
  21. // amount: 50,
  22. // };
  23. const transaction = req.body;
  24. const blockNumber = blockchain.createTransaction(transaction);
  25. res.status(200).send(`will be added to block ${blockNumber}`);
  26. });
  27. app.get("/chain", (req, res) => {
  28. res.status(200).send(blockchain.chain);
  29. });

5. 使用 postman 测试区块链。

测试 GET http://localhost:3000/chain

测试 GET http://localhost:3000/mine
 

mine.png


测试 POST http://localhost:3000/transactions/new
 

:transactions:new.png

 

文章不断跟新,欢迎长期关注,同时如有错误请评论区或私信纠正互相研究学习!

VX:LALAKO_2

社区:http://t.csdnimg.cn/CNPxZ

免责声明:我们研究和内容中提供的信息仅供参考,不应被视为财务或投资建议。投资或参与金融活动的任何决定完全由你负责。我们不认可或推荐任何特定的投资策略,个人在做出任何投资决策之前应进行自己的研究并寻求专业建议。我们不对因将我们的内容用于投资目的而导致的任何财务损失、损害或不便承担责任。请始终注意与金融市场相关的风险,并在做出任何投资选择之前仔细考虑你的财务状况和风险承受能力。 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/971815
推荐阅读
相关标签
  

闽ICP备14008679号