0% found this document useful (0 votes)
47 views

Code Source Java

The document describes code for implementing a basic blockchain with cryptocurrency functionality in Java. It includes classes for wallets, transactions, blocks, and the overall blockchain data structure. Key points include: - The Wallet class stores a public/private key pair to manage funds and allow signing of transactions. - Transactions contain inputs (referencing previous transaction outputs), outputs, and a signature and transfer funds between wallets. - Blocks contain a list of transactions, hash/nonce fields for proof of work mining, and methods for adding/verifying transactions. - The Blockchain class manages the full chain of blocks and unspent transaction outputs (UTXOs).

Uploaded by

mohsen gharbi
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
47 views

Code Source Java

The document describes code for implementing a basic blockchain with cryptocurrency functionality in Java. It includes classes for wallets, transactions, blocks, and the overall blockchain data structure. Key points include: - The Wallet class stores a public/private key pair to manage funds and allow signing of transactions. - Transactions contain inputs (referencing previous transaction outputs), outputs, and a signature and transfer funds between wallets. - Blocks contain a list of transactions, hash/nonce fields for proof of work mining, and methods for adding/verifying transactions. - The Blockchain class manages the full chain of blocks and unspent transaction outputs (UTXOs).

Uploaded by

mohsen gharbi
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

import java.security.PrivateKey;import java.security.

PublicKey;public class Wallet { public PrivateKey


privateKey; public PublicKey publicKey;
}

public void generateKeyPair() { try { KeyPairGenerator keyGen =


KeyPairGenerator.getInstance("ECDSA", "BC"); SecureRandom random =
SecureRandom.getInstance("SHA1PRNG"); ECGenParameterSpec ecSpec = new
ECGenParameterSpec("prime192v1"); keyGen.initialize(ecSpec, random); KeyPair keyPair =
keyGen.generateKeyPair(); // on récupère les clés générées pour notre Wallet privateKey =
keyPair.getPrivate(); publicKey = keyPair.getPublic(); } catch (Exception e) { throw new
RuntimeException(e); }
}

import java.security.PrivateKey;import java.security.PublicKey;import java.util.ArrayList;public class


Transaction { public String transactionId; public PublicKey sender; public PublicKey recipient;
public float value; public byte[] signature; public ArrayList<TransactionInput> inputs = new
ArrayList<TransactionInput>(); public ArrayList<TransactionOutput> outputs = new
ArrayList<TransactionOutput>(); // Nombre de transactions générées private static int sequence = 0;
public Transaction(PublicKey from, PublicKey to, float value, ArrayList<TransactionInput> inputs) {
this.sender = from; this.recipient = to; this.value = value; this.inputs = inputs; } // ...
}

import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;public


class Utils { // Application d'une signature avec les courbes elliptiques (ECDSA) public static byte[]
applyECDSASig(PrivateKey privateKey, String input) { Signature dsa; byte[] output = new byte[0];
try { dsa = Signature.getInstance("ECDSA", "BC"); dsa.initSign(privateKey); byte[] strByte =
input.getBytes(); dsa.update(strByte); byte[] realSig = dsa.sign(); output = realSig; } catch
(Exception e) { throw new RuntimeException(e); } return output; } // Vérification de la signature
pour les données d'entrée public static boolean verifyECDSASig(PublicKey publicKey, String data,
byte[] signature) { try { Signature ecdsaVerify = Signature.getInstance("ECDSA", "BC");
ecdsaVerify.initVerify(publicKey); ecdsaVerify.update(data.getBytes()); return
ecdsaVerify.verify(signature); } catch (Exception e) { throw new RuntimeException(e); } } // ...
}

public class Transaction { // ... private String calculateHash() { sequence++; return


Utils.applySha256(Utils.getStringFromKey(sender) + Utils.getStringFromKey(recipient) +
Float.toString(value) + sequence); } public void generateSignature(PrivateKey privateKey) {
String data = Utils.getStringFromKey(sender) + Utils.getStringFromKey(recipient)
+ Float.toString(value); signature = Utils.applyECDSASig(privateKey, data); } public
boolean verifiySignature() { String data = Utils.getStringFromKey(sender) +
Utils.getStringFromKey(recipient) + Float.toString(value); return
Utils.verifyECDSASig(sender, data, signature); } // ...
}

