Last active
November 6, 2018 05:55
-
-
Save felixklauke/432552438b3bb7d23137efb78b3d6bc6 to your computer and use it in GitHub Desktop.
BlockChain example.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.commons.codec.digest.DigestUtils; | |
import java.util.Collections; | |
import java.util.List; | |
/** | |
* Represents one block in the chain. | |
* | |
* @author Felix Klauke <info@felix-klauke.de> | |
*/ | |
public class Block { | |
/** | |
* The delimiter of the blocks hash. Can by like $ or |. | |
*/ | |
private static final String HASH_DELIMITER = "$"; | |
/** | |
* The timestamp when the block was created. | |
*/ | |
private final long timestamp = System.currentTimeMillis(); | |
/** | |
* The transactions this block will verify. | |
*/ | |
private final List<Transaction> transactions; | |
/** | |
* The hash of the previous block in the chain. | |
*/ | |
private final String previousBlockHash; | |
/** | |
* The proof that some work was done for earning this block. | |
*/ | |
private final int proofOfWork; | |
/** | |
* Create a new block by its underlying data. | |
* | |
* @param previousBlockHash The hash of the previous block in the chain. | |
* @param transactions The transactions this block will verify. | |
* @param proofOfWork The proof that some work was done for earning this block. | |
*/ | |
public Block(String previousBlockHash, List<Transaction> transactions, int proofOfWork) { | |
this.previousBlockHash = previousBlockHash; | |
this.transactions = transactions; | |
this.proofOfWork = proofOfWork; | |
} | |
public List<Transaction> getTransactions() { | |
return Collections.unmodifiableList(transactions); | |
} | |
public long getTimestamp() { | |
return timestamp; | |
} | |
public String getPreviousBlockHash() { | |
return previousBlockHash; | |
} | |
public int getProofOfWork() { | |
return proofOfWork; | |
} | |
public String getHash() { | |
return DigestUtils.sha256Hex(timestamp + HASH_DELIMITER + transactions.toString() + HASH_DELIMITER + previousBlockHash + HASH_DELIMITER + proofOfWork); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.commons.codec.digest.DigestUtils; | |
import java.util.ArrayList; | |
import java.util.Deque; | |
import java.util.LinkedList; | |
import java.util.List; | |
/** | |
* @author Felix Klauke <info@felix-klauke.de> | |
*/ | |
public class BlockChain { | |
/** | |
* The prefix a proof of work has to have to be valid. | |
*/ | |
private static final String VALIDATION_PREFIX = "0000000000000000000"; | |
/** | |
* The transactions the next created block will verify. | |
*/ | |
private final List<Transaction> transactions = new ArrayList<>(); | |
/** | |
* All blocks in the chain. | |
*/ | |
private final Deque<Block> blocks = new LinkedList<>(); | |
/** | |
* Start mining a new block. | |
* | |
* @return The block instance. | |
*/ | |
public Block mineBlock() { | |
int proofOfWork = proofOfWork(); | |
Block block = new Block(blocks.getLast().getHash(), transactions, proofOfWork); | |
transactions = new ArrayList(); | |
return block; | |
} | |
/** | |
* Add a transaction that will be verified by the next block. | |
* | |
* @param transaction The transaction. | |
*/ | |
public void addTransaction(Transaction transaction) { | |
transactions.add(transaction); | |
} | |
/** | |
* Add a block to the chain. | |
* | |
* @param block The block. | |
*/ | |
public void addBlock(Block block) { | |
boolean offer = blocks.offer(block); | |
} | |
/** | |
* Generate a new proof of work. | |
* | |
* @return The proof of work. | |
*/ | |
public int proofOfWork() { | |
return proofOfWork(blocks.getLast().getProofOfWork()); | |
} | |
private int proofOfWork(int lastProof) { | |
int proof = 0; | |
while (!validateProofOfWork(lastProof, proof)) { | |
proof++; | |
} | |
return proof; | |
} | |
private boolean validateProofOfWork(int lastProof, int currentProof) { | |
String result = lastProof + "" + currentProof; | |
return DigestUtils.sha256Hex(result).startsWith(VALIDATION_PREFIX); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.UUID; | |
/** | |
* @author Felix Klauke <info@felix-klauke.de> | |
*/ | |
public class Main { | |
public static void main(String[] args) { | |
// Genesis block | |
Block block = new Block("", new ArrayList<>(), 0); | |
BlockChain blockChain = new BlockChain(); | |
blockChain.addBlock(block); | |
blockChain.addTransaction(new Transaction(UUID.randomUUID(), 10, UUID.randomUUID())); | |
Block mineBlock = blockChain.mineBlock(); | |
System.out.println("Mined block: " + block.getHash()); | |
blockChain.addBlock(block); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.UUID; | |
/** | |
* @author Felix Klauke <info@felix-klauke.de> | |
*/ | |
public class Transaction { | |
private final UUID source; | |
private final long amount; | |
private final UUID destination; | |
public Transaction(UUID source, long amount, UUID destination) { | |
this.source = source; | |
this.amount = amount; | |
this.destination = destination; | |
} | |
public UUID getSource() { | |
return source; | |
} | |
public UUID getDestination() { | |
return destination; | |
} | |
public long getAmount() { | |
return amount; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment