编写智能合约

上一篇文章已经完成了项目初始化 这篇文章开始编写 智能合约

在项目中新建两个文件夹 contracts 用于存放合约代码(Solidity 代码) scripts 用于存放 JavaScript 脚本文件

contracts 文件夹下新建 NFTContract.sol 的文件 添加以下内容

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract NFTContract is ERC721 {
  using Counters for Counters.Counter;
  Counters.Counter private currentTokenId;

  constructor() ERC721("NFTContract", "NFT") {}

  function mintTo(address recipient)
    public
    returns (uint256)
  {
    currentTokenId.increment();
    uint256 newItemId = currentTokenId.current();
    _safeMint(recipient, newItemId);
    return newItemId;
  }
}

代码中的 constructor() ERC721("NFTContract", "NFT") {} 传入了两个参数 第一个参数为 合约名称name) 第二个参数为 代币名称symbol

到这里一个最基本的 智能合约 就已经编写完成了

编译智能合约

在编译之前 需要一个配置文件存储一些关键配置信息

在项目中新建 .env 文件 内容如下

ALCHEMY_KEY = "Alchemy API 密钥"
ACCOUNT_PRIVATE_KEY = "钱包私钥"

获取 Alchemy API 密钥 可以查看这个链接 https://docs.alchemy.com/alchemy/introduction/getting-started

获取 钱包私钥 可以在 MetaMask 中点击 账户详情 -> 导出私钥 进行查看

注意:私钥是你的钱包关键信息 千万不要泄漏 一旦泄漏 你的账户就是在裸奔

配置信息填写好之后 还需要在 hardhat.config.js 中添加以下代码

/**
* @type import('hardhat/config').HardhatUserConfig
*/

require('dotenv').config();
require("@nomiclabs/hardhat-ethers");

const { ALCHEMY_KEY, ACCOUNT_PRIVATE_KEY } = process.env;

module.exports = {
   solidity: "0.8.1",
   defaultNetwork: "rinkeby",
   networks: {
    hardhat: {},
    rinkeby: {
      url: `https://eth-rinkeby.alchemyapi.io/v2/${ALCHEMY_KEY}`,
      accounts: [`0x${ACCOUNT_PRIVATE_KEY}`]
    },
    ethereum: {
      chainId: 1,
      url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}`,
      accounts: [`0x${ACCOUNT_PRIVATE_KEY}`]
    },
  },
}

添加完之后命令行执行命令进行编译

npx hardhat compile

也可以在 package.json 中的 scripts 内添加脚本

"compile": "npx hardhat compile"

然后在命令行中执行命令

npm run compile

如果一切顺利的话命令行会输出

Compiled 11 Solidity files successfully

代表编译成功 artifacts 文件夹就是编译的合约及依赖项 cache 是编译缓存文件夹

部署合约

合约编译成功后 就可以部署了 在部署之前 需要新建一个部署脚本 在 scripts 文件夹中新建 deploy.js 文件 添加以下内容

async function main() {

  // Get our account (as deployer) to verify that a minimum wallet balance is available
  const [deployer] = await ethers.getSigners();

  console.log(`Deploying contracts with the account: ${deployer.address}`);
  console.log(`Account balance: ${(await deployer.getBalance()).toString()}`);

  // Fetch the compiled contract using ethers.js
  const NFTContract = await ethers.getContractFactory("NFTContract");
  // calling deploy() will return an async Promise that we can await on 
  const contract = await NFTContract.deploy();

  console.log(`Contract deployed to address: ${contract.address}`);
}

main()
.then(() => process.exit(0))
.catch((error) => {
  console.error(error);
  process.exit(1);
});

部署脚本编写完成后在命令行执行命令进行部署

部署智能合约是需要支付 Gas Fee (矿工费)的 在公链上谨慎部署(以免浪费钱)

npx hardhat run scripts/deploy.js --network rinkeby

也可以在 package.json 中的 scripts 内添加脚本

"deploy:rinkeby": "npx hardhat run scripts/deploy.js --network rinkeby"

然后在命令行中执行命令

npm run deploy:rinkeby

执行完成后命令行会输出

Deploying contracts with the account: 你的钱包地址
Account balance: 你的钱包余额
Contract deployed to address: 智能合约地址

如果看到上面的内容 就代表已经部署成功了 可以在 Rinkeby Etherscan 上输入上面部署好的 智能合约 地址 进行查看

这只是一个部署演示 并不是真正的部署发布 如果要铸造NFT 还需要修改一些代码 下一篇文章再做详细介绍

本篇文章代码 Github 地址 https://github.com/stephenml/nft-contract/tree/day-01

最后修改日期: 2022年7月10日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。