Appuyez sur ESC pour fermer

EIP-4844 et blobs Ethereum: Guide du stockage de données

Mars 2024 a bouleversé l'économie de la layer-2 une bonne fois pour toutes. Avant Dencun, les rollups comme Arbitrum ou Optimism brûlaient les budgets des équipes pour injecter du calldata sur le mainnet. Les smart contracts d'Ethereum gravaient ce tableau d'octets dans l'état global pour l'éternité, obligeant chaque validateur à le stocker à vie. Cela engloutissait jusqu'à quatre-vingt-dix pour cent des coûts des utilisateurs L2.

L'EIP-4844 a brisé ce schéma en introduisant les transactions de type 3 et les blobs. Mais derrière les chiffres flatteurs d'une réduction des frais par 10 à 50, se cache une foule de subtilités techniques que les marketeurs passent généralement sous silence.

Comment fonctionne un blob au niveau de la mémoire et du consensus

Un blob n'est pas juste un fichier balancé sur la blockchain. C'est un tableau de données isolé de précisément 131 072 octets (128 Ko) qui vit en parallèle de l'exécution de l'EVM. Les smart contracts sur Ethereum ne peuvent pas lire le contenu d'un blob à l'intérieur d'un appel CALL ou STATICCALL. Ils ont uniquement accès à un seul bytecode — l'opcode spécial BLOBHASH — qui renvoie la version et le hash d'engagement.

  • Taille du bloc : l'objectif est fixé à 3 blobs (~384 Ko), avec un pic max à 6 blobs (~768 Ko).
  • Durée de vie : environ 4 096 époques (soit près de 18 jours), après quoi les nœuds de consensus nettoient ces données de leurs disques.
  • Isolation du mempool : les blobs ne tournent pas dans le mempool d'exécution classique. Ils disposent de leur propre pool au niveau des clients de consensus (P2P blob pool), ce qui protège les files d'attente de transactions principales contre l'overload.

Paramètre | Calldata classique | Blob EIP-4844 (Type 3)
Où résident les données : Dans l'état EVM permanent | Dans le pool p2p de consensus temporaire
Temps de stockage : Pour toujours | ~18 jours
Accès depuis l'EVM : Direct (via lecture d'octets) | Indirect (uniquement via hash et KZG)
Tarification : Gas d'exécution partagé | Marché de blob gas indépendant (EIP-1559)

Fonctionnalités cachées et pièges architecturaux du proto-danksharding

Rarement on souligne la manière dont s'articule la tarification du blob gas. Contrairement au gas standard qui s'envole au moindre toussotement dans la DeFi, le marché des blobs est piloté par un algorithme d'ajustement indépendant. Si les rollups saturent les slots au-delà des trois blobs cibles, le prix se met à grimper de façon exponentielle. Si les slots restent vides, il chute au seuil plancher. En pratique, cela donne une situation où l'envoi d'un blob en heures creuses ne coûte qu'une fraction microscopique de centime, mais en cas de rush soudain sur le réseau, le tarif peut s'emballer des centaines de fois plus vite que dans la layer d'exécution.

Autre point de détail pointu : la vérification cryptographique via les engagements KZG (Kate-Zaverucha-Goldberg). Pas besoin pour les validateurs de télécharger l'intégralité des 128 Ko pour s'assurer de l'intégrité des données. Un polynôme de 48 octets leur suffit amplement. Cela allège la charge sur les processeurs des validateurs, mais reporte tout le poids sur la bande passante réseau.

Où balancer de la data « reloue » en pratique

La nature éphémère des blobs en fait le réceptacle parfait pour les données qui n'ont pas besoin d'une comptabilité éternelle, mais exigent une immutabilité cryptographique sur une courte fenêtre de validation :

  • Dumps d'oracles et métriques brutes : tableaux de données intermédiaires signés par les fournisseurs avant d'être agrégés dans un smart contract.
  • Snapshots d'état L3 et de métavers de jeux : variations d'état delta dont il suffit de valider l'exactitude sur la dernière semaine.
  • Logs d'audit de backend : lots de transactions ou reçus devant être vérifiables publiquement, mais perdant toute valeur opérationnelle au bout d'un mois.

Envoyer de la charge dans un blob via des scripts Python en web3.py demande d'emballer séparément les octets dans des polynômes et de générer un hash versionné préfixé par 0x01. Un calcul foireux du maxFeePerBlobGas au moment de l'émission garantit le plantage de la transaction dans le mempool.

La théorie et l'économie sont claires, mais à quoi ressemble concrètement l'utilisation des blobs au niveau du code ? Un simple appel send_transaction plantera direct, car les transactions de type 3 exigent de préparer manuellement les engagements KZG, de générer les preuves (proofs) et de calculer une limite de gas spécifique.

Envoyer une transaction Type-3 en Python

Voici un pattern fonctionnel pour balancer un blob en utilisant les bibliothèques actuelles pour interagir avec un nœud (Geth ou Reth) compatible avec l'upgrade Dencun :

