LogoLogo
WalletsEcosystemStart BuildingJoin the Community
  • Welcome to IoTeX 2.0
    • 💡Why IoTeX
    • 🪙Tokenomics
      • IOTX Utility in IoTeX 2.0
      • IOTX Emission, Deflation, and Re-Staking
    • 📖Whitepaper
    • ⚡Get Started
  • DePIN Infra Modules (DIM)
    • DIMs Overview
    • [IoTeX L1] DePIN Blockchain
      • Core Concepts
        • Consensus Mechanism
        • Voters and Delegates
        • Ethereum Virtual Machine
        • Accounts & Identities
        • Blockchain Actions
        • ERC20 and NFT Tokens
        • Smart Contracts
        • Interoperability
        • Governance
      • The IOTX Token
        • IOTX Token Exchange Support
        • Different Formats of the IOTX Token
        • IOTX Token Contracts
      • Wallets
        • Supported Wallet Apps
          • ioPay Mobile
          • IoTeX Web Wallet
          • OKX Wallet
          • Rabby Wallet
          • Metamask Desktop
          • Ledger Nano S & X
            • Use Ledger with Metamask
            • Use Ledger with Rabby Walet
            • Use Ledger with IoTeX Hub Portal
            • Migrate to the Ethereum Ledger App
          • IoTeX Desktop Wallet
          • 👩‍💻IoTeX HD Derivation Path
        • Buy IOTX Tokens
        • Execute Transactions
          • Transfer IOTX Tokens
          • Transfer ERC20 Tokens
          • Interact with Dapps
          • Explore transactions
        • Migrate Assets to a different wallet
      • Staking & Governance
        • About IoTeX Staking
        • IoTeX Staking Guide
          • Native staking
          • Staking as NFT
        • Join the Governance
          • Marshall DAO
          • Improvement Proposals
      • Exchange Integration
      • 👨‍💻Deploy Dapps on IoTeX
    • [ioID] DePIN Identities
      • Why ioID?
      • System Architecture
      • Technical Specification
      • API Overview
      • ioID Enabled Services
      • Integrating ioID
      • Example Use Cases
    • [W3bstream] DePIN Verification
      • Overview of W3bstream
      • Multi-Prover Architecture
      • 👨‍💻Build with W3bstream
        • Get Started
          • Sequencer Options
        • Build the Prover Code
          • Risc Zero
          • Halo2
          • zkWASM
        • Deploy to W3bstream
          • Create the Project File
          • W3bstream Outputs
          • Deploying Projects
          • Interacting with Projects
        • On-chain integration
          • Verify Risc0 Proofs
          • Verify Halo2 Proofs
          • Verify zkWASM profs
        • Sending Messages
      • 👩‍💻Node Operators
        • Configure a ZK Prover Node
        • Register your Node
    • [ioID-SDK] Hardware SDK
      • ioID-SDK Overview
      • Layered Architecture
      • Compatibility
      • Current Development Status
    • [MSP] Modular Security Pool
    • Third-Party DIMs
      • Data Sequencer Infras
      • Data Availability Infras
      • 👨‍💻W3bstream Tasks
  • Ecosystem
    • Assets on IoTeX
      • Mainstream Assets
      • IOTX and Derivatives
      • DePIN Tokens
      • MEME Coins
    • iotube Bridge
    • iotexscan Explorer
    • Ecosystem Apps
      • DePINScan
      • mimo DEX
      • ecosystem.iotex.io
    • "Powered by IoTeX" Devices
      • Pebble Tracker
        • Quick Start
        • Device Registration
        • Online Firmware Update
        • USB Firmware Update
        • Migrating to Pebble v2.0
          • 1.0 Device Registration
        • Tech Specs
        • Network Selection
        • Pebble Configuration
        • Query Pebble Data
        • Troubleshooting
        • Firmware Development
          • Hardware Setup
          • Build the Firmware
          • Flash the firmware
      • SenseCAP Indicator
      • UCam Home Camera
  • Builders
    • IoTeX Developer Portal
    • Dev Chat on Discord
    • Web3 Development
      • RPC Endpoints
      • Set up your Environment
      • Get Testnet IOTX Tokens
      • ioctl CLI
        • Installation
        • Create Accounts
        • Blockchain interaction
          • ioctl command reference
      • Chain Indexing
        • The Graph
        • SubQuery
        • IoTeX Analytics API
      • IoTeXscan API
      • Deterministic Deployment
      • Account Abstraction
        • Components of AA
        • 👩‍💻Creating new Accounts
        • 👨‍💻P256Account Example
      • Blob Transactions (EIP-4844)
      • Multicall3
      • EVM Precompiled Contracts
    • Building DePINs
      • ioID Step by Step Tutorial
        • Integrate ioID in the Device Firmware
        • Integrate ioID in your cloud
      • Decentralized WiFi Connectivity (DeWi)
        • Project Specification
        • The choice of Hardware
        • The Data API Service
        • DePIN Incentives Contract
    • Building DeFi
      • Deploy Tokens
        • Deploy an ERC20 Token
        • Deploy an NFT Token
      • Price Oracles
        • Chainlink Relayer
        • SupraOracles
      • Integrate IoTeX Staking
      • Liquid staking Dapps
    • Launch Dapps on IoTeX
      • Submit Tokens to the IoTeX Ecosystem
      • Submit tokens to the iotube bridge
      • Verify Smart Contracts
      • Audit your Contracts
      • Submit your Dapp to Portals
      • Useful tools
    • Node Operators
      • Fastblocks (Node as a Service)
      • Setup an IoTeX RPC Node
      • Run a Delegate Node
      • Rosetta API
    • Reference Docs
      • ioctl client
        • Accounts
        • HD Wallets
        • Aliases
        • Actions
        • Queries
        • Smart Contracts
        • Staking & Voting
        • Tokens
        • ioID Identities
        • W3bstream
        • Decentralized Identifiers (DID)
        • JWT Auth Tokens
      • Native IoTeX Development
        • IoTeX gRPC API
        • Account Cryptography
        • Address Conversion
        • Create Accounts
        • Estimate Gas Price
        • Make IOTX Transfers
        • Manage ERC20 Tokens
        • Smart Contract Interactions
        • ioPay Desktop
        • DID JWT Tokens
        • Calling any RPC method
      • Embedded Blockchain Clients
        • Arduino IDE
        • Linux Systems
        • PlatformIO
        • Examples
        • Tutorials
  • Participate
    • Crypto's Got Talent (CGT)
      • IoTeX x Polygon DePIN Grant
    • Governance
      • IoTeX Improvement Proposals
      • The Marshall DAO
    • Join the Community
    • Get in Touch
