Réaliser une transaction avec NBitcoin C# .NET

Introduction

  • Par soucis de « vulgarisation » et d’accessibilité au plus grand nombre, certains concepts clés évoqués dans cet article ont été « simplifiés » ou « raccourcis ». Il conviendra à chacun d’étoffer sa recherche à l’aide des liens fournis dans la rubrique « Ressources ».
  • Généralement, les présentations autour de Bitcoin commencent par une approche théorique des mécanismes permettant de sécuriser le réseau.
  • Dans cette présentation nous allons faire abstraction de tout cela → ?.
  • Nous allons  considérer la blockchain Bitcoin comme un service de stockage décentralisé que l’on va exploiter en mode Blockchain As a Service.
  • Nous consommerons ce service à l’aide de la librairie NBitcoin.net et de l’api QBitNinja.
  • Nous auront une approche pratique, qui consistera à programmer et signer un transfert Bitcoin entre deux adresses que nous allons créer.
  • La notion de « transfert » et de « vérification de propriété » est fondamentale pour le réseau Bitcoin puisqu’il à été spécialement conçu pour cela !
  • Tout en construisant notre transfert, nous découvrirons notamment à quoi servent une adresse, une clé privé, une clé publique et une transaction …

Généralités sur Bitcoin

  • Un système de transfert et de vérification de propriété,
  • Repose sur un réseau pair à pair,
  • Pas d’autorité centrale,
  • L’application initiale et l’innovation principale de ce réseau est un système de monnaie numérique décentralisé,
  • L’unité de compte au sein du réseau Bitcoin est nommée « Bitcoin »,
  • Bitcoin fonctionne avec des logiciels et un protocole,
  • Permet à ses participant d’émettre et de gérer des transactions de façon collective et automatique,
  • Un protocole libre et ouvert dont le code source est publié sous licence MIT,
  • Bitcoin est conçu pour s’auto-réguler,
  • Son bon fonctionnement est garanti par une organisation générale que tout le monde peut examiner,
  • Tout y est public : protocoles de base, algorithmes cryptographiques, programmes opérationnels, données de comptes, débats des développeurs …

Bitcoin Transfert : Problématique

  • Des fonds initiaux ont été envoyés à Bob,
  • Bob à réalisé un transfert de Bitcoin à Alice en lui laissant un message,
  • Nous allons recréer la transaction entre Bob et Alice à l’aide de NBitcoin,

Configuration du projet (.netCore + VSCode)

Auteur de NBitcoin et QBitNinja.Client : Nicolas Dorier, METACO SA

$ mkdir btcMeetup

$ cd btcMeetup

$ dotnet new console

$ dotnet add package NBitcoin

$ dotnet add package QBitNinja.Client

$ dotnet restore

Eléments fondamentaux

Pour réaliser un transfert sur le protocole Bitcoin, on s’appuie sur 5 éléments fondamentaux :

Private Key :

  • Permet de signer une transaction,
  • Donne le droit de dépenser les fonds liés à une adresse,
  • Ne doit pas être partagé, doit être conservé en lieu sûr.

Public Key :

  • Permet de s’assurer que vous êtes le propriétaire d’une adresse pouvant recevoir des fonds,
  • Est générée à partir de la clé privée (l’inverse étant « impossible ») Permet de s’assurer que vous êtes le propriétaire d’une adresse pouvant recevoir des fonds,
  • La clé public permet de générer une adresse bitcoin et un scriptPubKey.

ScriptPubKey :

  • C’est un peu l’équivalent d’une BitcoinAddress mais au niveau du protocole.
  • Vous n’envoyez donc pas des fonds à une adresse mais à un ScriptPubKey.
  • N’est pas facilement partageable contrairement à une adresse.

Bitcoin Address :

  • Pour recevoir un transfert de fonds,
  • Information facilement encodable en QR Code, 
  • Peut être communiquée à tout le monde.

Transaction :

  • Structure de données permettant d’encoder un transfert de valeur entre un ou plusieurs participants au réseau Bitcoin.

