6.设置配置
创建一个新的空白Android项目。在主目录中,创建一个称为 apikey.properties 的文件。然后,我们将添加从前一步获得的值。
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=""
进行回顾:
- 我们通过运行 ganache 命令来获得 wallet_address 。
- 我们在运行
truffle migrate --network development
并从 1_deploy_contract .js e节。 - 运行 ganache 命令并获得生成的种子后,我们获得了种子。
在依赖项下的build.gradle(模块)中,添加_web3j _library。
// Add support for web3j
implementation 'org.web3j:core:4.8.7-android'
在 build.gradle.gradle file的defaultConfig部分中添加配置。
// Load configuration from the apikey.properties file
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'])
不要忘记通过将以下行添加到<application
标签中的AndroidManifest.xml文件中添加Internet权限。
<uses-permission android:name="android.permission.INTERNET" />
7.开发Android包装器
使用_web3j _library,我们可以将我们的固体文件转换为Java,以便我们调用已写入Solidity文件中的方法。
web3j generate truffle --truffle-json .\build\contracts\lemurNFT.json -o ..\android\app\src\main\java\ -p com.example.lemur
成功运行此命令后,将生成一个新的Java文件LemurNFT.java。将文件靠近 mainActivity.kt 文件。
8.创建UI
用户界面非常简单,我们有一个称为 mint 的按钮。单击按钮时,它在_mainactivity.kt 文件中运行 mintnft _功能。
<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" />
整个activity_main.xml文件看起来像这样:
<?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>
该应用应该看起来像这样:
9.添加全局变量
在您的 mainActivity.kt 中添加以下变量为全局。
// inside of any of your application's code
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;
此代码从我们的_apikey.properties _file和buildConfig文件加载所有配置文件。
我们还有一个凭证变量,以后将在以后初始初始化,并且可以通过任何函数在全球范围内访问。
10.加载凭据
在 mainActivity.kt 文件中添加以下代码行。
/***
* Create credentials from a seed.
*/
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)
}
这会生成一个键盘(公共和私钥)来签署我们的交易。
11.加载凭据
在mainActivity.kt文件中添加以下代码。
/***
* Create credentials from a seed.
*/
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)
}
这会生成一个键盘(公共和私钥)来签署我们的交易。
12.显示回应
将交易发布到区块链后,我们需要显示响应。因此,我们将使用吐司通知。将以下代码添加到mainActivity.kt文件中。
/**
* Display the response as a toast notification.
*/
private fun showResponse(response: String){
val duration = Toast.LENGTH_LONG;
val toast = Toast.makeText(applicationContext, response, duration);
toast.show();
}
该函数接入字符串并在烤面包通知中显示。
13.薄荷nft
此处,mINTNFT函数与主用户界面中的按钮绑定。单击按钮后:
- 凭据将从 loadCredentials()函数中加载。
- 将创建一个新实例 web3j 实例,该实例将用于连接到节点。
- 然后,我们加载智能合约是 lemurnft 合同,并提供合同地址,Websocket连接,凭据和交易的气体。
- 然后,我们将智能合约功能称为薄荷nft,提供钱包地址以铸造NFT,然后 tokenuri 。。
- 然后,我们使用 log.e *和 *来记录响应,还可以通过吐司通知显示响应。
/**
* Mint an nft when the mint button is clicked.
*/
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;
}
MainActivity.kt然后看起来像这样:
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() {
// inside of any of your application's code
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)
}
/**
* Mint an nft when the mint button is clicked.
*/
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;
}
/**
* Display the response as a toast notification.
*/
private fun showResponse(response: String){
val duration = Toast.LENGTH_LONG;
val toast = Toast.makeText(applicationContext, response, duration);
toast.show();
}
/**
* Create a web3j web socket instance from the web socket url.
*/
private fun createWeb3j(): Web3j {
val webSocketService = WebSocketService(webSocketUrl, true)
try {
webSocketService.connect()
} catch (e: ConnectException) {
e.printStackTrace()
}
return Web3j.build(webSocketService)
}
/***
* Create credentials from a seed.
*/
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)
}
}
单击“薄荷”按钮时,一旦编译并运行了应用程序,吐司通知应带有交易收据。
14.结论
恭喜,您已经能够创建NFT智能合约并与Android应用程序进行交互。