Powered by GitBook
LogoLogo

This documentation portal is currently undergoing updates to align with the IoTeX 2.0 Whitepaper release. Information provided here may be incomplete, or out-of-date. Please use this portal for preliminary reference only, and check out the official IoTeX 2.0 Whitepaper for updated information.

  • .

2025 | IoTeX

On this page
  • Overview
  • Blob Data Structure
  • How to Generate a Blob Transaction
  • How to Send the Blob Transaction to IoTeX Blockchain
  • How to Fetch a Given Blob Transaction from IoTeX Blockchain
  • How to Verify the Received Blob Transaction
  • Reference

Was this helpful?

Export as PDF
  1. Builders
  2. Web3 Development

Blob Transactions (EIP-4844)

This guide demonstrates how to generate, send, fetch, and verify a Blob Transaction when integrating rollup data into the IoTeX blockchain using EIP-4844 Blob Transactions. These steps ensure scalability and data integrity for rollup-based systems.

Overview

EIP-4844 introduces a new transaction type called Blob Transactions to improve scalability by enabling the temporary storage of large amounts of data outside of a blockchain's execution layer.

Here are key points about the Blob transaction:

  • Blob transactions contain large amounts of data that are not directly stored in the Blockchain's execution layer (i.e., they are not part of the state or permanent history).

  • This data is ephemeral and is retained only for a short period (e.g., 20 days) to facilitate rollup proofs.

  • It is designed to significantly reduce the cost of rollup solutions (Layer 2 scaling technologies) by allowing them to post off-chain data (proofs, commitments) to a Blockchain more efficiently.

  • This off-chain data is essential for rollups to verify transactions but doesn't need to persist in the Blockchain's state.

  • Gas-efficient: Lower costs for rollups to post data compared to traditional calldata.

  • EIP-4844 reduces costs for Layer 2 solutions, setting the stage for Ethereum’s future scalability improvements, such as danksharding.

