6. Configure a configuração
Crie um projeto android em branco. Dentro do diretório inicial, crie um arquivo chamado apikey.properties. Em seguida, adicionaremos os valores obtidos nas etapas anteriores.
WALLET_ADDRESS="0x42703e1F2CCB08583088D96d71d4549Be08b52a7"
CONTRACT_ADDRESS="0x129Ff5b9D7C128527F3Be5ca5fb4F2E7A991482d"
WEB_SOCKET_URL="[wss://550b-105-163-1-231.ngrok.io](https://550b-105-163-1-231.ngrok.io)"
SEED="truth manual elephant border predict castle payment suspect mimic insect wish acoustic"
TOKEN_URI=""
Para uma recapitulação:
Obtivemos o WALLET_ADDRESS pegando a primeira chave pública após executar o comando ganache.
Adquirimos o CONTRACT_ADDRESS após rodarmos o
truffle migrate --network development
e pegamos o endereço do contrato da seção 1_deploy_contract.js.Obtivemos as SEMENTES após executarmos o comando ganache e assim, a semente gerada.
Dentro do build.gradle ( module ), em dependências, adicione a biblioteca web3j.
//Adiciona suporte para web3j
implementation 'org.web3j:core:4.8.7-android'
Adicione as configurações dentro da seção defaultConfig do arquivo build.gradle.
// Carrega a configuração do arquivo apikey.properties
buildConfigField("String", "WALLET_ADDRESS", apikeyProperties['WALLET_ADDRESS'])
buildConfigField("String", "CONTRACT_ADDRESS", apikeyProperties['CONTRACT_ADDRESS'])
buildConfigField("String", "WEB_SOCKET_URL", apikeyProperties['WEB_SOCKET_URL'])
buildConfigField("String", "SEED", apikeyProperties['SEED'])
buildConfigField("String", "TOKEN_URI", apikeyProperties['TOKEN_URI'])
Não se esqueça de adicionar permissões de internet dentro do arquivo AndroidManifest.xml adicionando a linha abaixo a tag <application
.
<uses-permission android:name="android.permission.INTERNET" />
7). Desenvolva o invólucro android
Usando a biblioteca web3j, podemos converter nosso arquivo solidity em um arquivo java para poder chamar os métodos que escrevemos no arquivo solidity.
web3j generate truffle --truffle-json .\build\contracts\lemurNFT.json -o ..\android\app\src\main\java\ -p com.example.lemur
Depois de executar este comando com sucesso, um novo arquivo java LemurNFT.java será gerado. Coloque o arquivo perto do arquivo MainActivity.kt.
8). Crie a interface do usuário
A interface do usuário é bem simples, temos um botão chamado MINT. Quando o botão é clicado, ele executa a função mintNFT no arquivo MainActivity.kt.
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="mintNft"
android:text="@string/button_text"
tools:layout_editor_absoluteX="161dp"
tools:layout_editor_absoluteY="407dp" />
O arquivo activity_main.xml inteiro se parece com isso:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LemurNFT"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="mintNft"
android:text="@string/button_text"
tools:layout_editor_absoluteX="161dp"
tools:layout_editor_absoluteY="407dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
O aplicativo deve ficar assim:
9). Adicionando variáveis globais
No seu arquivo MainActivity.kt adicione as seguintes variáveis como sendo globais.
// dentro de qualquer código da sua aplicação
var walletAddress: String = BuildConfig.WALLET_ADDRESS;
var contractAddress: String = BuildConfig.CONTRACT_ADDRESS;
var webSocketUrl: String = BuildConfig.WEB_SOCKET_URL;
var seed: String = BuildConfig.SEED;
var tokenUri: String = BuildConfig.TOKEN_URI;
private lateinit var credentials: Credentials;
Este código carrega todos os arquivos de configuração do nosso arquivo apikey.properties e do arquivo BuildConfig.
Também temos uma variável de credenciais que será inicializada posteriormente e que é globalmente acessível por qualquer função.
10). Carregue as credenciais
Dentro do arquivo MainActivity.kt adicione a seguinte linha de código.
/***
*Cria as credenciais à partir de uma semente
*/
fun loadCredentials(){
val masterKeypair = Bip32ECKeyPair.generateKeyPair(MnemonicUtils.generateSeed(seed, ""))
val path = intArrayOf(44 or HARDENED_BIT, 60 or HARDENED_BIT, HARDENED_BIT, 0, 0)
val x = Bip32ECKeyPair.deriveKeyPair(masterKeypair, path)
this.credentials = Credentials.create(x)
}
Isso gera um par de chaves (uma chave pública e outra privada), para assinar nossas transações.
11). Carregue as credenciais
Dentro do arquivo MainActivity.kt adicione a seguinte linha de código.
/***
*Crie as credenciais à partir de uma semente
*/
fun loadCredentials(){
val masterKeypair = Bip32ECKeyPair.generateKeyPair(MnemonicUtils.generateSeed(seed, ""))
val path = intArrayOf(44 or HARDENED_BIT, 60 or HARDENED_BIT, HARDENED_BIT, 0, 0)
val x = Bip32ECKeyPair.deriveKeyPair(masterKeypair, path)
this.credentials = Credentials.create(x)
}
Isso gera um par de chaves (uma chave pública e outra privada), para assinar nossas transações.
12). Mostrar a resposta
Precisamos mostrar a resposta depois de postar a transação na blockchain. Com isso, usaremos um alerta de notificação. Adicione o seguinte código ao arquivo MainActivity.kt.
/**
* Exibe a resposta como um alerta de notificação.
*/
private fun showResponse(response: String){
val duration = Toast.LENGTH_LONG;
val toast = Toast.makeText(applicationContext, response, duration);
toast.show();
}
A função pega uma sequência e a exibe em um alerta de notificação .
13). Cunhe um NFT
Aqui, a função mintNft está vinculada a um botão na interface principal do usuário. Depois que o botão é clicado:
As credenciais serão carregadas da função loadCredentials ( ).
Uma nova instância de web3j será criada, a qual será usada para se conectar ao nó.
Em seguida, carregamos o contrato inteligente, que é o contrato LemurNFT e fornecemos o endereço do contrato, a conexão WebSocket, as credenciais e o gas para as transações.
Em seguida, chamamos a função de contrato inteligente para cunhar um NFT, fornecendo o endereço da carteira para cunhar um NFT e o tokenURI.
Em seguida, efetuamos logout da resposta usando Log.e e também exibimos a resposta através de um alerta de notificação.
/**
* Cunha um nft quando o botão mint é clicado.
*/
fun mintNft(view: View) {
try {
loadCredentials();
val web3j: Web3j = createWeb3j()
val nft: LemurNFT = LemurNFT.load(contractAddress, web3j, credentials, DefaultGasProvider())
val transactionReceipt: TransactionReceipt = nft.mintNFT(walletAddress, tokenUri).send()
Log.e("Response", transactionReceipt.toString());
showResponse(transactionReceipt.toString());
} catch (e: Exception){
e.printStackTrace();
}
return;
}
O MainActivity.kt ficará assim:
package com.example.lemur
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import org.web3j.crypto.Bip32ECKeyPair
import org.web3j.crypto.Bip32ECKeyPair.HARDENED_BIT
import org.web3j.crypto.Credentials
import org.web3j.crypto.MnemonicUtils
import org.web3j.protocol.Web3j
import org.web3j.protocol.core.DefaultBlockParameterName
import org.web3j.protocol.core.methods.response.EthGetBalance
import org.web3j.protocol.core.methods.response.TransactionReceipt
import org.web3j.protocol.websocket.WebSocketService
import org.web3j.tx.gas.DefaultGasProvider
import java.math.BigInteger
import java.net.ConnectException
class MainActivity : AppCompatActivity() {
// dentro de qualquer parte do código da sua aplicação
var walletAddress: String = BuildConfig.WALLET_ADDRESS;
var contractAddress: String = BuildConfig.CONTRACT_ADDRESS;
var webSocketUrl: String = BuildConfig.WEB_SOCKET_URL;
var seed: String = BuildConfig.SEED;
var tokenUri: String = BuildConfig.TOKEN_URI;
private lateinit var credentials: Credentials;
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
/**
* Cunha um nft quando o botão mint é clicado.
*/
fun mintNft(view: View) {
try {
loadCredentials();
val web3j: Web3j = createWeb3j()
val nft: LemurNFT = LemurNFT.load(contractAddress, web3j, credentials, DefaultGasProvider())
val transactionReceipt: TransactionReceipt = nft.mintNFT(walletAddress, tokenUri).send()
Log.e("Response", transactionReceipt.toString());
showResponse(transactionReceipt.toString());
} catch (e: Exception){
e.printStackTrace();
}
return;
}
/**
* Exibe a resposta como um alerta de notificação.
.
*/
private fun showResponse(response: String){
val duration = Toast.LENGTH_LONG;
val toast = Toast.makeText(applicationContext, response, duration);
toast.show();
}
/**
* Cria uma instância web socket web3j à partir do url web socket.
*/
private fun createWeb3j(): Web3j {
val webSocketService = WebSocketService(webSocketUrl, true)
try {
webSocketService.connect()
} catch (e: ConnectException) {
e.printStackTrace()
}
return Web3j.build(webSocketService)
}
/***
* Cria as credenciais à partir de uma semente .
*/
private fun loadCredentials(){
val masterKeypair = Bip32ECKeyPair.generateKeyPair(MnemonicUtils.generateSeed(seed, ""))
val path = intArrayOf(44 or HARDENED_BIT, 60 or HARDENED_BIT, HARDENED_BIT, 0, 0)
val x = Bip32ECKeyPair.deriveKeyPair(masterKeypair, path)
this.credentials = Credentials.create(x)
}
}
Quando você clica no botão mint, depois de compilar e executar o aplicativo, um alerta de notificação deve aparecer com um recibo de transação.
14). Conclusão
Parabéns, você conseguiu criar um contrato inteligente NFT e interagir com ele a partir de um aplicativo Android.
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)