Implémentation d'une blockchain simple en Java

1. Vue d'ensemble

Dans ce tutoriel, nous allons apprendre les concepts de base de la technologie blockchain. Nous allons également implémenter une application de base en Java qui se concentre sur les concepts.

En outre, nous discuterons de certains concepts avancés et applications pratiques de cette technologie.

2. Qu'est-ce que la blockchain?

Alors, comprenons d'abord ce qu'est exactement la blockchain ...

Eh bien, cela remonte au livre blanc publié par Satoshi Nakamoto sur Bitcoin, en 2008.

La blockchain est un registre d'informations décentralisé . Il se compose de blocs de données connectés via l'utilisation de la cryptographie. Il appartient à un réseau de nœuds connectés sur le réseau public. Nous comprendrons mieux cela lorsque nous tenterons de créer un didacticiel de base plus tard.

Il y a quelques attributs importants que nous devons comprendre, alors passons en revue:

  • Inviolable: d'abord et avant tout, les données faisant partie d'un bloc sont inviolables . Chaque bloc est référencé par un condensé cryptographique, communément appelé hachage, ce qui rend le bloc inviolable.
  • Décentralisé: l'ensemble de la blockchain est complètement décentralisé sur le réseau. Cela signifie qu'il n'y a pas de nœud maître et que chaque nœud du réseau a la même copie.
  • Transparent: chaque nœud participant au réseau valide et ajoute un nouveau bloc à sa chaîne par consensus avec d'autres nœuds. Par conséquent, chaque nœud a une visibilité complète des données.

3. Comment fonctionne la blockchain?

Maintenant, comprenons comment fonctionne la blockchain.

Les unités fondamentales d'une blockchain sont des blocs . Un seul bloc peut encapsuler plusieurs transactions ou d'autres données précieuses:

3.1. Extraction d'un bloc

Nous représentons un bloc par une valeur de hachage. La génération de la valeur de hachage d'un bloc est appelée «extraction» du bloc. L'extraction d'un bloc est généralement coûteuse en calcul car elle sert de «preuve de travail».

Le hachage d'un bloc se compose généralement des données suivantes:

  • Principalement, le hachage d'un bloc se compose des transactions qu'il encapsule
  • Le hachage se compose également de l'horodatage de la création du bloc
  • Il comprend également un nonce, un nombre arbitraire utilisé en cryptographie
  • Enfin, le hachage du bloc courant inclut également le hachage du bloc précédent

Plusieurs nœuds du réseau peuvent rivaliser pour exploiter le bloc en même temps. En plus de générer le hachage, les nœuds doivent également vérifier que les transactions ajoutées dans le bloc sont légitimes. Le premier à miner un bloc remporte la course!

3.2. Ajouter un bloc dans la blockchain

Bien que l'extraction d'un bloc soit coûteuse en calcul, vérifier qu'un bloc est légitime est relativement beaucoup plus facile . Tous les nœuds du réseau participent à la vérification d'un bloc nouvellement extrait.

Ainsi, un bloc nouvellement extrait est ajouté à la blockchain sur le consensus des nœuds.

Maintenant, il existe plusieurs protocoles de consensus disponibles que nous pouvons utiliser pour la vérification. Les nœuds du réseau utilisent le même protocole pour détecter les branches malveillantes de la chaîne. Ainsi, une branche malveillante, même introduite, sera bientôt rejetée par la majorité des nœuds.

4. Blockchain de base en Java

Nous avons maintenant suffisamment de contexte pour commencer à créer une application de base en Java.

Notre exemple simple illustrera ici les concepts de base que nous venons de voir. Une application de niveau production implique de nombreuses considérations qui sortent du cadre de ce didacticiel. Nous aborderons cependant certains sujets avancés plus tard.

4.1. Implémentation d'un bloc

Tout d'abord, nous devons définir un POJO simple qui contiendra les données de notre bloc:

public class Block { private String hash; private String previousHash; private String data; private long timeStamp; private int nonce; public Block(String data, String previousHash, long timeStamp) { this.data = data; this.previousHash = previousHash; this.timeStamp = timeStamp; this.hash = calculateBlockHash(); } // standard getters and setters }

Comprenons ce que nous avons emballé ici:

