> ## 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.

# Solidityでデプロイ

> Quai Networkでシンプルなシングルチェーンスマートコントラクトをデプロイするためのガイド

## はじめに

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

## 前提条件

Quaiでシングルチェーンスマートコントラクトをデプロイするには、いくつかのツールキットと依存関係が必要です。使用する依存関係の概要は以下の通りです：

|                                                                                                  |                                                          |
| ------------------------------------------------------------------------------------------------ | -------------------------------------------------------- |
| [**NodeJS**](https://nodejs.org/en/download/)                                                    | Javascript実行環境。LTSバージョンを使用してください。                        |
| [**hardhat-example**](https://github.com/dominant-strategies/hardhat-example)                    | Quai Network用のサンプルコントラクトとデプロイスクリプトを含むHardhatプロジェクト       |
| [**Quais.js**](https://www.npmjs.com/package/quais)                                              | Quai Networkと対話するためのJavaScriptライブラリ                      |
| [**@quai/hardhat-deploy-metadata**](https://www.npmjs.com/package/@quai/hardhat-deploy-metadata) | コントラクトのメタデータをIPFSにプッシュするHardhatプラグイン。Quaiscanでの検証に使用します。 |
| [**@openzeppelin/contracts**](https://www.npmjs.com/package/@openzeppelin/contracts)             | サンプルのERC20およびERC721コントラクトで使用されるスマートコントラクトライブラリ。          |

## 環境設定

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

まず、`hardhat-example`リポジトリをクローンし、このチュートリアルで使用する`Solidity`ディレクトリに移動して、`npm`経由で依存関係をインストールします。

```bash theme={null}
git clone https://github.com/dominant-strategies/hardhat-example.git
cd hardhat-example/Solidity
npm install
```

### スマートコントラクト

`Solidity/`ディレクトリには、`contracts/`ディレクトリ内に2つのサンプルコントラクトが含まれています：`ERC20.sol`と`ERC721.sol`。両方のコントラクトは[Open Zeppelinライブラリ](https://www.openzeppelin.com/contracts)から派生した実装です。

このチュートリアルでは`ERC20.sol`サンプルコントラクトを使用しますが、独自のコントラクトを追加したり、他のライブラリのコントラクトを使用することもできます。

<Warning>
  Quai Network EVMはSolidityバージョン0.8.20までをサポートしています。
  より新しいバージョンのSolidityを使用すると、スマートコントラクトのデプロイ時にエラーが発生する可能性があります。
</Warning>

### 環境変数

`hardhat-example`リポジトリのルートには、トークンの詳細、秘密鍵、RPC URLを安全に管理するためのサンプル環境ファイル`.env.dist`が含まれています。

<Note>
  `.env.dist`ファイルはテンプレートファイルであり、そのまま使用すべきではありません。`.env.dist`ファイルを新しい`.env`ファイルにコピーする必要があります。

  このファイルは`hardhat-example`リポジトリのルートにあり、`Solidity/`ディレクトリの設定ファイルとして機能します。
</Note>

次のコマンドを使用して、ルートの`.env.dist`ファイルをリポジトリルートの新しい`.env`ファイルにコピーします：

```bash theme={null}
cp ../.env.dist ../.env
```

`.env`ファイルを開き、デプロイしたいコントラクトの秘密鍵、RPC URL、トークン引数を追加します。`.env`ファイルは次のようになります：

```bash .env theme={null}
## サンプル環境ファイル - 必要に応じてすべての値を変更してください

# デプロイアドレス用の一意の秘密鍵
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
```

<Note>
  サンプルの`.env.dist`は**Orchardテストネット**を対象としているため、実際のQUAIを消費せずにデプロイできます。
  メインネットにデプロイするには、`CHAIN_ID`を`9`に、`RPC_URL`を`https://rpc.quai.network`に変更してください。
</Note>

RPCエンドポイントに関する詳細情報は、[ネットワーク](/jp/build/networks)ページで確認できます。

`hardhat-example`リポジトリは、単一のRPC URLのみを使用してネットワーク接続を設定するために[Quais SDK](/jp/sdk/introduction)を使用します。SDKがネットワークプロバイダーを設定する方法の詳細については、[SDKプロバイダーの例](/jp/sdk/static/provider)セクションをご覧ください。

秘密鍵とRPC URLを入力したら、`hardhat.config.js`内で安全に使用する準備が整いました。

### Hardhat設定

Hardhatは`hardhat.config.js`ファイルを使用してスマートコントラクトのデプロイを設定します。設定ファイルでは、デプロイネットワーク、タスク、コンパイラーなどを定義できます。

`hardhat-example`には、Cyprus-1でスマートコントラクトをデプロイおよび検証するための設定が含まれた事前構築済みの`hardhat.config.js`ファイルがあります。

<Accordion title="Hardhat設定ファイルのサンプル" icon="file" iconType="solid">
  この設定ファイルのサンプルは`hardhat-example`リポジトリの一部として提供されています。

  ```javascript hardhat.config.js theme={null}
  /**
   * @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,
    },
  }
  ```

  <Info>
    Cyprus-1は現在Quai Networkで唯一アクティブなゾーンであるため、サンプル設定では単一の
    `cyprus1`ネットワークのみを定義しています。ゾーンエンドポイントの完全なリストについては、
    [ネットワーク](/jp/build/networks)を参照してください。
  </Info>

  <Warning>
    `metadata.bytecodeHash: 'ipfs'`と`useLiteralContent: true`コンパイラー設定は、
    `@quai/hardhat-deploy-metadata`が検証可能な出力を生成するために必要です。これらを削除すると、
    Quaiscanでの検証が機能しなくなります。
  </Warning>
</Accordion>

コントラクトをデプロイする際、`hardhat.config.js`は`.env`ファイルから秘密鍵とRPC URLを取得します。`solidity`オブジェクトでSolidityバージョンとコンパイラー設定を指定することもできます。

## デプロイと操作

<Steps>
  <Step title="Hardhatでコンパイル">
    Hardhatでのスマートコントラクトのコンパイルはシンプルで、CLIで`npx`を使用して実行できます。

    `contracts/`ディレクトリ内のすべてのコントラクトを以下でコンパイルします：

    ```bash theme={null}
    npx hardhat compile
    ```

    次のような出力が表示されます：

    ```bash theme={null}
    Downloading compiler 0.8.20

    Compiled 2 Solidity files successfully
    ```
  </Step>

  <Step title="デプロイスクリプトの設定">
    `scripts/`ディレクトリ内には、ERC20とERC721コントラクトの両方のデプロイスクリプトがあります：`deployERC20.js`と`deployERC721.js`。このチュートリアルでは、ERC20コントラクトをデプロイします。

    `deployERC20.js`スクリプトは、`hardhat.config.js`からネットワーク設定を、リポジトリルートの`.env`ファイルからトークン引数を取得し、それらを使用してコントラクトをデプロイします。

    トークン引数は`tokenArgs`配列で使用されます：

    ```js theme={null}
    const tokenArgs = [process.env.ERC20_NAME, process.env.ERC20_SYMBOL, quais.parseUnits(process.env.ERC20_INITIALSUPPLY)]
    ```

    コントラクトがデプロイされる前に、スクリプトは`@quai/hardhat-deploy-metadata`プラグインを使用してコンパイル済みコントラクトのメタデータをIPFSにプッシュし、生成されたCIDを返します：

    ```js theme={null}
    const { deployMetadata } = require("hardhat")
    // ...
    const ipfsHash = await deployMetadata.pushMetadataToIPFS("ERC20")
    ```

    その後、CIDは`ContractFactory`の4番目の引数として渡され、デプロイされたバイトコードに埋め込まれます。Quaiscanは後でそのCIDを読み取り、検証のためにソースコードを取得します — これがないと、コントラクトはデプロイできても検証はできません。

    ```js theme={null}
    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)
    ```

    次のステップでコントラクトをデプロイするために、これらの概念を使用してトークン引数とネットワーク仕様を適切に変更します。

    <Tip>
      `deployERC721.js`スクリプトも同じ構造に従いますが、異なるコントラクト引数と
      異なるABI/バイトコードを使用します。デプロイしたい任意のコントラクトに対して
      この設定を複製できます。
    </Tip>
  </Step>

  <Step title="コントラクトのデプロイ">
    デプロイスクリプトは、デプロイしたいネットワークを指定するための`--network`フラグを取ります。サンプル設定では`cyprus1`のみが定義されており、ここではそれを使用します。

    ```bash theme={null}
    npx hardhat run scripts/deployERC20.js --network cyprus1
    ```

    次のような出力が表示されます：

    ```bash theme={null}
    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トークンをデプロイしました！

    <Warning>
      `ERC20.sol`と`ERC721.sol`のサンプルコントラクトは、例示目的のための各トークンの基本的な実装です。
      本番環境で使用する前に、特定のユースケースに合わせてこれらのコントラクトを変更することを強く推奨します。
    </Warning>
  </Step>

  <Step title="コントラクトとの対話">
    Hardhatコンソールは現在、Quai Network上のスマートコントラクトとの対話をサポートしていません。

    コントラクトと対話するには、[Quais SDK](/jp/sdk/static/contract)を使用してシンプルなスクリプトを設定できます。以下のスクリプトは、`0x00735E9B2c731Fd3eCC8129a3653ACb99dF969cC`にデプロイしたERC20トークンの[Contract](/jp/sdk/content/classes/Contract)インスタンスを設定し、トークンの名前、シンボル、総供給量を取得します。

    ```javascript getContractDetails.js theme={null}
    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)
      })
    ```
  </Step>
</Steps>

## まとめ

これで、シンプルなHardhatプロジェクトの作成、デプロイ、独自のスマートコントラクトとの対話に必要なすべてのツールが揃いました。

デプロイスクリプトがコントラクトのメタデータをIPFSにプッシュしたので、Quaiscanで検証できます — 次のステップについては[Quaiscanでのコントラクト検証](/jp/guides/development/verifycontract)を参照してください。