import os
from eth_account import Account
from web3 import Web3
w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545"))
key = os.environ["OPERATOR_KEY"]
acct = Account.from_key(key)
FE_COUNT, FE_PAYLOAD = 4096, 31  # 31 octets de données par élément de champ
def encode_blob(data: bytes) -> bytes:
    data = len(data).to_bytes(4, "big") + data
    if len(data) > FE_COUNT * FE_PAYLOAD:
        raise ValueError("le payload ne rentre pas dans un seul blob")
    data = data.ljust(FE_COUNT * FE_PAYLOAD, b"\x00")
    # l'octet de poid fort de chaque élément = 0 pour que la valeur < module BLS
    return b"".join(b"\x00" + data[i:i + FE_PAYLOAD]
                    for i in range(0, len(data), FE_PAYLOAD))
blob = encode_blob(b"EXMON Infrastructure DA Payload: batch #98412")
# Prix actuel du blob gas avec une marge pour absorber la volatilité
blob_base_fee = int(w3.provider.make_request("eth_blobBaseFee", [])["result"], 16)
base_fee = w3.eth.get_block("latest")["baseFeePerGas"]
tx = {
    "type": 3,
    "chainId": w3.eth.chain_id,
    "nonce": w3.eth.get_transaction_count(acct.address),
    "gas": 21000,
    "maxPriorityFeePerGas": w3.to_wei(1, "gwei"),
    "maxFeePerGas": base_fee * 2 + w3.to_wei(1, "gwei"),
    "maxFeePerBlobGas": max(blob_base_fee * 2, w3.to_wei(1, "gwei")),
    "to": acct.address,  # pas de création de contrat : `to` est obligatoire pour une blob-tx
    "value": 0,
    "data": b"",
}
# ckzg calcule l'engagement, les proofs et le versioned hash ; le sidecar est injecté dans la raw tx
signed = Account.sign_transaction(tx, key, blobs=[blob])
tx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)
print(f"Blob-tx envoyée : {tx_hash.to_0x_hex()}")

Si tu ne prends pas en compte la volatilité du maxFeePerBlobGas, lors des pics de trafic des rollups, ta transaction va rester figée dans le mempool de consensus jusqu'à ce que le marché se calme.

Le problème des nœuds d'archives : que deviennent les données après 18 jours ?

Le piège principal lors de la conception d'une architecture basée sur des blobs concerne leur suppression. Les clients de consensus stockent les corps des blobs pendant au moins 4096 époques (environ 18 jours), puis les nettoient. La transaction en elle-même et l'engagement KZG restent ancrés dans la blockchain pour toujours, mais impossible de récupérer le contenu brut du blob à partir de ça. Si tu as besoin de récuperer les données du blob un mois plus tard, un nœud standard te renverra une erreur.

Les équipes qui construisent des produits par-dessus l'EIP-4844 doivent résoudre ce problème via l'une de ces trois options :

  • Des scrapers d'archives perso : déployer des services en arrière-plan qui aspirent les blobs du réseau P2P dès qu'ils popent pour les balancer dans du stockage froid (buckets compatibles S3).
  • Des archives décentralisées : utiliser des réseaux comme Celestia, Avail ou The Graph pour le stockage à long terme de la Data Availability.
  • L'impasse sur l'historique profond : stocker les index locaux uniquement sur la fenêtre active de deux semaines, tout en exportant les anciens agrégats sous forme compressée.

La pratique EXMON : optimisation du stockage

Dans l'infrastructure EXMON, nous exploitons les espaces de blobs temporaires pour décharger les lourds logs de transactions intermédiaires, les dumps de service et les snapshots de vérification.

Cela nous permet de faire d'une pierre deux coups :

  • Économies budgétaires : les coûts de publication des données ont chuté d'un ordre de grandeur par rapport aux anciennes méthodes via calldata.
  • Propreté de la blockchain : l'état global du réseau n'est pas pollué par des données poubelles qui perdent leur utilité en une semaine, tout en garantissant une vérifiabilité cryptographique à 100 % sur l'intervalle de cycle de vie des données.
Résumer cet article de blog avec :

FAQ

L EIP 4844 introduit le proto danksharding via des transactions de type 3 qui transportent des conteneurs de données temporaires appelés blobs, contournant le stockage permanent de l état EVM global. Chaque blob contient exactement 128 Ko de données gérées exclusivement au niveau de la couche de consensus P2P, validées par des engagements KZG sans accès direct depuis les contrats intelligents.

Les nœuds de consensus Ethereum conservent les blobs pendant environ 18 jours, soit exactement 4096 époques, avant de les supprimer définitivement de leur stockage disque local. En raison de cette purge, la récupération de données historiques brutes au delà de cette fenêtre nécessite des indexeurs décentralisés externes ou des archives dédiées plutôt qu un nœud L1 natif.

L envoi d une transaction blob en Python requiert la construction d un dictionnaire de transaction de type 3 via web3 py incluant un paramètre maxFeePerBlobGas distinct et un tableau blobVersionedHashes. Le payload doit être converti en hachis d engagement KZG avant que la transaction soit signée par la clé privée et diffusée dans le mempool P2P du consensus.
Astra EXMON

Astra is the official voice of EXMON and the editorial collective dedicated to bringing you the most timely and accurate information from the crypto market. Astra represents the combined expertise of our internal analysts, product managers, and blockchain engineers.

...

Partager votre avis

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués *