Polygonal Mind
  • Home
  • Metaverse Builder
  • CryptoAvatars
  • MegaCube
  • Blog
  • Decentraland
  • Projects
  • Assets

Blog

Transacciones de MANA en Decentraland

5/11/2020

0 Comments

 
English
Objetivo

Esta es una guía corta enfocada a aprender a programar con Typescript una transacción de MANA en Decentraland.
Recursos

  • Decentraland SDK
  • Basic DCL project
  • Metamask extension (solo para test)
Transacciones de MANA en Decentraland
Documentación oficial:

https://docs.decentraland.org/blockchain-integration/scene-blockchain-operations/
Librerías e imports al proyecto:

Para esto necesitarás instalar en tu proyecto de Typescript la libreria eth-connect para hacer de interfaz con los contratos de Ethereum y poder llamar a sus funciones.
npm install eth-connect
Además, necesitarás importar las siguientes funciones al archivo:

getUserAccount para obtener la dirección de Ethereum del usuario.

getProvider para crear una instancia del proveedor web3 a la interfaz de Metamask.
​
Ambos, getUserAccount y getProvider, son proporcionados por el SDK de Decentraland.
import { getProvider } from '@decentraland/web3-provider'
import { getUserAccount } from '@decentraland/EthereumController'
import * as EthConnect from '../node_modules/eth-connect/esm'
Para que estas librerías funcionen en la previsualización de DCL en modo localhost, necesitarás pegar &ENABLE_WEB3 a la URL.
​
Ejemplo:
​http://192.168.0.112:8000/?SCENE_DEBUG_PANEL&position=12%2C44&ENABLE_WEB3
Antes de empezar:

Para poder realizar un pago mediante MANA necesitas varias cosas...
La dirección de Ethereum a pagar el MANA, esta es la dirección que recibirá el MANA de los pagos de los usuarios:
 Ejemplo: const PAYMENT_ADDRESS ="0x4tU......8dY"
La cantidad de MANA que el usuario pagará.
 Ejemplo: const MANA_PAYMENT = 10
La dirección del contrato de MANA:
const MANA_ADDRESS = "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942"
La dirección del contrato de MANA falso (opcional), solo si quieres primero probar transacciones con dinero falso (MANA):
const FAKE_MANA_ADDRESS = "0x2a8fd99c19271f4f04b1b7b9c4f7cf264b626edb"
MANA contract ABI:
https://etherscan.io/address/0x0f5d2fb29fb7d3cfee444a200298f468908cc942#code
Crea un archivo vacío en tu proyecto, "/contracts/mana.ts" y pega el MANA ABI en export const abi, o pega directamente el contenido del siguiente archivo.
  • Ocultar
  • Mostrar
<
>
export const abi = [{"constant":true,"inputs":[],"name":"mintingFinished","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"finishMinting","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[],"name":"MintFinished","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}
Contrato de MANA ABI falso (opcional)
  • Ocultar
  • Mostrar
<
>
​export const abi = [
{
constant: true,
inputs: [],
name: 'mintingFinished',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'name',
outputs: [
{
name: '',
type: 'string'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_spender',
type: 'address'
},
{
name: '_value',
type: 'uint256'
}
],
name: 'approve',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'totalSupply',
outputs: [
{
name: '',
type: 'uint256'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_from',
type: 'address'
},
{
name: '_to',
type: 'address'
},
{
name: '_value',
type: 'uint256'
}
],
name: 'transferFrom',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'decimals',
outputs: [
{
name: '',
type: 'uint8'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [],
name: 'unpause',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_to',
type: 'address'
},
{
name: '_amount',
type: 'uint256'
}
],
name: 'mint',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_value',
type: 'uint256'
}
],
name: 'burn',
outputs: [],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'paused',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [
{
name: '_owner',
type: 'address'
}
],
name: 'balanceOf',
outputs: [
{
name: 'balance',
type: 'uint256'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [],
name: 'finishMinting',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [],
name: 'pause',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'owner',
outputs: [
{
name: '',
type: 'address'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [],
name: 'symbol',
outputs: [
{
name: '',
type: 'string'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: '_to',
type: 'address'
},
{
name: '_value',
type: 'uint256'
}
],
name: 'transfer',
outputs: [
{
name: '',
type: 'bool'
}
],
payable: false,
type: 'function'
},
{
constant: true,
inputs: [
{
name: '_owner',
type: 'address'
},
{
name: '_spender',
type: 'address'
}
],
name: 'allowance',
outputs: [
{
name: 'remaining',
type: 'uint256'
}
],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: 'to',
type: 'address'
},
{
name: 'amount',
type: 'uint256'
}
],
name: 'setBalance',
outputs: [],
payable: false,
type: 'function'
},
{
constant: false,
inputs: [
{
name: 'newOwner',
type: 'address'
}
],
name: 'transferOwnership',
outputs: [],
payable: false,
type: 'function'
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: 'to',
type: 'address'
},
{
indexed: false,
name: 'amount',
type: 'uint256'
}
],
name: 'Mint',
type: 'event'
},
{
anonymous: false,
inputs: [],
name: 'MintFinished',
type: 'event'
},
{
anonymous: false,
inputs: [],
name: 'Pause',
type: 'event'
},
{
anonymous: false,
inputs: [],
name: 'Unpause',
type: 'event'
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: 'burner',
type: 'address'
},
{
indexed: false,
name: 'value',
type: 'uint256'
}
],
name: 'Burn',
type: 'event'
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: 'owner',
type: 'address'
},
{
indexed: true,
name: 'spender',
type: 'address'
},
{
indexed: false,
name: 'value',
type: 'uint256'
}
],
name: 'Approval',
type: 'event'
},
{
anonymous: false,
inputs: [
{
indexed: true,
name: 'from',
type: 'address'
},
{
indexed: true,
name: 'to',
type: 'address'
},
{
indexed: false,
name: 'value',
type: 'uint256'
}
],
name: 'Transfer',
type: 'event'
}
]
Código

