
從[教學二]學會了工作量証明,這次在教學二的基礎上再作修改,簡單實現交易和挖礦獎勵,把教學二裹的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 部落格