区块链:通过演示Demo理解区块链运行原理

本文深入浅出地介绍了区块链的基本概念和技术细节,包括区块结构、散列算法、挖矿过程及P2P网络通信机制。通过具体示例展示了如何构建一个简单的区块链系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BlockChain Demo

打开比特币Demo演示网页区块链Demo演示地址,我们可以看到如下页面。

这里写图片描述

点击开始演示

这里写图片描述

接下来是BlockChain Demo 2.0的新功能介绍

这里写图片描述

关于Demo功能区的介绍

这里写图片描述

并附有JavaScript代码和gitHubDemo地址

显示每个区块存储的信息

这里写图片描述

介绍区块链中区块的索引

这里写图片描述

介绍创建区块时候的时间戳
这里写图片描述

介绍区块中hash散列加密

这里写图片描述

介绍区块hash散列中前导零也就是难度的介绍

这里写图片描述

// cosnt Block = reuqire("./Block.js");

// class Blockchain {
  // constructor() {
    // this.blockchain = [Block.genesis()];
    this.difficulty = 3;
  // }

  // get() { ... }
  // get latestBlock() { ... }

  isValidHashDifficulty(hash) {
    for (var i = 0; i < hash.length; i++) {
      if (hash[i] !== "0") {
        break;
      };
    }
    return i >= this.difficulty;
  }
// };

// module.exports = Blockchain;

介绍Hash散列的生成规则

(索引+上一个散列+时间戳+数据+随机数)=散列
(0 +“0”+ 1508270000000 +“欢迎使用Blockchain Demo 2.0!”+ 604)= 000dc75a315c77a1f9c98fb6247d03dd18ac52632d7dc6a9920261d8109b37cf

这里写图片描述

介绍关于上一个区块中的Hash值
这里写图片描述

关于区块中的数据,这也是我们关注的

这里写图片描述

关于数据的变化,数据的微小变化都可以给Hash值带来巨大的变化。Hash值的是否有效,是我们设置的前导零难度决定的,符合前导零难度的规则才算是有效的Hash

这里写图片描述

假如一个区块链中的某一个区块中Hash值失效,那么它后面的区块都会失效
这里写图片描述

生成有效Hash散列的唯二变量就是数据和随机数,当我们需要的数据固定时,只有挖掘匹配的前导零难度的随机数才能寻找到新的区块

这里写图片描述

// const Block = require("./Block.js");
// const crypto = require("crypto");

// class Blockchain {
  // constructor() { ... }
  // get() { ... }
  // get latestBlock() { ... }
  // isValidHashDifficulty(hash) { ... }
  // calculateHashForBlock(block) { ... }
  // calculateHash(...) { ... }

  mine(data) {
    const newBlock = this.generateNextBlock(data);
    try {
      this.addBlock(newBlock);
    } catch (err) {
      throw err;
    };
  }
// };

// module.exports = Blockchain;

匹配查找有效Hash的数字,从0开始找,直到找到。随着难度的不断增加,有效散列的数量减少,因此匹配的计算力也会逐渐增大

这里写图片描述

新增新的区块

这里写图片描述

// const Block = require("./Block.js");
// const crypto = require("crypto");

// class Blockchain {
  // constructor() { ... }
  // get() { ... }
  // get latestBlock() { ... }
  // isValidHashDifficulty(hash) { ... }
  // calculateHashForBlock(block) { ... }
  // calculateHash(...) { ... }
  // mine(data) { ... }
  // generateNextBlock(data) { ... }

  addBlock(newBlock) {
    if (this.isValidNewBlock(newBlock, this.latestBlock)) {
      this.blockchain.push(newBlock);
    } else {
      throw "Error: Invalid block";
    }
  }
// };

// module.exports = Blockchain;

新增区块需要满足的要求

  1. 上一个区块的索引+1等于新的索引
  2. 上一个区块的hash要等于下一个区块的前导hash
  3. hash要满足前导零难度要求
  4. 正确的hash值

这里写图片描述

// const Block = require("./Block.js");
// const crypto = require("crypto");

