Blockchain Python – Guide rapide – Bitcoin investissement

Carte de paiement Crypto

Demandez votre Carte de paiement Crypto ici

Recevez 8 € de BTC gratuitement

Inscrivez-vous à CoinBase









Actualité bitcoin



Annonces

Dans le tutoriel sur Blockchain, nous avons appris en détail la théorie derrière la blockchain. La blockchain est la pierre angulaire du Bitcoin, la monnaie numérique la plus populaire au monde. Le didacticiel a traité en profondeur des subtilités de Bitcoin, expliquant en détail l’architecture blockchain. La prochaine étape consiste à créer notre propre blockchain.

Satoshi Nakamoto a créé la première monnaie virtuelle au monde appelée Bitcoin. En regardant le succès de Bitcoin, beaucoup d'autres ont créé leurs propres monnaies virtuelles. Pour en nommer quelques-uns – Litecoin, Zcash, etc.

Maintenant, vous voudrez peut-être aussi lancer votre propre devise. Appelons cela TPCoin (TutorialsPoint Coin). Vous allez écrire une blockchain pour enregistrer toutes les transactions qui traitent avec TPCoin. Le TPCoin peut être utilisé pour acheter des pizzas, des hamburgers, des salades, etc. D'autres fournisseurs de services pourraient rejoindre votre réseau et commencer à accepter TPCoin comme devise pour la fourniture de leurs services. Les possibilités sont infinies.

Dans ce didacticiel, expliquons comment construire un tel système et lancer votre propre monnaie numérique sur le marché.

Composants impliqués dans le développement du projet Blockchain

L’ensemble du projet Blockchain comprend trois composantes principales:

Client

Le client est celui qui achètera les biens d'autres vendeurs. Le client lui-même peut devenir un vendeur et accepter de l'argent d'autres personnes contre les biens qu'il fournit. Nous supposons ici que le client peut être à la fois un fournisseur et un destinataire de TPCoins. Ainsi, nous allons créer une classe de clients dans notre code capable d'envoyer et de recevoir de l'argent.

Mineur

Le mineur est celui qui récupère les transactions dans un pool de transactions et les assemble en bloc. Le mineur doit fournir une preuve de travail valide pour obtenir la récompense minière. Tout l'argent que le mineur perçoit à titre de frais lui sera conservé. Il peut dépenser cet argent pour acheter des biens ou des services auprès d’autres fournisseurs inscrits sur le réseau, comme le fait un client décrit ci-dessus.

Blockchain

Enfin, une Blockchain est une structure de données qui enchaîne tous les blocs extraits dans un ordre chronologique. Cette chaîne est immuable et donc indemne.

Vous pouvez suivre ce tutoriel en tapant le code présenté à chaque étape dans un nouveau carnet Jupyter. Vous pouvez également télécharger l'intégralité du carnet Jupyter à l'adresse www.anaconda.com.

Dans le chapitre suivant, nous allons développer un client qui utilise notre système de blockchain.

Un client est une personne qui détient des TPCoins et les négocie pour des biens / services auprès d’autres fournisseurs sur le réseau, y compris le sien. Nous devrions définir un Client classe à cet effet. Pour créer une identification unique pour le client au niveau mondial, nous utilisons une infrastructure à clé publique (PKI). Dans ce chapitre, parlons de cela en détail.

Le client devrait pouvoir envoyer de l'argent de son portefeuille à une autre personne connue. De même, le client devrait pouvoir accepter de l’argent d’un tiers. Pour dépenser de l’argent, le client créerait une transaction spécifiant le nom de l’expéditeur et le montant à payer. Pour recevoir de l'argent, le client fournira son identité à la tierce partie – essentiellement un expéditeur de l'argent. Nous ne conservons pas le solde des fonds du client dans son portefeuille. Au cours d'une transaction, nous allons calculer le solde réel afin de nous assurer que le client dispose du solde suffisant pour effectuer le paiement.

Développer le Client classe et pour le reste du code dans le projet, nous devrons importer de nombreuses bibliothèques Python. Ceux-ci sont énumérés ci-dessous –




# bibliothèques d'importation
importer hashlib
importer au hasard
chaîne d'importation
importer json
importer binascii
importer numpy en tant que np
importer des pandas en tant que pd
importer pylab en tant que pl
enregistrement des importations
importer date / heure
importer des collections

En plus des bibliothèques standard ci-dessus, nous allons signer nos transactions, créer un hachage des objets, etc. Pour cela, vous devrez importer les bibliothèques suivantes:




Nombre d'importations suivantes sont requises par l'ICP
importer crypto
importer Crypto.Random
depuis Crypto.Hash, importer SHA
depuis Crypto.PublicKey, importez RSA
depuis l'importation Crypto.Signature PKCS1_v1_5

Dans le chapitre suivant, parlons de la classe de client.

le Client la classe génère le privé et Publique clés en utilisant le Python intégré RSA algorithme. Le lecteur intéressé peut se référer à ce tutoriel pour la mise en œuvre de RSA. Lors de l'initialisation de l'objet, nous créons des clés privées et publiques et stockons leurs valeurs dans la variable d'instance.




