Initial commit
This commit is contained in:
		
						commit
						8666ad8752
					
				| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
### IntelliJ IDEA ###
 | 
			
		||||
out/
 | 
			
		||||
!**/src/main/**/out/
 | 
			
		||||
!**/src/test/**/out/
 | 
			
		||||
target/
 | 
			
		||||
.idea/
 | 
			
		||||
 | 
			
		||||
### Eclipse ###
 | 
			
		||||
.apt_generated
 | 
			
		||||
.classpath
 | 
			
		||||
.factorypath
 | 
			
		||||
.project
 | 
			
		||||
.settings
 | 
			
		||||
.springBeans
 | 
			
		||||
.sts4-cache
 | 
			
		||||
bin/
 | 
			
		||||
!**/src/main/**/bin/
 | 
			
		||||
!**/src/test/**/bin/
 | 
			
		||||
 | 
			
		||||
### NetBeans ###
 | 
			
		||||
/nbproject/private/
 | 
			
		||||
/nbbuild/
 | 
			
		||||
/dist/
 | 
			
		||||
/nbdist/
 | 
			
		||||
/.nb-gradle/
 | 
			
		||||
 | 
			
		||||
### VS Code ###
 | 
			
		||||
.vscode/
 | 
			
		||||
 | 
			
		||||
### Mac OS ###
 | 
			
		||||
.DS_Store
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
 | 
			
		||||
  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_19">
 | 
			
		||||
    <output url="file://$MODULE_DIR$/target/classes" />
 | 
			
		||||
    <output-test url="file://$MODULE_DIR$/target/test-classes" />
 | 
			
		||||
    <content url="file://$MODULE_DIR$">
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/target" />
 | 
			
		||||
    </content>
 | 
			
		||||
    <orderEntry type="inheritedJdk" />
 | 
			
		||||
    <orderEntry type="sourceFolder" forTests="false" />
 | 
			
		||||
  </component>
 | 
			
		||||
</module>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
 | 
			
		||||
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 | 
			
		||||
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
 | 
			
		||||
    <groupId>groupId</groupId>
 | 
			
		||||
    <artifactId>DzieCoin</artifactId>
 | 
			
		||||
    <version>1.0-SNAPSHOT</version>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <maven.compiler.source>19</maven.compiler.source>
 | 
			
		||||
        <maven.compiler.target>19</maven.compiler.target>
 | 
			
		||||
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 | 
			
		||||
    </properties>
 | 
			
		||||
</project>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,118 @@
 | 
			
		|||