Blob Data Structure

The blob data structure in EIP-4844 is as follows:

// BlobTxSidecar contains the blobs of a blob transaction.
type BlobTxSidecar struct {
    Blobs       []kzg4844.Blob       // Blob is 128kB bytes array
    Commitments []kzg4844.Commitment // Commitment is 48-bytes
    Proofs      []kzg4844.Proof      // Proof is 48-bytes
}

A Blob represents 128kB of raw data, while a Commitment is a 48-byte cryptographic hash generated by applying a cryptographic commitment scheme (for example, KZG commitment) to the blob data. This provides a compact and efficient method for verifying the integrity of the blob data. The Proof, which is also 48 bytes, is generated by the commitment scheme and allows validators to verify that the blob data corresponds to the on-chain commitment without needing access to the full blob.

How to Generate a Blob Transaction

Blob data contains large amounts of off-chain data, such as rollup proofs from an L2 chain, which are required for rollup verification. In the context of IoTeX, blob data can also include device data generated by IoTeX’s W3bstream devices. This capability enables a wide range of IoT use cases, where data such as sensor readings or event logs can be efficiently bundled and posted to the blockchain.

To create blob data and associated transactions, use the Ethereum SDK or a similar toolkit. See the code example below:

package main

import (
        "github.com/ethereum/go-ethereum/core"
        "github.com/ethereum/go-ethereum/core/types"
        "github.com/ethereum/go-ethereum/crypto/kzg4844"
        "crypto/ecdsa"
        "log"
)

func createBlobTx() *types.BlobTx {
        // Example private key (replace with your own key securely)
        privateKey := "YOUR_PRIVATE_KEY"
        key, err := crypto.HexToECDSA(privateKey)
        if err != nil {
                log.Fatalf("Failed to load private key: %v", err)
        }

        // Prepare blob data
        blobData := []byte("Rollup proof or other off-chain data")
        // or it could be W3bstream device data
        deviceData := []byte("IoT device data from W3bstream")
        
        // generate commitment and proof
        commitment := kzg4844.BlobToCommitment(blobData)
        proof := kzg4844.ComputeBlobProof(blobData, commitment)

        // Create blob data
        blob := BlobTxSidecar {
            Blobs       []kzg4844.Blob{blobData}
            Commitments []kzg4844.Commitment{commitment}
            Proofs      []kzg4844.Proof{proof}
        }
        
        return &types.BlobTx {
            ChainID:   4689, // chain ID of the IoTeX blockchain
            Nonce:     nonce,
            GasTipCap: tipcap,
            GasFeeCap: maxFee,
            Gas:       gas,
            To:        to,
            Data:      calldata,
            BlobFeeCap: blobFeeCap,
            BlobHashes: blob.BlobHashes(),
            Sidecar:    &blob,
        }
}

How to Send the Blob Transaction to IoTeX Blockchain

The IoTeX blockchain is fully compatible with Ethereum, so it can accept Blob Transactions using its RPC interface. See the code example below to send a Blob Transaction to the IoTeX blockchain.

package main

import (
        "log"
        "github.com/ethereum/go-ethereum/core/types"
        "github.com/ethereum/go-ethereum/ethclient"
)

func main() {
        // Connect to IoTeX PRC endpoint
        client, err := ethclient.Dial("https://babel-mainnet.api.iotex.io")
        if err != nil {
                log.Fatalf("Failed to connect to IoTeX: %v", err)
        }
        
        // Example private key (replace with your own key securely)
        privateKey := "YOUR_PRIVATE_KEY"
        key, err := crypto.HexToECDSA(privateKey)
        if err != nil {
                log.Fatalf("Failed to load private key: %v", err)
        }

        // Sign the blob transaction
        tx := types.NewTx(createBlobTx())
        signedTx, err := types.SignTx(tx, types.NewCancunSigner(4689), key)
        if err != nil {
                log.Fatalf("Failed to sign blob transaction: %v", err)
        }

        // Send the transaction
        err := cli.SendTransaction(context.Background(), signedTx)
        if err != nil {
                log.Fatalf("Failed to send transaction: %v", err)
        }
        log.Printf("Transaction Sent: %s", signedTx.Hash().String())
}