self._private_key = RSA.generate (1024, aléatoire)
self._public_key = self._private_key.publickey ()

Notez que vous ne devriez jamais perdre votre clé privée. Pour la conservation des enregistrements, la clé privée générée peut être copiée sur un stockage externe sécurisé ou vous pouvez simplement en écrire la représentation ASCII sur un morceau de papier.

Le généré Publique clé sera utilisée comme identité du client. Pour cela, nous définissons une propriété appelée identité qui retourne la représentation HEX de la clé publique.




@propriété
   def identité (soi):
      revenir
binascii.hexlify (self._public_key.exportKey (format = 'DER'))
.decode ('ascii')

le identité est unique pour chaque client et peut être rendu public. Tout le monde pourrait vous envoyer de la monnaie virtuelle en utilisant cette identité et il sera ajouté à votre portefeuille.

Le code complet pour le Client la classe est montrée ici –




classe Client:
   def __init __ (auto):
      random = Crypto.Random.new (). read
      self._private_key = RSA.generate (1024, aléatoire)
      self._public_key = self._private_key.publickey ()
      self._signer = PKCS1_v1_5.new (self._private_key)

   @propriété
   def identité (soi):
      revenir
binascii.hexlify (self._public_key.exportKey (format = 'DER')). decode ('ascii')

Client de test

Maintenant, nous allons écrire du code qui illustrera comment utiliser le Client classe –




Dinesh = Client ()
print (Dinesh.identity)

Le code ci-dessus crée une instance de Client et l'assigne à la variable Dinesh. Nous imprimons la clé publique de Dinesh en appelant son identité méthode. La sortie est montrée ici –




30819f300d06092a864886f70d010101050003818d0030818902818100b547fafceeb131e07
0166a6b23fec473cce22c3f55c35ce535b31d4c74754fecd820aa94c1166643a49ea5f49f72
3181ff943eb3fdc5b2cb2db12d21c06c880ccf493e14d93e3f93a9e175325790004954c34d3
c7bc2ccc9f0eb5332014937f9e49bca9b7856d351a553d9812367dc8f2ac734992a4e6a6ff6
6f347bd411d07f0203010001

Nous allons maintenant créer une transaction dans le chapitre suivant.

Dans ce chapitre, créons un Transaction classe de sorte qu'un client puisse envoyer de l'argent à quelqu'un. Notez qu'un client peut être à la fois un expéditeur et un destinataire de l'argent. Lorsque vous souhaitez recevoir de l'argent, un autre expéditeur créera une transaction et précisera votre Publique adresse dedans. Nous définissons l'initialisation d'une classe de transaction comme suit –




def __init __ (auto, expéditeur, destinataire, valeur):
   self.sender = expéditeur
   self.recipient = destinataire
   self.value = valeur
   self.time = datetime.datetime.now ()

le init La méthode prend trois paramètres – la valeur de l'expéditeur Publique clé, le destinataire Publique clé, et le montant à envoyer. Celles-ci sont stockées dans les variables d'instance pour être utilisées par d'autres méthodes. De plus, nous créons une variable supplémentaire pour stocker le temps de transaction.

Ensuite, nous écrivons une méthode utilitaire appelée to_dict qui combine les quatre variables d’instance susmentionnées dans un objet dictionnaire. Cela consiste simplement à mettre toutes les informations de transaction accessibles via une seule variable.

Comme vous le savez dans le didacticiel précédent, le premier bloc de la blockchain est un Genèse bloquer. Le bloc Genesis contient la première transaction initiée par le créateur de la chaîne de blocs. L'identité de cette personne peut être gardée secrète, comme dans le cas des Bitcoins. Ainsi, lorsque cette première transaction est créée, le créateur peut simplement envoyer son identité en tant que Genèse. Ainsi, lors de la création du dictionnaire, nous vérifions si l'expéditeur est Genèse et si c'est le cas, nous affectons simplement une valeur de chaîne à la variable d'identité; sinon, nous attribuons l’identité de l’expéditeur au destinataire. identité variable.




si self.sender == "Genesis":
   identité = "Genèse"
autre:
   identité = self.sender.identity

Nous construisons le dictionnaire en utilisant la ligne de code suivante




renvoyer des collections.OrderedDict (
   'expéditeur': identité,
   'destinataire': self.recipient,
   'valeur': self.value,
   'time': self.time)

Le code complet pour le to_dict la méthode est indiquée ci-dessous –




def to_dict (self):
   si self.sender == "Genesis":
      identité = "Genèse"
   autre:
      identité = self.sender.identity

   renvoyer des collections.OrderedDict (
      'expéditeur': identité,
      'destinataire': self.recipient,
      'valeur': self.value,
      'time': self.time)

Enfin, nous allons signer cet objet dictionnaire en utilisant la clé privée de l'expéditeur. Comme précédemment, nous utilisons l’algorithme PKI intégré avec l’algorithme SHA. La signature générée est décodée pour obtenir la représentation ASCII à imprimer et à stocker dans notre blockchain. le signature_transaction Le code de la méthode est montré ici –




