diff --git a/src/blockchain/Block.java b/src/blockchain/Block.java new file mode 100644 index 0000000..eacfa16 --- /dev/null +++ b/src/blockchain/Block.java @@ -0,0 +1,33 @@ +package blockchain; + +public class Block { + + private final Integer id; + private final String hashPreviousBlock; + private final String hash; + private final Long timestamp; + + + public Block(Integer id, String hashPreviousBlock, String hash, Long timestamp) { + this.id = id; + this.hashPreviousBlock = hashPreviousBlock; + this.hash = hash; + this.timestamp = timestamp; + } + + public Integer getId() { + return id; + } + + public String getHashPreviousBlock() { + return hashPreviousBlock; + } + + public String getHash() { + return hash; + } + + public Long getTimestamp() { + return timestamp; + } +} diff --git a/src/blockchain/Blockchain.java b/src/blockchain/Blockchain.java new file mode 100644 index 0000000..dac77fc --- /dev/null +++ b/src/blockchain/Blockchain.java @@ -0,0 +1,43 @@ +package blockchain; + +import java.util.Collections; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; + +public class Blockchain implements Iterable { + + private final LinkedList blocks; + + public Blockchain() { + blocks = new LinkedList<>(Collections.singleton( + new Block(1, + "0", + StringUtil.applySha256("0"), + new Date().getTime())) + ); + } + + public void generate() { + Long timestamp = new Date().getTime(); + Block tailBlock = blocks.getLast(); + String hash = StringUtil.applySha256(tailBlock.getHash()); + blocks.add(new Block(tailBlock.getId() + 1, tailBlock.getHash(), hash, timestamp)); + } + + public boolean validate() { + for (int i = 1; i < blocks.size(); i++) { + Block prev = blocks.get(i - 1); + Block cur = blocks.get(i); + if (!cur.getHashPreviousBlock().equals(prev.getHash())) { + return false; + } + } + return true; + } + + @Override + public Iterator iterator() { + return blocks.iterator(); + } +} diff --git a/src/blockchain/Main.java b/src/blockchain/Main.java index adf1d02..e343207 100644 --- a/src/blockchain/Main.java +++ b/src/blockchain/Main.java @@ -1,7 +1,19 @@ package blockchain; public class Main { - public static void main(String[] args) { - System.out.print("Hello world!"); + + public static void main(String[] args) { + Blockchain blockchain = new Blockchain(); + for (int i = 0; i < 10; i++) { + blockchain.generate(); + } + + for (Block block : blockchain) { + System.out.printf("Block:\n"); + System.out.printf("Id: %s\n", block.getId()); + System.out.printf("Timestamp: %s\n", block.getTimestamp()); + System.out.printf("Hash of the previous block:\n%s\n", block.getHashPreviousBlock()); + System.out.printf("Hash of the block: \n%s\n\n", block.getHash()); } + } } \ No newline at end of file diff --git a/src/blockchain/StringUtil.java b/src/blockchain/StringUtil.java new file mode 100644 index 0000000..9a4c32d --- /dev/null +++ b/src/blockchain/StringUtil.java @@ -0,0 +1,28 @@ +package blockchain; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; + +public class StringUtil { + + /** + * Applies Sha256 to a string and returns a hash. + */ + public static String applySha256(String input) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8)); + StringBuilder hexString = new StringBuilder(); + for (byte elem : hash) { + String hex = Integer.toHexString(0xff & elem); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +}