> 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-pt/scenes-sdk7/blockchain/scene-blockchain-operations.md).

# Operações Blockchain da Scene

Saiba o que o SDK oferece para realizar operações com a blockchain Ethereum

Uma scene do Decentraland pode se conectar à blockchain Ethereum. Isso pode ser usado para obter dados sobre a carteira do usuário e os tokens nela, ou para acionar transações que podem envolver qualquer token Ethereum, fungível ou não fungível. Isso pode ser usado de muitas maneiras, por exemplo, para vender tokens, para recompensar tokens como parte de uma mecânica de jogo, para mudar como um jogador interage com uma scene se ele possuir certos tokens, etc.

Observe que todas as transações na mainnet Ethereum que forem acionadas por uma scene exigirão que um jogador aprove e pague uma taxa de gas.

Todas as operações de blockchain também precisam ser realizadas como [funções assíncronas](/creator/content-creator-pt/scenes-sdk7/padroes-de-programacao/async-functions.md), já que o timing depende de eventos externos.

## Obtenha a conta Ethereum de um jogador

Para obter a conta Ethereum de um jogador, use a `getPlayer()` função.

```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("O jogador não está conectado com Web3");
  }
}
```

Observe que, se um jogador tiver entrado no Decentraland como convidado, ele não terá uma carteira Ethereum conectada. Se estiver conectado como convidado, o `isGuest` campo na resposta de `getPlayer()` será verdadeiro. Caso contrário, você pode obter o endereço da carteira do jogador a partir do `userId` campo. Saiba mais sobre os dados que você pode obter de um jogador em [obter dados do jogador](/creator/content-creator-pt/scenes-sdk7/interatividade/user-data.md#get-player-data)

{% hint style="warning" %}
**📔 Observação**: Embora o endereço ETH possa conter caracteres maiúsculos, alguns navegadores convertem automaticamente a string retornada para minúsculas. Se você quiser comparar valores de endereço e fazer isso funcionar em todos os navegadores, use o `.toLowerCase()` método para converter o valor para minúsculas.
{% endhint %}

## Verificar o preço do gas

Após importar a `eth-connect` biblioteca, você deve instanciar um provider web3 e um request manager, o que permitirá que você se conecte via web3 ao Metamask no navegador do jogador.

A função abaixo obtém o preço atual do gas na mainnet Ethereum e o exibe.

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

executeTask(async function () {
  // criar uma instância do provider web3 para interfacear com o Metamask
  const provider = createEthereumProvider();
  // Crie o objeto que tratará do envio e recebimento de mensagens RPC
  const requestManager = new RequestManager(provider);
  // Verifique o preço atual do gas na rede Ethereum
  const gasPrice = await requestManager.eth_gasPrice();
  // registrar resposta
  console.log({ gasPrice });
});
```

{% hint style="info" %}
**💡 Dica**: Observe que as funções tratadas pelo `requestManager` devem ser chamadas usando `await`, já que dependem da obtenção de dados externos e podem levar algum tempo para serem concluídas.
{% endhint %}

## Importar um ABI de um contrato

Um ABI (Application Binary Interface) descreve como interagir com um contrato Ethereum, determinando quais funções estão disponíveis, quais entradas elas recebem e quais saídas produzem. Cada contrato Ethereum tem seu próprio ABI; você deve importar os ABIs de todos os contratos que deseja usar em seu projeto.

Por exemplo, aqui está um exemplo de uma função no ABI do MANA:

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

As definições de ABI podem ser bastante extensas, já que muitas vezes incluem muitas funções, então recomendamos colar o conteúdo JSON de um arquivo ABI em um `.ts` arquivo separado e importá-lo para outros arquivos de scene a partir dele. Também recomendamos manter todos os arquivos ABI em uma pasta separada da sua scene, chamada `/contracts`.

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

Aqui estão links para diferentes contratos do Decentraland. Obtenha o ABI de cada contrato clicando em *Export ABI* e escolhendo *JSON Format*.

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

Estes são os contratos para as várias coleções de wearable: (cada coleção foi emitida como um contrato separado)

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

{% hint style="info" %}
**💡 Dica**: Para ver claramente as funções expostas por um contrato, abra-o em [abitopic.io](https://abitopic.io). Basta colar o endereço do contrato ali e abrir a aba *functions* para ver a lista completa de funções suportadas e seus argumentos. Você pode até testar chamadas às funções com diferentes parâmetros pela página da web.
{% endhint %}

Configurar o TypeScript para poder importar de um arquivo JSON tem suas dificuldades. A solução alternativa mais fácil recomendada é alterar a `ABI.JSON` extensão do arquivo para `.ts` e modificá-lo ligeiramente para que seu conteúdo comece com `export default`.

Por exemplo, se o conteúdo do arquivo ABI começar com `[{"constant":true,"inputs":[{"internalType":"bytes4" ...etc`, modifique-o para que comece com `export default [{"constant":true,"inputs":[{"internalType":"bytes4" ...etc`.

### Instanciar um contrato

Após importar a `eth-connect` biblioteca e o contrato *abi*, você deve instanciar vários objetos que permitirão usar as funções no contrato e conectar ao Metamask no navegador do jogador.

Você também deve importar o provider web3. Isso porque o Metamask no navegador do jogador usa web3, então precisamos de uma forma de interagir com isso.

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

executeTask(async () => {
  // criar uma instância do provider web3 para interfacear com o Metamask
  const provider = createEthereumProvider();
  // Crie o objeto que tratará do envio e recebimento de mensagens RPC
  const requestManager = new RequestManager(provider);
  // Crie um objeto factory com base no abi
  const factory = new ContractFactory(requestManager, abi);
  // Use o objeto factory para instanciar um objeto `contract`, referenciando um contrato específico
  const contract = (await factory.at(
    "0x2a8fd99c19271f4f04b1b7b9c4f7cf264b626edb"
  )) as any;
});
```

{% hint style="info" %}
**💡 Dica**: Para contratos que seguem um mesmo padrão, como ERC20 ou ERC721, você pode importar uma única ABI genérica para todos. Então você gera um único `ContractFactory` objeto com essa ABI e usa essa mesma factory para instanciar interfaces para cada contrato.
{% endhint %}

### Chamar os métodos em um contrato

Depois de criar um `contract` objeto, você pode chamar facilmente as funções definidas em seu ABI, passando os 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 {
    // Etapas de configuração explicadas na seção acima
    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;
    }

    // Executar uma função do contrato
    const res = await contract.setBalance(
      "0xaFA48Fad27C7cAB28dC6E970E4BFda7F7c8D60Fb",
      100,
      {
        from: userData.userId,
      }
    );
    // Registrar resposta
    console.log(res);
  } catch (error: any) {
    console.log(error.toString());
  }
});
```

O exemplo acima usa o ABI de um *MANA falso* contrato de teste e chama seu `setBalance` método para conceder 100 *MANA falso* a uma conta. Ao adaptar este exemplo, substitua o endereço e o ABI pelos do contrato que você quer chamar, e chame os métodos que seu ABI define.

### Outras funções

A biblioteca eth-connect inclui vários outros auxiliares que você pode usar. Por exemplo, para:

* Obter um preço de gas estimado
* Obter o saldo de um endereço fornecido
* Obter um recibo de transação
* Obter o número de transações enviadas a partir de um endereço
* Converter entre vários formatos, incluindo hexadecimal, binário, utf8, etc.

## Usando a rede de testes Ethereum

Ao testar sua scene, para evitar transferir MANA real ou outras moedas, você pode usar a *rede de teste Ethereum Sepolia* e transferir MANA falsa da testnet em vez disso.

Para usar a rede de testes, você deve configurar a extensão Metamask do Chrome para usar a *rede de testes Sepolia* em vez da *rede principal*.

Você deve adquirir Ether de Sepolia, que pode obter gratuitamente em vários faucets externos como [este](https://www.alchemy.com/faucets/ethereum-sepolia/).

{% hint style="info" %}
**💡 Dica**: Para executar a transação de transferir MANA de Sepolia para sua Wallet, você precisará pagar uma taxa de gas em Ether de Sepolia.
{% endhint %}

Para pré-visualizar sua cena usando a rede de testes, cole a seguinte URL em uma guia do navegador. Isso abrirá a cena no cliente de desktop do Decentraland:

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

{% hint style="info" %}
**💡 Dica**: Altere o parâmetro de posição para as coordenadas da sua scene, para carregar diretamente na sua scene..
{% endhint %}

Quaisquer transações que você aceitar ao visualizar a cena neste modo ocorrerão apenas na rede de testes e não afetarão o saldo de MANA na sua Wallet real.

Se você precisar testar transações na Polygon Testnet e precisar ter MANA nessa testnet, você precisará fazer swap de MANA para essa rede depois de adquiri-lo em Sepolia. Para fazer bridge da MANA de Sepolia para a Polygon Testnet, visite sua [página da conta Decentraland em Sepolia](https://account.decentraland.zone/) e clique em ‘swap’ no lado Ethereum MANA.

Ao executar uma preview no cliente web legado, de uma scene que usa uma das bibliotecas Ethereum, você deve abrir a preview em uma janela separada do navegador, ter o Metamask aberto no seu navegador e incluir manualmente a string `&ENABLE_WEB3`.

## Enviar mensagens RPC personalizadas

Use a função `sendAsync()` para enviar mensagens pelo [protocolo RPC](https://en.wikipedia.org/wiki/Remote_procedure_call).

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

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

## Smart contracts do Decentraland

No link a seguir, você pode encontrar uma lista de smart contracts da Ethereum relevantes para o ecossistema Decentraland. A lista inclui os contratos na mainnet e em outras redes de teste 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-pt/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.
