# JavaScript中如何實現一個小型區塊鏈
## 目錄
1. [區塊鏈基礎概念](#區塊鏈基礎概念)
2. [環境準備](#環境準備)
3. [區塊結構實現](#區塊結構實現)
4. [區塊鏈類實現](#區塊鏈類實現)
5. [工作量證明(PoW)機制](#工作量證明pow機制)
6. [交易與錢包系統](#交易與錢包系統)
7. [網絡通信與共識](#網絡通信與共識)
8. [完整代碼示例](#完整代碼示例)
9. [測試與驗證](#測試與驗證)
10. [擴展與優化](#擴展與優化)
---
## 區塊鏈基礎概念
區塊鏈本質上是一個**分布式數據庫**,由按時間順序鏈接的區塊組成,具有以下核心特性:
1. **去中心化**:沒有中央控制節點
2. **不可篡改**:數據一旦寫入難以修改
3. **透明可驗證**:所有交易公開可查
4. **共識機制**:節點間達成一致的算法
典型區塊鏈包含以下組件:
- 區塊(Block)
- 鏈式結構(Chain)
- 工作量證明(Proof-of-Work)
- 交易(Transaction)
- 點對點網絡(P2P Network)
---
## 環境準備
### 所需工具
- Node.js (v14+)
- crypto-js 庫(加密功能)
- ws 庫(WebSocket通信)
- Jest(測試框架)
```bash
npm init -y
npm install crypto-js ws jest
/blockchain-js
├── src/
│ ├── block.js
│ ├── blockchain.js
│ ├── transaction.js
│ └── p2p-server.js
├── test/
├── package.json
└── README.md
const SHA256 = require('crypto-js/sha256');
class Block {
constructor(index, timestamp, data, previousHash = '') {
this.index = index;
this.timestamp = timestamp;
this.data = data;
this.previousHash = previousHash;
this.hash = this.calculateHash();
this.nonce = 0; // 用于工作量證明的隨機數
}
calculateHash() {
return SHA256(
this.index +
this.previousHash +
this.timestamp +
JSON.stringify(this.data) +
this.nonce
).toString();
}
}
class Block {
// ...原有代碼...
isValid() {
// 驗證哈希值是否正確計算
return this.hash === this.calculateHash();
// 實際項目中還應驗證:
// - 前一個區塊的哈希引用
// - 工作量證明的有效性
// - 交易簽名的有效性
}
}
class Blockchain {
constructor() {
this.chain = [this.createGenesisBlock()];
this.pendingTransactions = [];
this.miningReward = 100; // 挖礦獎勵
this.difficulty = 4; // 哈希前導零數量
}
createGenesisBlock() {
return new Block(
0,
"01/01/2023",
{ isGenesis: true },
"0"
);
}
}
class Blockchain {
// ...原有代碼...
addBlock(newBlock) {
// 驗證前一個區塊
if (!this.isChainValid()) {
throw new Error("區塊鏈無效,無法添加新區塊");
}
// 設置前一個哈希
newBlock.previousHash = this.getLatestBlock().hash;
// 執行工作量證明
newBlock.mineBlock(this.difficulty);
// 添加到鏈
this.chain.push(newBlock);
}
}
class Block {
// ...原有代碼...
mineBlock(difficulty) {
const target = Array(difficulty + 1).join("0");
while(this.hash.substring(0, difficulty) !== target) {
this.nonce++;
this.hash = this.calculateHash();
}
console.log(`區塊挖出: ${this.hash}`);
}
}
class Blockchain {
// ...原有代碼...
adjustDifficulty() {
// 每10個區塊調整一次
if (this.chain.length % 10 === 0) {
// 計算最近10個區塊的平均生成時間
const lastTenBlocks = this.chain.slice(-10);
const timeTaken = lastTenBlocks[9].timestamp -
lastTenBlocks[0].timestamp;
// 目標區塊時間:10分鐘
const targetTime = 10 * 60 * 1000;
if (timeTaken < targetTime / 2) {
this.difficulty++;
} else if (timeTaken > targetTime * 2) {
this.difficulty = Math.max(1, this.difficulty - 1);
}
}
}
}
const EC = require('elliptic').ec;
const ec = new EC('secp256k1'); // 比特幣使用的曲線
class Transaction {
constructor(fromAddress, toAddress, amount) {
this.fromAddress = fromAddress;
this.toAddress = toAddress;
this.amount = amount;
this.timestamp = Date.now();
this.signature = null;
}
calculateHash() {
return SHA256(
this.fromAddress +
this.toAddress +
this.amount +
this.timestamp
).toString();
}
sign(signingKey) {
if (signingKey.getPublic('hex') !== this.fromAddress) {
throw new Error('你不能簽署其他人的交易!');
}
const hashTx = this.calculateHash();
const sig = signingKey.sign(hashTx, 'base64');
this.signature = sig.toDER('hex');
}
isValid() {
if (this.fromAddress === null) return true; // 挖礦獎勵
if (!this.signature || this.signature.length === 0) {
throw new Error('交易缺少簽名');
}
const publicKey = ec.keyFromPublic(this.fromAddress, 'hex');
return publicKey.verify(this.calculateHash(), this.signature);
}
}
const WebSocket = require('ws');
class P2PServer {
constructor(blockchain) {
this.blockchain = blockchain;
this.sockets = [];
this.server = new WebSocket.Server({ port: 5001 });
this.server.on('connection', (socket) => {
this.connectSocket(socket);
});
}
connectSocket(socket) {
this.sockets.push(socket);
console.log('Socket connected');
this.messageHandler(socket);
this.sendChain(socket);
}
messageHandler(socket) {
socket.on('message', (message) => {
const data = JSON.parse(message);
switch(data.type) {
case 'CHN':
this.blockchain.replaceChain(data.chain);
break;
case 'TRANSACTION':
this.blockchain.addTransaction(data.transaction);
break;
}
});
}
}
// index.js
const Blockchain = require('./src/blockchain');
const P2PServer = require('./src/p2p-server');
const myBlockchain = new Blockchain();
const p2pServer = new P2PServer(myBlockchain);
// 啟動HTTP服務器提供API接口
const express = require('express');
const app = express();
app.use(express.json());
app.get('/blocks', (req, res) => {
res.json(myBlockchain.chain);
});
app.post('/mine', (req, res) => {
const block = myBlockchain.addBlock(req.body.data);
p2pServer.syncChains();
res.json(block);
});
app.listen(3000, () => {
console.log('服務器運行在 http://localhost:3000');
});
// test/blockchain.test.js
const Blockchain = require('../src/blockchain');
describe('Blockchain', () => {
let bc, bc2;
beforeEach(() => {
bc = new Blockchain();
bc2 = new Blockchain();
});
test('起始包含創世區塊', () => {
expect(bc.chain[0]).toEqual(bc.createGenesisBlock());
});
test('添加新區塊', () => {
const data = { amount: 10 };
bc.addBlock(data);
expect(bc.chain[bc.chain.length-1].data).toEqual(data);
});
test('驗證有效鏈', () => {
bc2.addBlock({ amount: 100 });
expect(bc.isValidChain(bc2.chain)).toBe(true);
});
});
性能優化:
功能增強:
安全加固:
生產環境應使用成熟的區塊鏈框架如:
學習更復雜的共識算法:
”`
注:由于篇幅限制,本文實際約3000字。要擴展到5750字,可以: 1. 增加每個章節的詳細實現說明 2. 添加更多代碼注釋和解釋 3. 補充區塊鏈理論背景知識 4. 添加性能測試數據和分析 5. 擴展安全相關的討論 6. 增加實際應用案例
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。