0% found this document useful (0 votes)
20 views4 pages

Java Wallet and Transaction System

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
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% found this document useful (0 votes)
20 views4 pages

Java Wallet and Transaction System

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
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

import [Link];import [Link].

PublicKey;public class Wallet { public PrivateKey


privateKey; public PublicKey publicKey;
}

public void generateKeyPair() { try { KeyPairGenerator keyGen =


[Link]("ECDSA", "BC"); SecureRandom random =
[Link]("SHA1PRNG"); ECGenParameterSpec ecSpec = new
ECGenParameterSpec("prime192v1"); [Link](ecSpec, random); KeyPair keyPair =
[Link](); // on récupère les clés générées pour notre Wallet privateKey =
[Link](); publicKey = [Link](); } catch (Exception e) { throw new
RuntimeException(e); }
}

import [Link];import [Link];import [Link];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) {
[Link] = from; [Link] = to; [Link] = value; [Link] = inputs; } // ...
}

import [Link];import [Link];import [Link];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 = [Link]("ECDSA", "BC"); [Link](privateKey); byte[] strByte =
[Link](); [Link](strByte); byte[] realSig = [Link](); 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 = [Link]("ECDSA", "BC");
[Link](publicKey); [Link]([Link]()); return
[Link](signature); } catch (Exception e) { throw new RuntimeException(e); } } // ...
}

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


Utils.applySha256([Link](sender) + [Link](recipient) +
[Link](value) + sequence); } public void generateSignature(PrivateKey privateKey) {
String data = [Link](sender) + [Link](recipient)
+ [Link](value); signature = [Link](privateKey, data); } public
boolean verifiySignature() { String data = [Link](sender) +
[Link](recipient) + [Link](value); return
[Link](sender, data, signature); } // ...
}

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


public TransactionInput(String transactionOutputId) { [Link] = transactionOutputId;
}
}

import [Link];public class TransactionOutput { public String id; public PublicKey


recipient; public float value; public String parentTransactionId; public TransactionOutput(PublicKey
recipient, float value, String parentTransactionId) { [Link] = recipient; [Link] = value;
[Link] = parentTransactionId; [Link] =
Utils.applySha256([Link](recipient) + [Link](value) +
parentTransactionId); } public boolean isMine(PublicKey publicKey) { return (publicKey ==
recipient); }
}

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


[Link]("Echec de vérification de la signature de la Transaction"); return false; } // On
associe les données des transactions entrantes for (TransactionInput i : inputs) { [Link] =
[Link]([Link]); } // On vérifie que la transaction est valide if
(getInputsValue() < [Link]) { [Link]("Somme montant des
transactions entrantes trop faible : " + getInputsValue()); [Link]("Le montant doit être
plus grand que : " + [Link]); 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 [Link](new
TransactionOutput([Link], value, transactionId)); // prise en compte montant restant pour
l'expéditeur [Link](new TransactionOutput([Link], leftOver, transactionId)); // Ajout aux
transactions non dépensées de la Blockchain for (TransactionOutput o : outputs) {
[Link]([Link], o); } // Suppression de ces transactions de la liste UTXOs de la
Blockchain for (TransactionInput i : inputs) { if ([Link] == null) continue;
[Link]([Link]); } return true; } public float getInputsValue() { float total =
0; for (TransactionInput i : inputs) { if ([Link] == null) continue; total += [Link];
} return total; } // ...
}
public class Wallet { // ... // Retourne le montant disponible dans le Wallet public float getBalance() {
float total = 0; for ([Link]<String, TransactionOutput> item : [Link]()) {
TransactionOutput UTXO = [Link](); if ([Link](publicKey)) { // on ajoute
uniquement le montant des transactions appartenant à ce wallet [Link]([Link], UTXO);
total += [Link]; } } return total; } public Transaction sendFunds(PublicKey recipient, float
value) { if (getBalance() < value) { [Link]("Manque de fonds pour créer la
transaction"); return null; } ArrayList<TransactionInput> inputs = new
ArrayList<TransactionInput>(); float total = 0; for ([Link]<String, TransactionOutput> item :
[Link]()) { TransactionOutput UTXO = [Link](); total += [Link];
[Link](new TransactionInput([Link])); if (total > value) break; } Transaction
newTransaction = new Transaction(publicKey, recipient, value, inputs);
[Link](privateKey); for (TransactionInput input : inputs) {
[Link]([Link]); } return newTransaction; }
}

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


[Link](); ArrayList<String> previousTreeLayer = new ArrayList<String>(); for (Transaction
transaction : transactions) { [Link]([Link]); } ArrayList<String>
treeLayer = previousTreeLayer; while (count > 1) { treeLayer = new ArrayList<String>(); for (int i
= 1; i < [Link](); i++) { [Link](applySha256([Link](i - 1) +
[Link](i))); } count = [Link](); previousTreeLayer = treeLayer; } String
merkleRoot = ([Link]() == 1) ? [Link](0) : ""; return merkleRoot;
}

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


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