// class Blockchain {
  // constructor() { ... }
  // get() { ... }
  // get latestBlock() { ... }
  // isValidHashDifficulty(hash) { ... }
  // calculateHashForBlock(block) { ... }
  // calculateHash(...) { ... }
  // mine(data) { ... }
  // generateNextBlock(data) { ... }
  // addBlock(newBlock) { ... }

  isValidNextBlock(nextBlock, previousBlock) {
    const nextBlockHash = this.calculateHashForBlock(nextBlock);

    if (previousBlock.index + 1 !== nextBlock.index) {
      return false;
    } else if (previousBlock.hash !== nextBlock.previousHash) {
      return false;
    } else if (nextBlockHash !== nextBlock.hash) {
      return false;
    } else if (!this.isValidHashDifficulty(nextBlockHash)) {
      return false;
    } else {
      return true;
    }
  }
// };

// module.exports = Blockchain;

全球的计算机网络共同维护,因此要确保区块链的安全性正确性一致性

P2p.js

const wrtc = require('wrtc');
const Exchange = require('peer-exchange');
const p2p = new Exchange("Blockchain Demo 2.0", { wrtc: wrtc });
const net = require("net");

class PeerToPeer {
  constructor(blockchain) {
    this.peers = [];
    this.blockchain = blockchain;
  }

  startServer(port) {
    const server = net
      .createServer(socket =>
        p2p.accept(socket, (err, conn) => {
          if (err) {
            throw err;
          } else {
            this.initConnection.call(this, conn);
          }
        })
      )
      .listen(port);
  }
}

module.exports = PeerToPeer;

同伴消息:链接对等方添加到网络

// const wrtc = require('wrtc');
// const Exchange = require('peer-exchange');
// const p2p = new Exchange(...);
// const net = require("net");

// class PeerToPeer {
  // constructor(blockchain) { ... }
  // startServer(port) { ... }

  discoverPeers() {
    p2p.getNewPeer((err, conn) => {
      if (err) {
        throw err;
      } else {
        this.initConnection.call(this, conn);
      }
    });
  }
// }

// module.exports = PeerToPeer;

同伴消息:Demo的三种同伴消息的状态

  • 蓝色:当前有效的
  • 绿色:连接的
  • 红色:断开连接的

改变:直接点击头像
链接:在红色对等方单击加号的图标
查看:在绿色的对等体单击短信图标
断开:点击绿色对等方上面的加号图标

这里写图片描述

P2p.js

// const wrtc = require('wrtc');
// const Exchange = require('peer-exchange');
// const p2p = new Exchange(...);
// const net = require("net");

// class PeerToPeer {
  // constructor(blockchain) { ... }
  // startServer(port) { ... }
  // discoverPeers() { ... }

  connectToPeer(host, port) {
    const socket = net.connect(port, host, () =>
      p2p.connect(socket, (err, conn) => {
        if (err) {
          throw err;
        } else {
          this.initConnection.call(this, conn);
        }
      })
    );
  }

  closeConnection() {
    p2p.close(err => {
      throw err;
    })
  }
// }

// module.exports = PeerToPeer;

同伴消息:确定谁拥有最新的区块链

Blockchain.js

// const wrtc = require('wrtc');
// const Exchange = require('peer-exchange');
// const p2p = new Exchange(...);
// const net = require("net");
const messageType = {
  REQUEST_LATEST_BLOCK: 0,
  RECEIVE_LATEST_BLOCK: 1,
  REQUEST_BLOCKCHAIN: 2,
  RECEIVE_BLOCKCHAIN: 3,
};
const {
  REQUEST_LATEST_BLOCK,
  RECEIVE_LATEST_BLOCK,
  REQUEST_BLOCKCHAIN,
  RECEIVE_BLOCKCHAIN,
  REQUEST_TRANSACTIONS,
  RECEIVE_TRANSACTIONS
} = messageType;

// class PeerToPeer { ... }
// module.exports = PeerToPeer;

class Messages {
  static getLatestBlock() {
    return {
      type: REQUEST_LATEST_BLOCK
    };
  }

  static sendLatestBlock(block) {
    return {
      type: RECEIVE_LATEST_BLOCK,
      data: block
    };
  }

  static getBlockchain() {
    return {
      type: REQUEST_BLOCKCHAIN
    };
  }

  static sendBlockchain(blockchain) {
    return {
      type: RECEIVE_BLOCKCHAIN,
      data: blockchain
    };
  }
}

逻辑图

这里写图片描述

P2p.js

// const wrtc = require('wrtc');
// const Exchange = require('peer-exchange');
// const p2p = new Exchange(...);
// const net = require("net");
// const messageType = { ... };
// const { ... } = messageType;

