メインコンテンツへスキップ

Documentation Index

Fetch the complete documentation index at: https://docs.qu.ai/llms.txt

Use this file to discover all available pages before exploring further.

はじめに

この記事では、HardhatとSolidityを使用してQuai Networkのチェーンにスマートコントラクトをデプロイする方法を説明します。

前提条件

Quaiでシングルチェーンスマートコントラクトをデプロイするには、いくつかのツールキットと依存関係が必要です。使用する依存関係の概要は以下の通りです:
NodeJSJavascript実行環境。LTSバージョンを使用してください。
hardhat-exampleQuai Network用のサンプルコントラクトとデプロイスクリプトを含むHardhatプロジェクト
Quais.jsQuai Networkと対話するためのJavaScriptライブラリ
@quai/hardhat-deploy-metadataコントラクトのメタデータをIPFSにプッシュするHardhatプラグイン。Quaiscanでの検証に使用します。
@openzeppelin/contractsサンプルのERC20およびERC721コントラクトで使用されるスマートコントラクトライブラリ。

環境設定

サンプルリポジトリのインストール

まず、hardhat-exampleリポジトリをクローンし、このチュートリアルで使用するSolidityディレクトリに移動して、npm経由で依存関係をインストールします。
git clone https://github.com/dominant-strategies/hardhat-example.git
cd hardhat-example/Solidity
npm install

スマートコントラクト

Solidity/ディレクトリには、contracts/ディレクトリ内に2つのサンプルコントラクトが含まれています:ERC20.solERC721.sol。両方のコントラクトはOpen Zeppelinライブラリから派生した実装です。 このチュートリアルではERC20.solサンプルコントラクトを使用しますが、独自のコントラクトを追加したり、他のライブラリのコントラクトを使用することもできます。
Quai Network EVMはSolidityバージョン0.8.20までをサポートしています。 より新しいバージョンのSolidityを使用すると、スマートコントラクトのデプロイ時にエラーが発生する可能性があります。

環境変数

hardhat-exampleリポジトリのルートには、トークンの詳細、秘密鍵、RPC URLを安全に管理するためのサンプル環境ファイル.env.distが含まれています。
.env.distファイルはテンプレートファイルであり、そのまま使用すべきではありません。.env.distファイルを新しい.envファイルにコピーする必要があります。このファイルはhardhat-exampleリポジトリのルートにあり、Solidity/ディレクトリの設定ファイルとして機能します。
次のコマンドを使用して、ルートの.env.distファイルをリポジトリルートの新しい.envファイルにコピーします:
cp ../.env.dist ../.env
.envファイルを開き、デプロイしたいコントラクトの秘密鍵、RPC URL、トークン引数を追加します。.envファイルは次のようになります:
.env
## サンプル環境ファイル - 必要に応じてすべての値を変更してください

# デプロイアドレス用の一意の秘密鍵
CYPRUS1_PK="0x0000000000000000000000000000000000000000000000000000000000000000" # 0x00で始まる公開鍵

# チェーンID(ローカル:1337、Orchardテストネット:15000、メインネット:9)
CHAIN_ID="15000"

# RPCエンドポイント
RPC_URL="https://orchard.rpc.quai.network"

# ERC20引数
ERC20_NAME="TestERC20"
ERC20_SYMBOL="TE20"
ERC20_INITIALSUPPLY=1000000

# ERC721引数
ERC721_NAME="TestERC721"
ERC721_SYMBOL="TE721"
ERC721_BASE_URI="ipfs://METADATA_CID/"
ERC721_MAX_TOKENS=1000
サンプルの.env.distOrchardテストネットを対象としているため、実際のQUAIを消費せずにデプロイできます。 メインネットにデプロイするには、CHAIN_ID9に、RPC_URLhttps://rpc.quai.networkに変更してください。
RPCエンドポイントに関する詳細情報は、ネットワークページで確認できます。 hardhat-exampleリポジトリは、単一のRPC URLのみを使用してネットワーク接続を設定するためにQuais SDKを使用します。SDKがネットワークプロバイダーを設定する方法の詳細については、SDKプロバイダーの例セクションをご覧ください。 秘密鍵とRPC URLを入力したら、hardhat.config.js内で安全に使用する準備が整いました。

