Skip to content

Instantly share code, notes, and snippets.

@marnix135
Last active November 13, 2018 02:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marnix135/ec4f51d07b7854abc56c431deb42b120 to your computer and use it in GitHub Desktop.
Save marnix135/ec4f51d07b7854abc56c431deb42b120 to your computer and use it in GitHub Desktop.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
/*
A simple example of a blockchain demonstrating how data stored in it cannot be changed.
*/
class Block {
private int index;
private String timeStamp;
private int previousHash;
private String[] data;
private int hash;
public Block(int index, String timeStamp, int previousHash, String[] data) {
this.previousHash = previousHash;
this.data = data;
// Calculate hash when initialising block
this.hash = calculateHash();
}
public int calculateHash() {
// Convert all the stored data into one hash
return Arrays.hashCode(new Object[] {index, timeStamp, previousHash, data});
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public String getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(String timeStamp) {
this.timeStamp = timeStamp;
}
public int getPreviousHash() {
return previousHash;
}
public void setPreviousHash(int previousHash) {
this.previousHash = previousHash;
}
public String[] getData() {
return data;
}
public void setData(String[] data) {
this.data = data;
}
public int getHash() {
return hash;
}
public void setHash(int hash) {
this.hash = hash;
}
}
class Blockchain {
private ArrayList<Block> list = new ArrayList<>();
public Blockchain(Block genesisBlock) {
this.list.add(genesisBlock);
}
public void addBlock(String[] data) {
// Add new block with at the end of the chain
Block block = new Block(list.size(), new Date().toString(), list.get(list.size() - 1).getHash(), data);
list.add(block);
}
public Block getBlock(int index) {
return list.get(index);
}
public void calculateHashes() {
// Calculate the hash for every block
list.forEach(Block::calculateHash);
}
public void check() throws Exception {
Block genesisBlock = list.get(0);
if (genesisBlock.getHash() != genesisBlock.calculateHash()) {
throw new Exception("Block 0 has an incorrect hash!");
}
for (int i = 1; i < list.size(); i++) {
Block current = list.get(i);
Block previous = list.get(i - 1);
// The stored hash is not correct
if (current.getHash() != current.calculateHash()) {
throw new Exception("Block " + i + " has an incorrect hash!");
}
// The previous hash is not equal to the hash of the previous block
if (current.getPreviousHash() != previous.getHash()) {
throw new Exception("Block " + (i - 1) + " has an incorrect hash!");
}
}
}
}
public class App {
public static void main( String[] args ) {
// Initialising the blockchain and the first (genesis) hash
Blockchain blockchain = new Blockchain(new Block(0, new Date().toString(), 0, new String[]{"First block", "Some data"}));
// Adding 100 more blocks
for (int i = 0; i < 100; i++) {
blockchain.addBlock(new String[]{i + "th block", "More data"});
}
// Changing data, which should throw an error
blockchain.getBlock(30).setData(new String[]{"Malicious data."});
blockchain.getBlock(31).setData(new String[]{"More malicious data."});
blockchain.getBlock(32).setData(new String[]{"Even more malicious data."});
// Recalculate hashes and check for errors
try {
blockchain.calculateHashes();
blockchain.check();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment