WEB3DEV

Cover image for Cunhando uma NFT em um aplicativo Android ( Parte 1 )
Adriano P. Araujo
Adriano P. Araujo

Posted on • Atualizado em

Cunhando uma NFT em um aplicativo Android ( Parte 1 )

Introdução

Não fungível significa que algo é único e não pode ser substituído por outra coisa. Blockchains como Ethereum, polygon e Iota agem como uma verdadeira fonte e de ajuda para quem mantém e negocia NFTs.

As NFTs têm vários casos de uso, desde música, moda, jogos, artigos de luxo, metaverso, cadeia de suprimentos e vendas de ingressos. A Nike fez parceria recentemente com a Polygon para lançar uma plataforma web3 para NFTs na forma de sapatos digitais https://decrypt.co/114494/nike-swoosh-web3-platform-polygon-nfts

A maioria dos blogs online demonstra como cunhar uma NFT usando um aplicativo da web. Neste blog, cunharemos uma NFT por meio de um aplicativo Android. O aplicativo móvel será parcialmente Java e parcialmente Kotlin.

O código de trabalho completo pode ser encontrado aqui

Pré-requisito

Os requisitos são:

1). Crie o contrato inteligente

Crie um novo projeto de truffle executando.


truffle init



Enter fullscreen mode Exit fullscreen mode

Instale o openzeppelin dentro do projeto truffle executando.


npm install --save-dev @openzeppelin/contracts

Enter fullscreen mode Exit fullscreen mode

Crie um contrato inteligente no diretório contract / directory lemurNFT.sol.


// SPDX-License-Identifier: MIT

pragma solidity >=0.4.22 <0.9.0;



import "openzeppelin-solidity/contracts/token/ERC721/ERC721.sol";

import "openzeppelin-solidity/contracts/utils/Counters.sol";

import "openzeppelin-solidity/contracts/token/ERC721/extensions/RRERC721URIStorage.sol";



contract lemurNFT is ERC721URIStorage {

    using Counters for Counters.Counter;

    Counters.Counter private _tokenIds;



    constructor() public ERC721("lemurNFT", "LMR") {}



    function mintNFT(address recipient, string memory tokenURI)

        public

        returns (uint256)

    {

        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();

        _mint(recipient, newItemId);

        _setTokenURI(newItemId, tokenURI);



        return newItemId;

    }

Enter fullscreen mode Exit fullscreen mode

No contrato inteligente:

  • _tokenIds.increment ( ): Aumenta o contador em 1, permitindo que o código gere um ID de token exclusivo.

  • uint256 newItemId = _tokenIds.current ( ) atribui o número da contagem atual a uma nova instância de _tokenIds nomeado newItemId.

  • _safeMint ( destinatário, newItemId ) cunha  newItemId e atribui ao destinatário ( um endereço ).

  • _setTokenURI ( newItemId, tokenURI ) define tokenURI do arquivo de metadados da NFTs, que criamos anteriormente.

2). Configurar o ambiente de desenvolvimento

Configure o arquivo truffle-config.js para usar o ambiente de desenvolvimento adicionando ou comentando a seção a seguir. Verifique se os WebSockets estão ativados. Isso ocorre porque nos conectaremos ao nosso nó via WebSockets.


 development: {

      host: "127.0.0.1", // Localhost (default: none)

      port: 8545, // Standard Ethereum port (default: none)

      network_id: "*", // Any network (default: none)

      websocket: true, // Enable EventEmitter interface for web3 (default: false)

    }

Enter fullscreen mode Exit fullscreen mode

3). Implante o contrato inteligente

Para compilar o contrato inteligente, execute

truffle compile

A saída deve parecer algo semelhante a


Compiling your contracts...

===========================

> Compiling .\contracts\Migrations.sol

> Compiling .\contracts\lemurNFT.sol

> Compiling openzeppelin-solidity\contracts\token\ERC721\ERC721.sol

> Compiling openzeppelin-solidity\contracts\token\ERC721\IERC721.sol

> Compiling openzeppelin-solidity\contracts\token\ERC721\IERC721Receiver.sol

> Compiling openzeppelin-solidity\contracts\token\ERC721\extensions\ERC721URIStorage.sol

> Compiling openzeppelin-solidity\contracts\token\ERC721\extensions\IERC721Metadata.sol

> Compiling openzeppelin-solidity\contracts\utils\Address.sol

> Compiling openzeppelin-solidity\contracts\utils\Context.sol

> Compiling openzeppelin-solidity\contracts\utils\Counters.sol

> Compiling openzeppelin-solidity\contracts\utils\Strings.sol

> Compiling openzeppelin-solidity\contracts\utils\introspection\ERC165.sol

> Compiling openzeppelin-solidity\contracts\utils\introspection\IERC165.sol

> Compilation warnings encountered:

    Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient.

  --> project:/contracts/lemurNFT.sol:12:5:

   |

12 |     constructor() public ERC721("lemurNFT", "LMR") {}

   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> Artifacts written to C:\Users\peter\Documents\GitHub\lemur-nft\contract\build\contracts

> Compiled successfully using:

   - solc: 0.8.13+commit.abaa5c0e.Emscripten.clang

Enter fullscreen mode Exit fullscreen mode

Execute um nó local executando

ganache

A saída deve parecer algo semelhante a


ganache v7.5.0 (@ganache/cli: 0.6.0, @ganache/core: 0.6.0)

Starting RPC server

Available Accounts

==================

(0) 0x42703e1F2CCB08583088D96d71d4549Be08b52a7 (1000 ETH)

(1) 0x859e7f120E751C505EB14C942A192eC3448a12a1 (1000 ETH)

(2) 0x2864E9c62dE39c44a97866D31546069fD86DF71E (1000 ETH)

(3) 0x656d2d16C6ad06677A9A87e105e786E9f0420d5c (1000 ETH)

(4) 0x70BDc8926bb41e3a778e3F812Fe18db181aa2602 (1000 ETH)

(5) 0x05A2e3a72a63D2e0A85c7259E3aD6A5b9773cb79 (1000 ETH)

(6) 0x135A6788B85973890d11AdED97a76BfD5acd9F37 (1000 ETH)

(7) 0x19fCd2F3F957b9761e52C5583A14CE2669bbF257 (1000 ETH)

(8) 0xaf47CA6B33E5b895E68D937fDb2CaEEB4e462845 (1000 ETH)

(9) 0x61cDEbBCc8579560A79aaA41936fc553E22615E2 (1000 ETH)

Private Keys

==================

(0) 0xbea5ebe59d051534239ec8e81018b9d2f8458eee5864584d9d520a0c4307de90

(1) 0x5c0fd2fc115d1ab0c8e0ab3f367ac68dcb6e8e9c037a7de791cfba3d50dff993

(2) 0x3d0f2dc97eb7203213c42363f2f2fad34aa4bd0d1029347e72dfad41f900bc2c

(3) 0xa697dc1f7e4d08e899bdbdef17b303048d425bb7bfa712653071f4270fef6a7b

(4) 0x9dd1cccefa2486212ac11cd451d36de3a956ae2be9d4740783b55f94053fa837

(5) 0x1044bba3f188578d08a5c36aae4d4f0bacbfaa60e31e2b96791e5c2b099278a6

(6) 0x02314898ed8983c1c3598e74757bb3e933d4506e4d238706938479f756da8b94

(7) 0x7a7988d32c9a7ab50a9d4d4a9bf5ddf05db49cf2a0f5e196b5fb076d183f4bec

(8) 0xaac1f5cfc3c8ad7c2ed6eb843e0412668e00b4f87e82341bd6090239acb561fe

(9) 0x5b072abfa5a17d7a88fe456867789d0ba97c625e1c969485921765301c916b90

HD Wallet

==================

Mnemonic:      truth manual elephant border predict castle payment suspect mimic insect wish acoustic

Base HD Path:  m/44'/60'/0'/0/{account_index}

Default Gas Price

==================

2000000000

BlockGas Limit

==================

30000000

Call Gas Limit

==================

50000000

Chain Id

==================

1337

RPC Listening on 127.0.0.1:8545

Enter fullscreen mode Exit fullscreen mode

