数字商品指南系列第三篇:编写智能合约并编译部署

文章目录

  • 前言
    • 警告
  • 完善项目结构
  • 编写合约代码
  • 编译合约
  • 部署合约
  • 总结
  • 捐赠渠道

前言

智能合约为数字藏品提供技术支持,它可以定义数字藏品的简称、全称、发行数量、铸造方法、版权税等等,所有关于数字藏品的现实信息都离不开智能合约。

这篇教程我们开始编写智能合约,智能合约标准我们使用的是ERC-721(非同质化代币),接着使用HardHat来编译,编译是为部署到区块链上做准备,最后我们会把智能合约部署到Rinkeby测试网络上。

警告

本指南仅供学习交流使用,不得用于违法用途,如果侵犯了国家法律,责任自负。

完善项目结构

为了让我们的项目看起来有迹可循,需要在我们的项目根目录下创建两个文件夹,一个文件夹存放智能合约代码,一个文件夹存放执行合约相关任务的脚本文件,使用cmd命令进入项目根目录,然后输入命令

mkdir contracts

按下回车键执行命令

mkdir scripts

按下回车键执行命令
contracts将存放合约代码文件,scripts将存放执行合约的脚本文件

编写合约代码

选择一款编辑器打开项目文件夹my-contract,在contracts文件夹下新建个文件,名字叫MyContract.sol,下边是我们的合约代码,我们使用了OpenZeppelin的ERC-721标准库,复制并粘贴到你的MyContract.sol文件

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

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract MyContract is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private currentTokenId;

    constructor() ERC721("OAXTOKEN", "OAX") {}

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

看起来有点难以理解?别慌,让我们一行接着一行看下去。

  • 第一行我们定义了使用的Solidity(智能合约语言)版本号。
  • 接下来从第4-6行引入了三个openzeppelin的关键类文件,来快速实现ERC-721的标准,而不需要我们再自己去一行一行的写合约代码。
    ERC721.sol,包含了实现以太坊ERC-721标准的所有方法,我们的合约将会继承它,这样就保证了我们的合约是有效的。
  • Counters.sol,提供计数器,只能递增或递减一次。我们的智能合约使用一个计数器来跟踪铸造的数字藏品总数,并在我们的新数字藏品上上设置唯一的ID。(使用智能合约创建的每个数字藏品都必须分配一个唯一的ID,我们的唯一ID仅由存在的NFT总数决定,例如,我们使用智能合约创建的第一个的ID为“1”,第二个的ID就是“2”,等等。)
  • ERC721URIStorage,为我们提供了公共方法setTokenURI来设置每个藏品对应的元数据信息,从而让我们的数字藏品有了现实意义,比如一张门票、一个视频、一张画。
  • 下边就是我们合约代码的正文了,只有一个计数器(currentTokenId),一个构造函数方法(constructor),和一个铸造方法(mintTo)。构造函数共有两个变量,第一个是我们数字藏品的全称(OAXTOKEN),第二个是简称(OAX),给你的数字藏品起一个你喜欢的全称和简称,改动这两项就可以。铸造方法也有两个变量,第一个是个以太坊地址,用以接收将要铸造成的藏品,第二个是元数据信息,一般的做法是设置一个网址,网址里存储信息,设置完成这两个参数后,会返回藏品的唯一ID给调用者。

在写完合约代码后,我们的项目结构会是这个样子
数字商品指南系列第三篇:编写智能合约并编译部署_第1张图片

编译合约

在编译合约前,请你确保按照第二篇教程已经完成所有配置,我们需要更新hardhat.config.js,代码如下,复制粘贴到你的文件里。

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

require('dotenv').config();
require("@nomiclabs/hardhat-ethers");
const { API_URL, PRIVATE_KEY } = process.env;

module.exports = {
  solidity: "0.8.1",
  defaultNetwork: "rinkeby",
  networks: {
    hardhat: {},
    rinkeby: {
      url: API_URL,
      accounts: [`0x${PRIVATE_KEY}`]
    },
    ethereum: {
      chainId: 1,
      url: API_URL,
      accounts: [`0x${PRIVATE_KEY}`]
    },
  },
}

通过设置配置项,我们定义了编译合约的solidity版本,区块链网络类型,接口地址和付费的地址私钥。
现在我们只需要执行编译命令就可以了,打开项目根目录my-contract,输入以下命令

npx hardhat compile

如果命令运行正常,会有如下提示

C:\Users\ThinkPad\my-contract>npx hardhat compile
Compiling 1 file with 0.8.1
Solidity compilation finished successfully

部署合约

最后一步就是把合约部署到区块链网络上,我们需要使用javascript写一个简单的部署脚本,然后使用HardHat运行它。
在scripts目录下,新建文件deploy.js,复制下边代码到文件中

async function main() {
    const [deployer] = await ethers.getSigners();
    const NFT = await ethers.getContractFactory("MyContract");
    await NFT.deploy();
    console.log('合约地址:',NFT.address);
}
main()
    .then(() => process.exit(0))
    .catch((error) => {
        console.error(error);
        process.exit(1);
    });

部署脚本将会从MyContract.sol拿到编译过的合约代码,然后部署到网络上,如果部署成功我们会看到部署后的合约地址。
在项目根目录下,使用HardHat执行部署脚本

npx hardhat --network rinkeby run scripts/deploy.js
C:\Users\ThinkPad\my-contract>npx hardhat --network rinkeby run scripts/deploy.js
合约地址: 0x116Ca6682A03547BffF8Fa8E12Efd301872a1383

复制合约地址到以太坊rinkeby区块浏览器去查看刚才我们部署的合约,如果可以查到恭喜你,顺利为你的数字藏品部署了智能合约。

总结

目前为止,我们完成了智能合约的编写、编译、部署,在下篇教程里我们会开始铸造我们的数字藏品,方法是通过调用合约的mintTo方法,与此同时使用IPFS(去中心化的文件存储)绑定元数据到每个铸造出的数字藏品。

捐赠渠道

本教程是由本人自发的项目,如果你要支持我,请通过支付宝发送口令红包,将口令发送到我的邮箱[email protected],捐赠仅凭个人意愿,感谢支持。

你可能感兴趣的:(数字藏品指南系列,智能合约,区块链,以太坊)