Générer une adresse pour Bob et une adresse pour Alice

Une adresse Bitcoin est une information que vous allez partager avec les autres utilisateurs du réseau pour recevoir des fonds.

Mais pour obtenir une adresse vous devez d’abord générer une clé privée !

  • Elle est le seul moyen de dépenser les bitcoins envoyés à votre adresse.
  • Les clés privées sont personnelles et ne sont pas stockées sur le réseau.
  • Elles peuvent être générées sans être connectées à internet.

NBitcoin supporte plusieurs standards pour générer des clés privées …

Nous allons utiliser les standards BIP32 et BIP39 qui permettent de générer une clé racine à partir d’une wordlist. C’est sur ce principe que fonctionnent les cold-wallets tel que Ledger Nano ou Trezor. Cette wordlist ou seed ou mnemonic permet de re-générer indéfiniment la même suite de clé.

Ci-après le processus de génération de clés que nous allons suivre :

Etape 1 : Générer une nouvelle mnémonique :

Etape 1 (bis) : Restaurer une mnémonique existante :

Etape 2 : On génère la clé racine  qui dérive de notre « Mnémonique » et d’un mot de passe :

Etape 3 : On peut maintenant générer deux « sous-clés », une pour  Bob, une pour Alice, en dérivant de notre clé racine :

Remarque : Grâce à ce mécanisme de dérivation, il est possible de générer et régénérer des arborescences complexes de clés. On peut par exemple construire une arborescence de clés basées sur l’organigramme d’une entreprise.

Etape 4 : A partir de nos deux clés privées, nous allons pouvoir obtenir leurs clés publiques respectives :

  • On génère une clé publique à partir d’une clé privée au moyen d’une fonction à sens unique.
  • C’est à dire une fonction qui peut aisément être calculée mais difficilement inversée.
  • La clé publique permet de recevoir des fonds et d’attester que vous être le propriétaire d’une adresse.
  • En revanche, elle ne permet pas de dépenser les fonds d’une adresse.

Etape 5 : Après avoir généré les clés publiques d’Alice et Bob, nous allons pouvoir obtenir leurs adresses :

  • Il existe 2 réseaux Bitcoins : MainNet et TestNet,
  • On obtient une adresse Bitcoin à partir de sa clé publique, et en précisant le réseau sur lequel on souhaite opérer.
  • Remarque: sur le MainNet, les erreurs peuvent coûter cher ? !

Etape 6 : Consulter les comptes de Bob et d’Alice :

Adresse de Bob : 16joUFCsaVDfacYsDxCm2oF5mRyLTq6DvY

Adresse d’Alice : 13hA6HP6W4BCwmtr89CKh6fTra19Exm4bL

Si on regarde d’un peu plus près les informations fournies par BlockCypher concernant l’adresse de Bob, on peut remarquer deux choses plutôt curieuses au premier abord :

  • la différence entre le total des inputs et des outputs (0.000355 BTC) → Frais de minage.
  • Bob se renvoie à lui même une partie des fonds impliqués dans la transaction → Tous les fonds impliqués doivent être dépensés.

Etape 7 : Analyser une transaction Bitcoin

Pour envoyer des fonds de Bob vers Alice, il va donc nous falloir construire une transaction et la soumettre au réseau Bitcoin.

Les transactions sont au coeur du système Bitcoin, elles contiennent les informations relatives aux transferts de valeur entre les participants du réseau.

Pour envoyer des fonds à Alice, il va donc falloir faire référence à l’output d’une transaction qui à transféré des fonds initiaux à Bob et que ce dernier n’à pas dépensé …

En consultant la dernière transaction liées à l’adresse de Bob, on retrouve rapidement cette information :

Notre nouvelle transaction va donc « s’accrocher » à l’output non dépensé de celle-ci !

QBitNinja va nous permettre de récupérer ces informations afin de les manipuler dans notre application console.

Etape 8 : Récupérer une transaction stockée sur la blockchain avec le client QBitNinja :

