
從[教學二]學會了工作量証明,這次在教學二的基礎上再作修改,簡單實現交易和挖礦獎勵,把教學二裹的data資料更改成transactions交易,每一筆交易都放到Block區塊,然後計算Hash值的過程就像挖礦,需要消耗挖礦者的一些資源去計算。為了吸引更多的人參予挖礦,每一個完成計算區塊Hash值的人就會得到獎勵。
在此範例裹,minePendingTransactions函式計算出新Hash值的區塊,然後放入區塊鏈,並對挖礦者給予獎勵。
const SHA256 = require('crypto-js/sha256'); /* * 交易 */ class Transaction { constructor(fromAddress, toAddress, amount) { this.fromAddress = fromAddress; this.toAddress = toAddress; this.amount = amount; } } /* * 區塊 */ class Block { constructor(timestamp, transactions, previousHash = '') { this.timestamp = timestamp; this.transactions = transactions; this.previousHash = previousHash; this.hash = this.calculateHash(); this.nonce = 0; } /* * 計算區塊的hash */ calculateHash() { return SHA256(this.previousHash + this.timestamp + JSON.stringify(this.transactions) + this.nonce).toString(); } mineBlock(difficulty) { while(this.hash.substring(0, difficulty) !== Array(difficulty + 1).join("0")){ this.nonce++; this.hash = this.calculateHash(); } } } /* * 區塊鏈 */ class Blockchain { constructor() { this.chain = [this.createGenesisBlock()]; this.difficulty = 2; this.pendingTransactions = []; this.miningReward = 100; } /* * 建立第一個區塊 */ createGenesisBlock() { return new Block("2018-03-19", "Genesis block", "0"); } /* * 取得最新的一個區塊 */ getLatestBlock() { return this.chain[this.chain.length - 1]; } /* * 挖掘等待陣列裹的交易記錄 */ minePendingTransactions(miningRewardAddress) { let block = new Block(Date.now(), this.pendingTransactions); block.mineBlock(this.difficulty); console.log('\nBlock successfully mined'); this.chain.push(block); this.pendingTransactions = [ new Transaction(null, miningRewardAddress, this.miningReward) ]; } /* * 將交易記錄加入至等待陣列 */ createTransaction(transaction) { this.pendingTransactions.push(transaction); } /* * 取得地址的結餘金額 */ getBalanceOfAddress(address) { let balance = 0; for(const block of this.chain) { for(const trans of block.transactions) { if(trans.fromAddress === address) { balance -= trans.amount; } if(trans.toAddress === address) { balance += trans.amount; } } } return balance; } } let testCoin = new Blockchain(); testCoin.createTransaction(new Transaction('address1', 'address2', 100)); testCoin.createTransaction(new Transaction('address2', 'address1', 50)); console.log('\nStarting the miner...'); testCoin.minePendingTransactions('mining-address'); console.log('\nBalance of mining-address is ', testCoin.getBalanceOfAddress('mining-address')); console.log('\nString the miner 2...'); testCoin.minePendingTransactions('mining-address'); console.log('\nBalance of mining-address is ', testCoin.getBalanceOfAddress('mining-address'));
相關文章:
Javascript實現Proof-of-Work區塊鏈(教學二)
鏈結到這頁!
Pingback: Javascript實現Proof-of-Work區塊鏈(教學二) | Alvin's Blog 部落格
Pingback: 簡單Javascript製作區塊鏈(教學一) | Alvin's Blog 部落格