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).
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0 ratings0% found this document useful (0 votes)
51 views4 pages
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).
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; } // ... }
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; } }
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")); }