Hardhat設定

Hardhatはhardhat.config.jsファイルを使用してスマートコントラクトのデプロイを設定します。設定ファイルでは、デプロイネットワーク、タスク、コンパイラーなどを定義できます。 hardhat-exampleには、Cyprus-1でスマートコントラクトをデプロイおよび検証するための設定が含まれた事前構築済みのhardhat.config.jsファイルがあります。
この設定ファイルのサンプルはhardhat-exampleリポジトリの一部として提供されています。
hardhat.config.js
/**
 * @type import('hardhat/config').HardhatUserConfig
 */

require('@nomicfoundation/hardhat-toolbox')
require('@quai/quais-upgrades')
require('@quai/hardhat-deploy-metadata')

const dotenv = require('dotenv')
dotenv.config({ path: '../.env' })

module.exports = {
  defaultNetwork: 'cyprus1',
  networks: {
    cyprus1: {
      url: process.env.RPC_URL,
      accounts: [process.env.CYPRUS1_PK],
      chainId: Number(process.env.CHAIN_ID),
    },
  },

  solidity: {
    compilers: [
      {
        version: '0.8.17',
        settings: {
          optimizer: { enabled: true, runs: 1000 },
          metadata: {
            bytecodeHash: 'ipfs',
            useLiteralContent: true,
          },
          evmVersion: 'london',
        },
      },
      {
        version: '0.8.20',
        settings: {
          optimizer: { enabled: true, runs: 1000 },
          metadata: {
            bytecodeHash: 'ipfs',
            useLiteralContent: true,
          },
          evmVersion: 'london',
        },
      },
    ],
  },

  paths: {
    sources: './contracts',
    cache: './cache',
    artifacts: './artifacts',
  },
  mocha: {
    timeout: 20000,
  },
}
Cyprus-1は現在Quai Networkで唯一アクティブなゾーンであるため、サンプル設定では単一の cyprus1ネットワークのみを定義しています。ゾーンエンドポイントの完全なリストについては、 ネットワークを参照してください。
metadata.bytecodeHash: 'ipfs'useLiteralContent: trueコンパイラー設定は、 @quai/hardhat-deploy-metadataが検証可能な出力を生成するために必要です。これらを削除すると、 Quaiscanでの検証が機能しなくなります。
コントラクトをデプロイする際、hardhat.config.js.envファイルから秘密鍵とRPC URLを取得します。solidityオブジェクトでSolidityバージョンとコンパイラー設定を指定することもできます。

デプロイと操作

1

Hardhatでコンパイル

Hardhatでのスマートコントラクトのコンパイルはシンプルで、CLIでnpxを使用して実行できます。contracts/ディレクトリ内のすべてのコントラクトを以下でコンパイルします:
npx hardhat compile
次のような出力が表示されます:
Downloading compiler 0.8.20

Compiled 2 Solidity files successfully
2

デプロイスクリプトの設定

