Skip to forum
Benachrichtigungen
Alles löschen

Hilfe bei Blockchain Code in Javascript

8 Beiträge
3 Benutzer
11 Reactions
1,513 Ansichten
Sim87
Joined: 29.10.2006

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;

Antwort
Zitat
7 replies
 if(!transaction.fromAddress || transaction.toAddress){
            throw new Error('Transaction must include from and to address')
        }

Sollte die Bedingung nicht beide male mit not-operator sein?
Die Fehlermeldung impliziert eigentlich !transaction.fromAddress && !transaction.toAddress
Sollte ja auch nur kommen, wenn beide nicht vorhanden sind.
Ansonsten probier erst mal einfach die zweite Bedingung auch zu negieren, also !transaction.fromAddress || !transaction.toAddress


Antwort
Zitat
Sim87
Joined: 29.10.2006

Danke, das war der Fehler, plus bei blockchain.js
const rewardTx = new Transaction(null, miningRewardAddress, this.miningreward);
this.miningreward muss this.miningReward sein

:f_drink:


Antwort
Zitat
jonnyyman12
Joined: 10.01.2011

Hey, darüber würde ich gerne mehr wissen. Wie kann ich mir das Verständnis dafür aneignen? Habe leider null Berührungspunkte zum Coden, bin aber neugierig!


Antwort
Zitat

Zu Blockchain oder Programmieren an sich?


Antwort
Zitat
jonnyyman12
Joined: 10.01.2011

Zum Programmieren an sich. Ich versuche mich dahingehend schon länger nebenbei zu informieren, jedoch ist das Angebot erschlagend und gefühlt setzen alle Kurse einiges an Grundwissen voraus, was ich absolut nicht habe.

Über die Blockchain möchte ich auch mehr erfahren, da geht mein Interesse aber eher in Richtung Verständnis allgemein der Idee, welche dahinter steckt.
Ich möchte keine eigene Blockchain programmieren, zumal ich glaube ich überhaupt keine Ahnung habe, was das bedeutet.


Antwort
Zitat

Ich hab damit gute Erfahrung gemacht: https://www.freecodecamp.org/

Gratis, gute Einstiege und begleitete Codebeispiele. Ist super für den Einstieg. Beim Coden muss man im Grunde ein paar Grundprinzipien verstanden haben und anwenden können, dann ist die Sprache fast egal (viele ähneln sich ohnehin und setzen die Grundprinzipien im Grunde nur in einer anderen Sprache um).

Ich fühl mich selbst noch als Anfänger, obwohl ich schon 2 Jahre fulltime in dem Bereich arbeite. Den meisten Lernfortschritt und Spaß hatte ich aber, als ich mein eignes Projekt gefunden hab, was ich in der Freizeit jetzt baue und überrascht und begeistert bin, wenn alles funktioniert wie es soll :f_cool:

Also versuche irgendwas zu finden, wo du glaubst es könnte dir im Alltag irgendwas erleichtern und versuch es dann umzusetzen mit einer Sprache, mit der du grundlegende Dinge umsetzen kannst (meist ist alles lediglich Daten erfassen, Daten verarbeiten und Daten wieder ausgeben). Darum beginnen viele mit To-Do Apps, da man dort etwas eingeben kann, was dann gespeichert und wieder angezeigt wird und man damit simple Operationen wie Hinzufügen, Editieren und Entfernen durchführen kann. Darauf aufbauend kann man schon komplexere Datenerfassungssysteme schreiben, zB Inventarlisten, eCommerce-Systeme usw, die im Grunde das gleiche machen nur im größeren Rahmen und etwas mehr auf Security-Aspekte bedacht.

Aber das ist schon Fortgeschritten. Für den Anfang ist es schon ein Erfolg etwas einzugeben und ein formatiertes Ergebnis wird ausgespuckt.


Antwort
Zitat
jonnyyman12
Joined: 10.01.2011

Vielen lieben Dank für die ausführliche Antwort und den Link. Nach der Klausurphase werde ich mich dort eingehender umsehen.
Ich habe mich gerade einmal bis zur ersten Kursauswahl nach der Anmeldung durchgeklickt und die Seite erscheint mir intuitiv.
Wenn du interessiert daran bist, lasse ich dich wissen, was ich lerne und wie mein Stand ist, wenn ich etwas vorzuweisen habe. Vielleicht möchtest du dich auch
austauschen?:f_drink:


Antwort
Zitat