DEV Community

Cover image for EigenDA: Empieza a desarrollar con Blobs hoy
Ahmed Castro
Ahmed Castro

Posted on

EigenDA: Empieza a desarrollar con Blobs hoy

El lanzamiento de Danksharding está próximo, brindando a los desarrolladores de rollups más espacio de bloque (o mas bien blobs) a un costo reducido. Sin embargo, a pesar de este avance, es posible que esto no satisfaga todos los casos de uso. Esto ha llevado a diferentes proyectos a desarrollar sus propias soluciones de disponibilidad de datos, conocidas como DA o Data Availability en inglés. Celestia, Near y otros ya están desarrollando sus productos, pero hasta el momento, mi preferido es EigenDA.

¿Porqué EigenDA?

Considero que EigenDA ofrece las mejores garantías económicas y una mayor compatibilidad con dApps en Ethereum y L2s. Esto es porque EigenLayer es un proyecto nativo en Ethereum Mainnet asegurado por el re-staking de Ether, como moneda base. Mi interés reciente se ha centrado en la construcción de dApps en L3s sin incentivos económicos para ser atacadas, como es el caso de aplicaciones web3 sociales o videojuegos. A pesar que EigenDA no ofrece el mismo nivel de seguridad que Ethereum y además trae un riesgo sistémico para L1, pienso que se presta para este tipo de dApps. Es este enfoque lo que me ha llevado a investigar más a fondo la tecnología de EigenDA.

Este artículo resume mi progreso en las investigaciones que he hecho sobre EigenDA, donde he aprendido a interactuar con blobs. Cómo guardarlos y cómo los rollups los usan para escalar.

Establece tu entorno de desarrollo

Instala grpcurl

EigenDA sugiere el uso de grpcurl para dispersar y obtener blobs.

MacOS

brew install grpcurl
Enter fullscreen mode Exit fullscreen mode

Linux

Para instalarlo ocupamos el compilador de Go, instálalo si aún no lo tienes.

https://go.dev/dl/go1.22.0.linux-amd64.tar.gz
rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz 
export PATH=$PATH:/usr/local/go/bin
Enter fullscreen mode Exit fullscreen mode

Ahora instala grpcurl.

go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
Enter fullscreen mode Exit fullscreen mode

Ahora grpcurl está instalado en $HOME/go/bin/grpcurl.

Instala foundry

Instala el comando forge si aún no lo tienes.

curl -L https://foundry.paradigm.xyz | bash
foundryup
Enter fullscreen mode Exit fullscreen mode

Clona el repo

Ahora clona el repo de EigenDA e ingresa en él.

git clone https://github.com/Layr-Labs/eigenda.git
cd eigenda
Enter fullscreen mode Exit fullscreen mode

1. Dispersa un Blob

Comenzemos poniendo data en EigenDA, este proceso es llamado "Dispersar un Blob". Si estás construyendo un rollup vas a querer ofrecer a tus usuarios una manera de reconstruir el estado de tu L2 para ofrecer la posibilidad de forzar una transacción y retirar assets, fondos o cualquier información. Para lograr esto es necesario guardar todo el histórico de la L2, usualmente en el formato de raíces de árboles merkle para ahorrar gas. Vamos a querer guardar todo el histórico de las raices una por una, cada cierto tiempo.

Por ahora vamos a hacer un ejemplo sencillo, vamos a guardar "Hola Eigen DA!" en un blob, cambia la data a tu gusto si deseas para este ejemplo.

$HOME/go/bin/grpcurl -import-path ./api/proto -proto ./api/proto/disperser/disperser.proto -d '{"data": "Hola Eigen DA!", "security_params": [{"quorum_id": 0, "adversary_threshold": 25, "quorum_threshold": 50}]}' disperser-goerli.eigenda.xyz:443 disperser.Disperser/DisperseBlob
Enter fullscreen mode Exit fullscreen mode

Esto devolverá un json con el estado de tu blob que incluye un requestId, guárdalo en algún lugar. Lo vamos a ocupar en los siguientes pasos.

2. Obtenén el estado de un blob

Espera al rededor de un minuto y haz el siguiente llamado.

$HOME/go/bin/grpcurl -import-path ./api/proto -proto ./api/proto/disperser/disperser.proto -d '{"request_id": "YOUR REQUEST ID"}' disperser-goerli.eigenda.xyz:443 disperser.Disperser/GetBlobStatus
Enter fullscreen mode Exit fullscreen mode

Esto devolverá un json con el estado de tu blob. Guárdalo en algún lugar, lo necesitaremos a continuación

Opcional: Obtén la data guardada en el blob haciendo la siguiente llamada pasando como parámetro el hash que puedes encontrar en el estado de tu blob en el valor info.blobVerificationProof.batchHeaderHash.

$HOME/go/bin/grpcurl -import-path ./api/proto -proto ./api/proto/disperser/disperser.proto -d '{"batch_header_hash": "YOUR BLOB HEADER HASH", "blob_index":"0"}' disperser-goerli.eigenda.xyz:443 disperser.Disperser/RetrieveBlob
Enter fullscreen mode Exit fullscreen mode

3. Verifica tu blob on-chain

Ahora crea un archivo contracts/scripts/BlobVerification.sol y pon la información del estado de tu blob como se detalla a continuación. La infomación está encodeada usando base64, te recomiendo usar este decodificador para convertirla a hexadecimal, y este conversor de hex a dec para los puntos X y Y del commitment.

contracts/scripts/BlobVerification.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import "forge-std/Script.sol";
import "../src/rollup/MockRollup.sol";
import {EigenDARollupUtils} from "../src/libraries/EigenDARollupUtils.sol";