Affichons l’intégralité de la transaction :

Résultat :

Etape 9 : Construire la transaction Bitcoin

Maintenant que l’ont sait quoi dépenser, on peut commencer à construire notre nouvelle transaction :

Et ajouter un nouvel input à cette nouvelle transaction :

Si on visualise notre transaction à ce stade, on obtient :

Voyons maintenant comment dépenser notre input …

On calcule la répartition des fonds entre les différents Outputs de notre future transaction en respectant le fait que :

  • tous les fonds en input de la transaction doivent être dépensés,
  • la différence entre le montant total des inputs et des outputs sera reversé au mineur,
  • des frais de minages trop faibles entrainent un traitement plus long de la transaction (voire elle n’est jamais traitée),

Pour calculer les frais de minages on peut directement chercher sur google :

  • plus vous payez, plus vite est traitée votre transaction,
  • il s’agit d’une moyenne, le prix est fixé en fonction du poids de votre transaction.
  • si vous ajoutez un message, vous devrez augmenter les frais.
  • pour calculer les frais adéquats :

https://bitcoinfees.earn.com/ (coût par byte)

La répartition des fonds entre les différents outputs est prête, on peut les créer et les ajouter à notre transaction :

Etape 10 : Joindre un message à votre transaction

Output contenant le message :

  • On peut donc stocker une information sans forcément transférer de la valeur, du moment que les frais de minage sont couverts !
  • Ce message est inaltérable et incensurable.
  • Vous payez pour écrire ce message, mais sa lecture est « gratuite », par n’importe qui ou n’importe quoi ayant accès au réseau Bitcoin.

Etape 11 : Signer la transaction avec votre clé privée :

Avant de pouvoir diffuser votre transaction, vous devez d’abord la signer à l’aide de votre clé privée :

Etape 12 : Diffuser la transaction sur le réseau Bitcoin :

Il est désormais temps de diffuser notre transaction au réseau !

Pour cela, il faut la transmettre à un noeud du réseau,

Plusieurs options s’offrent à vous :

  • Copier le code Hexadécimal de votre transaction et le pusher via un explorateur de blocks tel que BlockCypher :
  • Passer par l’API QBitNinja :

Etape 13 : Consulter l’état de la transaction diffusée :

Pour consulter l’état de notre transaction diffusée, rendez-vous sur un explorateur de Block tel que BlockCypher :

Transaction ID : a9172485a20e06b9a745f5105cd23cabd9f866e890b0bd4c25c3d29c073cce14

Si on consulte l’adresse d’Alice :

Conclusions et perspectives

L’application première du réseau Bitcoin est l’échange de la cryptomonnaie du même nom.

D’ailleurs sur ce réseau tout se paye en Bitcoins.

Mais il peut également servir à autre chose (et NBitcoin supporte tout cela):

  • stocker des données de façon indélébile et non-censurable,
  • émettre et détruire votre propre « tokens » pour représenter les parts d’une entreprise, des actions ou des votes,
  • attacher un « contrat ricardien » à un token (une sorte de smart contract lisible par l’homme et destiné au monde juridique).

Le protocole est en perpétuelle évolution et vise à devenir de plus en plus efficient (plus rapide, moins coûteux).

Il est également à noter que le coût de transaction n’est pas proportionnel au montant transféré et dépends de la « taille » en bytes de votre transaction. Ainsi, transférer 10$ ou 10M$ aura un coût de transaction équivalent !

Si aujourd’hui la lenteur et les frais de transaction élevés limite l’usage du réseaux, des mises à jour comme le « Lightning Network » ont le potentiel de changer la donne et maintenir Bitcoin sur le devant de la scène.

Ressources :

Programming the Blockchain in C# (Nicolas Dorier, Metaco SA)

NBitcoin (Nicolas Dorier, Metaco SA)

QBitNinja (Nicolas Dorier, Metaco SA)

Stratis Platform (Blockchain As A Service / BaaS, C# Smart-Contracts)

Microsoft Visual Studio Code (IDE)