> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/blockchain/scene-blockchain-operations.md).

# Operaciones Blockchain de la escena

Aprende qué ofrece el SDK para realizar operaciones con la blockchain de Ethereum

Una escena de Decentraland puede interactuar con la blockchain de Ethereum. Esto puede servir para obtener datos sobre la wallet del usuario y los tokens en ella, o para desencadenar transacciones que podrían involucrar cualquier token de Ethereum, fungible o no fungible. Esto puede usarse de muchas maneras; por ejemplo, para vender tokens, para recompensar tokens como parte de una mecánica de juego, para cambiar cómo un jugador interactúa con una escena si posee ciertos tokens, etc.

Ten en cuenta que todas las transacciones en la mainnet de Ethereum que se desencadenen desde una escena requerirán que un jugador las apruebe y pague una tarifa de gas.

Todas las operaciones de blockchain también deben realizarse como [funciones asíncronas](/creator/content-creator-es/scenes-sdk7/patrones-de-programacion/async-functions.md), ya que el momento depende de eventos externos.

## Obtener la cuenta Ethereum de un jugador

Para obtener la cuenta Ethereum de un jugador, usa la `getPlayer()` función.

```ts
import { getPlayer } from "@dcl/sdk/src/players";

export function main() {
  let userData = getPlayer();
  if (!userData) return;
  if (!userData.isGuest) {
    console.log(userData.userId);
  } else {
    console.log("El jugador no está conectado con Web3");
  }
}
```

