Habe zum Spaß anhand eines Tutorials eine kleine Blockchain geschrieben und finde jetzt am Ende den Fehler nicht (Visual Studio Code). Was muss ich ändern damit er die Transaction versteht?
Fehler:
PS C:\Users\simon\Desktop\Programmieren\Javascript\SimCoin> node main.js
C:\Users\simon\Desktop\Programmieren\Javascript\SimCoin\blockchain.js:105
throw new Error('Transaction must include from and to address')
^
Error: Transaction must include from and to address
at Blockchain.addTransaction (C:\Users\simon\Desktop\Programmieren\Javascript\SimCoin\blockchain.js:105:19)
at Object.<anonymous> (C:\Users\simon\Desktop\Programmieren\Javascript\SimCoin\main.js:13:9)
Sourcecodes
Spoiler
main.js
const {Blockchain, Transaction} = require('./blockchain');
const EC = require('elliptic').ec;
const ec = new EC('secp256k1');
const myKey = ec.keyFromPrivate('a4e15e1f9f8bcd673ba77847da34c44ef26d77e732ba80d27ebdce3fa36595eb');
const myWalletAddress = myKey.getPublic('hex');
let simCoin = new Blockchain();
const tx1 = new Transaction(myWalletAddress, 'public key of receiver', 10);
tx1.signTransaction(myKey);
simCoin.addTransaction(tx1);
console.log('\n Starting the miner...')
simCoin.minePendingTransactions(myWalletAddress);
console.log('\n Balance of mineraddress1 is ', simCoin.getBalanceOfAdress(myWalletAddress));
keygenerator.js
const EC = require('elliptic').ec;
const ec = new EC('secp256k1');
const key = ec.genKeyPair();
const publicKey = key.getPublic('hex');
const privateKey = key.getPrivate('hex');
console.log();
console.log('Private key: ', privateKey);
console.log();
console.log('Public key: ', publicKey);
blockchain.js
const SHA256 = require('crypto-js/sha256');
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;
}
calculateHash(){
return SHA256(this.fromAddress + this.toAddress + this.amount).toString();
}
signTransaction(singingKey){
if(singingKey.getPublic('hex') !== this.fromAddress){
throw new Error('You cannot sign transactions for other wallets!');
}
const hashTx = this.calculateHash();
const sig = singingKey.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('No signature in this transaction');
}
const publicKey = ec.keyFromPublic(this.fromAddress, 'hex')
return publicKey.verify(this.calculateHash(), this.signature);
}
}
class Block {
constructor(timestamp, transactions, previousHash = ''){
this.timestamp = timestamp;
this.transactions = transactions;
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();
}
mineBlock(difficulty){
while(this.hash.substring(0, difficulty) !== Array(difficulty + 1).join("0")){
this.nonce++;
this.hash = this.calculateHash();
}
console.log("Block mined: " + this.hash);
}
hasValidTransactions(){
for(const tx of this.transactions){
if(!tx.isValid()){
return false;
}
}
return true;
}
}
class Blockchain{
constructor(){
this.chain = [this.createGenesisBlock()];
this.difficulty = 2;
this.pendingTransactions = [];
this.miningReward = 100;
}
createGenesisBlock(){
return new Block("01/01/2022", "Genesis block", "0");
}
getLatestBlock(){
return this.chain[this.chain.length - 1];
}
minePendingTransactions(miningRewardAddress){
const rewardTx = new Transaction(null, miningRewardAddress, this.miningreward);
this.pendingTransactions.push(rewardTx);
let block = new Block(Date.now(), this.pendingTransactions);
block.mineBlock(this.difficulty);
console.log('Block successfully mined!')
this.chain.push(block);
this.pendingTransactions = [];
}
addTransaction(transaction){
if(!transaction.fromAddress || transaction.toAddress){
throw new Error('Transaction must include from and to address')
}
if(!transaction.isValid()){
throw new Error('Cannot add invalid transaction to chain');
}
this.pendingTransactions.push(transaction);
}
getBalanceOfAdress(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;
}
isChainValid() {
for (let i = 1; i < this.chain.length; i++){
const currentBlock = this.chain[i];
const previousBLock = this.chain[i - 1];
if(!currentBlock.hasValidTransactions()){
return false;
}
if(!currentBlock.hasValidTransactions()){
return false;
}
if(currentBlock.hash !== currentBlock.calculateHash()){
return false;
}
}
return true;
}
}
module.exports.Blockchain = Blockchain;
module.exports.Transaction = Transaction;