If you have a cryptocurrency, then you own something digitally, you have an asset, considered to be a coin because it is relatively rare, hard to get and everybody also wants to have it. That’s what makes this digital property be considered money, hence has value and you can exchange for other things (goods or services) that you also desire.
Basically, that’s the same thing that happens with the printed paper you have in your wallet/pocket, it has value because the govern (the owner of the printer) it says so, and you trust them (don’t you?). Let’s not forget our internet banking account balance, that numbers are completely virtual (digital, there’s nothing concrete behind), it is money because you (and the others) trust in your Bank (as long as they are considered economically “healthy”).
In its not-so-technical version explanation, normally directed to business people interested in this subject, usually, blockchain is presented as a distributed ledger, a decentralized database with encrypted transactions. That’s perfectly fine, there’s no centralized server controlling the information (like a Bank, Govern, etc.), there’s no master, every participating node has its own copy, and when new data is appended, all of them has to come to a consensus that the new block is trustable, valid and consistency to be part of the chain. With the word consensus I mean, a complex mathematical cryptographic calculation that must be solved, otherwise the block is not valid and will not be appended.
By the way, the blockchain it is an append-only repository, nothing can be modified, only added.
For us, as software engineers, regarding this subject the most interesting to check out, is actually, what’s behind the scenes, that is, the technology that makes possible the existence of cryptocurrencies, the blockchain, I am referring to the software pattern called blockchain.
The blockchain is a pattern that allows constructing interconnected information (blocks) that are linked to each other using cryptography to ensure security and integrity. Any modification to any one of the blocks will turn all the chain invalid. It was made to be resistant to modification, getting the characteristic of being an append-only repository.
Check the image below, they are interconnected by their hashes, each block generates its identification (its hash) based on the identification of the previous one (previous hash), any modification on one of them impacts them all, invalidating and turns the chain untrustable.
In addition to that, the generation of the block’s hash might also take into consideration in the equation some other data (for instance, the total amount of the transactions in the block), this way the integrity would be impacted if any of the transactions is touched.
With this vision in mind… sounds like it is something suitable to build a chain of money transactions, isn’t it? So, let’s do it! Here in this article, the aim is to analyze blockchain with a software perspective, and we will perform this implementing our own simplified version of a cryptocurrency.
Coding Our Cryptocurrency
Let’s start with the Block, defining the data necessary that it should have to work a chain of blocks. The attributes below represents the block header information.
public abstract class AbstractBlock { @Getter @Setter(AccessLevel.PUBLIC) private Integer height; @Getter @Setter(AccessLevel.PROTECTED) private String hash; @Getter @Setter(AccessLevel.PUBLIC) private String previousBlock; @Getter @Setter(AccessLevel.PUBLIC) private String nextBlock; @Getter @Setter(AccessLevel.PROTECTED) private Long timeStamp; @Getter @Setter(AccessLevel.PROTECTED) private Integer nonce; @Getter @Setter(AccessLevel.PROTECTED) private String merkleRoot; ... }
We generalize all the information of a block in an Abstract Class, this way we can create later other types of blockchains for different scenarios, we’ll see (in a future article, hope so) that cryptocurrency is only one of them, and we will use this same abstraction to handle blocks for different solutions of blockchain.
In the case of the CurrencyBlock the data that we take care are the transactions, where the money (coins) goes from one to another, so the concrete implementation has a list of them.
public class CurrencyBlock extends AbstractBlock { @Getter private List<Transaction> transactions = new ArrayList<Transaction>(); ... protected void calculateHashBlock(String data, int difficulty) { if ( this.getHash() != null ) { throw new RuntimeException("The Hash of this Block were already calculated"); } int _nonce = -1; String calculatedhash = ""; while ( !isHashValid(calculatedhash, difficulty) ) { calculatedhash = Security.applySHA256( data + Long.toString(this.getTimeStamp()) + this.getPreviousBlock() + (_nonce+=1) ); } this.setNonce(_nonce); this.setHash( calculatedhash ); } ... }
One thing to highlight at the CurrencyBlock object is the method where it is calculated the Hash of the Block (line 5). In the loop command (line 13 to 20) we are “mining” for a valid Hash to create this Block, based on the parameter named difficulty, that dictates the level of difficulty to come up with one. Each iteration of the loop we increment the nonce variable by one, to have a different value expecting to achieve a valid hash. Sometimes it can take 200 iterations, others 19.000 iterations, it is unpredictable. As higher the difficulty, harder it gets to achieve a valid hash, in our sample application we set the difficulty to 3. Basically, the challenge is to come up with a hash with 3 leading zeros.
By the time this article was being written, the Bitcoin Blockchain has a difficulty of 18 leading zeros. Try it on your own (test the power of you computer processor), download the sample application and change the 3 leading zeros to 18, and check the time it takes, grab a cup of coffee to wait this.
This Block at Bitcoin Blockchain, we can note(or count) in the right upper corner the leading zeros of the hashes.
Merkle Root
One important information that is part of the block header is the Merkle Root (merkleRoot attribute defined in the AbstractBlock class code above), a hash created based on all of the hashes of the transactions added to the block. The Merkle Root is a binary hash tree used to check the integrity of the block, any subtle change in one of the transactions of the block, would turn the Merkle Root value invalid.
As all the hashes of this binary tree have its origin from the result of a calculation using the set of transactions, this makes everything interconnected, and the Merkle Root value becomes like a digital fingerprint of the block. There’s no way to match the right value (once calculated) if any transaction data were changed, other than recalculated everything from the bottom up to the top, the whole tree.
The image below shows a simple illustration of how a hash binary tree Merkle Root works, basically, from bottom-up all the way to the top we go in pairs producing a hash until we finish with only one hash left, that’ll be Merkle Root (aka Merkle Hash).
With our CurrencyBlock already defined, we need to build a class that will control the chain, that will be responsible to manage the blocks (add, validate), we will call it CurrencyBlockChain. This class has a series of supporting Services (other classes) that will help it to carry out the blockchain functionalities, we will go with the most relevant, but first… to help understand what it is coming, let’s understand what it means UTXO.
UTXO is an acronym from the BitCoin technical glossary that means Unspent Transaction Output, i.e. the output of the transactions that can be spent (used as money, as an input) in new transactions. We keep the track of all UTXOs in our UTXOService class:
@Service public class UTXOService { private Map<String,TransactionOutput> UTXOs = new HashMap<String,TransactionOutput>(); public void addTransaction(TransactionOutput transactionOutput) { UTXOs.put(transactionOutput.getHash(), transactionOutput); } ... }
The collections of blocks in the chain will be controlled by the object CurrencyBlockRepository. The Blockchain will be created from the beginning, i.e. not loaded from a distributed node but started from scratch. That’s why we need to come up with the first block of the chain (with some coins in it), commonly called genesis block, we’ll see later. Everything is going to be kept in-memory only.
@Repository public class CurrencyBlockRepository { // In-memory private List<CurrencyBlock> repository = new ArrayList<CurrencyBlock>(); public void reset() { this.repository = new ArrayList(); } public boolean isEmpty() { return this.repository.isEmpty(); } public void addBlock(CurrencyBlock currencyBlock) { this.repository.add(currencyBlock); } ... }
The next object is self-explanatory by its name, called Wallet.
@Component @Scope("prototype") public class Wallet { @Autowired private TransactionService transactionServices; private Security security; private CurrencyBlockChain currencyBlockChain; private String owner; private KeyPair keyPairs; private Map<String,TransactionOutput> UTXOs = new HashMap<String,TransactionOutput>(); @Autowired public Wallet(Security security, CurrencyBlockChain currencyBlockChain, String owner) { this.security = security; this.currencyBlockChain = currencyBlockChain; this.owner = owner; this.generateOrLoadKeyPair(); } ... public Transaction sendMoney(Wallet recipient, float amount) { if ( this.getPublicKey() == recipient ) { throw new RuntimeException("Transaction invalid! The sender cannot be the recipient of the own money"); } isThereFundsToPerformPayment(amount); List<TransactionInput> inputs = new ArrayList<TransactionInput>(); collectAvailableMoneyForPayment(amount, inputs); Transaction transaction = transactionServices.createTransaction(this, recipient , amount, inputs); if ( !transaction.processTransaction() ) { throw new RuntimeException("The transaction could no be processed"); } removeFromAvailableTheMoneySpent(inputs); return transaction; } ... }
Some points to verify at the Wallet object:
- From line 11 to 13 are the attributes that compose a Wallet:
- keyPairs: this is the Keys (Private/Public) of the owner’s Wallet, the private it’s like his secret password, used to sign the transaction. The public is the key used by everyone interested in to verify whether the transaction belongs to the owner’s Wallet, performing the signature checking
- Line 35:
- That’s the creation of the transaction with the payment (inputs) being sending to the recipient (using the Recipient’s Public Key as its unique identification)
- Line 36:
- At the moment the transaction is processed, the INPUTs (payments) and the OUTPUTs (changes) are created. Also, the first thing performed at the calling of this method is, the signature checking, i.e. verify with the Sender’s Public Key whether this transaction was really create by him/her.
- Line 40:
- At this method we withdraw the transactions outputs (used as input at the new one created, line 35) from the UTXOs (the list of unspent transaction).
Now let’s back to the object CurrencyBlockChain, responsible for the management of the our CryptoCurrency Blockchain, go through some interesting parts of it.
@Component @Slf4j public class CurrencyBlockChain { @Autowired private WalletService walletService; @Autowired private TransactionService transactionService; @Autowired private CurrencyBlockRepository currencyBlockRepository; @Autowired private UTXOService utxoService; public static float MINIMUM_TRANSACTION = 5; public static int DIFFICULTY = 3; ... public Wallet bigBan() { currencyBlockRepository.reset(); Wallet genesitWallet = walletService.createGenesisWallet(); CurrencyBlock genesisBlock = createGenesisBlock(genesitWallet); genesisBlock.calculateHashBlock(); genesisBlock.setHeight(0); currencyBlockRepository.addBlock( genesisBlock ); return genesitWallet; } ... public void addBlock(CurrencyBlock block) { // The BlockChain must be started, the "Genesis" Transaction must appear before if ( currencyBlockRepository.isEmpty() ) { throw new RuntimeException("The BlockChain must be initialized"); } // Get the previous block hash to set this one with it CurrencyBlock previousBlock = currencyBlockRepository.getLastBlock(); block.setPreviousBlock( previousBlock.getHash() ); // Calculate its own hash block.calculateHashBlock(); // Set its position on the chain block.setHeight(currencyBlockRepository.size()); // Calculate the Merkle Root of the Block block.calculateMerkleRoot(); // Join the Block to the Chain currencyBlockRepository.addBlock(block); // Inform to set the former last Block which are the next now in the chain previousBlock.setNextBlock(block.getHash()); } ... }
The highlights here:
- Line 22:
- Well, everything has a beginning, so we need to “forge” some coins in order to start the distribution of the money, turning feasible the transactions among the users. That’s what perform our bigBan method, it creates the first Block in the chain, what so called Genesis Block, we create it with a transaction of an amount of $1000 (Note: in real applications, don’t do like me, and call your method like this, Uncle Bob could be watching you, so keep your Code Clean :-).
- Line 34 to 53: The method that handles the reception of the new block and its insertion in the Blockchain, and some other things:
- Calculate its Hash, taking into consideration the Hash of the previous Block in the Blockchain (44).
- Calculate the Merkle Root of the Block (48).
- Link the Blocks in the chain, the new with the previous, and previous with the new Block (44, 52).
Our CryptoCurrency In Action!
Now that we have met the main objects and methods of our solution, let’s use them all to perform transactions among CryptoCurrency owners. In the CurrencyBlockChainTest, our JUnit testing class, we will put everything together and check its functionalities.
... @Before public void createTheWorld() { genesisWallet = currencyBlockChain.bigBan(); } @Test public void firstTestBlockChainTwoBlocks() { Wallet janeWallet = walletServices.createWallet("jane"); Wallet johnWallet = walletServices.createWallet("john"); // Even list transaction CurrencyBlock block = new CurrencyBlock(); Transaction transaction0 = genesisWallet.sendMoney(janeWallet, 50f); Transaction transaction1 = genesisWallet.sendMoney(johnWallet, 180f); Transaction transaction2 = johnWallet.sendMoney(janeWallet, 25f); Transaction transaction3 = janeWallet.sendMoney(johnWallet, 5f); Transaction transaction4 = genesisWallet.sendMoney(janeWallet, 50f); Transaction transaction5 = genesisWallet.sendMoney(johnWallet, 180f); Transaction transaction6 = johnWallet.sendMoney(janeWallet, 25f); Transaction transaction7 = janeWallet.sendMoney(johnWallet, 5f); block = new CurrencyBlock(); block.addTransaction(transaction0) .addTransaction(transaction1) .addTransaction(transaction2) .addTransaction(transaction3) .addTransaction(transaction4) .addTransaction(transaction5) .addTransaction(transaction6) .addTransaction(transaction7) ; currencyBlockChain.addBlock(block); String blockMerkleRoot = block.getMerkleRoot(); assertNotNull("Merkle Root is Null?",blockMerkleRoot); assertEquals("Block is valid? (MerkleRoot value is OK?)", true, currencyBlockChain.validateBlock(block)); double janeWalletBalance = currencyBlockChain.queryBalance(janeWallet).doubleValue(); double johnWalletBalance = currencyBlockChain.queryBalance(johnWallet).doubleValue(); double genesisWalletBalance = currencyBlockChain.queryBalance(genesisWallet).doubleValue(); assertEquals("Jane Wallet",140d, janeWalletBalance,0); assertEquals("John Wallet",320d, johnWalletBalance,0); assertEquals("Genesis Wallet",540d, genesisWalletBalance,0); assertEquals("Total Balance BlockChain",1000d, (janeWalletBalance+johnWalletBalance+genesisWalletBalance),0); block = new CurrencyBlock(); transaction0 = genesisWallet.sendMoney(janeWallet, 50f); transaction1 = genesisWallet.sendMoney(johnWallet, 180f); transaction2 = johnWallet.sendMoney(janeWallet, 25f); block = new CurrencyBlock(); block.addTransaction(transaction0) .addTransaction(transaction1) .addTransaction(transaction2); currencyBlockChain.addBlock(block); assertNotNull("Merkle Root is Null?",block.getMerkleRoot()); janeWalletBalance = currencyBlockChain.queryBalance(janeWallet).doubleValue(); johnWalletBalance = currencyBlockChain.queryBalance(johnWallet).doubleValue(); genesisWalletBalance = currencyBlockChain.queryBalance(genesisWallet).doubleValue(); assertEquals("Jane Wallet",215d, janeWalletBalance,0); assertEquals("John Wallet",475, johnWalletBalance,0); assertEquals("Genesis Wallet",310d, genesisWalletBalance,0); assertEquals("Total Balance BlockChain",1000d, (janeWalletBalance+johnWalletBalance+genesisWalletBalance),0); ... block.getTransactions().stream() .skip(1).skip(1).findFirst().get().setValue(new BigDecimal(44)); assertEquals("Block is valid? (MerkleRoot value is OK?) In this case it shouldn't", false, currencyBlockChain.validateBlock(block)); ... printerConsole.print(currencyBlockChain.listBlockChain()); } }
It is quite self-explanatory read the code and understand what it is performing. We create two Wallets (Jane and John – line 9 and 10), apart from the genesis automatically created (4), and they interchange some amount of coins afterward.
Subsequently, we create a Block, add eight transactions on it, and insert this new Block in the Blockchain (22 to 32).Following, we realize some ordinary checkings and asserts, like: validate the Merkle Root and query the money each one should have. We also check the expected balance in the Blockchain, that should be of $1000, the amount we use to create the genesis block (45).
We could go on and keep adding more Blocks with new transactions, in the end, the balance should always be $1000, as we are just transferring among each one of them the property of the coins available in our Blockchain. The only thing that deserves a little more attention is the attempt to tamper the Block, performing a change in one of the transactions already added to the Block, as a result, the Merkle Root should not be valid anymore (67 to 69).
Now, let’s print our Blockchain to see what is inside of it:
... ╔═════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ BLOCK #0000 ► genesis ◄ ║ ║ ► Hash........: 0002f06be5faa75c676282284597305b490562179421bcaf7ddfe1c1a3bcd339 ║ ║ ► Previous....: 000 ║ ║ ► Next........: 00062339476ab0cf893a37ebf64b1b4a13cc58a5f9791b711718e87790dcec46 ║ ║ ► TimeStamp...: 15/05/2018 09:03:38.188 ║ ║ ► Nonce.......: 3,426 ║ ║ ► Merkle Root.: 8bbb2be28b6dd809b2e1e3fec325c32d71ff16c02177c4d93f32e265b90a9e78 ║ ╟─────────┬───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0001├─► TRANSACTION: Hash.......: d4c752c0118b70cb63e2a808227da694538d2d2944506a9602c3c901ae53c48b ║ ║ │ Value......: $1,000.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.171 ║ ║ │ From → To..: genesis ---→ genesis ║ ║ │ INPUTS --→ ║ ║ │ ←-- OUTPUTS ║ ║ │ - $1,000.00 TO genesis ║ ╚═════════╧═══════════════════════════════════════════════════════════════════════════════════════════════╝ ╔═════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ BLOCK #0001 of 0002 ║ ║ ► Hash........: 00062339476ab0cf893a37ebf64b1b4a13cc58a5f9791b711718e87790dcec46 ║ ║ ► Previous....: 0002f06be5faa75c676282284597305b490562179421bcaf7ddfe1c1a3bcd339 ║ ║ ► Next........: 00036f0debd054c6e99f06d259b760ce847ef187673f36726f50050aae13f09c ║ ║ ► TimeStamp...: 15/05/2018 09:03:38.292 ║ ║ ► Nonce.......: 8,646 ║ ║ ► Merkle Root.: ebc31add24a971e2a8f812b9081925ce51fbdb7d126a523f052987bd50fe1c87 ║ ╟─────────┬───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0001├─► TRANSACTION: Hash.......: 4d4da99ff7158c25e658d314bf8ff00de858bb5e388308811288a80592e1db42 ║ ║ │ Value......: $50.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.272 ║ ║ │ From → To..: genesis ---→ jane ║ ║ │ INPUTS --→ ║ ║ │ + $1,000.00 FROM genesis ║ ║ │ ←-- OUTPUTS ║ ║ │ - $50.00 TO jane ║ ║ │ - $950.00 TO genesis ║ ╟─────────┼───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0002├─► TRANSACTION: Hash.......: 08c92e751c23e2112504b86367ac4debdd6653467a747b209cddc79b6d8b7dcb ║ ║ │ Value......: $180.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.277 ║ ║ │ From → To..: genesis ---→ john ║ ║ │ INPUTS --→ ║ ║ │ + $950.00 FROM genesis ║ ║ │ ←-- OUTPUTS ║ ║ │ - $180.00 TO john ║ ║ │ - $770.00 TO genesis ║ ╟─────────┼───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0003├─► TRANSACTION: Hash.......: 27e11e7d7d88bc14cef911b73ddcda55681c4fa75a1c10e411ff40c982c457b4 ║ ║ │ Value......: $25.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.279 ║ ║ │ From → To..: john ---→ jane ║ ║ │ INPUTS --→ ║ ║ │ + $180.00 FROM john ║ ║ │ ←-- OUTPUTS ║ ║ │ - $25.00 TO jane ║ ║ │ - $155.00 TO john ║ ╟─────────┼───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0004├─► TRANSACTION: Hash.......: 553a481cf92cc5506d96cf67bdf27d15be047782588c584e65a7079a0f453fa7 ║ ║ │ Value......: $5.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.282 ║ ║ │ From → To..: jane ---→ john ║ ║ │ INPUTS --→ ║ ║ │ + $50.00 FROM jane ║ ║ │ ←-- OUTPUTS ║ ║ │ - $5.00 TO john ║ ║ │ - $45.00 TO jane ║ ╟─────────┼───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0005├─► TRANSACTION: Hash.......: 014fb19f9edde5aa6774a9fc61a7d03f63c118a27dc4148c4c60548a2fab965a ║ ║ │ Value......: $50.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.284 ║ ║ │ From → To..: genesis ---→ jane ║ ║ │ INPUTS --→ ║ ║ │ + $770.00 FROM genesis ║ ║ │ ←-- OUTPUTS ║ ║ │ - $50.00 TO jane ║ ║ │ - $720.00 TO genesis ║ ╟─────────┼───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0006├─► TRANSACTION: Hash.......: 2b385abd9a8a9249c1de9b596a3235e61bac4c399fa12c3afc79450949b1845d ║ ║ │ Value......: $180.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.286 ║ ║ │ From → To..: genesis ---→ john ║ ║ │ INPUTS --→ ║ ║ │ + $720.00 FROM genesis ║ ║ │ ←-- OUTPUTS ║ ║ │ - $180.00 TO john ║ ║ │ - $540.00 TO genesis ║ ╟─────────┼───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0007├─► TRANSACTION: Hash.......: 0992631de4384e98732675653042d5904d7d923d59c87d7388bb691b12345c53 ║ ║ │ Value......: $25.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.288 ║ ║ │ From → To..: john ---→ jane ║ ║ │ INPUTS --→ ║ ║ │ + $5.00 FROM john ║ ║ │ + $180.00 FROM john ║ ║ │ ←-- OUTPUTS ║ ║ │ - $25.00 TO jane ║ ║ │ - $160.00 TO john ║ ╟─────────┼───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0008├─► TRANSACTION: Hash.......: 090da7953654e0ef1c65fda4c2d0892ad54536179c1e6cfd050c1e45dce37729 ║ ║ │ Value......: $5.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.289 ║ ║ │ From → To..: jane ---→ john ║ ║ │ INPUTS --→ ║ ║ │ + $25.00 FROM jane ║ ║ │ ←-- OUTPUTS ║ ║ │ - $5.00 TO john ║ ║ │ - $20.00 TO jane ║ ╚═════════╧═══════════════════════════════════════════════════════════════════════════════════════════════╝ ╔═════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ BLOCK #0002 of 0002 ║ ║ ► Hash........: 00036f0debd054c6e99f06d259b760ce847ef187673f36726f50050aae13f09c ║ ║ ► Previous....: 00062339476ab0cf893a37ebf64b1b4a13cc58a5f9791b711718e87790dcec46 ║ ║ ► Next........: ║ ║ ► TimeStamp...: 15/05/2018 09:03:38.308 ║ ║ ► Nonce.......: 6,304 ║ ║ ► Merkle Root.: 744382dc3133964a6d94a2e2d56926fc2db3b3573f48872cf9f6e13e7048c5af ║ ╟─────────┬───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0001├─► TRANSACTION: Hash.......: d2d66b659c42323af8ce14a5e6f69310af722d501b5f72a72737cc034ede4a78 ║ ║ │ Value......: $50.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.303 ║ ║ │ From → To..: genesis ---→ jane ║ ║ │ INPUTS --→ ║ ║ │ + $540.00 FROM genesis ║ ║ │ ←-- OUTPUTS ║ ║ │ - $50.00 TO jane ║ ║ │ - $490.00 TO genesis ║ ╟─────────┼───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0002├─► TRANSACTION: Hash.......: a217ba3913acaab3a3141335fd78e33d614f23de41c9654ec1c981ea0df62705 ║ ║ │ Value......: $180.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.305 ║ ║ │ From → To..: genesis ---→ john ║ ║ │ INPUTS --→ ║ ║ │ + $490.00 FROM genesis ║ ║ │ ←-- OUTPUTS ║ ║ │ - $180.00 TO john ║ ║ │ - $310.00 TO genesis ║ ╟─────────┼───────────────────────────────────────────────────────────────────────────────────────────────╢ ║ #0003├─► TRANSACTION: Hash.......: db2748188a5bdf1f5ed91fe930d0f5dd39cbe586af75ef426f064526539efdc6 ║ ║ │ Value......: $44.00 ║ ║ │ TimeStamp..: 15/05/2018 09:03:38.307 ║ ║ │ From → To..: john ---→ jane ║ ║ │ INPUTS --→ ║ ║ │ + $5.00 FROM john ║ ║ │ + $155.00 FROM john ║ ║ │ ←-- OUTPUTS ║ ║ │ - $25.00 TO jane ║ ║ │ - $135.00 TO john ║ ╚═════════╧═══════════════════════════════════════════════════════════════════════════════════════════════╝ ...
The first Block, the genesis, the purpose is only “feed” the Blockchain with $1000 (line 18), so let’s leave it aside and analyze some points at the two posterior Blocks, from the real users John and Jane.
The first Block we had 8 transactions added to it, taking the 7th as an example, we can see: the value of the transaction (90), who is the Sender and the Recipient (92), the INPUTs (94-95, the total amount added to this transaction for payment to the Recipient) and the OUTPUTs (97-98, the amount that belongs to the Recipient as agreed, and the rest is the change to the Sender).
Remember the imposed difficulty!? The amount of leading zeros that must have a valid hash (in our sample application 3)?! So, check our Block header and see how many loops it took while our processor was “mining” for a valid one, it was necessary 8.646 iterations (line 22 the valid hash, line 26 the nonce value).
At the Block header we have the hashes printed together (the current, the previous and the next), reminding that the hash of the current Block was created taking as input the hash of the previous one, chaining all the blocks in sequence together.
At last, but not least, at the header of each block is also presented the calculated Merkle Root (line 27), as we’ve seen, based on the values of all transactions present in the Block.
Conclusion
The most interesting thing regarding all the talking about Cryptocurrencies is what is behind of all that, what makes possible the existence of them: the Blockchain pattern. We could use it for other purposes also, not only for money transactions, basically everything that needs to keep the control of a sequence of events, ensuring the integrity and security, could be a candidate for the Blockchain pattern be used at the solution implementation. Try on your own (at you Lab), start with small ideas, over small problems, prove them, grow smoothly if it gets interesting, and maybe could be a match for a real future challenge you could face.