def sign_transaction (self):
   private_key = self.sender._private_key
   signataire = PKCS1_v1_5.new (clé privée)
   h = SHA.new (str (self.to_dict ()). encode ('utf8'))
   retourne binascii.hexlify (signer.sign (h)). decode ('ascii')

Nous allons maintenant tester cela Transaction classe.

Test de la classe de transaction

Pour cela, nous allons créer deux utilisateurs, appelés Dinesh et Ramesh. Dinesh enverra 5 TPCoins à Ramesh. Pour cela, nous créons d'abord les clients appelés Dinesh et Ramesh.




Dinesh = Client ()
Ramesh = Client ()

Rappelez-vous que lorsque vous instanciez un Client classe, la public et des clés privées uniques au client seraient créées. Comme Dinesh envoie le paiement à Ramesh, il aura besoin de la clé publique de Ramesh obtenue à l'aide de la propriété d'identité du client.

Ainsi, nous allons créer l’instance de transaction en utilisant le code suivant –




t = transaction (
   Dinesh,
   Ramesh.identité,
   5.0
)

Notez que le premier paramètre est l'expéditeur, le deuxième paramètre est la clé publique du destinataire et le troisième paramètre est le montant à transférer. le signature_transaction La méthode récupère la clé privée de l'expéditeur à partir du premier paramètre permettant de chanter la transaction.

Une fois l’objet transaction créé, vous le signerez en appelant son signature_transaction méthode. Cette méthode retourne la signature générée au format imprimable. Nous générons et imprimons la signature en utilisant les deux lignes de code suivantes:




signature = t.sign_transaction ()
imprimer (signature) 

Lorsque vous exécutez le code ci-dessus, vous verrez une sortie semblable à celle-ci –




7c7e3c97629b218e9ec6e86b01f9abd8e361fd69e7d373c38420790b655b9abe3b575e343c7
13703ca1aee781acd7157a0624db3d57d7c2f1172730ee3f45af943338157f899965856f6b0
0e34db240b62673ad5a08c8e490f880b568efbc36035cae2e748f1d802d5e8e66298be826f5
c6363dc511222fb2416036ac04eb972

Maintenant que notre infrastructure de base pour créer un client et une transaction est prête, nous aurons maintenant plusieurs clients effectuant plusieurs transactions comme dans une situation réelle.

Les transactions effectuées par différents clients sont mises en file d'attente dans le système. les mineurs récupèrent les transactions de cette file d'attente et les ajoutent au bloc. Ils exploiteront ensuite le bloc et le mineur gagnant aura le privilège d'ajouter le bloc à la blockchain et gagnera ainsi de l'argent pour lui-même.

Nous décrirons ce processus d’extraction plus tard lorsque nous discuterons de la création de la blockchain. Avant d'écrire le code pour plusieurs transactions, ajoutons une petite fonction utilitaire pour imprimer le contenu d'une transaction donnée.

Affichage de la transaction

le display_transaction fonction accepte un seul paramètre de type de transaction. L’objet dictionnaire de la transaction reçue est copié dans une variable temporaire appelée dict et en utilisant les touches du dictionnaire, les différentes valeurs sont imprimées sur la console.




def display_transaction (transaction):
   #pour transaction en transaction:
   dict = transaction.to_dict ()
   print ("expéditeur:" + dict['sender'])
   impression ('-----')
   print ("destinataire:" + dict['recipient'])
   impression ('-----')
   print ("valeur:" + str (dict['value']))
   impression ('-----')
   print ("time:" + str (dict['time']))
   impression ('-----')

Ensuite, nous définissons une file d'attente de transactions pour stocker nos objets de transaction.

File d'attente de transaction

Pour créer une file d'attente, nous déclarons un global liste variable appelée transactions comme suit –




transactions = []

Nous allons simplement ajouter chaque transaction nouvellement créée à cette file d'attente. Veuillez noter que par souci de brièveté, nous n'implémenterons pas la logique de gestion des files d'attente dans ce didacticiel.

Créer plusieurs clients

Maintenant, nous allons commencer à créer des transactions. Premièrement, nous allons créer quatre clients qui s’enverront de l’argent pour obtenir divers services ou biens auprès d’autres.




Dinesh = Client ()
Ramesh = Client ()
Seema = Client ()
Vijay = Client ()

À ce stade, nous avons quatre clients appelés Dinesh, Ramesh, Seema et Vijay. Nous supposons actuellement que chacun de ces clients détient des TPCoins dans leur portefeuille pour effectuer des transactions. L'identité de chacun de ces clients serait spécifiée à l'aide de la propriété d'identité de ces objets.

Création de la première transaction

Maintenant, nous initions notre première transaction comme suit –




t1 = transaction (
   Dinesh,
   Ramesh.identité,
   15.0
)

Dans cette transaction, Dinesh envoie 5 TPCoins à Ramesh. Pour que la transaction réussisse, nous devrons nous assurer que Dinesh a suffisamment d’argent dans son portefeuille pour effectuer ce paiement. Notez que nous aurons besoin d’une transaction de genèse pour démarrer la circulation de TPCoin dans le système. Au fur et à mesure de votre lecture, vous écrirez le code de transaction pour cette transaction de genèse.