package pl.mikorosa.dziecoin;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class Block {
 | 
			
		||||
    private String hash;
 | 
			
		||||
    private String prevHash;
 | 
			
		||||
    private int height;
 | 
			
		||||
    private List<Transaction> transactions;
 | 
			
		||||
    private List<NFT> nfts;
 | 
			
		||||
    private int nonce;
 | 
			
		||||
 | 
			
		||||
    public Block() {
 | 
			
		||||
        this.transactions = new ArrayList<>();
 | 
			
		||||
        this.nfts = new ArrayList<>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Block(String prevHash, int height, List<Transaction> transactions) {
 | 
			
		||||
        this.prevHash = prevHash;
 | 
			
		||||
        this.height = height;
 | 
			
		||||
        this.transactions = transactions;
 | 
			
		||||
        this.nfts = new ArrayList<>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Block(String hash, String prevHash, int height, List<Transaction> transactions, List<NFT> nfts, int nonce) {
 | 
			
		||||
        this.hash = hash;
 | 
			
		||||
        this.prevHash = prevHash;
 | 
			
		||||
        this.height = height;
 | 
			
		||||
        this.transactions = transactions;
 | 
			
		||||
        this.nfts = nfts;
 | 
			
		||||
        this.nonce = nonce;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void mineBlock() {
 | 
			
		||||
        String blockStruct = this.prevHash + this.height;
 | 
			
		||||
        for (Transaction transaction : this.transactions) {
 | 
			
		||||
            blockStruct += transaction.toString();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (NFT nft : nfts) {
 | 
			
		||||
            blockStruct += nft.toString();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int nonce = 0;
 | 
			
		||||
 | 
			
		||||
        String hash;
 | 
			
		||||
 | 
			
		||||
        System.out.println();
 | 
			
		||||
        while(true) {
 | 
			
		||||
            hash = CalculateHash.sha256sum(blockStruct + nonce);
 | 
			
		||||
            if(hash.startsWith("0".repeat(Main.difficulty))) break;
 | 
			
		||||
            nonce++;
 | 
			
		||||
            System.out.print("\rMining block " + height + "... " + nonce);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        System.out.println("\nSuccessfully mined block " + height + " (nonce: " + nonce + ")");
 | 
			
		||||
 | 
			
		||||
        this.hash = hash;
 | 
			
		||||
        this.nonce = nonce;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addTransaction(Transaction transaction) {
 | 
			
		||||
        transactions.add(transaction);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addNFT(NFT nft) {
 | 
			
		||||
        nfts.add(nft);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum VerifyCodes {
 | 
			
		||||
        SUCCESS,
 | 
			
		||||
        INVALID_POW_SIGNATURE,
 | 
			
		||||
        HASH_MISMATCH,
 | 
			
		||||
        INVALID_BLOCK_HASH
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public VerifyCodes verifyBlock() {
 | 
			
		||||
        String blockStruct = this.prevHash + this.height;
 | 
			
		||||
        for (Transaction transaction : this.transactions) {
 | 
			
		||||
            blockStruct += transaction.toString();
 | 
			
		||||
        }
 | 
			
		||||
        for (NFT nft : nfts) {
 | 
			
		||||
            blockStruct += nft.toString();
 | 
			
		||||
        }
 | 
			
		||||
        blockStruct += this.nonce;
 | 
			
		||||
 | 
			
		||||
        String calculatedHash = CalculateHash.sha256sum(blockStruct);
 | 
			
		||||
 | 
			
		||||
        if(!calculatedHash.equals(this.hash)) return VerifyCodes.INVALID_BLOCK_HASH;
 | 
			
		||||
        if(!calculatedHash.startsWith("0".repeat(Main.difficulty))) return VerifyCodes.INVALID_POW_SIGNATURE;
 | 
			
		||||
        return VerifyCodes.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Transaction> getTransactions() {
 | 
			
		||||
        return transactions;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getHeight() {
 | 
			
		||||
        return height;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<NFT> getNFTs() {
 | 
			
		||||
        return nfts;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getHash() {
 | 
			
		||||
        return hash;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getPrevHash() {
 | 
			
		||||
        return prevHash;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getNonce() {
 | 
			
		||||
        return nonce;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
package pl.mikorosa.dziecoin;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class Blockchain {
 | 
			
		||||
    private List<Block> blocks;
 | 
			
		||||
    private int length;
 | 
			
		||||
 | 
			
		||||
    public Blockchain(String genesisBlockRecipient) {
 | 
			
		||||
        blocks = new ArrayList<>();
 | 
			
		||||
        length = blocks.size();
 | 
			
		||||
 | 
			
		||||
        Transaction firstTransaction = new Transaction("0", genesisBlockRecipient, 10);
 | 
			
		||||
        List<Transaction> transactions = new ArrayList<>();
 | 
			
		||||
        transactions.add(firstTransaction);
 | 
			
		||||
 | 
			
		||||
        Block genesisBlock = new Block("0", 1, transactions);
 | 
			
		||||
 | 
			
		||||
        genesisBlock.mineBlock();
 | 
			
		||||
        if(genesisBlock.verifyBlock() != Block.VerifyCodes.SUCCESS) throw new IllegalStateException("Genesis block is invalid");
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            addBlock(genesisBlock);
 | 
			
		||||
        } catch (BlockchainIntegrityException e) {
 | 
			
		||||
            System.out.println("Blockchain Integrity Exception: " + e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getLength() {
 | 
			
		||||
        return length;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Block> getBlocks() {
 | 
			
		||||
        return blocks;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Block getLatestBlock() {
 | 
			
		||||
        return blocks.get(length - 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Block.VerifyCodes validateChain() {
 | 
			
		||||
        for (int i = 1; i < (length - 1); i++) {
 | 
			
		||||
            if(blocks.get(i).verifyBlock() != Block.VerifyCodes.SUCCESS) return blocks.get(i).verifyBlock();
 | 
			
		||||
            if(!blocks.get(i).getHash().equals(blocks.get(i + 1).getPrevHash())) return Block.VerifyCodes.HASH_MISMATCH;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (Block block : blocks) {
 | 
			
		||||
            if(!block.getHash().startsWith("0".repeat(Main.difficulty))) return Block.VerifyCodes.INVALID_POW_SIGNATURE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return Block.VerifyCodes.SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void addBlock(Block block) throws BlockchainIntegrityException {
 | 
			
		||||
        Block.VerifyCodes status = block.verifyBlock();
 | 
			
		||||
 | 
			
		||||
        if(status == Block.VerifyCodes.HASH_MISMATCH) throw new BlockchainIntegrityException("Block " + block.getHeight() + " calculated hash and actual hash does not match");
 | 
			
		||||
        if(status == Block.VerifyCodes.INVALID_POW_SIGNATURE) throw new BlockchainIntegrityException("Block " + block.getHeight() + " contains invalid proof of work signature");
 | 
			
		||||
        if(status == Block.VerifyCodes.INVALID_BLOCK_HASH) throw new BlockchainIntegrityException("Block " + block.getHeight() + " contains invalid hash");
 | 
			
		||||
 | 
			
		||||
        if(length != 0) { // don't check for very first block
 | 
			
		||||
            if (!getLatestBlock().getHash().equals(block.getPrevHash())) throw new BlockchainIntegrityException("Block " + block.getHeight() + " previous hash does not match");
 | 
			
		||||
 | 
			
		||||
            for (Transaction transaction : block.getTransactions()) {
 | 
			
		||||
                if(this.getAddressBalance(transaction.getSender()) < transaction.getAmount())
 | 
			
		||||
                    throw new BlockchainIntegrityException("Wallet " + transaction.getSender() + " at block " + block.getHeight() + " tried to spend too much\nBalance: " + this.getAddressBalance(transaction.getSender()) + "\nTried to spend: " + transaction.getAmount());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        blocks.add(block);
 | 
			
		||||
        length++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getAddressBalance(String walletAddress) {
 | 
			
		||||
        int amount = 0;
 | 
			
		||||
 | 
			
		||||
        for (Block block : blocks) {
 | 
			
		||||
            for (Transaction transaction : block.getTransactions()) {
 | 
			
		||||
                if(transaction.getSender().equals(walletAddress)) amount -= transaction.getAmount();
 | 
			
		||||
                if(transaction.getRecipient().equals(walletAddress)) amount += transaction.getAmount();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return amount;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
package pl.mikorosa.dziecoin;
 | 
			
		||||
 | 
			
		||||
public class BlockchainIntegrityException extends Exception {
 | 
			
		||||
    public BlockchainIntegrityException(String message) {
 | 
			
		||||
        super(message);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
package pl.mikorosa.dziecoin;
 | 
			
		||||
 | 
			
		||||
import java.nio.charset.StandardCharsets;
 | 
			
		||||
import java.security.MessageDigest;
 | 
			
		||||
import java.security.NoSuchAlgorithmException;
 | 
			
		||||
 | 
			
		||||
public abstract class CalculateHash {
 | 
			
		||||
    public static String sha256sum(String input) {
 | 
			
		||||
        MessageDigest md;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            md = MessageDigest.getInstance("SHA-256");
 | 
			
		||||
        } catch(NoSuchAlgorithmException e) {
 | 
			
		||||
            throw new IllegalArgumentException(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        byte[] sha256sum = md.digest(input.getBytes(StandardCharsets.UTF_8));
 | 
			
		||||
        StringBuilder sb = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
        for(byte b : sha256sum) {
 | 
			
		||||
            sb.append(String.format("%02x", b));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String md5sum(String input) {
 | 
			
		||||
        MessageDigest md;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            md = MessageDigest.getInstance("MD5");
 | 
			
		||||
        } catch(NoSuchAlgorithmException e) {
 | 
			
		||||
            throw new IllegalArgumentException(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        byte[] md5sum = md.digest(input.getBytes(StandardCharsets.UTF_8));
 | 
			
		||||
        StringBuilder sb = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
        for(byte b : md5sum) {
 | 
			
		||||
            sb.append(String.format("%02x", b));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return sb.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
package pl.mikorosa.dziecoin;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class Main {
 | 
			
		||||
    public static int difficulty;
 | 
			
		||||
    public static Blockchain blockchain;
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        Wallet w1 = new Wallet();
 | 
			
		||||
        Wallet w2 = new Wallet();
 | 
			
		||||
        Wallet w3 = new Wallet();
 | 
			
		||||
 | 
			
		||||
        difficulty = 4;
 | 
			
		||||
        blockchain = new Blockchain(w1.getAddress());
 | 
			
		||||
 | 
			
		||||
        NFT n1 = new NFT(w1.getAddress(), "licencja na wozek widlowy");
 | 
			
		||||
 | 
			
		||||
        List<Transaction> t1 = new ArrayList<>();
 | 
			
		||||
        t1.add(new Transaction(w1.getAddress(), w2.getAddress(), 5));
 | 
			
		||||
 | 
			
		||||
        Block b1 = new Block(blockchain.getLatestBlock().getHash(), blockchain.getLength() + 1, t1);
 | 
			
		||||
 | 
			
		||||
        b1.addNFT(n1);
 | 
			
		||||
 | 
			
		||||
        b1.mineBlock();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            blockchain.addBlock(b1);
 | 
			
		||||
        } catch (BlockchainIntegrityException e) {
 | 
			
		||||
            System.out.println("Blockchain Integrity Exception: " + e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Transaction> t2 = new ArrayList<>();
 | 
			
		||||
        t2.add(new Transaction(w1.getAddress(), w3.getAddress(), 2));
 | 
			
		||||
        t2.add(new Transaction(w2.getAddress(), w3.getAddress(), 3));
 | 
			
		||||
 | 
			
		||||
        Block b2 = new Block(blockchain.getLatestBlock().getHash(), blockchain.getLength() + 1, t2);
 | 
			
		||||
        b2.mineBlock();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            blockchain.addBlock(b2);
 | 
			
		||||
        } catch (BlockchainIntegrityException e) {
 | 
			
		||||
            System.out.println("Blockchain Integrity Exception: " + e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (Block block : blockchain.getBlocks()) {
 | 
			
		||||
            System.out.println("Block " + block.getHeight() + ": " + block.getHash());
 | 
			
		||||
            for (Transaction transaction : block.getTransactions()) {
 | 
			
		||||
                System.out.println("    " + transaction.getSender() + " => " + transaction.getRecipient() + " - " + transaction.getAmount());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        System.out.println("Balances:");
 | 
			
		||||
        System.out.println("Wallet 1: " + blockchain.getAddressBalance(w1.getAddress()));
 | 
			
		||||
        System.out.println("Wallet 2: " + blockchain.getAddressBalance(w2.getAddress()));
 | 
			
		||||
        System.out.println("Wallet 3: " + blockchain.getAddressBalance(w3.getAddress()));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
package pl.mikorosa.dziecoin;
 | 
			
		||||
 | 
			
		||||
public class NFT {
 | 
			
		||||
    private String contract;
 | 
			
		||||
    private String owner;
 | 
			
		||||
    private String data;
 | 
			
		||||
 | 
			
		||||
    public NFT(String owner, String data) {
 | 
			
		||||
        this.owner = owner;
 | 
			
		||||
        this.data = data;
 | 
			
		||||
        this.contract = CalculateHash.md5sum(owner + data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public NFT(String contract, String owner, String data) {
 | 
			
		||||
        String testHash = CalculateHash.md5sum(owner + data);
 | 
			
		||||
        if(!testHash.equals(contract)) throw new IllegalStateException("NFT contract and data does not match");
 | 
			
		||||
        this.owner = owner;
 | 
			
		||||
        this.data = data;
 | 
			
		||||
        this.contract = contract;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    public String getContract() {
 | 
			
		||||
        return contract;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getOwner() {
 | 
			
		||||
        return owner;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getData() {
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "NFT{" +
 | 
			
		||||
                "contract='" + contract + '\'' +
 | 
			
		||||
                ", owner='" + owner + '\'' +
 | 
			
		||||
                ", data='" + data + '\'' +
 | 
			
		||||
                '}';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,34 @@
 | 
			
		|||
package pl.mikorosa.dziecoin;
 | 
			
		||||
 | 
			
		||||
public class Transaction {
 | 
			
		||||
    private String sender;
 | 
			
		||||
    private String recipient;
 | 
			
		||||
    private int amount;
 | 
			
		||||
 | 
			
		||||
    public Transaction(String sender, String recipient, int amount) {
 | 
			
		||||
        this.sender = sender;
 | 
			
		||||
        this.recipient = recipient;
 | 
			
		||||
        this.amount = amount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getSender() {
 | 
			
		||||
        return sender;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getRecipient() {
 | 
			
		||||
        return recipient;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getAmount() {
 | 
			
		||||
        return amount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "Transaction{" +
 | 
			
		||||
                "sender='" + sender + '\'' +
 | 
			
		||||
                ", recipient='" + recipient + '\'' +
 | 
			
		||||
                ", amount=" + amount +
 | 
			
		||||
                '}';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
package pl.mikorosa.dziecoin;
 | 
			
		||||
 | 
			
		||||
import java.security.*;
 | 
			
		||||
 | 
			
		||||
public class Wallet {
 | 
			
		||||
    private String address;
 | 
			
		||||
    private PublicKey publicKey;
 | 
			
		||||
    private PrivateKey privateKey;
 | 
			
		||||
 | 
			
		||||
    Wallet() {
 | 
			
		||||
        try {
 | 
			
		||||
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
 | 
			
		||||
            keyGen.initialize(1024);
 | 
			
		||||
            KeyPair keyPair = keyGen.genKeyPair();
 | 
			
		||||
            privateKey = keyPair.getPrivate();
 | 
			
		||||
            publicKey = keyPair.getPublic();
 | 
			
		||||
            address = CalculateHash.md5sum(publicKey.getEncoded().toString());
 | 
			
		||||
        } catch (NoSuchAlgorithmException e) {
 | 
			
		||||
            System.out.println("No such algo: " + e);
 | 
			
		||||
        } catch (ProviderException e) {
 | 
			
		||||
            System.out.println("Provider exception: " + e);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            System.out.println("General exception: " + e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getAddress() {
 | 
			
		||||
        return address;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue