Javascript實現區塊鏈挖礦獎勵和交易(教學三)

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

Javascript實現Proof-of-Work區塊鏈(教學二)

One Reply to “Javascript實現區塊鏈挖礦獎勵和交易(教學三)”

  1. Pingback: 簡單Javascript製作區塊鏈(教學一) | Alvin's Blog 部落格

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *

*

驗證碼 * Time limit is exhausted. Please reload CAPTCHA.

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料