Nous allons signer cette transaction à l'aide de la clé privée de Dinesh et l'ajouter à la file d'attente des transactions comme suit:




t1.sign_transaction ()
transactions.append (t1)

Après la première transaction effectuée par Dinesh, nous créerons plusieurs autres transactions entre différents clients que nous avons créés ci-dessus.

Ajouter plus de transactions

Nous allons maintenant créer plusieurs autres transactions, chaque transaction donnant quelques TPCoins à une autre partie. Lorsque quelqu'un dépense de l'argent, il n'est pas nécessaire qu'il vérifie si le solde de son portefeuille est suffisant. De toute façon, le mineur serait en train de valider chaque transaction pour le solde de l'expéditeur lors du lancement de la transaction.

En cas de solde insuffisant, le mineur marquera cette transaction comme non valide et ne l'ajoutera pas à ce bloc.

Le code suivant crée et ajoute neuf transactions supplémentaires à notre file d'attente.




t2 = transaction (
   Dinesh,
   Seema.identity,
   6.0
)
t2.sign_transaction ()
transactions.append (t2)
t3 = transaction (
   Ramesh,
   Vijay.identity,
   2.0
)
t3.sign_transaction ()
transactions.append (t3)
t4 = transaction (
   Seema,
   Ramesh.identité,
   4.0
)
t4.sign_transaction ()
transactions.append (t4)
t5 = transaction (
   Vijay,
   Seema.identity,
   7,0
)
t5.sign_transaction ()
transactions.append (t5)
t6 = transaction (
   Ramesh,
   Seema.identity,
   3.0
)
t6.sign_transaction ()
transactions.append (t6)
t7 = transaction (
   Seema,
   Dinesh.identity,
   8.0
)
t7.sign_transaction ()
transactions.append (t7)
t8 = transaction (
   Seema,
   Ramesh.identité,
   1,0
)
t8.sign_transaction ()
transactions.append (t8)
t9 = transaction (
   Vijay,
   Dinesh.identity,
   5.0
)
t9.sign_transaction ()
transactions.append (t9)
t10 = transaction (
   Vijay,
   Ramesh.identité,
   3.0
)
t10.sign_transaction ()
transactions.append (t10)

Lorsque vous exécutez le code ci-dessus, vous aurez dix transactions dans la file d'attente pour que les mineurs créent leurs blocs.

Opérations de dumping

En tant que responsable de la blockchain, vous souhaiterez régulièrement revoir le contenu de la file d'attente des transactions. Pour cela, vous pouvez utiliser le display_transaction fonction que nous avons développée plus tôt. Pour vider toutes les transactions de la file d'attente, il suffit de modifier la liste des transactions et, pour chaque transaction référencée, appelez le display_transaction fonctionne comme indiqué ici –




pour transaction en transaction:
   display_transaction (transaction)
   impression ('--------------')

Les transactions sont séparées par une ligne en pointillé pour la distinction. Si vous exécutez le code ci-dessus, vous verrez la liste des transactions comme indiqué ci-dessous –




expéditeur:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c49214
4a9f463480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329e
c86794b04d773eb4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b
47e5157f8fe56c2ce3279c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311
c4d866c12d79d3fc3034563dfb0203010001
-----
bénéficiaire:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e
674abe7abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8ad
d126b6e1a1308fb98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa93977
04de625d1836d3f42c7ee5683f6703259592cc24b09699376807f28fe0e00ff882974484
d805f874260dfc2d1627473b910203010001
-----
valeur: 15.0
-----
temps: 2019-01-14 16: 18: 01.859915
-----
--------------
expéditeur:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c49214
4a9f463480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329e
c86794b04d773eb4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b
47e5157f8fe56c2ce3279c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311
c4d866c12d79d3fc3034563dfb0203010001
-----
bénéficiaire:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae14
3cbe59b3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fb
d9ee74b9e7ea12334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0
961b4f212d1fd5b5e49ae09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d0623
75799742a359b8f22c5362e5650203010001
-----
valeur: 6.0
-----
temps: 2019-01-14 16: 18: 01.860966
-----
--------------
expéditeur:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e
674abe7abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8ad
d126b6e1a1308fb98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa93977
04de625d1836d3f42c7ee5683f6703259592cc24b09699376807f28fe0e00ff882974484
d805f874260dfc2d1627473b910203010001
-----
bénéficiaire:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876
f41338c62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cc
e25be99452a81df4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47
452590137869c25d9ff83d68ebe6d616056a8425b52e69715b8b85ae807b84638d8f0
0e321b65e4c33acaf6469e18e30203010001
-----
valeur: 2.0
-----
temps: 2019-01-14 16: 18: 01.861958
-----
--------------

Par souci de brièveté, je n'ai imprimé que les premières transactions dans la liste. Dans le code ci-dessus, nous imprimons toutes les transactions commençant par la toute première transaction, à l'exception de la transaction Genesis qui n'a jamais été ajoutée à cette liste. Comme les transactions sont ajoutées aux blocs périodiquement, vous ne voudrez généralement afficher que la liste des transactions qui doivent encore être extraites. Dans ce cas, vous devrez créer un fichier approprié. pour boucle pour parcourir les transactions qui ne sont pas encore minées.

