Skip to content
EIP-4844 Blob Transactions Support in Web3j
Nischal Sharma

Published On - February 28, 2024

EIP-4844 Blob Transactions Support in Web3j

In an exciting development for the Ethereum and blockchain developer community, Web3j has become the first web3 library to implement support for sending EIP-4844 blob transactions to Ethereum clients. This update brings us one step closer to the future of Ethereum scalability and efficiency, offering a glimpse into what full data sharding could eventually look like for the network.

Understanding EIP-4844 and its impact

EIP-4844, known for introducing "blob-carrying transactions" to Ethereum, is designed to accommodate large amounts of data that cannot be accessed by EVM execution, but whose commitment can be accessed. This innovative approach allows for significant data to be temporarily stored on the beacon node, enhancing the network's capacity to handle large information.


Full data sharding will still take a considerable amount of time to finish implementing and deploying. This EIP provides a stop-gap solution until that point by implementing the transaction format that would be used in sharding, but not actually sharding those transactions. Instead, the data from this transaction format is simply part of the beacon chain and is fully downloaded by all consensus nodes (but can be deleted after only a relatively short delay). Compared to full data sharding, this EIP has a reduced cap on the number of these transactions that can be included, corresponding to a target of ~0.375 MB per block and a limit of ~0.75 MB. 


Currently L2 networks or Rollups spend a lot to make sure that their transaction data is available to all of their nodes and validators. Most rollups do this by writing their data to Ethereum as calldata. That costs about $1000 per megabyte at current prices. Good rollups cut that to $300 per megabyte by using advanced data compression. Still, data posting cost makes up the largest portion of L2 transaction fees. With EIP4844 blob data, Ethereum meets the data availability needs of rollups, so they provide a new, and hopefully cheaper, way for rollups to record their data, which would help in significantly lowering the transaction fees on Layer 2 networks like Optimism, Polygon zkEVM, Arbitrum, Starknet, etc.


A cheaper way for rollups to record their data


New Transaction Type Spec in EIP-4844

EIP-4844 transactions follow the new type of EIP-2718 transaction, “blob transaction”, where the TransactionType is BLOB_TX_TYPE = Bytes1(0x03). The fields chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, value, data, and access_list follow the same semantics as EIP-1559.

There are two more added fields max_fee_per_blob_gas is a uint256 and the field blob_versioned_hashes represents a list of hash outputs from kzg_to_versioned_hash.


Blob transaction network wrapper

Networking

We can send a signed EIP-4844 transaction using web3j to eth_sendRawTransaction API and the raw form must be the network form. This means it includes the tx_payload_body, blobs, KZG commitments, and KZG proofs.


Each of these elements are defined as follows:

  • tx_payload_body - is the TransactionPayloadBody of standard EIP-2718 blob transaction
  • blobs - list of Blob items
  • commitments - list of KZGCommitment of the corresponding blobs
  • proofs - list of KZGProof of the corresponding blobs and commitments
Code Example: Sending a Blob Transaction with Web3j

Before proceeding with the following code example, please ensure that the network you are working with has EIP-4844 support enabled.


To utilize the EIP-4844 blob transaction feature in Web3j, developers can follow this example:

 

public class Web3jEIP4844Example {


    public static void main(String[] args) throws Exception {

        // Initialize Web3j and Credentials

        Web3j web3j = Web3j.build(new HttpService("<nodeUrl>"));

        Credentials credentials = Credentials.create("<privateKey>");


        // Get the current nonce for the account

        BigInteger nonce = web3j.ethGetTransactionCount(

                credentials.getAddress(), DefaultBlockParameterName.LATEST)

                .send()

                .getTransactionCount();


    // Get the Current Base Fee Per Blob Gas value

    BigInteger blobBaseFee = web3j.ethGetBaseFeePerBlobGas();

    System.out.println("blobBaseFee = " + blobBaseFee);


// Multiply baseFeePerBlobGasValue with appropriate number to set it as our maxFeePerBlobGas value

BigInteger maxFeePerBlobGas =  BigInteger.valueOf((long) (web3j.ethGetBaseFeePerBlobGas().longValue() * 1.1));


        // Create a blob transaction

        RawTransaction rawTransaction = createEip4844Transaction(

                nonce, maxFeePerBlobGas);


        // Sign the transaction

        byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);

        String hexValue = Numeric.toHexString(signedMessage);


        // Send the transaction

        EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();


        System.out.println("Transaction hash: " + ethSendTransaction.getTransactionHash());

System.out.println("Tx Receipt = " + web3j.ethGetTransactionReceipt(ethSendTransaction.getTransactionHash()).send().getTransactionReceipt());

    }


private static RawTransaction createEip4844RawTransaction(BigInteger nonce, BigInteger maxFeePerBlobGas) {

        List<Blob> blobs = new ArrayList<>();


        blobs.add(new Blob("<blobData_in_Bytes>"));

        return RawTransaction.createTransaction(

                blobs,

                11155111L,

                nonce,

                BigInteger.valueOf(10_000_000_000L),

                BigInteger.valueOf(50_000_000_000L),

                BigInteger.valueOf(3_00_000L),

                "<toAddress>",

                BigInteger.valueOf(0),

                "",

                maxFeePerBlobGas);

    }

}


If we just want to calculate KZG commitment and KZG proofs from a blob, we can do that using BlobUtils Class functions.


Blob blob = new Blob(

        Numeric.hexStringToByteArray(

                loadResourceAsString("blob_data.txt")));

Bytes commitment = BlobUtils.getCommitment(blob);

Bytes proofs = BlobUtils.getProof(blob, commitment);

Bytes versionedHashes = BlobUtils.kzgToVersionedHash(commitment);

BlobUtils.checkProofValidity(blob, commitment, proofs)


For Developers who are interested in checking out the PRs related to EIP-4844 in web3j -

  1. Implementing Blob Trasnactions - https://github.com/web3j/web3j/pull/2000
  2. Implementing New Block Header format, getting Base Blob Fee, and new Transaction Receipt format - https://github.com/web3j/web3j/pull/2006

These PRs are included in web3j release version >=4.11.0

Conclusion

The recent integration of EIP-4844 blob transactions by Web3j as the first web3 library to embrace this innovation showcases its commitment to blockchain development and latest advancements.


This blog post has delved into the technical intricacies of EIP-4844, from its potential impact on Ethereum's scalability to the specificities of the new transaction type it introduces. 


Furthermore, practical insights into utilising Web3j for sending EIP-4844 transactions provide developers with the tools necessary to explore this new frontier.

 

The Chainlens Blockchain Explorer provides all of the business metrics you need to support your blockchain and smart contract applications.
We provide SLA-backed production support for Ethereum networks running Quorum and Hyperledger Besu.
Traditional financial markets infrastructure is being redefined by blockchain and DLT technology. We can ensure you’re prepared.
With dedicated support from the creators of Web3j you can ensure you have a trusted partner to support your most critical blockchain applications.
Web3j, Hyperledger Besu