public class TransactionInput { public String transactionOutputId; public TransactionOutput UTXO;


public TransactionInput(String transactionOutputId) { this.transactionOutputId = transactionOutputId;
}
}

import java.security.PublicKey;public class TransactionOutput { public String id; public PublicKey


recipient; public float value; public String parentTransactionId; public TransactionOutput(PublicKey
recipient, float value, String parentTransactionId) { this.recipient = recipient; this.value = value;
this.parentTransactionId = parentTransactionId; this.id =
Utils.applySha256(Utils.getStringFromKey(recipient) + Float.toString(value) +
parentTransactionId); } public boolean isMine(PublicKey publicKey) { return (publicKey ==
recipient); }
}

public class Transaction { // ... public boolean processTransaction() { if (verifiySignature() == false) {


System.out.println("Echec de vérification de la signature de la Transaction"); return false; } // On
associe les données des transactions entrantes for (TransactionInput i : inputs) { i.UTXO =
Blockchain.UTXOs.get(i.transactionOutputId); } // On vérifie que la transaction est valide if
(getInputsValue() < Blockchain.minimumTransaction) { System.out.println("Somme montant des
transactions entrantes trop faible : " + getInputsValue()); System.out.println("Le montant doit être
plus grand que : " + Blockchain.minimumTransaction); return false; } // Génération des
transactions sortantes // Calcul montant restant float leftOver = getInputsValue() - value;
transactionId = calulateHash(); // prise en compte envoi du montant au destinataire outputs.add(new
TransactionOutput(this.recipient, value, transactionId)); // prise en compte montant restant pour
l'expéditeur outputs.add(new TransactionOutput(this.sender, leftOver, transactionId)); // Ajout aux
transactions non dépensées de la Blockchain for (TransactionOutput o : outputs) {
Blockchain.UTXOs.put(o.id, o); } // Suppression de ces transactions de la liste UTXOs de la
Blockchain for (TransactionInput i : inputs) { if (i.UTXO == null) continue;
Blockchain.UTXOs.remove(i.UTXO.id); } return true; } public float getInputsValue() { float total =
0; for (TransactionInput i : inputs) { if (i.UTXO == null) continue; total += i.UTXO.value;
} return total; } // ...
}
public class Wallet { // ... // Retourne le montant disponible dans le Wallet public float getBalance() {
float total = 0; for (Map.Entry<String, TransactionOutput> item : Blockchain.UTXOs.entrySet()) {
TransactionOutput UTXO = item.getValue(); if (UTXO.isMine(publicKey)) { // on ajoute
uniquement le montant des transactions appartenant à ce wallet UTXOs.put(UTXO.id, UTXO);
total += UTXO.value; } } return total; } public Transaction sendFunds(PublicKey recipient, float
value) { if (getBalance() < value) { System.out.println("Manque de fonds pour créer la
transaction"); return null; } ArrayList<TransactionInput> inputs = new
ArrayList<TransactionInput>(); float total = 0; for (Map.Entry<String, TransactionOutput> item :
UTXOs.entrySet()) { TransactionOutput UTXO = item.getValue(); total += UTXO.value;
inputs.add(new TransactionInput(UTXO.id)); if (total > value) break; } Transaction
newTransaction = new Transaction(publicKey, recipient, value, inputs);
newTransaction.generateSignature(privateKey); for (TransactionInput input : inputs) {
UTXOs.remove(input.transactionOutputId); } return newTransaction; }
}

public static String getMerkleRoot(ArrayList<Transaction> transactions) { int count =


transactions.size(); ArrayList<String> previousTreeLayer = new ArrayList<String>(); for (Transaction
transaction : transactions) { previousTreeLayer.add(transaction.transactionId); } ArrayList<String>
treeLayer = previousTreeLayer; while (count > 1) { treeLayer = new ArrayList<String>(); for (int i
= 1; i < previousTreeLayer.size(); i++) { treeLayer.add(applySha256(previousTreeLayer.get(i - 1) +
previousTreeLayer.get(i))); } count = treeLayer.size(); previousTreeLayer = treeLayer; } String
merkleRoot = (treeLayer.size() == 1) ? treeLayer.get(0) : ""; return merkleRoot;
}

public class Block { // ... public ArrayList<Transaction> transactions = new ArrayList<Transaction>();


// ... public void mineBlock(int difficulty) { String merkleRoot = Utils.getMerkleRoot(transactions);
data = (!"".equals(merkleRoot)) ? merkleRoot : data; nonce = 0; while (!getHash().substring(0,
difficulty).equals(Utils.zeros(difficulty))) { nonce++; hash = Block.calculateHash(this); } }
public boolean addTransaction(Transaction transaction) { if (transaction == null) return false; if
(previousHash != null) { if (!transaction.processTransaction()) { System.out.println("Transaction
non valide. Ajout annulé"); return false; } } transactions.add(transaction);
System.out.println("Transaction ajoutée avec succès au bloc"); return true; }
}

import java.security.Security;import java.util.ArrayList;import java.util.HashMap;import


java.util.List;public class Blockchain { public static float minimumTransaction = 0.1f; private int
difficulty; private List<Block> blocks;
public static HashMap<String, TransactionOutput> UTXOs = new HashMap<String,
TransactionOutput>();
public Wallet walletA; public Wallet walletB; public Transaction genesisTransaction; public
Blockchain(int difficulty) { Security.addProvider(new
org.bouncycastle.jce.provider.BouncyCastleProvider()); // Création des Wallets walletA = new
Wallet(); walletB = new Wallet(); Wallet baseWallet = new Wallet(); // Transaction genèse
genesisTransaction = new Transaction(baseWallet.publicKey, walletA.publicKey, 100f, null); //
Signature de de la transaction genesisTransaction.generateSignature(baseWallet.privateKey);
genesisTransaction.transactionId = "0";
genesisTransaction.outputs.add(new TransactionOutput(genesisTransaction.recipient,
genesisTransaction.value, genesisTransaction.transactionId));
// Ajout à la liste UTXOs des transactions non dépensées
UTXOs.put(genesisTransaction.outputs.get(0).id, genesisTransaction.outputs.get(0)); this.difficulty =
difficulty; blocks = new ArrayList<>(); // Création du bloc genèse Block b = new Block(0,
System.currentTimeMillis(), null, "Genesis Block"); b.transactions.add(genesisTransaction);
b.mineBlock(difficulty); // Ajout du Bloc addBlock(b); } // ...
}

public static void main(String[] args) { Blockchain blockchain = new Blockchain(4);


System.out.println("\nWallet A montant : " + blockchain.walletA.getBalance());
System.out.println("Wallet A essaie d'envoyer 40 au Wallet B ..."); Block b =
blockchain.newBlock("Block 2");
b.addTransaction(blockchain.walletA.sendFunds(blockchain.walletB.publicKey, 40f));
blockchain.addBlock(b); System.out.println("Wallet A montant : " + blockchain.walletA.getBalance());
System.out.println("Wallet B montant : " + blockchain.walletB.getBalance());
System.out.println("\nWallet A essaie d'envoyer plus (100) que ce qu'il possède ..."); b =
blockchain.newBlock("Block 3");
b.addTransaction(blockchain.walletA.sendFunds(blockchain.walletB.publicKey, 1000f));
blockchain.addBlock(b); System.out.println("Wallet A montant : " + blockchain.walletA.getBalance());
System.out.println("Wallet B montant : " + blockchain.walletB.getBalance());
System.out.println("\nWallet B essaie d'envoyer 20 au Wallet A ..."); System.out.println("Wallet A essaie
d'envoyer 10 au Wallet B ..."); b = blockchain.newBlock("Block 4");
b.addTransaction(blockchain.walletB.sendFunds(blockchain.walletA.publicKey, 20f));
b.addTransaction(blockchain.walletA.sendFunds(blockchain.walletB.publicKey, 10f));
blockchain.addBlock(b); System.out.println("Wallet A montant : " + blockchain.walletA.getBalance());
System.out.println("Wallet B montant : " + blockchain.walletB.getBalance()); System.out.println();
System.out.println(blockchain); System.out.println("Blockchain valide : " +
(blockchain.isBlockChainValid() ? "Oui" : "Non"));
}

You might also like