Jusqu'à présent, vous avez appris à créer des clients, à les autoriser à se mettre entre eux et à maintenir une file d'attente des transactions en attente à exploiter. Maintenant, vient la partie la plus importante de ce tutoriel et crée une blockchain elle-même. Vous apprendrez cela dans la prochaine leçon.

Un bloc consiste en un nombre variable de transactions. Pour des raisons de simplicité, dans notre cas, nous supposerons que le bloc consiste en un nombre fixe de transactions, qui est trois dans ce cas. Comme le bloc doit stocker la liste de ces trois transactions, nous allons déclarer une variable d'instance appelée vérifié_transactions comme suit –




self.verified_transactions = []

Nous avons nommé cette variable vérifié_transactions pour indiquer que seules les transactions valides vérifiées seront ajoutées au bloc. Chaque bloc contient également la valeur de hachage du bloc précédent, de sorte que la chaîne de blocs devient immuable.

Pour stocker le hachage précédent, nous déclarons une variable d'instance comme suit –




self.previous_block_hash = ""

Enfin, nous déclarons une autre variable appelée Nonce pour stocker le nonce créé par le mineur pendant le processus d'extraction.




self.Nonce = ""

La définition complète de la Bloquer la classe est donnée ci-dessous –




bloc de classe:
   def __init __ (auto):
      self.verified_transactions = []
      self.previous_block_hash = ""
      self.Nonce = ""

Chaque bloc ayant besoin de la valeur du hachage du bloc précédent, nous déclarons une variable globale appelée last_block_hash comme suit –




last_block_hash = ""

Créons maintenant notre premier bloc dans la blockchain.

Nous supposons que l'initiateur des TPCoins a initialement attribué 500 TPCoins à un client connu Dinesh. Pour cela, il crée d'abord une instance de Dinesh –




Dinesh = Client ()

Nous créons ensuite une transaction de genèse et envoyons 500 TPCoins à l’adresse publique de Dinesh.




t0 = transaction (
   "Genèse",
   Dinesh.identity,
   500.0
)

Maintenant, nous créons une instance de Bloquer classe et l'appelle bloc0.




block0 = Block ()

Nous initialisons le previous_block_hash et Nonce variables d'instance à Aucun, car c’est la toute première transaction à être stockée dans notre blockchain.




block0.previous_block_hash = None
Nonce = Aucun

Ensuite, nous allons ajouter la transaction t0 ci-dessus à la vérifié_transactions liste maintenue dans le bloc –




block0.verified_transactions.append (t0)

À ce stade, le bloc est complètement initialisé et est prêt à être ajouté à notre blockchain. Nous allons créer la blockchain à cet effet. Avant d’ajouter le bloc à la blockchain, nous allons hacher le bloc et stocker sa valeur dans la variable globale appelée last_block_hash que nous avons déclaré précédemment. Cette valeur sera utilisée par le prochain mineur de son bloc.

Nous utilisons les deux lignes de code suivantes pour hacher le bloc et stocker la valeur de résumé.




digérer = hash (block0)
last_block_hash = digérer

Enfin, nous créons une blockchain, comme nous le verrons dans le chapitre suivant.

Une blockchain contient une liste de blocs chaînés les uns aux autres. Pour stocker la liste complète, nous allons créer une variable de liste appelée TPCoins –




TPCoins = []

Nous allons également écrire une méthode utilitaire appelée dump_blockchain pour vider le contenu de la blockchain entière. Nous imprimons d'abord la longueur de la blockchain afin de savoir combien de blocs sont actuellement présents dans la blockchain.




def dump_blockchain (auto):
   print ("Nombre de blocs dans la chaîne:" + str (len (self)))

Notez qu'au fil du temps, le nombre de blocs dans la blockchain serait extraordinairement élevé pour l'impression. Ainsi, lorsque vous imprimez le contenu de la blockchain, vous devrez peut-être choisir la plage que vous souhaitez examiner. Dans le code ci-dessous, nous avons imprimé la blockchain complète car nous n’ajouterions pas trop de blocs dans la démo actuelle.

Pour parcourir la chaîne, nous avons créé un pour boucle comme suit –




pour x dans la plage (len (TPCoins)):
   block_temp = TPCoins[x] 

Chaque bloc référencé est copié dans une variable temporaire appelée block_temp.

Nous imprimons le numéro de bloc comme en-tête pour chaque bloc. Notez que les nombres commenceraient par zéro, le premier bloc est un bloc de genèse numéroté zéro.




print ("block #" + str (x))

Dans chaque bloc, nous avons stocké une liste de trois transactions (à l’exception du bloc de genèse) dans une variable appelée vérifié_transactions. Nous itérons cette liste dans un pour boucle et pour chaque élément récupéré, nous appelons display_transaction fonction pour afficher les détails de la transaction.




pour la transaction dans block_temp.verified_transactions:
   display_transaction (transaction)

La définition complète de la fonction est indiquée ci-dessous –




