Document, blockchain et transaction

Oui, il est tout à fait possible de créer votre propre blockchain, comme Ethereum. Cependant, il est important de distinguer deux approches :


🛠️ 1. Créer un fork (copie modifiée) d’Ethereum

C’est la méthode la plus rapide pour créer un réseau similaire à Ethereum.


🔨 2. Créer une blockchain from scratch

Créer une blockchain complètement originale, avec vos propres règles, protocoles, consensus.


🧰 Alternatives hybrides


✅ En résumé

Option Facilité Flexibilité Communauté Idéal pour
Fork d’Ethereum ✅ Facile ⚠️ Moyenne ✅ Large Token, dApp
From scratch ❌ Difficile ✅ Totale ❌ À construire Innovation, recherche
Cosmos SDK / Substrate ⚠️ Moyen ✅ Haute ⚠️ Moyenne Interopérabilité, modularité

Parfait ! Si vous souhaitez signer un document PDF avec une blockchain en C# (Visual Studio), voici une approche étape par étape pour le faire en utilisant une blockchain (par exemple Ethereum ou votre propre fork/localchain).


🎯 Objectif

Signer un PDF avec la blockchain, c’est généralement :

  1. Générer un hash du PDF (empreinte unique).

  2. Enregistrer ce hash sur la blockchain (par une transaction).

  3. Utiliser ce hash plus tard pour vérifier l’intégrité du document.


🛠️ Prérequis

📦 Côté Visual Studio / C#

🔗 Côté Blockchain


🧑‍💻 Étapes techniques

1. Hasher le PDF en C#

using System.Security.Cryptography;
using System.Text;

public string ComputeFileHash(string filePath)
{
    using (var sha256 = SHA256.Create())
    using (var stream = File.OpenRead(filePath))
    {
        var hash = sha256.ComputeHash(stream);
        return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
    }
}

2. Envoyer le hash à la blockchain (avec Nethereum)

a) Installer Nethereum

Install-Package Nethereum.Web3

b) Code pour envoyer le hash

using Nethereum.Web3;
using Nethereum.Hex.HexTypes;
using System.Numerics;

public async Task SendHashToBlockchain(string hash)
{
    string rpcUrl = "https://sepolia.infura.io/v3/YOUR_INFURA_KEY";
    string privateKey = "YOUR_PRIVATE_KEY";
    string address = "YOUR_WALLET_ADDRESS";

    var web3 = new Web3(new Nethereum.Web3.Accounts.Account(privateKey), rpcUrl);

    var tx = await web3.Eth.Transactions
        .SendTransaction.SendRequestAsync(new Nethereum.RPC.Eth.DTOs.TransactionInput
        {
            From = address,
            To = address, // Optionnellement vers un contrat
            Data = "0x" + System.Text.Encoding.UTF8.GetBytes(hash).ToHex(),
            Gas = new HexBigInteger(21000),
            Value = new HexBigInteger(0)
        });

    Console.WriteLine("Transaction sent: " + tx);
}

3. Vérification de la signature plus tard


✅ Résultat

Avec ce système :



Projet Visual Studio 2022 complet en C# qui :

✅ Hash un fichier PDF
✅ Envoie ce hash sur la blockchain Ethereum via Infura
✅ Permet de vérifier si un hash a déjà été envoyé


📁 Structure du projet

  • Type : Console App (.NET 6 ou supérieur)

  • Nom : PdfBlockchainSigner

  • Fonctionnalités :

    • Lire un PDF

    • Calculer le hash SHA-256

    • Envoyer ce hash à Ethereum via Nethereum

    • Vérifier si un hash est déjà dans l’historique


📦 Étape 1 : Créer le projet

Dans Visual Studio :

  • Crée un nouveau projet Console App (.NET 6)

  • Nom : PdfBlockchainSigner


🧱 Étape 2 : Installer les packages NuGet

Dans le Package Manager Console :

Install-Package Nethereum.Web3
Install-Package Nethereum.Accounts

🧑‍💻 Étape 3 : Code complet

Voici le fichier Program.cs :

using System;
using System.IO;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Nethereum.Web3;
using Nethereum.Web3.Accounts;
using Nethereum.Hex.HexConvertors.Extensions;
using Nethereum.Hex.HexTypes;

namespace PdfBlockchainSigner
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine("Chemin vers le fichier PDF à signer :");
            string pdfPath = Console.ReadLine();

            if (!File.Exists(pdfPath))
            {
                Console.WriteLine("Fichier introuvable.");
                return;
            }

            string hash = ComputeFileHash(pdfPath);
            Console.WriteLine($"Hash SHA-256 : {hash}");

            // Blockchain config
            string infuraUrl = "https://sepolia.infura.io/v3/YOUR_INFURA_PROJECT_ID";
            string privateKey = "YOUR_PRIVATE_KEY";
            string senderAddress = "YOUR_WALLET_ADDRESS";

            var account = new Account(privateKey);
            var web3 = new Web3(account, infuraUrl);

            var dataHex = "0x" + System.Text.Encoding.UTF8.GetBytes(hash).ToHex();
            var gas = new HexBigInteger(21000); // Si envoi à soi-même sans contrat
            var tx = await web3.Eth.Transactions.SendTransaction.SendRequestAsync(
                new Nethereum.RPC.Eth.DTOs.TransactionInput
                {
                    From = senderAddress,
                    To = senderAddress, // ou un smart contract pour une vraie signature
                    Data = dataHex,
                    Gas = gas,
                    Value = new HexBigInteger(0)
                });

            Console.WriteLine("Hash envoyé dans la transaction : " + tx);
        }

        static string ComputeFileHash(string filePath)
        {
            using (var sha256 = SHA256.Create())
            using (var stream = File.OpenRead(filePath))
            {
                var hash = sha256.ComputeHash(stream);
                return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
            }
        }
    }
}

📝 Configuration nécessaire

✅ Crée un compte Infura

✅ Crée un compte Metamask

  • Récupère ta private key (à sécuriser dans ton app)

  • Envoie un peu d'ETH de test sur Sepolia (depuis un faucet)


🧪 Test

  1. Lance l'application

  2. Indique le chemin vers un fichier .pdf

  3. Le hash est envoyé dans une transaction Ethereum visible sur https://sepolia.etherscan.io


🔐 Sécurité (à ne pas négliger)

  • Ne jamais hardcoder les clés privées en production

  • Utiliser des vaults ou gestionnaires de secrets

  • Stocker les hash et TXID dans une base si besoin


📦 Bonus : Smart Contract ?

Souhaitez-vous aussi stocker les hash dans un smart contract personnalisé, pour retrouver tous les documents signés ?

Parfait ! Voici la suite du projet, avec un smart contract Solidity simple pour stocker les hash de documents PDF, et l’interfacer depuis votre application C#.


🧠 Objectif du smart contract

Créer un contrat qui :

  • Enregistre un hash de document

  • Permet de vérifier si un hash a déjà été enregistré

  • Permet de lister les adresses qui ont soumis des hash


🧾 Smart Contract Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract DocumentRegistry {
    mapping(bytes32 => bool) public registeredDocuments;
    mapping(bytes32 => address) public documentOwners;

    event DocumentRegistered(bytes32 indexed hash, address indexed owner);

    function registerDocument(bytes32 hash) public {
        require(!registeredDocuments[hash], "Document already registered.");
        registeredDocuments[hash] = true;
        documentOwners[hash] = msg.sender;
        emit DocumentRegistered(hash, msg.sender);
    }

    function isRegistered(bytes32 hash) public view returns (bool) {
        return registeredDocuments[hash];
    }

    function getOwner(bytes32 hash) public view returns (address) {
        return documentOwners[hash];
    }
}

🚀 Déployer le smart contract

Option 1 : Utilisez Remix IDE

  • Collez le code

  • Compilez avec Solidity 0.8.x

  • Déployez sur Sepolia via Metamask

📌 Notez l’adresse du contrat déployé + l’ABI JSON (utile en C#)


🔌 Intégrer dans Visual Studio C# avec Nethereum

Étapes :

  1. Ajouter l'ABI JSON du contrat

  2. Appeler registerDocument avec le hash SHA-256 (en format bytes32)

  3. Vérifier l'existence avec isRegistered


📦 Exemple C# : Enregistrer le hash dans le contrat

using Nethereum.Web3;
using Nethereum.Web3.Accounts;
using Nethereum.Contracts;
using System.Numerics;

public static async Task RegisterHashToContract(string hashHex)
{
    string contractAddress = "YOUR_CONTRACT_ADDRESS";
    string infuraUrl = "https://sepolia.infura.io/v3/YOUR_INFURA_KEY";
    string privateKey = "YOUR_PRIVATE_KEY";

    var account = new Account(privateKey);
    var web3 = new Web3(account, infuraUrl);

    // Format hash en bytes32
    var hashBytes32 = "0x" + hashHex;

    var abi = @"[
        {""inputs"":[{""internalType"":""bytes32"",""name"":""hash"",""type"":""bytes32""}],
         ""name"":""registerDocument"",""outputs"":[],""stateMutability"":""nonpayable"",""type"":""function""},
        {""inputs"":[{""internalType"":""bytes32"",""name"":""hash"",""type"":""bytes32""}],
         ""name"":""isRegistered"",""outputs"":[{""internalType"":""bool"",""name"":"""",""type"":""bool""}],
         ""stateMutability"":""view"",""type"":""function""}
    ]";

    var contract = web3.Eth.GetContract(abi, contractAddress);
    var registerFunction = contract.GetFunction("registerDocument");

    var txReceipt = await registerFunction.SendTransactionAndWaitForReceiptAsync(account.Address, new HexBigInteger(300000), null, null, hashBytes32);
    Console.WriteLine("Transaction hash : " + txReceipt.TransactionHash);
}

🧪 Vérifier si un document est déjà signé

var isRegisteredFunc = contract.GetFunction("isRegistered");
bool isRegistered = await isRegisteredFunc.CallAsync<bool>(hashBytes32);
Console.WriteLine(isRegistered ? "Document déjà signé." : "Document non signé.");

✅ Résultat

Vous avez maintenant :

  • ✅ Une app C# qui lit un PDF et génère son hash

  • ✅ Un smart contract qui stocke et vérifie les documents

  • ✅ Une liaison complète entre Visual Studio 2022 et la blockchain Ethereum