# B4 — La preuve de travail

## Avant de commencer

Ce carnet facultatif explore le hachage et la preuve de travail, hors du socle actuel. Il ne constitue pas un devoir supplémentaire. Si je le retiens comme bonus pour un cycle, je préciserai en cours les exercices attendus, le dossier de dépôt et l’échéance. Les anciennes dates de remise ne s’appliquent plus.

## Le sujet

Votre mini-blockchain sait hacher un bloc. Nous allons maintenant chercher un nonce qui donne un hachage commençant par plusieurs chiffres hexadécimaux nuls.

Écrivez `Work.digest(payload, nonce)` : SHA-256 du binaire `payload <> ":" <> Integer.to_string(nonce)`, en hexadécimal minuscule. Puis `Work.mine(payload, difficulty, max_nonce)` : recherchez de 0 à `max_nonce` **inclus**, dans l'ordre, et renvoyez `{:ok, nonce, hash}` pour le premier résultat commençant par `difficulty` zéros, ou `:not_found`. Limitez la difficulté à `0..4` et le nonce maximal à un entier positif ou nul ; refusez les autres arguments avec `ArgumentError`.

Commencez par une difficulté de 1 ou 2. Mesurez ensuite le nombre d'essais plutôt que d'affirmer que chaque zéro multiplie exactement le temps par 16 : les essais restent aléatoires. Ce mécanisme pédagogique ne sécurise pas à lui seul une blockchain.

## À vous

```elixir
defmodule Work do
  def digest(payload, nonce), do: nil
  def mine(payload, difficulty, max_nonce), do: nil
end
```

## Vérifications

```elixir
payload = "bloc AP"
expected = :crypto.hash(:sha256, "bloc AP:0") |> Base.encode16(case: :lower)
true = Work.digest(payload, 0) == expected
{:ok, 0, ^expected} = Work.mine(payload, 0, 0)
{:ok, nonce, hash} = Work.mine(payload, 1, 1000)
true = String.starts_with?(hash, "0")
true = Work.digest(payload, nonce) == hash
true = Enum.all?(Enum.take(0..nonce, nonce), fn n -> not String.starts_with?(Work.digest(payload, n), "0") end)
{:ok, ^nonce, ^hash} = Work.mine(payload, 1, nonce)
if nonce > 0, do: :not_found = Work.mine(payload, 1, nonce - 1)
IO.puts("Premier nonce valide : #{nonce}")
```

## Votre explication

Ajoutez une cellule Markdown pour expliquer votre démarche, les cas limites vérifiés et ce que vous avez observé. Pour toute question : aurelien.noce@minesparis.psl.eu, avec aurelien.noce@imagine-app.fr en copie.