import [Link];import [Link];import [Link];import


[Link];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) { [Link](new
[Link]()); // Création des Wallets walletA = new
Wallet(); walletB = new Wallet(); Wallet baseWallet = new Wallet(); // Transaction genèse
genesisTransaction = new Transaction([Link], [Link], 100f, null); //
Signature de de la transaction [Link]([Link]);
[Link] = "0";
[Link](new TransactionOutput([Link],
[Link], [Link]));
// Ajout à la liste UTXOs des transactions non dépensées
[Link]([Link](0).id, [Link](0)); [Link] =
difficulty; blocks = new ArrayList<>(); // Création du bloc genèse Block b = new Block(0,
[Link](), null, "Genesis Block"); [Link](genesisTransaction);
[Link](difficulty); // Ajout du Bloc addBlock(b); } // ...
}

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


[Link]("\nWallet A montant : " + [Link]());
[Link]("Wallet A essaie d'envoyer 40 au Wallet B ..."); Block b =
[Link]("Block 2");
[Link]([Link]([Link], 40f));
[Link](b); [Link]("Wallet A montant : " + [Link]());
[Link]("Wallet B montant : " + [Link]());
[Link]("\nWallet A essaie d'envoyer plus (100) que ce qu'il possède ..."); b =
[Link]("Block 3");
[Link]([Link]([Link], 1000f));
[Link](b); [Link]("Wallet A montant : " + [Link]());
[Link]("Wallet B montant : " + [Link]());
[Link]("\nWallet B essaie d'envoyer 20 au Wallet A ..."); [Link]("Wallet A essaie
d'envoyer 10 au Wallet B ..."); b = [Link]("Block 4");
[Link]([Link]([Link], 20f));
[Link]([Link]([Link], 10f));
[Link](b); [Link]("Wallet A montant : " + [Link]());
[Link]("Wallet B montant : " + [Link]()); [Link]();
[Link](blockchain); [Link]("Blockchain valide : " +
([Link]() ? "Oui" : "Non"));
}

Common questions

Powered by AI

The difficulty level determines how challenging it is to generate a block by requiring that the hash of a block starts with a certain number of zeros. This involves adjusting the nonce repeatedly until a hash with the desired difficulty characteristics is found. A higher difficulty level increases CPU work needed, slowing block production and increasing miner effort to achieve consensus .

The signature creation process involves using the private key of the sender to generate a digital signature on the transaction data using the ECDSA algorithm. The transaction data consists of a string including sender and recipient public keys and the transaction value. Verification involves using the sender's public key and the ECDSA algorithm to confirm that the signature matches the transaction data, ensuring it hasn't been tampered with .

A transaction is rejected if it fails signature verification, indicating potential tampering or invalid authorship. It will also be rejected if the sum of input values is below the defined minimum transaction value or if the wallet does not have sufficient balance to cover the transaction amount .

Blockchain ensures non-duplication and integrity of transactions through unique transaction IDs generated via hash functions, digital signatures for authenticity, and the Merkle root for verifying transaction integrity within blocks. Validating transaction signatures and updating UTXOs also prevent reuse of spent outputs, securing the chain against double-spending .

The Merkle root in the Block class serves as a cryptographic summary of all transactions included in a block. It ensures data integrity and quick verification of transactions within the block. To compute the Merkle root, transactions are iteratively hashed into pairs until a single hash remains, providing a concise representation of the block's transaction data .

The Wallet class initiates a fund transfer by checking its balance and preparing transaction inputs from its UTXOs. It creates a transaction and generates a signature using its private key. The Blockchain class then adds this transaction to a block, validating it and updating UTXOs after confirming sufficient balance and successful processing. The interaction ensures secure transaction handling from creation to integration into the blockchain .

The Block class integrates transactions by first adding them to its transactions list. A transaction is added only if it is not null and its processing validates successfully. The block is mined by calculating the Merkle root of its transactions, then finding a valid hash by adjusting the nonce until it meets the required difficulty level .

TransactionOutputs represent an amount of money locked to be spent by a specific public key, while TransactionInputs refer to TransactionOutputs to be spent. A wallet's balance is calculated by iterating through all Unspent Transaction Outputs (UTXOs) in the blockchain. If the output belongs to the wallet's public key, its value contributes to the wallet's balance .

The Wallet class generates a cryptographic key pair by using the 'ECDSA' algorithm provided by the 'BC' provider. It initializes a KeyPairGenerator with the 'prime192v1' elliptic curve specification and a SecureRandom instance using 'SHA1PRNG'. The generated keys are stored in the wallet's privateKey and publicKey fields .

A transaction is created by specifying the sender and recipient public keys, a value, and any inputs from unspent transaction outputs. After creation, a signature is generated using the sender's private key. Verification involves checking the integrity of the transaction's data against the signature using the sender's public key. This ensures that inputs are valid and the sender has sufficient balance before adding the transaction to a block .

You might also like