Skip to content
Snippets Groups Projects
Commit 4766f5ec authored by saintdi25u's avatar saintdi25u
Browse files

feat-transaction : avancement dans la création des transactions

parent 72de8f1a
Branches
No related tags found
No related merge requests found
Showing
with 166 additions and 151 deletions
File deleted
{
"java.configuration.updateBuildConfiguration": "automatic"
}
\ No newline at end of file
File added
File deleted
package fr.miage;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args ) throws NoSuchAlgorithmException, InterruptedException
{
public class App {
public static void main(String[] args) throws NoSuchAlgorithmException, InterruptedException {
System.out.println("Début de la blockchain");
// Création de 2 wallets
Wallet bobWallet = new Wallet("jesuislacleprivedebob", "bob");
//Wallet aliceWallet = new Wallet("je suis la clé privé de alice", "alice");
Wallet aliceWallet = new Wallet("je suis la clé privé de alice", "alice");
Set<Wallet> wallets = new HashSet<Wallet>() {
{
add(bobWallet);
//add(aliceWallet);
}
};
List<Wallet> wallets = Arrays.asList(bobWallet, aliceWallet);
Blockchain blockchain = new Blockchain("BloBlockchain", wallets);
System.out.println("Wallet de bob : " + bobWallet.getUtxos());
System.out.println("Wallet de alice : " + aliceWallet.getUtxos());
// System.out.println("Utxos du wallet de bob : " + bobWallet.getUtxos());
// System.out.println("Utxos du wallet de alice : " + aliceWallet.getUtxos());
// Transaction transaction = new Transaction(bobWallet, aliceWallet, 2, EnumTypeTransaction.NORMAL);
// Transaction transaction = new Transaction(bobWallet, aliceWallet, 2,
// EnumTypeTransaction.NORMAL);
// System.out.println("Transaction : ");
// System.out.println("Bob envoie : " + transaction.getInputs());
// System.out.println("Alice reçoit : " + transaction.getOutputs());
// System.out.println(transaction);
// int i = 1;
// while(blockchain.transactionsPool.size() <20){
// System.out.println("Transaction n°" + i);
// blockchain.createTrasaction();
// i++;
// }
int i = 1;
while (blockchain.transactionsPool.size() < 20) {
System.out.println("Transaction n°" + i);
blockchain.createTrasaction();
i++;
}
System.out.println("Transactions pool count : " + blockchain.transactionsPool.size());
// // print all utxo in the utxo set
// for (UTxO utxo : Blockchain.utxos) {
// System.out.println("UTXO ID: " + utxo);
// System.out.println("UTXO ID: " + utxo);
// }
//TODO : S'asurer de créer une bonne transaction avec les UTxO etc...
//TODO : Faire la signature de la transaction
// TODO : S'asurer de créer une bonne transaction avec les UTxO etc...
// TODO : Faire la signature de la transaction
//
// Set<Wallet> wallets = new HashSet<Wallet>() {
// {
// add(bobWallet);
// add(aliceWallet);
// }
// {
// add(bobWallet);
// add(aliceWallet);
// }
// };
// // Création de la blockchain
// // MinageManager minageManager = new MinageManager(blockchain);
// // minageManager.mineABloc();
}
......
......@@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import org.apache.commons.codec.digest.DigestUtils;
......@@ -46,11 +47,11 @@ public class Bloc {
this.transactions = transactions;
}
public static Bloc createGenuineBloc(Set<Wallet> wallets) {
public static Bloc createGenuineBloc(List<Wallet> wallets) {
List<Transaction> transactions = new ArrayList<Transaction>();
for (Wallet wallet : wallets) {
int amount = RandomNumberGenerator.getRandomNumber(1, 20);
UTxO utxo = new UTxO(null, amount);
UTxO utxo = new UTxO(null, wallet.getPublicKey(), amount);
wallet.addUTxO(utxo);
Blockchain.utxos.add(utxo);
List<UTxO> utxos = new ArrayList<UTxO>() {
......@@ -58,10 +59,11 @@ public class Bloc {
add(utxo);
}
};
Coinbase coinbase = new Coinbase(utxos, wallet.getPublicKey(), EnumTypeTransaction.COINBASE);
transactions.add(coinbase);
}
System.out.println("Set UTxO INITIAL " + Blockchain.utxos);
BlocHeader blocHeader = new BlocHeader("", Instant.now().toEpochMilli(), 0);
String header = blocHeader.toString();
......@@ -88,13 +90,12 @@ public class Bloc {
}
}
@Override
public String toString() {
return "{" +
" hash='" + getHash() + "'" +
", transactions='" + getTransactions() + "'" +
", header='" + getHeader() + "'" +
"}";
" hash='" + getHash() + "'" +
", transactions='" + getTransactions() + "'" +
", header='" + getHeader() + "'" +
"}";
}
}
package fr.miage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
......@@ -7,13 +9,13 @@ import java.util.Random;
import java.util.Set;
public class Blockchain {
private String name;
private String name;
private LinkedList<Bloc> blocs;
private Set<Wallet> wallets;
private List<Wallet> wallets;
public static Set<UTxO> utxos = new HashSet<>();
public Set<Transaction> transactionsPool = new HashSet<>();
public Blockchain(String name, Set<Wallet> wallets) {
public Blockchain(String name, List<Wallet> wallets) {
this.name = name;
this.wallets = wallets;
// Création du premier bloc contenant les transactions de coinbase
......@@ -25,28 +27,49 @@ public class Blockchain {
;
}
//Permet de créer une transaction avec deux wallets aléatoire et de l'ajouter dans la transaction pool;
public void createTrasaction(){
//Random wallet selection
Set<Wallet> walletsCopy = new HashSet<>(wallets);
// Permet de créer une transaction avec deux wallets aléatoire et de l'ajouter
// dans la transaction pool;
public void createTrasaction() {
// Random wallet selection
List<Wallet> walletsCopy = new ArrayList<>();
walletsCopy.addAll(wallets);
int walletIndexSender = new Random().nextInt(walletsCopy.size());
Wallet walletSender = selectWallet(walletIndexSender);
Wallet walletSender = selectWallet(walletsCopy);
walletsCopy.remove(walletSender);
int walletIndexReceiver = new Random().nextInt(walletsCopy.size());
Wallet walletReceiver = selectWallet(walletIndexReceiver);
Wallet walletReceiver = selectWallet(walletsCopy);
walletsCopy.remove(walletReceiver);
double amountWalletSender = walletSender.getUtxos().stream().mapToDouble(utxo -> utxo.getMontant()).sum();
double randomAmountToSend = new Random().nextInt((int) amountWalletSender);
double randomAmountToSend = new Random().nextDouble(amountWalletSender);
System.out.println("Amount to send : " + randomAmountToSend);
System.out.println("Envoie de " + walletSender.getName() + " à " + walletReceiver.getName());
System.out.println();
System.out.println("Utxos de " + walletSender.getName() + " : " + walletSender.getUtxos());
System.out.println("Utxos de " + walletReceiver.getName() + " : " + walletReceiver.getUtxos());
System.out.println();
if (walletSender.getUtxos().isEmpty() || walletReceiver.getUtxos().isEmpty()) {
System.out.println("Wallets vides");
return;
}
Transaction tx = new Transaction(walletSender, walletReceiver, randomAmountToSend, EnumTypeTransaction.NORMAL);
this.transactionsPool.add(tx);
}
public Wallet selectWallet(int index){
public Wallet selectWallet(List<Wallet> wallets) {
if (wallets.size() == 0) {
return null;
}
if (wallets.size() == 1) {
return wallets.get(0);
}
int index = new Random().nextInt(wallets.size());
int i = 0;
for (Wallet wallet : wallets) {
if(i == index){
if (i == index) {
return wallet;
}
i++;
......@@ -71,16 +94,16 @@ public class Blockchain {
return this.blocs;
}
public Set<Wallet> getWallets() {
public List<Wallet> getWallets() {
return this.wallets;
}
@Override
public String toString() {
return "{" +
" name='" + getName() + "'" +
", blocs='" + getBlocs() + "'" +
", wallets='" + getWallets() + "'" +
"}";
" name='" + getName() + "'" +
", blocs='" + getBlocs() + "'" +
", wallets='" + getWallets() + "'" +
"}";
}
}
......@@ -13,7 +13,7 @@ public class Transaction {
private Wallet sender;
private Wallet receiver;
private List<UTxO> inputs;
private List<UTxO> outputs;
private List<UTxO> outputs;
private EnumTypeTransaction typeTransaction;
public Transaction(List<UTxO> inputs, List<UTxO> outputs, String signature, EnumTypeTransaction typeTransaction) {
......@@ -23,36 +23,37 @@ public class Transaction {
this.id = UUID.randomUUID();
}
public Transaction(Wallet sender, Wallet receiver ,double amount, EnumTypeTransaction typeTransaction) {
public Transaction(Wallet sender, Wallet receiver, double amount, EnumTypeTransaction typeTransaction) {
this.inputs = sender.getUTxOsForTransaction(amount);
if (inputs != null ) {
if(isValidTransaction(inputs)){
System.out.println("Inputs : " + this.inputs);
System.out.println("Set UTxO : " + Blockchain.utxos);
if (inputs != null) {
if (isValidTransaction(inputs)) {
this.sender = sender;
this.receiver = receiver;
this.typeTransaction = typeTransaction.NORMAL;
this.id = UUID.randomUUID();
UTxO utxoAmount = new UTxO(receiver.getPublicKey(), getTotalAmountUtxoInput(inputs)); // peut etre changr par amout
UTxO utxoAmount = new UTxO(this.id, receiver.getPublicKey(), amount); // peut
// etre
// changr par
// amout
this.receiver.addUTxO(utxoAmount);
UTxO utxoRest = new UTxO(sender.getPublicKey(), getTotalAmountUtxoInput(inputs) - amount);
UTxO utxoRest = new UTxO(this.id, sender.getPublicKey(), getTotalAmountUtxoInput(inputs) - amount);
this.sender.addUTxO(utxoRest);
this.outputs = Arrays.asList(utxoAmount, utxoRest);
updateSetUtxo();
Blockchain.utxos.addAll(this.outputs);
} else {
System.err.println("Transaction invalide, utxo absent");
}
} else {
System.out.println("Solde insuffisant");
System.out.println("Solde insuffisant");
}
}
public void updateSetUtxo(){
Blockchain.utxos.clear();
Blockchain.utxos.addAll(this.outputs);
Blockchain.utxos.removeAll(this.inputs);
}
// public void signTransaction() throws NoSuchAlgorithmException{
// Signature signature = Signature.getInstance("SHA256withRSA");
// signature.initSign(sender.getPrivateKey());
// Signature signature = Signature.getInstance("SHA256withRSA");
// signature.initSign(sender.getPrivateKey());
// }
public double getTotalAmountUtxoInput(List<UTxO> inputs) {
......@@ -63,7 +64,7 @@ public class Transaction {
return total;
}
public boolean isValidTransaction( List<UTxO> inputs) {
public boolean isValidTransaction(List<UTxO> inputs) {
boolean isValid = true;
for (UTxO utxo : inputs) {
if (!Blockchain.utxos.contains(utxo)) {
......@@ -77,7 +78,6 @@ public class Transaction {
return this.id;
}
public void setId(UUID id) {
this.id = id;
}
......@@ -90,7 +90,6 @@ public class Transaction {
return this.outputs;
}
public EnumTypeTransaction getTypeTransaction() {
return this.typeTransaction;
}
......@@ -98,10 +97,10 @@ public class Transaction {
@Override
public String toString() {
return "{" +
" id='" + getId() + "'" +
", inputs='" + getInputs() + "'" +
", outputs='" + getOutputs() + "'" +
", typeTransaction='" + getTypeTransaction() + "'" +
"}";
" id='" + getId() + "'" +
", inputs='" + getInputs() + "'" +
", outputs='" + getOutputs() + "'" +
", typeTransaction='" + getTypeTransaction() + "'" +
"}";
}
}
......@@ -4,28 +4,32 @@ import java.util.UUID;
public class UTxO implements Comparable {
//UTXO : Hash qui renvoie a la transaction d'avant
private UUID uuid; // identifiant
private String transactionHash; // transaction de provenance de l'Utxo (provenance de l'argent) --> peut etre meme que le hash de la transaction
private UUID uuid; // identifiant (transaction de provenances)
private String ownerAdresss; // clé publique du wallet
private double montant;
public UTxO(String transactionHash, double montant) {
this.transactionHash = transactionHash;
public UTxO(UUID provenance, String ownerAdresss, double montant) {
this.uuid = provenance;
this.ownerAdresss = ownerAdresss;
this.montant = montant;
}
public String getTransaction() {
return this.transactionHash;
public String ownerAdress() {
return this.ownerAdresss;
}
public double getMontant() {
return this.montant;
}
public UUID getUuid() {
return uuid;
}
@Override
public String toString() {
return "UTxO [uuid=" + uuid + ", transactionHash=" + transactionHash + ", montant=" + montant + "]";
return "UTxO [uuid=" + uuid + ", ownerAdress=" + ownerAdresss + ", montant=" + montant + "]";
}
@Override
......
......@@ -15,8 +15,10 @@ public class Wallet {
private String privateKey; // pour la signature
private double solde;
private List<UTxO> utxos;
private String name; // temp
public Wallet(String privateKey, String name) throws NoSuchAlgorithmException, InterruptedException {
this.name = name;
this.privateKey = privateKey;
initWallet();
createKeyPair(privateKey, name);
......@@ -27,38 +29,41 @@ public class Wallet {
this.utxos = new ArrayList<>();
}
public void createKeyPair(String privateKey, String name) throws InterruptedException{
public void createKeyPair(String privateKey, String name) throws InterruptedException {
String command = "keytool -genkeypair -alias wallet_"+name+" -keyalg RSA -keysize 2048 -dname \"CN=" + name + "\" -validity 365 -storetype JKS -keystore keystore.jks -storepass \"" + privateKey + "\"";
String command = "keytool -genkeypair -alias wallet_" + name + " -keyalg RSA -keysize 2048 -dname \"CN=" + name
+ "\" -validity 365 -storetype JKS -keystore keystore.jks -storepass \"" + privateKey + "\"";
System.out.println(command);
ProcessBuilder processBuilder = new ProcessBuilder(command.split("\\s+"));
processBuilder.redirectErrorStream(true);
try {
Process process = processBuilder.start();
OutputStream outputStream = process.getOutputStream();
outputStream.write("\n".getBytes(StandardCharsets.UTF_8));
outputStream.flush();
outputStream.close();
// try {
// // Process process = processBuilder.start();
// // OutputStream outputStream = process.getOutputStream();
// // outputStream.write("\n".getBytes(StandardCharsets.UTF_8));
// // outputStream.flush();
// // outputStream.close();
InputStream inputStream = process.getInputStream();
InputStream errorStream = process.getErrorStream();
// // InputStream inputStream = process.getInputStream();
// // InputStream errorStream = process.getErrorStream();
byte[] buffer = new byte[1024];
int bytesRead;
// // byte[] buffer = new byte[1024];
// // int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
System.out.write(buffer, 0, bytesRead);
}
// // while ((bytesRead = inputStream.read(buffer)) != -1) {
// // System.out.write(buffer, 0, bytesRead);
// // }
while ((bytesRead = errorStream.read(buffer)) != -1) {
System.err.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("Erreur lors de la création du keypair");
}
// // while ((bytesRead = errorStream.read(buffer)) != -1) {
// // System.err.write(buffer, 0, bytesRead);
// }
// }catch(
// IOException e)
// {
// e.printStackTrace();
System.out.println("Erreur lors de la création du keypair");
System.out.println("Le wallet de " + name + " a été créé avec succès");
}
......@@ -69,30 +74,41 @@ public class Wallet {
}
public List<UTxO> getUTxOsForTransaction(double amount) {
List<UTxO> result = new ArrayList<>();
int res = 0;
boolean stop = false;
Collections.sort(this.utxos);
for (UTxO utxo : this.utxos) {
if(res >= amount) {
stop = true;
List<UTxO> result = new ArrayList<>();
double res = 0;
boolean stop = false;
Collections.sort(this.utxos);
for (UTxO utxo : this.utxos) {
if (res >= amount) {
stop = true;
}
if (res < amount && !stop) {
result.add(utxo);
res += utxo.getMontant();
}
}
if (res < amount && !stop) {
result.add(utxo);
res += utxo.getMontant();
}
}
utxos.removeAll(result);
if (res < amount) {
return null;
} else {
return result;
}
}
public String getPublicKey() {
return this.publicKey;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrivateKey() {
return this.privateKey;
}
......@@ -104,13 +120,13 @@ public class Wallet {
public void addUTxO(UTxO utxo) {
this.utxos.add(utxo);
}
@Override
public String toString() {
return "{" +
" publicKey='" + getPublicKey() + "'" +
", privateKey='" + getPrivateKey() + "'" +
", utxos='" + getUtxos() + "'" +
"}";
" publicKey='" + getPublicKey() + "'" +
", privateKey='" + getPrivateKey() + "'" +
", utxos='" + getUtxos() + "'" +
"}";
}
}
File deleted
File deleted
#Created by Apache Maven 3.9.6
artifactId=blockchain-project
groupId=fr.miage
version=1.0-SNAPSHOT
fr/miage/Transaction.class
fr/miage/Bloc.class
fr/miage/UTxO.class
fr/miage/App.class
fr/miage/Blockchain.class
fr/miage/EnumTypeTransaction.class
fr/miage/MinageManager.class
fr/miage/Wallet.class
fr/miage/BlocHeader.class
/Users/corentinstd/Library/CloudStorage/OneDrive-Personnel/Cours/M2_S1/Blockchain/blockchain-project/src/main/java/fr/miage/EnumTypeTransaction.java
/Users/corentinstd/Library/CloudStorage/OneDrive-Personnel/Cours/M2_S1/Blockchain/blockchain-project/src/main/java/fr/miage/Bloc.java
/Users/corentinstd/Library/CloudStorage/OneDrive-Personnel/Cours/M2_S1/Blockchain/blockchain-project/src/main/java/fr/miage/Blockchain.java
/Users/corentinstd/Library/CloudStorage/OneDrive-Personnel/Cours/M2_S1/Blockchain/blockchain-project/src/main/java/fr/miage/App.java
/Users/corentinstd/Library/CloudStorage/OneDrive-Personnel/Cours/M2_S1/Blockchain/blockchain-project/src/main/java/fr/miage/MinageManager.java
/Users/corentinstd/Library/CloudStorage/OneDrive-Personnel/Cours/M2_S1/Blockchain/blockchain-project/src/main/java/fr/miage/Transaction.java
/Users/corentinstd/Library/CloudStorage/OneDrive-Personnel/Cours/M2_S1/Blockchain/blockchain-project/src/main/java/fr/miage/Wallet.java
/Users/corentinstd/Library/CloudStorage/OneDrive-Personnel/Cours/M2_S1/Blockchain/blockchain-project/src/main/java/fr/miage/BlocHeader.java
/Users/corentinstd/Library/CloudStorage/OneDrive-Personnel/Cours/M2_S1/Blockchain/blockchain-project/src/main/java/fr/miage/UTxO.java
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment