# Operações Blockchain da Scene

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

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

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

## Obter a conta ethereum de um jogador

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

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

export function main() {
	let userData = getPlayer()
	if (!userData.isGuest) {
		console.log(userData.userId)
	} else {
		log('Player is not connected with Web3')
	}
}
```

Observe que se um jogador entrou na Decentraland como guest, ele não terá uma carteira ethereum conectada. Se eles estiverem conectados como guests, o `isGuest` campo na resposta de `getPlayer()` será true. Se `hasConnectedWeb3` for true, então você pode obter o endereço do jogador no campo `publicKey`. Saiba mais sobre os dados que você pode obter de um jogador em [get player data](https://docs.decentraland.org/creator/content-creator-pt/interatividade/user-data#get-player-data)

Você deve envolver a função em um `async()` function, saiba mais sobre isso em [funções assíncronas](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/padroes-de-programacao/async-functions)

{% hint style="warning" %}
**📔 Nota**: Mesmo que o endereço eth possa conter caracteres em maiúsculas, alguns navegadores convertem a string retornada para minúsculas automaticamente. Se você quiser comparar valores de endereço e fazê-lo funcionar em todos os navegadores, use o `.toLowerCase()` método para converter o valor em minúsculas.
{% endhint %}

## Verificar preço do gas

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

A função abaixo busca o preço atual do gas na rede principal do Ethereum e o imprime.

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

executeTask(async function () {
	// create an instance of the web3 provider to interface with Metamask
	const provider = createEthereumProvider()
	// Create the object that will handle the sending and receiving of RPC messages
	const requestManager = new RequestManager(provider)
	// Check the current gas price on the Ethereum network
	const gasPrice = await requestManager.eth_gasPrice()
	// log response
	console.log({ gasPrice })
})
```

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

## Importar um ABI de 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 o que elas retornam. 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 longas, pois 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 em outros arquivos de cena a partir daí. Também recomendamos manter todos os arquivos ABI em uma pasta separada da sua cena, chamada `/contracts`.

```ts
import { abi } from '../contracts/mana'
```

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

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

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

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

{% hint style="info" %}
**💡 Tip**: 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 lá e abrir a *functions* aba para ver a lista completa de funções suportadas e seus argumentos. Você pode até testar chamar as funções com diferentes parâmetros pela página web.
{% endhint %}

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

Por exemplo, se o conteúdo do arquivo ABI começa 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 *abi*, você deve instanciar vários objetos que permitirão usar as funções do contrato e conectar-se ao Metamask no navegador do jogador.

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

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

executeTask(async () => {
	// create an instance of the web3 provider to interface with Metamask
	const provider = createEthereumProvider()
	// Create the object that will handle the sending and receiving of RPC messages
	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" %}
**💡 Tip**: Para contratos que seguem o mesmo padrão, como ERC20 ou ERC721, você pode importar um único ABI genérico para todos. Em seguida, gera um único `ContractFactory` objeto com esse 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 facilmente chamar 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.isGuest) {
			return
		}

		// Execute 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 do contrato MANA em Ropsten e transfere 100 *MANA falso* para sua conta na rede de teste Ropsten.

### Outras funções

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

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

## Usando a rede de testes Ethereum

Enquanto testa sua cena, para evitar transferir MANA real ou outras moedas, você pode usar a *rede de teste Ethereum Sepolia* e transferir MANA de teste fake nessa rede.

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

Você deve adquirir Ether de Sepolia, que pode obter gratuitamente de várias faucets externas como [esta aqui](https://www.alchemy.com/faucets/ethereum-sepolia/).

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

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

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

{% hint style="info" %}
**💡 Tip**: Altere o parâmetro position para as coordenadas da sua cena, para carregar diretamente na sua cena.
{% endhint %}

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

Se precisar testar transações na Polygon Testnet e precisar ter MANA nessa testnet, será necessário trocar o MANA para essa rede após adquiri-lo em Sepolia. Para fazer bridge do MANA de Sepolia para a Polygon Testnet, visite sua [página de conta Decentraland em Sepolia](https://account.decentraland.zone/) e clique em ‘swap’ do lado do Ethereum MANA.

Ao executar uma pré-visualização no cliente web legado, de uma cena que usa uma das bibliotecas ethereum, você deve abrir a pré-visualização em uma janela de navegador separada, 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 através do [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 }',
})
```

## Contratos inteligentes da Decentraland

No link a seguir você pode encontrar uma lista de contratos inteligentes Ethereum relevantes para o ecossistema Decentraland. A lista inclui os contratos na mainnet assim como em outras redes de teste Ethereum.

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