// class PeerToPeer {
  // constructor(blockchain) { ... }
  // startServer(port) { ... }
  // discoverPeers() { ... }
  // connectToPeer(host, port) { ... }
  // closeConnection() { ... }

  broadcastLatest() {
    this.broadcast(Messages.sendLatestBlock(this.blockchain.latestBlock));
  }

  broadcast(message) {
    this.peers.forEach(peer => this.write(peer, message));
  }

  write(peer, message) {
    peer.write(JSON.stringify(message));
  }

  initConnection(connection) {
    this.peers.push(connection);
    this.initMessageHandler(connection);
    this.initErrorHandler(connection);
    this.write(connection, Messages.getLatestBlock());
  }

  initMessageHandler(connection) {
    connection.on("data", data => {
      const message = JSON.parse(data.toString("utf8"));
      this.handleMessage(connection, message);
    });
  }

  initErrorHandler(connection) {
    connection.on("error", err => {
      throw err;
    });
  }

  handleMessage(peer, message) {
    switch (message.type) {
      case REQUEST_LATEST_BLOCK:
        this.write(peer, Messages.sendLatestBlock(this.blockchain.latestBlock));
        break;
      case REQUEST_BLOCKCHAIN:
        this.write(peer, Messages.sendBlockchain(this.blockchain.get()));
        break;
      case RECEIVE_LATEST_BLOCK:
        this.handleReceivedLatestBlock(message, peer);
        break;
      case RECEIVE_BLOCKCHAIN:
        this.handleReceivedBlockchain(message);
        break;
      default:
        throw "Received invalid message.";
    }
  }
// }

// module.exports = PeerToPeer;
// class Messages { ... }

这里写图片描述

P2p.js

// const wrtc = require('wrtc');
// const Exchange = require('peer-exchange');
// const p2p = new Exchange(...);
// const net = require("net");
// const messageType = { ... };
// const { ... } = messageType;

// class PeerToPeer {
  // constructor(blockchain) { ... }
  // startServer(port) { ... }
  // discoverPeers() { ... }
  // connectToPeer(host, port) { ... }
  // closeConnection() { ... }
  // broadcastLatest() { ... }
  // broadcast(message) { ... }
  // write(peer, message) { ... }
  // initConnection(connection) { ... }
  // initMessageHandler(connection) { ... }
  // initErrorHandler(connection) { ... }
  // handleMessage(peer, message) { ... }

  handleReceivedLatestBlock(message, peer) {
    const receivedBlock = message.data;
    const latestBlock = this.blockchain.latestBlock;

    if (latestBlock.hash === receivedBlock.previousHash) {
      try {
        this.blockchain.addBlock(receivedBlock);
      } catch(err) {
        throw err;
      }
    } else if (receivedBlock.index > latestBlock.index) {
      this.write(peer, Messages.getBlockchain());
    } else {
      // Do nothing.
    }
  }
// }

// module.exports = PeerToPeer;
// class Messages { ... }

这里写图片描述

P2p.js

handleReceivedLatestBlock(message, peer) {
    // if (latestBlock.hash === receivedBlock.previousHash) {
    // ...
    } else if (receivedBlock.index > latestBlock.index) {
      this.write(peer, Messages.getBlockchain());
    } else {
      // Do nothing.
    }
  }

  handleReceivedBlockchain(message) {
    const receivedChain = message.data;

    try {
      this.blockchain.replaceChain(receivedChain);
    } catch(err) {
      throw err;
    }
  }

这里写图片描述

 isValidChain(chain) {
    if (JSON.stringify(chain[0]) !== JSON.stringify(Block.genesis)) {
      return false;
    }

    const tempChain = [chain[0]];
    for (let i = 1; i < chain.length; i = i + 1) {
      if (this.isValidNextBlock(chain[i], tempChain[i - 1])) {
        tempChain.push(chain[i]);
      } else {
        return false;
      }
    }
    return true;
  }

  isChainLonger(chain) {
    return chain.length > this.blockchain.length;
  }

  replaceChain(newChain) {
    if (this.isValidChain(newChain) && this.isChainLonger(newChain)) {
      this.blockchain = JSON.parse(JSON.stringify(newChain));
    } else {
      throw "Error: invalid chain";
    }
  }

这里写图片描述

这里写图片描述

终端演示

安装命令行工具