Ahora que ya tenemos recopilada toda la información y las librerías instaladas es hora de desarrollar el código.
Importa las funciones que necesites al principio del archivo.
import { getProvider } from '@decentraland/web3-provider'
import { getUserAccount } from '@decentraland/EthereumController'
import * as EthConnect from '../node_modules/eth-connect/esm'
Importa el MANA ABI (o el falso MANA ABI para hacer pruebas)
import { abi } from './contracts/mana'
Ahora ya puedes crear una función de pago y llamarla a uso cuando quieras hacer que el usuario realice la transacción. 
const PAYMENT_ADDRESS ="0x4tU......8dY"
const MANA_ADDRESS = "0x0F5D2fB29fb7d3CFeE444a200298f468908cC942"
const MANA_PAYMENT = 10
function payment(callback = function(error?, result?){}) {
  executeTask(async () => {
    try {
      const provider = await getProvider()
      const requestManager = new EthConnect.RequestManager(provider)

      const factory = new EthConnect.ContractFactory(requestManager, abi)
      const contract = (await factory.at(
        MANA_ADDRESS
      )) as any
      const address = await getUserAccount()

      const res = await contract.transfer(
         PAYMENT_ADDRESS, MANA_PAYMENT*1000000000000000000,
         { from: address }
      )
    } catch (error) {
      callback(error)
      log(error.toString())
    }
  })
Cuando esta función es llamada, Metamask abrirá una ventana emergente pidiendo la confirmación del pago, si ocurriere algun problema con el pago, durante el pago, o el usuario rechazara este pago, la función payment() capturara un error. Si lo deseas puedes poner tu propia función para gestionar el error.
payment(function(error, result){
if (!error) {
//Payment success
}
else{
//Payment fail
}
})
Pruebas con pagos mediante MANA falso

Antes de que hagas funcionar tu código por primera vez tal vez quieras probarlo primero con MANA falso y Ethereum falso. Es una buena idea para comprobar que todo el código y su funcionalidad están funcionando correctamente y no perder MANA real en el proceso de creación.
Primero de todo necesitas cambiar tu tipo de red en Metamask al modo Ropsten Test Network.
MetaMask Ropsten Test Network
Segundo, necesitas obtener gratuitamente Ether y MANA falso en la red Ropsten.
Falso Ethereum: 
https://faucet.ropsten.be/
Falso MANA: 
https://faucet.decentraland.today/
MetaMask con Ethereum y MANA falso
Por último, necesitas cambiar la dirección de contrato de MANA colocada en el código al igual que cambiar el MANA ABI por los falsos.
import { abi } from './contracts/fakemana'
const MANA_ADDRESS = "0x2a8fd99c19271f4f04b1b7b9c4f7cf264b626edb"
Con estos cambios las pruebas en los pagos de MANA se harán bajo la Ropsten Test Network, y se enviarán a la PAYMENT_ADDRESS de la misma red también.

Picture
Alex Picaxo
PROGRAMADOR
Videogame programmer, love developing cool stuff. Always searching for new interesting stories.
LinkedIn
0 Comments



Leave a Reply.

    Categories

    All
    Blender
    CryptoAvatars
    Decentraland
    Decentraland En Español
    Maya
    Metaverse
    Mixamo
    Morphite
    Substance Painter
    The Sandbox
    Totally Reliable Delivery Service
    Unity 3D
    Updates
    Vrchat

    Archives

    March 2022
    July 2021
    June 2021
    May 2021
    April 2021
    March 2021
    February 2021
    January 2021
    December 2020
    October 2020
    August 2020
    July 2020
    June 2020
    May 2020
    April 2020
    March 2020
    February 2020
    December 2019
    October 2019
    September 2019
    August 2019
    June 2019
    May 2019
    February 2019
    January 2019
    December 2018
    November 2018
    October 2018
    September 2016

    Picture
Home
Projects
Assets

Picture
Crypto
Friendly
Picture

Subscribe to get some 💚 in your inbox once in a while.

Follow us and your visit will never be forgotten!
Picture
Picture
Picture

 © 2015-2022 POLYGONAL MIND LTD. ALL RIGHTS RESERVED.
  • Home
  • Metaverse Builder
  • CryptoAvatars
  • MegaCube
  • Blog
  • Decentraland
  • Projects
  • Assets