  • Hash du bloc précédent, une partie importante pour construire la chaîne
  • Les données réelles, toute information ayant de la valeur, comme un contrat
  • L'horodatage de la création de ce bloc
  • Un nonce, qui est un nombre arbitraire utilisé en cryptographie
  • Enfin, le hachage de ce bloc, calculé à partir d'autres données

4.2. Calcul du hachage

Maintenant, comment calculer le hachage d'un bloc? Nous avons utilisé une méthode CalculateBlockHash mais n'avons pas encore vu d'implémentation. Avant de mettre en œuvre cette méthode, il vaut la peine de passer du temps à comprendre ce qu'est exactement un hachage.

Un hachage est une sortie de quelque chose connu sous le nom de fonction de hachage. Une fonction de hachage mappe les données d'entrée de taille arbitraire aux données de sortie de taille fixe . Le hachage est assez sensible à tout changement dans les données d'entrée, aussi petit soit-il.

De plus, il est impossible de récupérer les données d'entrée uniquement à partir de leur hachage. Ces propriétés rendent la fonction de hachage très utile en cryptographie.

Voyons donc comment nous pouvons générer le hachage de notre bloc en Java:

public String calculateBlockHash() { String dataToHash = previousHash + Long.toString(timeStamp) + Integer.toString(nonce) + data; MessageDigest digest = null; byte[] bytes = null; try { digest = MessageDigest.getInstance("SHA-256"); bytes = digest.digest(dataToHash.getBytes(UTF_8)); } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) { logger.log(Level.SEVERE, ex.getMessage()); } StringBuffer buffer = new StringBuffer(); for (byte b : bytes) { buffer.append(String.format("%02x", b)); } return buffer.toString(); }

Il se passe beaucoup de choses ici, comprenons-les en détail:

  • Tout d'abord, nous concaténons différentes parties du bloc pour générer un hachage à partir de
  • Ensuite, nous obtenons une instance de la fonction de hachage SHA-256 de MessageDigest
  • Ensuite, nous générons la valeur de hachage de nos données d'entrée, qui est un tableau d'octets
  • Enfin, nous transformons le tableau d'octets en une chaîne hexadécimale, un hachage est généralement représenté sous la forme d'un nombre hexadécimal à 32 chiffres

4.3. Avons-nous déjà exploité le bloc?

Tout semble simple et élégant jusqu'à présent, à l'exception du fait que nous n'avons pas encore exploité le bloc. Alors, qu'est-ce qui implique exactement l'extraction d'un bloc, qui a capturé la fantaisie des développeurs depuis un certain temps maintenant!

Eh bien, extraire un bloc signifie résoudre une tâche complexe en termes de calcul pour le bloc. Bien que calculer le hachage d'un bloc soit quelque peu trivial, trouver le hachage commençant par cinq zéros ne l'est pas. Encore plus compliqué serait de trouver un hachage commençant par dix zéros, et nous avons une idée générale.

Alors, comment pouvons-nous faire cela exactement? Honnêtement, la solution est beaucoup moins sophistiquée! C'est avec la force brute que nous tentons d'atteindre cet objectif. Nous utilisons ici nonce:

public String mineBlock(int prefix) { String prefixString = new String(new char[prefix]).replace('\0', '0'); while (!hash.substring(0, prefix).equals(prefixString)) { nonce++; hash = calculateBlockHash(); } return hash; }

Voyons ce que nous essayons de faire ici:

  • Nous commençons par définir le préfixe que nous souhaitons trouver
  • Ensuite, nous vérifions si nous avons trouvé la solution
  • Sinon on incrémente le nonce et on calcule le hachage dans une boucle
  • La boucle continue jusqu'à ce que nous atteignions le jackpot

Nous commençons par la valeur par défaut de nonce ici et l'incrémentons de un. Mais il existe des stratégies plus sophistiquées pour démarrer et incrémenter un nonce dans des applications du monde réel. De plus, nous ne vérifions pas nos données ici, ce qui est généralement une partie importante.

4.4. Examinons l'exemple

Maintenant que nous avons défini notre bloc avec ses fonctions, nous pouvons l'utiliser pour créer une simple blockchain. Nous allons stocker ceci dans une ArrayList :

List blockchain = new ArrayList(); int prefix = 4; String prefixString = new String(new char[prefix]).replace('\0', '0');

De plus, nous avons défini un préfixe de quatre, ce qui signifie en fait que nous voulons que notre hachage commence par quatre zéros.

Voyons comment ajouter un bloc ici:

@Test public void givenBlockchain_whenNewBlockAdded_thenSuccess() { Block newBlock = new Block( "The is a New Block.", blockchain.get(blockchain.size() - 1).getHash(), new Date().getTime()); newBlock.mineBlock(prefix); assertTrue(newBlock.getHash().substring(0, prefix).equals(prefixString)); blockchain.add(newBlock); }

4.5. Vérification de la blockchain

Comment un nœud peut-il valider qu'une blockchain est valide? Bien que cela puisse être assez compliqué, pensons à une version simple:

@Test public void givenBlockchain_whenValidated_thenSuccess() { boolean flag = true; for (int i = 0; i < blockchain.size(); i++) { String previousHash = i==0 ? "0" : blockchain.get(i - 1).getHash(); flag = blockchain.get(i).getHash().equals(blockchain.get(i).calculateBlockHash()) && previousHash.equals(blockchain.get(i).getPreviousHash()) && blockchain.get(i).getHash().substring(0, prefix).equals(prefixString); if (!flag) break; } assertTrue(flag); }

