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:
Web3j: A biblioteca leve de Java e Android para integração com clientes Ethereum. https://www.web3labs.com/web3j-sdk
Android Studio: Ambiente oficial de desenvolvimento integrado para o sistema operacional Android do Google. https://developer.android.com/studio
Truffle: Ferramenta inteligente de desenvolvimento de contratos. https://trufflesuite.com
Ngrok: Um serviço de proxy reverso para a front do seu serviço da web. https://ngrok.com/
1). Crie o contrato inteligente
Crie um novo projeto de truffle executando.
truffle init
Instale o openzeppelin dentro do projeto truffle executando.
npm install --save-dev @openzeppelin/contracts
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;
}
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)
}
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
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
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
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
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
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
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:
{
"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"
}
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.
Latest comments (0)