Mantenha o processo em execução. Armazene a semente em um local seguro, ela será necessária para o aplicativo Android  mais tarde. Não use as chaves ou sementes privadas em nenhum outro lugar ou corre o risco de ser hackeado.

O mnemônico  (truth manual elephant border predict castle payment suspect mimic insect wish acoustic) será usado ao configurar a configuração do android.

Também usaremos o primeiro endereço público 0x42703e1F2CCB08583088D96d71d4549Be08b52a7 como o endereço da carteira.

Execute o comando de desenvolvimento para implantar o contrato inteligente.


truffle migrate --network development

Enter fullscreen mode Exit fullscreen mode

Se for bem-sucedido, deve mostrar


Compiling your contracts...

===========================

> Compiling .\contracts\Migrations.sol

> Compiling .\contracts\lemurNFT.sol

> Compiling openzeppelin-solidity\contracts\token\ERC721\ERC721.sol

> Compiling openzeppelin-solidity\contracts\token\ERC721\IERC721.sol

> Compiling openzeppelin-solidity\contracts\token\ERC721\IERC721Receiver.sol

> Compiling openzeppelin-solidity\contracts\token\ERC721\extensions\ERC721URIStorage.sol

> Compiling openzeppelin-solidity\contracts\token\ERC721\extensions\IERC721Metadata.sol

> Compiling openzeppelin-solidity\contracts\utils\Address.sol

> Compiling openzeppelin-solidity\contracts\utils\Context.sol

> Compiling openzeppelin-solidity\contracts\utils\Counters.sol

> Compiling openzeppelin-solidity\contracts\utils\Strings.sol

> Compiling openzeppelin-solidity\contracts\utils\introspection\ERC165.sol

> Compiling openzeppelin-solidity\contracts\utils\introspection\IERC165.sol

> Compilation warnings encountered:

    Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient.

  --> project:/contracts/lemurNFT.sol:12:5:

   |

12 |     constructor() public ERC721("lemurNFT", "LMR") {}

   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> Artifacts written to C:\Users\peter\Documents\GitHub\lemur-nft\contract\build\contracts

> Compiled successfully using:

   - solc: 0.8.13+commit.abaa5c0e.Emscripten.clang

Starting migrations...

======================

> Network name:    'development'

> Network id:      1668618749782

> Block gas limit: 30000000 (0x1c9c380)

1_deploy_contract.js

====================

   Deploying 'lemurNFT'

   --------------------

   > transaction hash:    0xbe14c78e8b59c002e2537a3cbc9a4f616fbbddafd94f4722a59c719d42137860

   > Blocks: 0            Seconds: 0

   > contract address:    0x129Ff5b9D7C128527F3Be5ca5fb4F2E7A991482d

   > block number:        1

   > block timestamp:     1668618761

   > account:             0x7b2D85916C1fc56BBa4706DF0cE1D86532fB3839

   > balance:             999.99153599275

   > gas used:            2507854 (0x26444e)

   > gas price:           3.375 gwei

   > value sent:          0 ETH

   > total cost:          0.00846400725 ETH

   > Saving artifacts

   -------------------------------------

   > Total cost:       0.00846400725 ETH

1_initial_migration.js

======================

   Deploying 'Migrations'

   ----------------------

   > transaction hash:    0x7d4912cdabd080e6d49d0b244a88f86de933f61d491c76ef2847c133626e2d11

   > Blocks: 0            Seconds: 0

   > contract address:    0x12365fE3BA0F866A6E392BD3614B4322D73244C3

   > block number:        2

   > block timestamp:     1668618762

   > account:             0x7b2D85916C1fc56BBa4706DF0cE1D86532fB3839

   > balance:             999.990714509168638856

   > gas used:            250154 (0x3d12a)

   > gas price:           3.283911436 gwei

   > value sent:          0 ETH

   > total cost:          0.000821483581361144 ETH

   > Saving migration to chain.

   > Saving artifacts

   -------------------------------------

   > Total cost:     0.000821483581361144 ETH

Summary

=======

> Total deployments:   2

> Final cost:          0.009285490831361144 ETH

Enter fullscreen mode Exit fullscreen mode