Nous effectuons donc ici trois vérifications spécifiques pour chaque bloc:

  • Le hachage stocké du bloc actuel est en fait ce qu'il calcule
  • Le hachage du bloc précédent stocké dans le bloc actuel est le hachage du bloc précédent
  • Le bloc actuel a été miné

5. Quelques concepts avancés

Bien que notre exemple de base fasse ressortir les concepts de base d'une blockchain, il n'est certainement pas complet. Pour mettre cette technologie en pratique, plusieurs autres considérations doivent être prises en compte.

Bien qu'il ne soit pas possible de tous les détailler, passons en revue certains des plus importants:

5.1. Vérification des transactions

Calculating the hash of a block and finding the desired hash is just one part of mining. A block consists of data, often in the form of multiple transactions. These must be verified before they can be made part of a block and mined.

A typical implementation of blockchain sets a restriction on how much data can be part of a block. It also sets up rules on how a transaction can be verified. Multiple nodes in the network participate in the verification process.

5.2. Alternate Consensus Protocol

We saw that consensus algorithm like “Proof of Work” is used to mine and validate a block. However, this is not the only consensus algorithm available for use.

There are several other consensus algorithms to choose from, like Proof of Stake, Proof of Authority, and Proof of Weight. All of these have their pros and cons. Which one to use depends upon the type of application we intend to design.

5.3. Mining Reward

A blockchain network typically consists of voluntary nodes. Now, why would anyone want to contribute to this complex process and keep it legit and growing?

This is because nodes are rewarded for verifying the transactions and mining a block. These rewards are typically in the form of coin associated with the application. But an application can decide the reward to be anything of value.

5.4. Node Types

A blockchain completely relies on its network to operate. In theory, the network is completely decentralized, and every node is equal. However, in practice, a network consists of multiple types of nodes.

While a full node has a complete list of transactions, a light node only has a partial list. Moreover, not all nodes participate in verification and validation.

5.5. Secure Communication

One of the hallmarks of blockchain technology is its openness and anonymity. But how does it provide security to transactions being carried within? This is based on cryptography and public key infrastructure.

The initiator of a transaction uses their private key to secure it and attach it to the public key of the recipient. Nodes can use the public keys of the participants to verify transactions.

6. Practical Applications of Blockchain

So, blockchain seems to be an exciting technology, but it also must prove useful. This technology has been around for some time now and – needless to say – it has proved to be disruptive in many domains.

Its application in many other areas is being actively pursued. Let's understand the most popular applications:

  • Currency: This is by far the oldest and most widely known use of blockchain, thanks to the success of Bitcoin. They provide secure and frictionless money to people across the globe without any central authority or government intervention.
  • Identity: Digital identity is fast becoming the norm in the present world. However, this is mired by security issues and tampering. Blockchain is inevitable in revolutionizing this area with completely secure and tamper-proof identities.
  • Healthcare: Healthcare industry is loaded with data, mostly handled by central authorities. This decreases transparency, security, and efficiency in handling such data. Blockchain technology can provide a system without any third party to provide much-needed trust.
  • Government: This is perhaps an area which is well open to disruption by the blockchain technology. Government is typically at the center of several citizen services which are often laden with inefficiencies and corruption. Blockchain can help establish much better government-citizen relations.

7. Tools of the Trade

While our basic implementation here is useful to elicit the concepts, it's not practical to develop a product on blockchain from scratch. Thankfully, this space has matured now, and we do have some quite useful tools to start from.

Let's go through some of the popular tools to work within this space:

  • Solidity: Solidity is a statically-typed and object-oriented programming language designed for writing smart contracts. It can be used to write smart contracts on various blockchain platforms like Ethereum.
  • Remix IDE: Remix is a powerful open-source tool to write smart contracts in Solidity. This enables the user to write smart contracts right from the browser.
  • Truffle Suite: Truffle provides a bunch of tools to get a developer up and started in developing distributed apps. This includes Truffle, Ganache, and Drizzle.
  • Ethlint/Solium: Solium allows developers to ensure that their smart contracts written on Solidity is free from style and security issues. Solium also helps in fixing these issues.
  • Parité: La parité aide à mettre en place l'environnement de développement du contrat intelligent sur Etherium. Il fournit un moyen rapide et sécurisé d'interagir avec la blockchain.

8. Conclusion

Pour résumer, dans ce tutoriel, nous avons passé en revue les concepts de base de la technologie blockchain. Nous avons compris comment un réseau mine et ajoute un nouveau bloc dans la blockchain. De plus, nous avons implémenté les concepts de base en Java. Nous avons également discuté de certains des concepts avancés liés à cette technologie.

Enfin, nous avons terminé avec quelques applications pratiques de la blockchain et des outils disponibles.

Comme toujours, le code peut être trouvé sur GitHub.