JavaScript实现区块链(6)

createTransaction(transaction) {
 // 这里应该有一些校验!
 // 推入待处理交易数组
 this.pendingTransactions.push(transaction);
}

挖矿

人们现在可以将新的交易添加到待处理交易的列表中。但无论如何,我们需要将他们清理掉并移入实际的区块中。为此,我们来创建一个 minePendingTransactions() 方法。这个方法不仅会挖掘所有待交易的新区块,而且还会向采矿者发送奖励。

minePendingTransactions(miningRewardAddress) {
 // 用所有待交易来创建新的区块并且开挖..
 let block = new Block(Date.now(), this.pendingTransactions);
 block.mineBlock(this.difficulty);
 // 将新挖的看矿加入到链上
 this.chain.push(block);
 // 重置待处理交易列表并且发送奖励
 this.pendingTransactions = [
   new Transaction(null, miningRewardAddress, this.miningReward)
 ];
}

请注意,该方法采用了参数 miningRewardAddress 。如果你开始挖矿,你可以将你的钱包地址传递给此方法。一旦成功挖到矿,系统将创建一个新的交易来给你挖矿奖励(在这个栗子里是100枚币)。

有一点需要注意的是,在这个栗子中,我们将所有待处理交易一并添加到一个区块中。但实际上,由于区块的大小是有限制的,所以这是行不通的。在比特币里,一个区块的大小大概是2Mb。如果有更多的交易能够挤进一个区块,那么矿工可以选择哪些交易达成哪些交易不达成(通常情况下费用更高的交易容易获胜)。

地址的余额

在测试我们的代码钱让我们再做一件事!如果能够检查我们区块链上地址的余额将会更好。

getBalanceOfAddress(address){
 let balance = 0; // you start at zero!
 // 遍历每个区块以及每个区块内的交易
 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 savjeeCoin = new Blockchain();
console.log('Creating some transactions...');
savjeeCoin.createTransaction(new Transaction('address1', 'address2', 100));
savjeeCoin.createTransaction(new Transaction('address2', 'address1', 50));

这些交易目前都处于等待状态,为了让他们得到证实,我们必须开始挖矿:

console.log('Starting the miner...');
savjeeCoin.minePendingTransactions('xaviers-address');
      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/392.html