修改智能合约进行NFT铸造
上一篇文章已经完成了一个简单的部署演示 如果需要进行NFT铸造的话 还需要再编写一些代码进行改进我们的 智能合约
重命名 .env
文件为 .env.development
并再新建一个 .env.production
的文件 用来区分 测试链
和 公链
的配置
.env.development
和.env.production
中的配置方式和之前的.env
一样 为了方便描述 后面统称为env
指的就是这两个配置文件
修改 package.json
中的 scripts
内的脚本为
"compile:rinkeby": "NODE_ENV=development npx hardhat compile",
"deploy:rinkeby": "NODE_ENV=development npx hardhat run scripts/deploy.js --network rinkeby"
并再添加下公链对应的脚本 完整的内容为
将 hardhat.config.js
中的 require('dotenv').config();
改为
require('dotenv').config({ path: `.env.${process.env.NODE_ENV}` });
这样就可以动态的获取当前要执行的环境变量了
以上内容修改完之后 编译和部署命令将变更为
# 编译rinkeby测试链合约
npm run compile:rinkeby
# 部署rinkeby测试链合约
npm run deploy:rinkeby
在 env
中添加一个配置 NETWORK
表示要部署的网络 .env.development
就填 rinkeby
.env.production
就填 homestead
例如
NETWORK = "rinkeby"
至于为什么这样填可以看下文档 https://docs.ethers.io/ethers.js/v3.0/html/api-providers.html
然后在 scripts
文件夹中新建 helpers.js
文件 添加以下内容
const { ethers } = require("ethers");
// Helper method for fetching environment variables from .env
function getEnvVariable(key) {
if (process.env[key]) {
return process.env[key];
}
throw `${key} is not defined and no default value was provided`;
}
// Helper method for fetching a connection provider to the Ethereum network
function getProvider() {
return ethers.getDefaultProvider(getEnvVariable("NETWORK"), {
alchemy: getEnvVariable("ALCHEMY_KEY"),
});
}
// Helper method for fetching a wallet account using an environment variable for the PK
function getAccount() {
return new ethers.Wallet(getEnvVariable("ACCOUNT_PRIVATE_KEY"), getProvider());
}
module.exports = {
getEnvVariable,
getProvider,
getAccount,
}
这个文件提供了3个函数 getEnvVariable
根据 key
获取配置信息 OpenSea
文档 中 是有两个参数的 可以给一个默认值 我们这里不需要 因为我们已经用 NODE_ENV
环境变量区分了配置信息
getProvider
获取一个连接以太坊网络的提供者
getAccount
检查钱包账户信息
修改 scripts
文件夹中的deploy.js
文件为
const { task } = require("hardhat/config");
const { getAccount } = require("./helpers");
task("check-balance", "Prints out the balance of your account").setAction(async function (taskArguments, hre) {
const account = getAccount();
console.log(`Account balance for ${account.address}: ${await account.getBalance()}`);
});
task("deploy", "Deploys the NFTContract.sol contract").setAction(async function (taskArguments, hre) {
const NFTContractFactory = await hre.ethers.getContractFactory("NFTContract", getAccount());
const contract = await NFTContractFactory.deploy();
console.log(`Contract deployed to address: ${contract.address}`);
});
这里创建了两个 Hardhat
的 task
用来检查我们的账户信息和部署 智能合约
了
然后将 scripts
文件夹中的deploy.js
引入到 hardhat.config.js
中
require("./scripts/deploy.js");
可以在命令行运行一下以下命令 验证 task
是否创建成功
NODE_ENV=development npx hardhat
如果没有报错的话 应该就是添加成功了 下面的输出信息中可以找到我们添加的两个 task
然后可以使用 我们创建的 task
进行操作
查看 账户信息
NODE_ENV=development npx hardhat check-balance
部署 智能合约
NODE_ENV=development npx hardhat deploy
顺便将这些命令添加到 package.json
中的 scripts
内的脚本里吧
因为我们将部署
智能合约
的操作已经做成了task
所以之前的部署脚本也要做下相应的修改 顺便也添加下部署到公链上的脚本
"compile:rinkeby": "NODE_ENV=development npx hardhat compile",
"hardhat:rinkeby": "NODE_ENV=development npx hardhat",
"check-balance:rinkeby": "NODE_ENV=development npx hardhat check-balance",
"deploy:rinkeby": "NODE_ENV=development npx hardhat deploy",
"compile:ethereum": "NODE_ENV=production npx hardhat compile",
"hardhat:ethereum": "NODE_ENV=production npx hardhat",
"check-balance:ethereum": "NODE_ENV=production npx hardhat check-balance",
"deploy:ethereum": "NODE_ENV=production npx hardhat deploy"
compile:xxx
编译指定网络的 智能合约
hardhat:xxx
获取指定网络的 Hardhat task
check-balance:xxx
检查指定网络的钱包账户信息 deploy:xxx
部署指定网络的 智能合约
上面的步骤都完成后 就可以在命令行运行以下命令 在 Rinkeby
测试链上部署我们的 智能合约
了
记得重新编译一下 执行下编译命令 再部署即可
npm run deploy:rinkeby
部署完成后命令行会输出一条类似下面的消息
Contract deployed to address: 智能合约地址
上面的 智能合约
地址记得保存下来 后面需要使用 直接放到 env
中即可
NFT_CONTRACT_ADDRESS = "你刚部署的智能合约地址"
合约部署好了之后 我们就可以开始铸造(mint)我们的 NFT
了
在 scripts
文件夹中的helpers.js
文件中添加一个函数 getContract
完整的 helpers.js
文件内容如下
const { ethers } = require("ethers");
const { getContractAt } = require("@nomiclabs/hardhat-ethers/internal/helpers");
// Helper method for fetching environment variables from .env
function getEnvVariable(key) {
if (process.env[key]) {
return process.env[key];
}
throw `${key} is not defined and no default value was provided`;
}
// Helper method for fetching a connection provider to the Ethereum network
function getProvider() {
return ethers.getDefaultProvider(getEnvVariable("NETWORK"), {
alchemy: getEnvVariable("ALCHEMY_KEY"),
});
}
// Helper method for fetching a wallet account using an environment variable for the PK
function getAccount() {
return new ethers.Wallet(getEnvVariable("ACCOUNT_PRIVATE_KEY"), getProvider());
}
// Helper method for fetching a contract instance at a given address
function getContract(contractName, hre) {
const account = getAccount();
return getContractAt(hre, contractName, getEnvVariable("NFT_CONTRACT_ADDRESS"), account);
}
module.exports = {
getEnvVariable,
getProvider,
getAccount,
getContract,
}
然后在 scripts
文件夹中新建 mint.js
文件 添加以下内容
const { task } = require("hardhat/config");
const { getContract } = require("./helpers");
task("mint", "Mints from the NFT contract").addParam("address", "The address to receive a token").setAction(async function (taskArguments, hre) {
const contract = await getContract("NFTContract", hre);
const transactionResponse = await contract.mintTo(taskArguments.address, {
gasLimit: 500_000,
});
console.log(`Transaction Hash: ${transactionResponse.hash}`);
});
这里创建了一个 Hardhat
的 task
用来铸造(mint)NFT
其中的 gasLimit
指的是铸造(mint)时消耗 gas
的上限单位 值越大 费用越高 但也不能太小 太小的话可能会铸造失败(搬运费不够了 得加钱)
这里可以直接搜索下具体的含义(我没找到官方的文档 所以就不贴地址了)
然后将 scripts
文件夹中的mint.js
引入到 hardhat.config.js
中
require("./scripts/mint.js");
添加完成后 可以使用 npm run hardhat:rinkeby
查看下 task
是否添加成功
全部都完成后 就可以在命令行中使用下面的命令 进行铸造(mint)NFT
了 (需要支付 Gas Fee
(矿工费))
NODE_ENV=development npx hardhat mint --address 你的钱包地址
不出意外的话 命令行会输出类似以下信息 就代表铸造(mint)成功了
Transaction Hash: 此次铸造(mint)的交易哈希值
可以在 Rinkeby Etherscan 上输入上面的交易哈希值 进行查看交易明细
也可以将这条命令添加到 package.json
中的 scripts
内的脚本里(公链上铸造(mint)的脚本的也添加下)
"mint:rinkeby": "NODE_ENV=development npx hardhat mint --address",
"mint:ethereum": "NODE_ENV=production npx hardhat mint --address"
命令行运行下面的命令就可以在对应网络上进行铸造(mint)了
npm run mint:xxx --address 你的钱包地址
铸造完成后 可以在 OpenSea
的 测试网 进行查看你铸造(mint)的 NFT
打开后你会发现 图片是空的 因为我们还没有跟 原数据(metadata )进行关联 而且现在也无法让玩家进行自己铸造(mint) 后面的文章再做详细介绍吧
本篇文章代码 Github
地址 https://github.com/stephenml/nft-contract/tree/day-02
留言