Once the Blob Transaction has been successfully sent to the IoTeX blockchain, it will be mined into a block and retained in ephemeral storage for a short period (approximately 20 days).

How to Fetch a Given Blob Transaction from IoTeX Blockchain

You can access the IoTeX RPC endpoint to retrieve any transaction (including a Blob Transaction) by its hash. See the code example below:

package main

import (
        "context"
        "github.com/ethereum/go-ethereum/ethclient"
        "log"
)

func main() {
        // Connect to IoTeX PRC endpoint
        client, err := ethclient.Dial("https://babel-mainnet.api.iotex.io")
        if err != nil {
                log.Fatalf("Failed to connect to IoTeX: %v", err)
        }

        // Query the transaction by hash
        transactionHash := "TRANSACTION_HASH"
        tx, pending, err := cli.TransactionByHash(transactionHash)
        if err != nil {
                log.Fatalf("Failed to fetch transaction: %v", err)
        }

        log.Printf("Fetched Transaction: %v", tx)
}

How to Verify the Received Blob Transaction

Once the Blob Transaction has been retrieved, you can verify it by checking the commitment against the raw blob data. The verification process consists of two steps:

  1. Verify that the lengths of hashes, blobs, commitments, and proofs match, and that the blob hashes match the hashes in the transaction.

  2. Verify the blob data against the commitments and proofs.

See the code example below:

package main

import (
        "github.com/ethereum/go-ethereum/core/types"
        "log"
)

func ValidateBlobTransaction() {
        // tx is received Blob transaction
        sidecar := tx.BlobTxSidecar()
        if sidecar == nil {
            return fmt.Errorf("missing sidecar in blob transaction")
        }
        // Ensure the number of items in the blob transaction and various side
        // data match up before doing any expensive validations
        hashes := tx.BlobHashes()
        if len(hashes) == 0 {
            return fmt.Errorf("blobless blob transaction")
        }
        if len(hashes) > params.MaxBlobGasPerBlock/params.BlobTxBlobGasPerBlob {
            return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), params.MaxBlobGasPerBlock/params.BlobTxBlobGasPerBlob)
        }
        if len(sidecar.Blobs) != len(hashes) {
            return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", len(sidecar.Blobs), len(hashes))
        }
        if len(sidecar.Commitments) != len(hashes) {
            return fmt.Errorf("invalid number of %d blob commitments compared to %d blob hashes", len(sidecar.Commitments), len(hashes))
        }
        if len(sidecar.Proofs) != len(hashes) {
            return fmt.Errorf("invalid number of %d blob proofs compared to %d blob hashes", len(sidecar.Proofs), len(hashes))
        }
        // Blob quantities match up, validate that the provers match with the
        // transaction hash before getting to the cryptography
        hasher := sha256.New()
        for i, vhash := range hashes {
            computed := kzg4844.CalcBlobHashV1(hasher, &sidecar.Commitments[i])
            if vhash != computed {
                return fmt.Errorf("blob %d: computed hash %#x mismatches transaction one %#x", i, computed, vhash)
            }
        }
        // Blob commitments match with the hashes in the transaction, verify the
        // blobs themselves via KZG
        for i := range sidecar.Blobs {
            if err := kzg4844.VerifyBlobProof(sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil {
                return fmt.Errorf("invalid blob %d: %v", i, err)
            }
        }
        return nil
}

Reference

PreviousP256Account ExampleNextMulticall3

Last updated 2 months ago

Was this helpful?

EIP-4844:

Ethereum code base:

https://eips.ethereum.org/EIPS/eip-4844
https://github.com/ethereum/go-ethereum