npm install blockchain-cli -g


blockchain


blockchian ->后面输入blockchain或者bc查看创始区块结构。

创世区块
这里写图片描述

  • Index (Block #): 第几个区块? (创世区块链的索引为0)
  • Hash: 当前区块的hash值
  • Previous Hash: 上一个区块的hash值
  • Timestamp: 当前区块创建时的时间戳
  • Data: 存储在当前区块上的交易信息
  • Nonce: 在找到有效区块之前,我们经历的迭代次数

mine data数据

这里写图片描述

创建好了第一个区块


Hash是怎么计算的?

Hash值是一个十六进制固定长度为64位的唯一的标识。

hash值是由index, previous block hash, timestamp, block data, 和 nonce 作为输入数据计算而得。

CryptoJS.SHA256(index + previousHash + timestamp + data + nonce)

四个前导0是有效散列的最低要求。 所需的前导0的数量称为难度

下面的方法验证hash难度是否有效。

function isValidHashDifficulty(hash, difficulty) {
  for (var i = 0, b = hash.length; i < b; i ++) {
      if (hash[i] !== '0') {
          break;
      }
  }
  return i >= difficulty;
}

nonce是一个用来找到满足条件的hash值的数字。

let nonce = 0;
let hash;
let input;
while(!isValidHashDifficulty(hash)) {     
  nonce = nonce + 1;
  input = index + previousHash + timestamp + data + nonce;
  hash = CryptoJS.SHA256(input)
}

nonce值一直迭代,直到hash值有效为止。在我们案例中一个有效的hash值是最少有4个前导0。找到nonce值以满足合适条件的hash值的过程就叫做挖矿

随着难度的增加,可能的有效散列数减少。 使用较少可能的有效散列,需要更多的处理能力才能找到有效的散列。

学习参考链接

### 区块链概念图解释 区块链的概念可以通过一张概念图清晰地展示其核心要素和工作机制。以下是对区块链概念图的详细解释: #### 1. **节点与去中心化** 在区块链网络中,每个参与者(节点)都拥有完整的账本副本,并通过共识机制共同维护账本的一致性[^4]。这种去中心化的结构消除了对中心化机构的依赖,确保了系统的安全性和可靠性。 #### 2. **区块结构** 每个区块包含三部分主要内容: - **前一区块哈希值**:用于链接上一个区块,形成链条结构。 - **时间戳**:记录区块生成的时间。 - **交易数据**:区块中存储的具体交易信息,通常以哈希树(Merkle Tree)的形式表示[^2]。 #### 3. **共识机制** 区块链通过共识机制(如PoW、PoS等)确保所有节点对账本内容达成一致。共识机制是区块链不可篡改特性的基础,任何试图修改已确认区块的行为都会被网络中的其他节点拒绝[^3]。 #### 4. **不可篡改性** 区块链的数据一旦经过验证并添加到区块链中,就会变得极其难以更改。这是因为每个区块都包含前一区块的哈希值,任何篡改行为都会破坏整个链条的完整性[^2]。 #### 5. **透明性与隐私保护** 虽然区块链上的所有交易记录都是公开透明的,但参与者的身份可以通过加密技术进行匿名处理,从而在保证透明性的同时保护用户隐私。 ```python # 示例代码:生成一个简单的区块链结构 class Block: def __init__(self, previous_hash, timestamp, data): self.previous_hash = previous_hash self.timestamp = timestamp self.data = data self.hash = self.calculate_hash() def calculate_hash(self): import hashlib sha = hashlib.sha256() sha.update(f"{self.previous_hash}{self.timestamp}{self.data}".encode('utf-8')) return sha.hexdigest() # 创建第一个区块 block1 = Block("0", "2023-10-01", "First block data") print(f"Block Hash: {block1.hash}") ``` ### 区块链概念图的核心要素 一张典型的区块链概念图通常包括以下元素: - **节点网络**:展示区块链的去中心化特性。 - **区块链接**:用箭头或线条连接各个区块,表示区块之间的顺序关系。 - **交易数据**:在每个区块中展示具体的交易记录。 - **哈希值**:标注每个区块的哈希值以及与前一区块的关联。 #### 图片建议 可以搜索关键词“区块链概念图”或“Blockchain Diagram”,找到相关的示意图。这些图片通常会以图形化的方式展示区块链的工作原理,帮助用户更直观地理解其结构和特点。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值