Ten en cuenta que, si un jugador ha entrado en Decentraland como invitado, no tendrá una wallet de Ethereum conectada. Si están conectados como invitados, el `isGuest` campo en la respuesta de `getPlayer()` será true. De lo contrario, puedes obtener la dirección de la wallet del jugador desde el `userId` campo. Obtén más información sobre los datos que puedes obtener de un jugador en [obtener datos del jugador](/creator/content-creator-es/scenes-sdk7/interactividad/user-data.md#get-player-data)

{% hint style="warning" %}
**📔 Nota**: Aunque la dirección de ETH puede contener caracteres en mayúsculas, algunos navegadores convierten la cadena devuelta a minúsculas automáticamente. Si deseas comparar valores de direcciones y que funcione en todos los navegadores, usa el `.toLowerCase()` método para convertir el valor a minúsculas.
{% endhint %}

## Comprobar el precio del gas

Después de importar la `eth-connect` librería, debes instanciar un proveedor de web3 y un administrador de solicitudes, lo que te permitirá conectarte vía web3 a Metamask en el navegador del jugador.

La función de abajo obtiene el precio actual del gas en la red principal de Ethereum y lo imprime.

```ts
import { RequestManager } from "eth-connect";
import { createEthereumProvider } from "@dcl/sdk/ethereum-provider";

executeTask(async function () {
  // crear una instancia del proveedor de web3 para interactuar con Metamask
  const provider = createEthereumProvider();
  // Crear el objeto que gestionará el envío y la recepción de mensajes RPC
  const requestManager = new RequestManager(provider);
  // Comprobar el precio actual del gas en la red Ethereum
  const gasPrice = await requestManager.eth_gasPrice();
  // registrar la respuesta
  console.log({ gasPrice });
});
```

{% hint style="info" %}
**💡 Consejo** : Ten en cuenta que las funciones gestionadas por el `requestManager` deben llamarse usando `await`, ya que dependen de obtener datos externos y pueden tardar un tiempo en completarse.
{% endhint %}

## Importar un ABI de un contrato

Un ABI (Application Binary Interface) describe cómo interactuar con un contrato de Ethereum, determinando qué funciones están disponibles, qué entradas reciben y qué salidas producen. Cada contrato de Ethereum tiene su propio ABI, debes importar los ABIs de todos los contratos que quieras usar en tu proyecto.

Por ejemplo, aquí tienes un ejemplo de una función en el ABI de MANA:

```ts
{
  anonymous: false,
  inputs: [
    {
      indexed: true,
      name: 'burner',
      type: 'address'
    },
    {
      indexed: false,
      name: 'value',
      type: 'uint256'
    }
  ],
  name: 'Burn',
  type: 'event'
}
```

Las definiciones de ABI pueden ser bastante extensas, ya que a menudo incluyen muchas funciones, por lo que recomendamos pegar el contenido JSON de un archivo ABI en un `.ts` archivo aparte e importarlo desde allí en otros archivos de escena. También recomendamos guardar todos los archivos ABI en una carpeta separada de tu escena, llamada `/contracts`.

```ts
import { abi } from "../contracts/mana";
```

Aquí tienes enlaces a distintos contratos de Decentraland. Obtén el ABI de cada contrato haciendo clic en *Exportar ABI* y eligiendo *Formato JSON*.

* [ABI del token MANA](https://etherscan.io/address/0x0f5d2fb29fb7d3cfee444a200298f468908cc942#code)
* [Decentraland Marketplace](https://etherscan.io/address/0x19a8ed4860007a66805782ed7e0bed4e44fc6717#code)
* [ABI de LAND](https://etherscan.io/address/0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d#code)
* [ABI de Estate](https://etherscan.io/address/0x959e104e1a4db6317fa58f8295f586e1a978c297#code)
* [ABI de AvatarNameRegistry](https://etherscan.io/address/0x894b883905bfEe2CC448880F1b59f4A762E67566)
* [ABI de Catalyst](https://etherscan.io/address/0xcc054fab08127c19f621ab83ade5962cd10584ec)

Estos son los contratos de las distintas colecciones de wearables: (cada colección se emitió como un contrato independiente)

* [ABI de ExclusiveMasksCollection](https://etherscan.io/address/0xc04528c14c8ffd84c7c1fb6719b4a89853035cdd)
* [ABI de Halloween2019Collection](https://etherscan.io/address/0xc1f4b0eea2bd6690930e6c66efd3e197d620b9c2)
* [ABI de Halloween2019CollectionFactory](https://etherscan.io/address/0x07ccfd0fbada4ac3c22ecd38037ca5e5c0ad8cfa)
* [ABI de Xmas2019Collection](https://etherscan.io/address/0xc3af02c0fd486c8e9da5788b915d6fff3f049866)
* [ABI de MCHCollection](https://etherscan.io/address/0xf64dc33a192e056bb5f0e5049356a0498b502d50)
* [ABI de CommunityContestCollection](https://etherscan.io/address/0x32b7495895264ac9d0b12d32afd435453458b1c6)
* [ABI de DCLLaunchCollection](https://etherscan.io/address/0xd35147be6401dcb20811f2104c33de8e97ed6818)
* [ABI de DCGCollection](https://etherscan.io/address/0x3163d2cfee3183f9874e2869942cc62649eeb004)

{% hint style="info" %}
**💡 Consejo** : Para ver claramente las funciones expuestas por un contrato, ábrelo en [abitopic.io](https://abitopic.io). Solo pega allí la dirección del contrato y abre la *pestaña de funciones* para ver la lista completa de funciones compatibles y sus argumentos. Incluso puedes probar a llamar las funciones con distintos parámetros a través de la página web.
{% endhint %}

Configurar TypeScript para poder importar desde un archivo JSON tiene sus dificultades. La solución alternativa más sencilla recomendada es cambiar el `ABI.JSON` la extensión del archivo a `.ts` y modificarlo ligeramente para que su contenido comience con `export default`.

Por ejemplo, si el contenido del archivo ABI comienza con `[{"constant":true,"inputs":[{"internalType":"bytes4" ...etc`, modifícalo para que comience con `export default [{"constant":true,"inputs":[{"internalType":"bytes4" ...etc`.

### Instanciar un contrato

Después de importar la `eth-connect` librería y el ABI de un contrato *ABI*, debes instanciar varios objetos que te permitirán usar las funciones del contrato y conectarte a Metamask en el navegador del jugador.

También debes importar el proveedor de web3. Esto se debe a que Metamask en el navegador del jugador usa web3, así que necesitamos una forma de interactuar con ello.

```ts
import { RequestManager, ContractFactory } from "eth-connect";
import { createEthereumProvider } from "@dcl/sdk/ethereum-provider";
import { abi } from "../contracts/mana";

executeTask(async () => {
  // crear una instancia del proveedor de web3 para interactuar con Metamask
  const provider = createEthereumProvider();
  // Crear el objeto que gestionará el envío y la recepción de mensajes RPC
  const requestManager = new RequestManager(provider);
  // Crear un objeto factory basado en el ABI
  const factory = new ContractFactory(requestManager, abi);
  // Usar el objeto factory para instanciar un objeto `contract`, haciendo referencia a un contrato específico
  const contract = (await factory.at(
    "0x2a8fd99c19271f4f04b1b7b9c4f7cf264b626edb"
  )) as any;
});
```

{% hint style="info" %}
**💡 Consejo** : Para contratos que siguen un mismo estándar, como ERC20 o ERC721, puedes importar un único ABI genérico para todos. Luego generas un único `ContractFactory` objeto ContractFactory con ese ABI y usas ese mismo factory para instanciar interfaces para cada contrato.
{% endhint %}

### Llamar a los métodos de un contrato

Una vez que hayas creado un `objeto contract,` puedes llamar fácilmente a las funciones definidas en su ABI, pasándole los parámetros de entrada especificados.

```ts
import { getPlayer } from "@dcl/sdk/src/players";
import { createEthereumProvider } from "@dcl/sdk/ethereum-provider";
import { RequestManager, ContractFactory } from "eth-connect";
import { abi } from "../contracts/mana";

executeTask(async () => {
  try {
    // Los pasos de configuración se explican en la sección anterior
    const provider = createEthereumProvider();
    const requestManager = new RequestManager(provider);
    const factory = new ContractFactory(requestManager, abi);
    const contract = (await factory.at(
      "0x2a8fd99c19271f4f04b1b7b9c4f7cf264b626edb"
    )) as any;
    let userData = getPlayer();
    if (!userData || userData.isGuest) {
      return;
    }

    // Ejecutar una función del contrato
    const res = await contract.setBalance(
      "0xaFA48Fad27C7cAB28dC6E970E4BFda7F7c8D60Fb",
      100,
      {
        from: userData.userId,
      }
    );
    // Registrar la respuesta
    console.log(res);
  } catch (error: any) {
    console.log(error.toString());
  }
});
```

El ejemplo anterior usa el ABI de un *MANA ficticio* contrato de prueba, y llama a su `setBalance` método para otorgar 100 *MANA ficticio* a una cuenta. Al adaptar este ejemplo, sustituye la dirección y el ABI por los del contrato que quieras llamar, y llama a los métodos que defina su ABI.

### Otras funciones

La librería eth-connect incluye una serie de otras funciones auxiliares que puedes usar. Por ejemplo, para:

* Obtener un precio estimado del gas
* Obtener el saldo de una dirección dada
* Obtener un comprobante de transacción
* Obtener el número de transacciones enviadas desde una dirección
* Convertir entre varios formatos, incluidos hexadecimal, binario, utf8, etc.

## Usando la red de prueba de Ethereum

Mientras pruebas tu escena, para evitar transferir MANA real u otras monedas, puedes usar la *red de pruebas Ethereum Sepolia* y transferir MANA ficticio de la testnet en su lugar.

Para usar la red de prueba debes configurar tu extensión de Chrome Metamask para usar la *red de prueba Sepolia* en lugar de *red principal*.

Debes obtener Sepolia Ether, que puedes conseguir gratis en varios faucets externos como [este](https://www.alchemy.com/faucets/ethereum-sepolia/).

{% hint style="info" %}
**💡 Consejo**: Para realizar la transacción de transferir MANA de Sepolia a tu wallet, tendrás que pagar una tarifa de gas en Ether de Sepolia.
{% endhint %}

Para previsualizar tu escena usando la red de prueba, pega la siguiente URL en una pestaña del navegador. Esto abrirá la escena en el cliente de escritorio de Decentraland:

`decentraland://realm=http://127.0.0.1:8000&local-scene=true&debug=true&dclenv=zone&position=0,0`

{% hint style="info" %}
**💡 Consejo**: Cambia el parámetro de posición a las coordenadas de tu escena, para cargar directamente en tu escena.
{% endhint %}

Cualquier transacción que aceptes mientras ves la escena en este modo solo ocurrirá en la red de prueba y no afectará el saldo de MANA en tu wallet real.

Si necesitas probar transacciones en la Polygon Testnet y necesitas tener MANA en esa testnet, tendrás que intercambiar MANA a esa red después de adquirirlo en Sepolia. Para puentear MANA de Sepolia a la Polygon Testnet, visita tu [página de cuenta de Decentraland en Sepolia](https://account.decentraland.zone/) y haz clic en ‘swap’ en el lado de Ethereum MANA.

Al ejecutar un preview en el cliente web heredado de una scene que usa una de las librerías de Ethereum, debes abrir el preview en una ventana separada del navegador, tener Metamask abierto en tu navegador e incluir manualmente la cadena `&ENABLE_WEB3`.

## Enviar mensajes RPC personalizados

Usa la función `sendAsync()` para enviar mensajes a través del [protocolo RPC](https://en.wikipedia.org/wiki/Remote_procedure_call).

```ts
import { sendAsync } from "~system/EthereumController";

// enviar un mensaje
await sendAsync({
  id: 1,
  method: "myMethod",
  jsonParams: "{ myParam: myValue }",
});
```

## Smart contracts de Decentraland

En el siguiente enlace puedes encontrar una lista de smart contracts de Ethereum relevantes para el ecosistema de Decentraland. La lista incluye los contratos en mainnet, así como en otras redes de prueba de Ethereum.

[contracts.decentraland.org](https://contracts.decentraland.org/links)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/blockchain/scene-blockchain-operations.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