scripts/ディレクトリ内には、ERC20とERC721コントラクトの両方のデプロイスクリプトがあります:deployERC20.jsdeployERC721.js。このチュートリアルでは、ERC20コントラクトをデプロイします。deployERC20.jsスクリプトは、hardhat.config.jsからネットワーク設定を、リポジトリルートの.envファイルからトークン引数を取得し、それらを使用してコントラクトをデプロイします。トークン引数はtokenArgs配列で使用されます:
const tokenArgs = [process.env.ERC20_NAME, process.env.ERC20_SYMBOL, quais.parseUnits(process.env.ERC20_INITIALSUPPLY)]
コントラクトがデプロイされる前に、スクリプトは@quai/hardhat-deploy-metadataプラグインを使用してコンパイル済みコントラクトのメタデータをIPFSにプッシュし、生成されたCIDを返します:
const { deployMetadata } = require("hardhat")
// ...
const ipfsHash = await deployMetadata.pushMetadataToIPFS("ERC20")
その後、CIDはContractFactoryの4番目の引数として渡され、デプロイされたバイトコードに埋め込まれます。Quaiscanは後でそのCIDを読み取り、検証のためにソースコードを取得します — これがないと、コントラクトはデプロイできても検証はできません。
const provider = new quais.JsonRpcProvider(hre.network.config.url, undefined, { usePathing: true })
const wallet = new quais.Wallet(hre.network.config.accounts[0], provider)
const ERC20 = new quais.ContractFactory(ERC20Json.abi, ERC20Json.bytecode, wallet, ipfsHash)
次のステップでコントラクトをデプロイするために、これらの概念を使用してトークン引数とネットワーク仕様を適切に変更します。
deployERC721.jsスクリプトも同じ構造に従いますが、異なるコントラクト引数と 異なるABI/バイトコードを使用します。デプロイしたい任意のコントラクトに対して この設定を複製できます。
3

コントラクトのデプロイ

デプロイスクリプトは、デプロイしたいネットワークを指定するための--networkフラグを取ります。サンプル設定ではcyprus1のみが定義されており、ここではそれを使用します。
npx hardhat run scripts/deployERC20.js --network cyprus1
次のような出力が表示されます:
File added with CID: QmPCoBa1bCFmRoTD7GuexJqBAy7pqg8J4b8B48q5DgxUEV
Original IPFS hash found in bytecode: QmPCoBa1bCFmRoTD7GuexJqBAy7pqg8J4b8B48q5DgxUEV
Metadata JSON for ERC20 saved to /.../hardhat-example/Solidity/metadata/ERC20_metadata.json
Transaction broadcasted: 0x235fdeb85db5b6cee8da9780e2246907e8342751849f5ce3514847a5dffd916f
Contract deployed to:  0x00735E9B2c731Fd3eCC8129a3653ACb99dF969cC
最初の行に出力されるCIDは、Quaiscanでコントラクトを検証するために必要なIPFSハッシュです — 保存してください。おめでとうございます!Quai NetworkにERC20トークンをデプロイしました!
ERC20.solERC721.solのサンプルコントラクトは、例示目的のための各トークンの基本的な実装です。 本番環境で使用する前に、特定のユースケースに合わせてこれらのコントラクトを変更することを強く推奨します。
4

コントラクトとの対話

Hardhatコンソールは現在、Quai Network上のスマートコントラクトとの対話をサポートしていません。コントラクトと対話するには、Quais SDKを使用してシンプルなスクリプトを設定できます。以下のスクリプトは、0x00735E9B2c731Fd3eCC8129a3653ACb99dF969cCにデプロイしたERC20トークンのContractインスタンスを設定し、トークンの名前、シンボル、総供給量を取得します。
getContractDetails.js
const quais = require('quais')
const ERC20Json = require('../artifacts/contracts/ERC20.sol/ERC20.json')

async function getContractDetails() {
  // プロバイダー、ウォレット、コントラクトファクトリーの設定
  const provider = new quais.JsonRpcProvider(hre.network.config.url, undefined, { usePathing: true })
  const wallet = new quais.Wallet(hre.network.config.accounts[0], provider)
  const ERC20 = new quais.Contract("0x00735E9B2c731Fd3eCC8129a3653ACb99dF969cC", ERC20Json.abi, wallet)

  const tokenName = await ERC20.name()
  const tokenSymbol = await ERC20.symbol()
  const tokenDecimals = await ERC20.decimals()
  const tokenTotalSupply = await ERC20.totalSupply()
}

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

まとめ

これで、シンプルなHardhatプロジェクトの作成、デプロイ、独自のスマートコントラクトとの対話に必要なすべてのツールが揃いました。 デプロイスクリプトがコントラクトのメタデータをIPFSにプッシュしたので、Quaiscanで検証できます — 次のステップについてはQuaiscanでのコントラクト検証を参照してください。