def dump_blockchain (auto):
   print ("Nombre de blocs dans la chaîne:" + str (len (self)))
   pour x dans la plage (len (TPCoins)):
      block_temp = TPCoins[x]
      print ("block #" + str (x))
      pour la transaction dans block_temp.verified_transactions:
         display_transaction (transaction)
         impression ('--------------')
      print ('====================================)

Notez que nous avons inséré ici les séparateurs aux endroits appropriés du code pour délimiter les blocs et les transactions qu’il contient.

Comme nous avons maintenant créé une blockchain pour stocker des blocs, notre tâche suivante est de créer des blocs et de commencer à l'ajouter à la blockchain. A cette fin, nous allons ajouter un bloc de genèse que vous avez déjà créé à l'étape précédente.

L’ajout d’un bloc à la blockchain implique l’ajout du bloc créé à notre TPCoins liste.




TPCoins.append (block0)

Notez que, contrairement au reste des blocs du système, le bloc de genèse contient une seule transaction qui est initiée par l'auteur du système TPCoins. Maintenant, vous allez vider le contenu de la blockchain en appelant notre fonction globale dump_blockchain




dump_blockchain (TPCoins)

Lorsque vous exécutez cette fonction, vous verrez la sortie suivante –




Nombre de blocs dans la chaîne: 1
bloc # 0
expéditeur: Genesis
-----
bénéficiaire:
30819f300d06092a864886f70d010101050003818d0030818902818100ed272b52ccb539
e2cd779c6cc10ed1dfadf5d97c6ab6de90ed0372b2655626fb79f62d0e01081c163b0864
cc68d426bbe9438e8566303bb77414d4bfcaa3468ab7febac099294de10273a816f7047d
4087b4bafa11f141544d48e2f10b842cab91faf33153900c7bf6c08c47e7a7df8aa7e60d
c9e0798fb2ba3484bbdad2e4430203010001
-----
valeur: 500.0
-----
temps: 2019-01-14 16: 18: 02.042739
-----
--------------
=====================================

À ce stade, le système de blockchain est prêt à être utilisé. Nous allons maintenant permettre aux clients intéressés de devenir des mineurs en leur fournissant une fonctionnalité d'exploration de données.

Pour permettre l’exploitation minière, nous devons développer une fonction minière. La fonctionnalité d'exploration de données doit générer un résumé sur une chaîne de message donnée et fournir une preuve de travail. Laissez-nous en discuter dans ce chapitre.

Fonction de résumé de message

Nous allons écrire une fonction utilitaire appelée sha256 pour créer un condensé sur un message donné –




def sha256 (message):
renvoie hashlib.sha256 (message.encode ('ascii')). hexdigest ()

le sha256 la fonction prend message en tant que paramètre, il le code en ASCII, génère un condensé hexadécimal et renvoie la valeur à l'appelant.

Fonction minière

Nous développons maintenant le mien fonction qui met en œuvre notre propre stratégie minière. Notre stratégie dans ce cas serait de générer un hachage sur le message donné, préfixé par un nombre donné de 1. Le nombre donné de 1 est spécifié en tant que paramètre pour mien fonction spécifiée comme niveau de difficulté.

Par exemple, si vous spécifiez un niveau de difficulté de 2, le hachage généré sur un message donné doit commencer par deux 1, comme 11xxxxxxxx. Si le niveau de difficulté est 3, le hachage généré doit commencer par trois 1 – comme 111xxxxxxxx. Compte tenu de ces exigences, nous allons maintenant développer la fonction d’extraction selon les étapes décrites ci-dessous.

Étape 1

La fonction d'exploration prend deux paramètres: le message et le niveau de difficulté.




def mine (message, difficulté = 1):

Étape 2

Le niveau de difficulté doit être supérieur ou égal à 1, nous l’assurons avec l’affirmation suivante:




affirmer difficulté> = 1

Étape 3

Nous créons un préfixe variable en utilisant le niveau de difficulté défini.




préfixe = '1' * difficulté

Notez que si le niveau de difficulté est 2, le préfixe sera «11» et si le niveau de difficulté est 3, le préfixe sera «111», et ainsi de suite. Nous vérifierons si ce préfixe existe dans le résumé généré du message. Pour digérer le message lui-même, nous utilisons les deux lignes de code suivantes:




pour i dans la gamme (1000):
   digérer = sha256 (str (hash (message)) + str (i))

Nous continuons à ajouter un nouveau numéro je au hachage du message à chaque itération et générer un nouveau résumé sur le message combiné. En tant que contribution à la sha256 changements de fonction à chaque itération, la digérer la valeur changerait aussi. Nous vérifions si cela digérer la valeur a dépassé préfixe.




si digest.startswith (préfixe):

Si la condition est remplie, nous mettrons fin à la pour boucle et retourne le digérer valeur à l'appelant.

L'ensemble mien le code est montré ici –




def mine (message, difficulté = 1):
   affirmer difficulté> = 1
   préfixe = '1' * difficulté
   pour i dans la gamme (1000):
      digérer = sha256 (str (hash (message)) + str (i))
      si digest.startswith (préfixe):
         print ("après" + str (i) + "itérations trouvées nonce:" + digest)
      retourner digérer

Pour votre compréhension, nous avons ajouté le impression instruction qui imprime la valeur de résumé et le nombre d'itérations nécessaires pour remplir la condition avant de revenir de la fonction.

Test de la fonction d'exploration

Pour tester notre fonction d'exploration, exécutez simplement l'instruction suivante –




mine ("message de test", 2)

Lorsque vous exécutez le code ci-dessus, vous verrez une sortie similaire à celle ci-dessous –




après 138 itérations trouvées nonce:
11008a740eb2fa6bf8d55baecda42a41993ca65ce66b2d3889477e6bfad1484c

Notez que le résumé généré commence par «11». Si vous modifiez le niveau de difficulté à 3, le résumé généré commencera par «111» et, bien entendu, il nécessitera probablement plus d'itérations. Comme vous pouvez le constater, un mineur disposant de plus de puissance de traitement sera en mesure de traiter un message plus tôt. C’est ainsi que les mineurs se font concurrence pour gagner leurs revenus.

Nous sommes maintenant prêts à ajouter plus de blocs à notre blockchain. Laissez-nous apprendre cela dans notre prochain chapitre.

Chaque mineur récupérera les transactions dans un pool de transactions créé précédemment. Pour suivre le nombre de messages déjà exploités, nous devons créer une variable globale –




last_transaction_index = 0

Nous allons maintenant demander à notre premier mineur d'ajouter un bloc à la blockchain.

Ajout du premier bloc

Pour ajouter un nouveau bloc, nous créons d’abord une instance du Bloquer classe.




block = Block ()

Nous récupérons les 3 principales transactions de la file d'attente –




pour i dans la gamme (3):
   temp_transaction = transactions[last_transaction_index]
   # valider la transaction

Avant d’ajouter la transaction au bloc, le mineur vérifiera la validité de la transaction. La validité de la transaction est vérifiée en testant l’égalité du hachage fourni par l’expéditeur par rapport au hachage généré par le mineur à l’aide de la clé publique de l’expéditeur. En outre, le mineur vérifiera que l'expéditeur dispose d'un solde suffisant pour payer la transaction en cours.

Par souci de brièveté, nous n’avons pas inclus cette fonctionnalité dans le didacticiel. Une fois la transaction validée, nous l’ajoutons au vérifié_transactions liste dans le bloquer exemple.




block.verified_transactions.append (temp_transaction)

Nous incrémentons le dernier indice de transaction afin que le prochain mineur récupère les transactions suivantes dans la file d'attente.




last_transaction_index + = 1

Nous ajoutons exactement trois transactions au bloc. Ceci fait, nous initialiserons le reste des variables d’instance du Bloquer classe. Nous ajoutons d'abord le hash du dernier bloc.




block.previous_block_hash = last_block_hash

Ensuite, nous exploitons le bloc avec un niveau de difficulté de 2.




block.Nonce = mine (block, 2)

Notez que le premier paramètre de la mien fonction est un objet binaire. Nous hachons maintenant le bloc entier et créons un résumé sur celui-ci.




digérer = hachage (bloc)

Enfin, nous ajoutons le bloc créé à la blockchain et réinitialisons la variable globale. last_block_hash pour l'utilisation dans le bloc suivant.

Le code complet pour l'ajout du bloc est présenté ci-dessous –




block = Block ()
pour i dans la gamme (3):
   temp_transaction = transactions[last_transaction_index]
   # valider la transaction
   # si valide
   block.verified_transactions.append (temp_transaction)
   last_transaction_index + = 1

block.previous_block_hash = last_block_hash
block.Nonce = mine (block, 2)
digérer = hachage (bloc)
TPCoins.append (bloc)
last_block_hash = digérer

Ajouter plus de blocs

Nous allons maintenant ajouter deux autres blocs à notre blockchain. Le code pour ajouter les deux blocs suivants est donné ci-dessous –




# Miner 2 ajoute un bloc
block = Block ()

pour i dans la gamme (3):
   temp_transaction = transactions[last_transaction_index]
   # valider la transaction
   # si valide
   block.verified_transactions.append (temp_transaction)
   last_transaction_index + = 1
block.previous_block_hash = last_block_hash
block.Nonce = mine (bloc, 2) digérer = hash (bloc)
TPCoins.append (block) last_block_hash = digérer
# Miner 3 ajoute un bloc
block = Block ()

pour i dans la gamme (3):
   temp_transaction = transactions[last_transaction_index]
   #display_transaction (temp_transaction)
   # valider la transaction
   # si valide
   block.verified_transactions.append (temp_transaction)
   last_transaction_index + = 1

block.previous_block_hash = last_block_hash
block.Nonce = mine (block, 2)
digérer = hachage (bloc)

TPCoins.append (bloc)
last_block_hash = digérer

Lorsque vous ajoutez ces deux blocs, vous verrez également le nombre d'itérations qu'il a fallu pour trouver le Nonce. À ce stade, notre blockchain est composée de 4 blocs au total, dont le bloc de genèse.

Dumping de toute la blockchain

Vous pouvez vérifier le contenu de la blockchain entière à l’aide de l’instruction suivante –




dump_blockchain (TPCoins)

Vous verriez une sortie similaire à celle montrée ci-dessous –




Nombre de blocs dans la chaîne: 4
bloc # 0
expéditeur: Genesis
-----
bénéficiaire:
30819f300d06092a864886f70d010101050003818d0030818902818100ed272b52ccb539e2cd779
c6cc10ed1dfadf5d97c6ab6de90ed0372b2655626fb79f62d0e01081c163b0864cc68d426bbe943
8e8566303bb77414d4bfcaa3468ab7febac099294de10273a816f7047d4087b4bafa11f141544d4
8e2f10b842cab91faf33153900c7bf6c08c9e47a7df8aa7e60dc9e0798fb2ba3484bbdad2e44302
03010001
-----
value: 500.0
-----
time: 2019-01-14 16:18:02.042739
-----
--------------
=====================================
block # 1
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001
-----
value: 15.0
-----
time: 2019-01-14 16:18:01.859915
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
value: 6.0
-----
time: 2019-01-14 16:18:01.860966
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876f41338c
62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cce25be99452a81d
f4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47452590137869c25d9ff83
d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f00e321b65e4c33acaf6469e18e302
03010001
-----
value: 2.0
-----
time: 2019-01-14 16:18:01.861958
-----
--------------
=====================================
block # 2
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001
-----
value: 4.0
-----
time: 2019-01-14 16:18:01.862946
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876f41338c
62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cce25be99452a81d
f4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47452590137869c25d9ff83
d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f00e321b65e4c33acaf6469e18e302
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
value: 7.0
-----
time: 2019-01-14 16:18:01.863932
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
value: 3.0
-----
time: 2019-01-14 16:18:01.865099
-----
--------------
=====================================
block # 3
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001
-----
value: 8.0
-----
time: 2019-01-14 16:18:01.866219
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100a070c82b34ae143cbe59b
3a2afde7186e9d5bc274955d8112d87a00256a35369acc4d0edfe65e8f9dc93fbd9ee74b9e7ea12
334da38c8c9900e6ced1c4ce93f86e06611e656521a1eab561892b7db0961b4f212d1fd5b5e49ae
09cf8c603a068f9b723aa8a651032ff6f24e5de00387e4d062375799742a359b8f22c5362e56502
03010001
-----
recipient:
30819f300d06092a864886f70d010101050003818d0030818902818100be93b516b28c6e674abe7
abdb11ce0fdf5bb728b75216b73f37a6432e4b402b3ad8139b8c0ba541a72c8add126b6e1a1308f
b98b727beb63c6060356bb177bb7d54b54dbe87aee7353d0a6baa9397704de625d1836d3f42c7ee
5683f6703259592cc24b09699376807f28fe0e00ff882974484d805f874260dfc2d1627473b9102
03010001
-----
value: 1.0
-----
time: 2019-01-14 16:18:01.867223
-----
--------------
sender:
30819f300d06092a864886f70d010101050003818d0030818902818100cba097c0854876f41338c
62598c658f545182cfa4acebce147aedf328181f9c4930f14498fd03c0af6b0cce25be99452a81d
f4fa30a53eddbb7bb7b203adf8764a0ccd9db6913a576d68d642d8fd47452590137869c25d9ff83
d68ebe6d616056a8425b85b52e69715b8b85ae807b84638d8f00e321b65e4c33acaf6469e18e302
03010001
-----
recipient: 
30819f300d06092a864886f70d010101050003818d0030818902818100bb064c99c492144a9f463
480273aba93ac1db1f0da3cb9f3c1f9d058cf499fd8e54d244da0a8dd6ddd329ec86794b04d773e
b4841c9f935ea4d9ccc2821c7a1082d23b6c928d59863407f52fa05d8b47e5157f8fe56c2ce3279
c657f9c6a80500073b0be8093f748aef667c03e64f04f84d311c4d866c12d79d3fc3034563dfb02
03010001
-----
value: 5.0
-----
time: 2019-01-14 16:18:01.868241
-----
--------------
=====================================

In this tutorial, we have learnt how to construct a blockchain project in Python. There are many areas where you need to add further functionality to this project.

For instance, you will need to write functions for managing the transactions queue. After the transactions are mined and the mined block is accepted by the system, they need not be stored any more.

Also, the miners would certainly prefer to pick up the transactions with the highest fee. At the same time, you will have to ensure that the transactions with low or no fee would not starve forever.

You will need to develop algorithms for managing the queue. Also, the current tutorial does not include the client interface code. You will need to develop this for both normal clients and the miners. The full-fledged blockchain project would run into several more lines of code and is beyond the scope of this tutorial. The interested reader may download the bitcoin source for further study.

Conclusions

This crisp tutorial should get you started on creating your own blockchain project.

For full-fledged blockchain project development, you can learn more from the bitcoin source.

For larger commercial or non-commercial projects, you may consider using Ethereum − a ready to use blockchain app platform.



Traduit depuis https://www.tutorialspoint.com/python_blockchain/python_blockchain_quick_guide.htm

Carte de paiement Crypto

Demandez votre Carte de paiement Crypto ici

Recevez 8 € de BTC gratuitement


Inscrivez-vous à CoinBase