文章目录

  • 手把手教你区块链java开发智能合约nft-第五篇(铸造第一个NFT)
  • 回顾
  • 部署NFT721
  • 铸造NFT
  • 根据tokenId查看NFT链上数据
  • 完整代码
  • [NFT721 相关智能合约源码下载](https://download.csdn.net/download/huangxuanheng/86260438)

手把手教你区块链java开发智能合约nft-第五篇(铸造第一个NFT)

回顾

初学区块链,那真叫一个痛苦并无助。如果没有人带你的话

今天写的这篇是在前面文章基础上写的,初学区块链的朋友建议先看我前面写的文章
手把手教你区块链java开发智能合约nft-第一篇
手把手教你区块链java开发智能合约nft-第二篇(部署第一个NFT智能合约)
手把手教你区块链java开发智能合约nft token-第三篇(部署token)
手把手教你区块链java开发智能合约nft(第四篇)-如何动态获取gasPrice和gasLimit?

部署NFT721

关于部署NFT721 ,可以参考之前的文章:
手把手教你区块链java开发智能合约nft-第二篇(部署第一个NFT智能合约)

部署完成后,将得到一个NFT721的智能合约地址:contractAddress,这个智能合约地址值需要保存好,待会铸造NFT时需要用到它

比如我在部署合约完成后,得到的contractAddress值为:0x1fc51bf18b49d29f7a40825914e8c68f4ce7b255

铸造NFT

铸造NFT也是比较简单的,直接调用NFT721 的方法mint 就可以了,主要难点是在对数据的签名上
直接上代码吧

 @Testpublic void mint() throws Exception {//NFT721合约地址String contractAddress="0x1fc51bf18b49d29f7a40825914e8c68f4ce7b255";String tokenId="2"; //上链的NFT idString tokenURI="/static/uploadQmVJoMsgcsCCz75ZHzup7e8boqhBz9R8SKYwKknFEWamzA.png"; //上链的tokenId对应的值//铸造NFT需要用到的私钥,在部署合约时指定的地址对应的私钥String miner="0x5369576889297382912123166219811286283737728368986117127236719812";TransactionManager transactionManager = getRawTransactionManager();ContractGasProvider contractGasProvider = getContractGasProvider();NFT721 nft721 = NFT721.load(contractAddress, web3j, transactionManager, contractGasProvider);Credentials credentials = getCredentials();ECKeyPair ecKeyPair = ECKeyPair.create(Numeric.hexStringToByteArray(miner));Type<BigInteger> tId = new Uint(new BigInteger(tokenId));String a = contractAddress + Numeric.cleanHexPrefix(TypeEncoder.encode(tId));a = Hash.sha3(a);byte[] b = Numeric.hexStringToByteArray(a);Sign.SignatureData data = Sign.signPrefixedMessage(b, ecKeyPair);ArrayList<NFT721.Fee> fees = Lists.newArrayList(new NFT721.Fee(credentials.getAddress(), BigInteger.valueOf(200)));TransactionReceipt transactionReceipt = nft721.mint(new BigInteger(tokenId), new BigInteger(data.getV()), data.getR(), data.getS(),fees, tokenURI).send();System.out.println("mint:hash::"+transactionReceipt.getTransactionHash());System.out.println("mint:getContractAddress::"+transactionReceipt.getContractAddress());}

关键代码说明:

  • 首先定义了一些传入的参数,这里当做局部变量定义出来
  • 加载智能合约NFT721对象,要用这个对象来调用mint铸造NFT
 NFT721 nft721 = NFT721.load(contractAddress, web3j, transactionManager, contractGasProvider);
  • 对上链数据进行签名
//利用签名账户对应的私钥对上链的tokenId等数据进行签名 ECKeyPair ecKeyPair = ECKeyPair.create(Numeric.hexStringToByteArray(miner));Type<BigInteger> tId = new Uint(new BigInteger(tokenId));String a = contractAddress + Numeric.cleanHexPrefix(TypeEncoder.encode(tId));a = Hash.sha3(a);byte[] b = Numeric.hexStringToByteArray(a);Sign.SignatureData data = Sign.signPrefixedMessage(b, ecKeyPair);
  • 铸造NFT
ArrayList<NFT721.Fee> fees = Lists.newArrayList(new NFT721.Fee(credentials.getAddress(), BigInteger.valueOf(200)));TransactionReceipt transactionReceipt = nft721.mint(new BigInteger(tokenId), new BigInteger(data.getV()), data.getR(), data.getS(),fees, tokenURI).send();

mint方法参数说明:
public RemoteFunctionCall mint(BigInteger tokenId, BigInteger v, byte[] r, byte[] s, List _fees, String tokenURI)

tokenId:上链的tokenId,或者可以理解为NFT的id,必须保证在链上唯一
v: 签名数据的v
r:签名数据的R
s:签名数据的S
_fees: (我也不太理解具体是什么)从字面上理解是费用信息,

Fee构造方法需要传入两个参数:
public Fee(String recipient, BigInteger value) {
super(new Address(recipient),
new Uint256(value));
this.recipient = recipient;
this.value = value;
}
从命名上看:
recipient : 接受者
value:费用

tokenURI:tokenURI,具体上链的数据,上链后可以通过tokenId查看的数据,一个tokenId需要指定一个tokenURI

执行完以上代码,没有报错的话,等一会就会铸造成功了
这样就完成了NFT的铸造了

根据tokenId查看NFT链上数据

@Testpublic void tokenURI() throws Exception {String contractAddress="0x1fc51bf18b49d29f7a40825914e8c68f4ce7b255";String tokenId="2";TransactionManager transactionManager = getRawTransactionManager();ContractGasProvider contractGasProvider = getContractGasProvider();NFT721 nft721 = NFT721.load(contractAddress, web3j, transactionManager, contractGasProvider);String tokenURI = nft721.tokenURI(new BigInteger(tokenId)).send();System.out.println("tokenURI::"+tokenURI);}

完整代码

package net.sandboxol.support.deploy.mint;import net.sandboxol.support.deploy.NFT721;import net.sandboxol.support.utils.Web3Util;import org.assertj.core.util.Lists;import org.junit.Test;import org.web3j.abi.TypeEncoder;import org.web3j.abi.datatypes.Type;import org.web3j.abi.datatypes.Uint;import org.web3j.crypto.Credentials;import org.web3j.crypto.ECKeyPair;import org.web3j.crypto.Hash;import org.web3j.crypto.Sign;import org.web3j.protocol.Web3j;import org.web3j.protocol.core.methods.response.TransactionReceipt;import org.web3j.protocol.http.HttpService;import org.web3j.tx.RawTransactionManager;import org.web3j.tx.TransactionManager;import org.web3j.tx.gas.ContractGasProvider;import org.web3j.tx.gas.StaticGasProvider;import org.web3j.utils.Numeric;import java.io.IOException;import java.math.BigInteger;import java.util.ArrayList;public class DeployMintTest {Web3j web3j = Web3j.build(new HttpService("http://192.168.159.101:8545/"));private String userId="214158";private String siteId="ishow";@Testpublic void mint() throws Exception {String contractAddress="0x1fc51bf18b49d29f7a40825914e8c68f4ce7b255";String tokenId="2";String tokenURI="/static/uploadQmVJoMsgcsCCz75ZHzup7e8boqhBz9R8SKYwKknFEWamzA.png";//私钥String miner="0x5369576889297382912123166219811286283737728368986117127236719812";TransactionManager transactionManager = getRawTransactionManager();ContractGasProvider contractGasProvider = getContractGasProvider();NFT721 nft721 = NFT721.load(contractAddress, web3j, transactionManager, contractGasProvider);Credentials credentials = getCredentials();ECKeyPair ecKeyPair = ECKeyPair.create(Numeric.hexStringToByteArray(miner));Type<BigInteger> tId = new Uint(new BigInteger(tokenId));String a = contractAddress + Numeric.cleanHexPrefix(TypeEncoder.encode(tId));a = Hash.sha3(a);byte[] b = Numeric.hexStringToByteArray(a);Sign.SignatureData data = Sign.signPrefixedMessage(b, ecKeyPair);ArrayList<NFT721.Fee> fees = Lists.newArrayList(new NFT721.Fee(credentials.getAddress(), BigInteger.valueOf(200)));TransactionReceipt transactionReceipt = nft721.mint(new BigInteger(tokenId), new BigInteger(data.getV()), data.getR(), data.getS(),fees, tokenURI).send();System.out.println("mint:hash::"+transactionReceipt.getTransactionHash());System.out.println("mint:getContractAddress::"+transactionReceipt.getContractAddress());}@Testpublic void tokenURI() throws Exception {String contractAddress="0x1fc51bf18b49d29f7a40825914e8c68f4ce7b255";String tokenId="1";TransactionManager transactionManager = getRawTransactionManager();ContractGasProvider contractGasProvider = getContractGasProvider();NFT721 nft721 = NFT721.load(contractAddress, web3j, transactionManager, contractGasProvider);String tokenURI = nft721.tokenURI(new BigInteger(tokenId)).send();System.out.println("tokenURI::"+tokenURI);}private Credentials getCredentials () {//这个Web3Util 是自己定义的工具,能根据userId和siteId生成Credentials 对象的工具,大家可以自己构造,我这个有其他依赖,不方便提供源码return Web3Util.getUserCredentials(userId,siteId);}private TransactionManager getRawTransactionManager() throws IOException {BigInteger chainId = web3j.ethChainId().send().getChainId();return new RawTransactionManager(web3j, getCredentials(),chainId.longValue());}private ContractGasProvider getContractGasProvider(){return new StaticGasProvider(BigInteger.valueOf(22_000_000_000l),BigInteger.valueOf(6_700_000l));}}

NFT721 相关智能合约源码下载