contract MockRollupDeployer is Script {
    function run() external {
        vm.startBroadcast();

        IEigenDAServiceManager.QuorumBlobParam[]
            memory quorumBlobParams = new IEigenDAServiceManager.QuorumBlobParam[](1);

        quorumBlobParams[0] = IEigenDAServiceManager.QuorumBlobParam(
            /*quorumNumber*/0,
            /*adversaryThresholdPercentage*/25,
            /*quorumThresholdPercentage*/50,
            /*chunkLength*/1);

        IEigenDAServiceManager.BlobHeader memory blobHeader = IEigenDAServiceManager.BlobHeader(
            BN254.G1Point(/*X*/4317633011943442688312675280968246407649523414935450151451943114581321374794,
                          /*Y*/19103178923486544823523596462585377039936043999112285141018622651122914686888),
            /*dataLength*/ 1,
            quorumBlobParams
        );

        address eigenDAServiceManager = 0xa3b1689Ab85409B15e07d2ED50A6EA9905074Ee5;
        //0x1eEa1C6b573f192F33BE6AA56dC9080314a89491;

        IEigenDAServiceManager.BatchHeader memory batchHeader 
            = IEigenDAServiceManager.BatchHeader(
                /*bytes32 blobHeadersRoot*/ 0x1d1af6d981553efb8d0a7b6d6022b56d1fbf2a615d1dd5a034e6870e87159a68,
                /*bytes quorumNumbers*/ hex"00",
                /*bytes quorumThresholdPercentages*/ hex"5f", 
                /*uint32 referenceBlockNumber*/ 10544012
            );

        IEigenDAServiceManager.BatchMetadata memory batchMetadata
            = IEigenDAServiceManager.BatchMetadata(
                batchHeader,
                /*bytes32 signatoryRecordHash*/ 0x3bb6b9f58f262b89fb02e339a045438b4765f6f09ca136d045556b3869e07b70,
                /*uint96 fee*/0,
                /*uint32 confirmationBlockNumber*/10544016
            );

        EigenDARollupUtils.BlobVerificationProof memory blobVerificationProof
            = EigenDARollupUtils.BlobVerificationProof(
                /*uint32 batchId*/ 12580,
                /*uint8 blobIndex*/ 9,
                batchMetadata,
                /*bytes inclusionProof*/ hex"082915e241f357b6c2f43fac8767a909286b7f9e392c04a40caf9be28486e561b2127431770921e8f3461e1a4d845e2991e803d1c6591655873bf1cc03702cb5626b47f9b14bb86bbfaf11ad723b5bdaa3a25fc33dda9f768e58c1df463d9e0d279e7a791b0bdcbe8f32610c0ff7cfb99fd15ad0aa9091d2d02ab520a34536793829e2605b7aa684f488b51ffff369f49e23fc075b1d0413fca94f9bb670b92a024b2b6efbf73d9f0522191941d18c15ea5713fb87c679cd7abf2fdec390b5fd",
                /*bytes quorumThresholdIndexes*/ hex"00"
            );

        EigenDARollupUtils.verifyBlob(blobHeader, IEigenDAServiceManager(eigenDAServiceManager), blobVerificationProof);

        vm.stopBroadcast();
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Pruébalo en Goerli

Actualmente, EigenDA está lanzado en Goerli testnet. Forkiémoslo y corramos un RPC local.

anvil --fork-url https://goerli.gateway.tenderly.co
#https://rpc.tornadoeth.cash/goerli
Enter fullscreen mode Exit fullscreen mode

Si todo está correcto, el siguiente comando no debería revertir.

cd contracts
forge script script/BlobVerification.sol --rpc-url http://127.0.0.1:8545
Enter fullscreen mode Exit fullscreen mode

¿Qué sigue?

Ahora que sabemos cómo llamar la función verifyBlob() de EigenDA, somos capaces de verificar data de un rollup guardada on-chain en un formato similar al siguiente borrador.

// SPDX-License-Identifier: MIT

pragma solidity >=0.8.20;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

struct G1Point {
    uint256 X;
    uint256 Y;
}

contract MyNaiveOptimisticCrentralizedRollupDA is Ownable {
    mapping(uint timestamp => bytes32 data) public dataHistory;
    mapping(uint timestamp => G1Point commitment) public commitmentsHistory;

    function postData(uint timestamp, bytes32 data) public onlyOwner {
        dataHistory[timestamp] = data;
    }

    function postCommitment(uint timestamp, G1Point memory commitment) public onlyOwner {
        commitmentsHistory[timestamp] = commitment;
    }
}
Enter fullscreen mode Exit fullscreen mode

Ten en consideración que necesitamos un actor de confianza para guardar la data on-chain. Esta responsabilidad es parte del rol que usualmente conocemos como "El Secuenciador" quien se encarga de:

  1. Recolectar y procesar todas las transacciones de los usuarios en L2
  2. Disparcirla en EigenDA
  3. Postear la data y el commitment en L1 que puede ser verificado por la funcion verifyBlob() de EigenDA

Observa este ejemplo oficial de EigenDA donde se muestra una implementación bastante sencilla de un Rollup donde validadores de confianza postean de una manera optimista la data on-chain y luego se puede chequear que todo esté bien llamando la función challenge.

Además, visita la documentación oficial para más información.

Pienso que los blobs darán bastante que hablar y vendrán más y mejores herramientas que estaré investigando por este medio. ¡Pendientes!

¡Gracias por leer este tutorial!

Sígueme en dev.to y en Youtube para todo lo relacionado al desarrollo en Blockchain en Español.

Top comments (0)