Certifique-se de armazenar o endereço do contrato ( neste exemplo 0x129Ff5b9D7C128527F3Be5ca5fb4F2E7A991482d), localizado em 1_deploy_contracts pois usaremos isso como o endereço do contrato ao configurar as configurações para o android.

4). Configurando um WebSocket

Antes de executar esta etapa, verifique se o ganache está em execução. Depois que o ganache estiver em execução, execute o comando:


ngrok http 8545

Enter fullscreen mode Exit fullscreen mode

Ngrok atuará como um proxy de avanço. Ele expõe a rede local 127.0.0.1: 8085 e fornece um endereço da Web que você pode usar para conectar seu aplicativo Android. A resposta deve ficar assim:


ngrok

Add Okta or Azure to protect your ngrok dashboard with SSO: <https://ngrok.com/dashSSO>

Session Status:         online

Account:                P.Okwara (Plan: Free)

Version:                3.1.0

Region:                 United States (us)

Latency:                265ms

Web Interface:          http://127.0.0.1:4040

Forwarding:             <https://550b-105-163-1-231.ngrok.io> -> http://localhost:8545

Connections:            ttl opn rt1 rt5 p50 p90 0 0 0.00 0.00 0.00 0.00

Enter fullscreen mode Exit fullscreen mode

Usaremos o endereço de encaminhamento https://550b-105-163-1-231.ngrok.io como o URL do websocket. Ao adicionar à configuração, alteraremos https: para wss para que o URL que usaremos no final seja assim:

wss: // 550b-105-163-1-231.ngrok.io

5). Configure os metadados da sua NFT usando IPFS

Nossa função de contrato inteligente lemurNFT recebe um parâmetro tokenURI que deve ser resolvido para um documento JSON descrevendo os metadados das NFTs, que é realmente o que dá vida à NFT, permitindo que ela tenha propriedades configuráveis, como nome, descrição, imagem e outros atributos.

O Sistema de Arquivos Interplanetários ( IPFS ) é um protocolo descentralizado e uma rede ponto a ponto para armazenar e compartilhar dados em um sistema de arquivos distribuído.

Vamos usar Pinata, uma API e kit de ferramentas convenientes do IPFS, para armazenar nossos ativos e metadados NFT e garantir que nossa NFT seja realmente descentralizada. Se você não possui uma conta Pinata, crie em uma conta gratuita aqui.

Depois de criar uma conta:

  • Navegue até o botão Pinata Upload no canto superior direito

  • Carregue uma imagem no pinata - este será o ativo da imagem da sua NFT. Sinta-se à vontade para nomear o ativo que você desejar

  • Após o upload, na parte superior da página, deve haver um pop-up verde que permita visualizar o hash do seu upload --- > Copie esse hashcode. Você pode visualizar seu upload em: https://gateway.pinata.cloud/ipfs/https://gateway.pinata.cloud/ipfs/<

No diretório raiz, crie um novo arquivo chamado nft-metadata.json e adicione o seguinte código json:

nft-metadata.json


{

    "attributes" : [ {

      "trait_type" : "Breed",

      "value" : "Maltipoo"

    }, {

      "trait_type" : "Eye color",

      "value" : "Mocha"

    } ],

    "description" : "The world's most adorable and sensitive pup.",

    "image" : "https://gateway.pinata.cloud/ipfs/QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb",

    "name" : "Ramses"

}

Enter fullscreen mode Exit fullscreen mode

Sinta-se à vontade para alterar os dados no json. Você pode adicionar ou remover atributos. Mais importante ainda, verifique se o campo de imagem aponta para o local da sua imagem IPFS, caso contrário, sua NFT não incluirá uma foto.

Depois de terminar de editar o arquivo json, salve-o e faça o upload para Pinata, seguindo as mesmas etapas que fizemos para fazer o upload da imagem.

Lembre-se do metadata.json você enviou para Pinata? Obtenha o hashcode da Pinata. Usaremos esse hash e o URL para o próximo passo.


Este artigo foi escrito por Peter Okwara e traduzido por Adriano P. de Araujo. O original em inglês pode ser encontrado aqui.

Top comments (0)