Scroll es una Layer 2 construida por desarrolladores de Ethereum para desarrolladores de Ethereum. Scroll utiliza zkEVM como componente principal, y todo su ecosistema gira en torno a ello.

En esta ocasión, deployaremos un Smart Contract ficticio en Sepolia o Scroll e interactuaremos con él desde su cadena opuesta. Para ello, usaremos ScrollMessenger que se implementa tanto en Sepolia como en Scroll. ¡Comencemos!


Deployando el Smart Contract…

En primer lugar, comencemos implementando el contrato base. Para este ejemplo, usaremos el contrato Greeter, pero vos podés usar cualquier otro contrato e implementarlo en Sepolia o Scroll, es indistinto. ¡Todo esto, lo estamos realizando en Remix! Tené en cuenta, que en Scroll, L1 y L2 utilizan la misma API, así que no tenes de que preocuparte, podés elegir tranquilamente. Vos decidís en cuál.
¡Manos a la obra!

Primero, ingresamos a Remix y creamos un nuevo archivo (click derecho – New File) y le ponemos como nombre Greeter.sol

Remix Scroll

Una vez creado el mismo, escribimos el siguiente código:


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

// This Greeter contract will be interacted with through the ScrollMessenger across the bridge
contract Greeter {
  string public greeting = "Hello World!";

  // This function will be called by executeFunctionCrosschain on the Operator Smart Contract
  function setGreeting(string memory greeting_) public {
    greeting = greeting_;
  }
}

Ahora, siempre en el mismo contrato estamos trabajando; ejecutaremos el setGreeting en forma cross-chain.

Smart Contract del operador

Acá debemos cambiarnos a la otra cadena y desplegamos el GreeterOperator. Entonces, si implementó el contrato Greeter en L1, implemente el GreeterOperator en L2 o viceversa.

Debería quedarte algo así:


// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

// The Scroll Messenger interface is the same on both L1 and L2, it allows sending cross-chain transactions
// Let's import it directly from the Scroll Contracts library
import "@scroll-tech/contracts@0.1.0/libraries/IScrollMessenger.sol";

// The GreeterOperator is capable of executing the Greeter function through the bridge
contract GreeterOperator {
  // This function will execute setGreeting on the Greeter contract
  function executeFunctionCrosschain(
    address scrollMessengerAddress,
    address targetAddress,
    uint256 value,
    string memory greeting,
    uint32 gasLimit
  ) public payable {
    IScrollMessenger scrollMessenger = IScrollMessenger(scrollMessengerAddress);
    // sendMessage is able to execute any function by encoding the abi using the encodeWithSignature function
    scrollMessenger.sendMessage{ value: msg.value }(
      targetAddress,
      value,
      abi.encodeWithSignature("setGreeting(string)", greeting),
      gasLimit,
      msg.sender
    );
  }
}

Llamando a la función Cross-chain

Debemos pasar el mensaje ejecutando executeFunctionCrosschain y establecer los siguientes parámetros:

  • scrollMessengerAddress: esto dependerá de en principio dónde implementó el contrato GreeterOperator.
    • Si lo implementaste en Sepolia, usa 0x50c7d3e7f7c656493D1D76aaa1a836CedfCBB16A
    • Si lo implementtaste en Scroll Sepolia, usa 0xBa50f5340FB9F3Bd074bD638c9BE13eCB36E603d
  • En targetAddress, debes indicar la dirección del contrato de Greeter de la cadena opuesta.
  • En value, en este caso es 0 porque el setGreeting no es pagadero.
  • greeting es el parámetro que se enviará a través del mensaje. Intente pasar “¡Este mensaje era cross-chain!
  • gasLimit:
    • Si el mensaje que deseas enviar va de L1 a L2, un límite de alrededor de 1000000 de gas debería ser más que suficiente. Dicho esto, si lo configuras demasiado alto y el msg.value no cubre el gasLimit * baseFee, la transacción se revertirá. Si msg.value es mayor que la tarifa del gas, se reembolsará la parte no utilizada. Es preferible que suceda esto último.
    • Si el mensaje que deseas enviar va de L2 a L1, utiliza 0, ya que la transacción se completará directamente ejecutando una transacción adicional en la L1.

Retransmitir el mensaje al enviar de L2 a L1

Cuando una transacción pasa de L2 a L1, se debe enviar una “execute withdrawal transaction” adicional en L1, es decir, una transacción de retiro de ejecución adicional en L1. Para hacer esto, debemos llamar a la función RelayMessageWithProof en el contrato L1 Scroll Messenger desde una wallet EOA. ¿Cómo haces esto?

Bueno, podes hacer esto directamente desde Etherscan Sepolia. Para hacerlo, primero deberás aprobar una prueba de inclusión Merkle para la transacción del bridge y otros parámetros. Todos ellos, los consultarás utilizando la API Scroll Bridge. La cual es la siguiente:


curl "https://sepolia-api-bridge.scroll.io/api/claimable?page_size=10&page=1&address=GREETER_OPERATOR_ADDRESS_ON_L2"

Debes remplazar el GREETER_OPERATOR_ADDRESS_ON_L2 con la dirección de contrato de tu GreeterOperator tal cual se lanzó en la L2.

¡Ya estamos!

Después de ejecutar y confirmar la transacción tanto en L1 como en L2, el nuevo estado del greeting en el contrato Greeter debería ser “¡Este mensaje fue entre cadenas!“.
Cabe resaltar, que enviar un mensaje de una cadena a otra debería tardar unos 20 minutos después de que se confirmen las transacciones en la cadena de origen.

¡Eso es todo, Felicitaciones, acabas de ejecutar una transacción de una cadena a otra usando el bridge nativo de Scroll!

También te puede interesar

  • ¿Qué es Scroll?

    ¿Qué es Scroll?

    ¿Cómo es posible que Scroll no solo afronte, sino que transforme los problemas que acechan a Ethereum? Descubrí que es Scroll y como hace frente a la escalabilidad.

    Leer más

  • Misión de Scroll

    Misión de Scroll

    Descubre cuál es la misión de Scroll; donde la esencia de Ethereum se entrelaza y se posiciona como principio clave. Conoce la misión de Scroll.

    Leer más

  • Visión de Scroll

    Visión de Scroll

    La visión de un proyecto no solo es un faro guía, sino el cimiento mismo sobre el cual se construye su impacto. Conoce la visión de Scroll a detalle.

    Leer más