🔨

Ginco One Platformを使ってスマコンをデプロイしてみよう!

2024/09/21に公開

はじめに

みなさん、こんにちは!

今回は、Ginco 社が提供しているブロックチェーン用の API エンドポイントサービスを使ってスマコンをデプロイしてみましたのでその内容を共有したいと思います!

制限がありますが、今は無料で使えるようになっています!

Ginco 社について

Ginco 社はウォレットやインデクサーなど Web3 アプリ開発に必須となる Web3 インフラ機能を提供している会社です。

https://ginco.co.jp/company/

先日国際的なセキュリティ認証の証として知られる SOC2 Type-Ⅱ を取得されたことが発表されてたりしています。

https://prtimes.jp/main/html/rd/p/000000164.000031033.html

インドにも会社を設立したりしている勢いのある会社です!

https://prtimes.jp/main/html/rd/p/000000146.000031033.html

Progmat や Chainalysis 社とも協業を発表しています。

https://prtimes.jp/main/html/rd/p/000000110.000036656.html

https://prtimes.jp/main/html/rd/p/000000159.000031033.html

テックブログも非常に面白い記事ばかりなのでおすすめです。

個人的には Kubernetes を使ったブロックチェーンノード運用 の記事が面白かったです!

https://tech.ginco.io/post/ginco-engineer-meetup-2018-kubernetes/

他にもオンラインウェビナーや月次のレポートを配信していたりと情報発信も積極的に行っています!

https://peatix.com/user/14098075

Ginco One Platform を使ってスマコンをデプロイしてみた!

Ginco 社は今年に入って Alchemy のようにブロックチェーンネットワークにアクセスするための API エンドポイントを提供してくれるポータルサイトを展開しています。

利用制限がありますが、 Alchemy で使っているみたいにメールアドレスでユーザー登録した後に無料で API エンドポイントを使うことができます!!

今回はその API エンドポイントを使ってスマコンをデプロイしてみたのでその時の記録を共有していきたいと思います!!

ソースコードは以下に格納されています!!

https://github.com/mashharuki/Ginco-One-Platform-Sample

まずは以下のサイトにアクセスしてユーザー登録を行います!!

https://console.cloud.ginco.com/nodes/api

その後、 Create API Key ボタンを押して API キーを登録します!!

すると以下の画面のようにネットワーク毎にエンドポイントアクセス用の URL が表示されるのでこの値を控えておきます!!

ではこの値を控えたら GitHub のリポジトリを自分の環境にクローンしてきます!

git clone https://github.com/mashharuki/Ginco-One-Platform-Sample

セットアップ

セットアップの方法は README.mdファイルにも記載されていますが、 まず .envファイルを作成して以下 2 つの値を埋めます。

GINCO_API_KEY には先ほど控えた値を貼り付けてください!!

PRIVATE_KEY=""
GINCO_API_KEY=""

次に必要なライブラリをインストールします!!

yarn

これで準備 OK です!!

動かしてみよう!

以下のコマンドを打っていけばもろもろ機能を試せます!!

今回は hardhat を使っていますが、 0.8.27の最新バージョンを使っていたり、 ignitionviem も使っています!!

  • compile

    このコマンドでスマートコントラクトをコンパイルできます。

    yarn compile
    
  • test

    このコマンドでスマートコントラクトをテストできます。

    yarn test
    
  • deploy contract

    以下のコマンドで Ethereum のテストネット (holesky) にスマートコントラクトをデプロイできます!!

    yarn deploy:Lock --network holesky
    

    今回は、 iginition を使っています!

    import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
    import { parseEther } from "viem";
    
    const JAN_1ST_2030 = 1893456000;
    const ONE_GWEI: bigint = parseEther("0.001");
    
    const LockModule = buildModule("LockModule", (m) => {
      const unlockTime = m.getParameter("unlockTime", JAN_1ST_2030);
      const lockedAmount = m.getParameter("lockedAmount", ONE_GWEI);
    
      const lock = m.contract("Lock", [unlockTime], {
        value: lockedAmount,
      });
    
      return { lock };
    });
    
    export default LockModule;
    

    scripts フォルダ内にデプロイ用のスクリプトを作っていた頃と比べると少しやり方が変わるので慣れが必要ですが、 デプロイしたアドレスがネットワーク毎に json ファイルに書き出されるのでタスクファイルを実行する時に便利になります!!


    ignition が導入されたことによる変更点に関しては、 Kyuzan の Komy さんがわかりやすく解説してくれています!!


    https://x.com/ryoheikomy/status/1771006845873995846


    hardhat.config.tsの中身は以下の通りとなっています。

    ネットワークの URL の指定の部分に Ginco の API エンドポイントを割り当てています。

    import type { HardhatUserConfig } from "hardhat/config";
    import "@nomicfoundation/hardhat-toolbox-viem";
    import fs from "fs";
    import path from "path";
    import * as dotenv from "dotenv";
    
    dotenv.config();
    
    const { PRIVATE_KEY, GINCO_API_KEY } = process.env;
    
    // タスクファイルを読み込むための設定
    const SKIP_LOAD = process.env.SKIP_LOAD === "true";
    if (!SKIP_LOAD) {
      const taskPaths = ["", "utils", "lock"];
      taskPaths.forEach((folder) => {
        const tasksPath = path.join(__dirname, "tasks", folder);
        fs.readdirSync(tasksPath)
          .filter((_path) => _path.includes(".ts"))
          .forEach((task) => {
            require(`${tasksPath}/${task}`);
          });
      });
    }
    
    const config: HardhatUserConfig = {
      solidity: {
        compilers: [
          {
            version: "0.8.27",
            settings: {
              viaIR: true,
            },
          },
        ],
      },
      networks: {
        hardhat: {
          allowUnlimitedContractSize: true,
        },
        holesky: {
          // Ginco社のエンドポイントを利用する設定にしています。
          url: `https://testnet.node.gincoapis.com/ethereum/holesky/v1/${GINCO_API_KEY}`,
          accounts: PRIVATE_KEY !== undefined ? [PRIVATE_KEY] : [],
        },
      },
    };
    
    export default config;
    
  • get chain info

    viem を使ってチェーンの情報をとってくるタスクを実行できます!!

    yarn getChainInfo --network holesky
    

    タスクファイルの中身は以下の通りになっています!!

    viem が統合されてめっちゃ便利です!!

    import { task } from "hardhat/config";
    import { HardhatRuntimeEnvironment } from "hardhat/types";
    import { formatEther } from "viem";
    
    /**
     * 【Task】	getChainInfo of connected chain
     */
    task("getChainInfo", "getChainInfo of connected chain").setAction(
      async (taskArgs: any, hre: HardhatRuntimeEnvironment) => {
        console.log(
          "################################### [START] ###################################"
        );
    
        const publicClient = await hre.viem.getPublicClient();
        const chainId = await publicClient.getChainId();
        const blockNumber = await publicClient.getBlockNumber();
        const count = await publicClient.getBlockTransactionCount();
        const gasPrice = await publicClient.getGasPrice();
        const gasPriceInEther = formatEther(gasPrice);
    
        console.log(`
          Chain ID: ${chainId}
          Block Number: ${blockNumber}
          Transaction Count: ${count}
          Gas Price: ${gasPriceInEther} ETH
        `);
    
        console.log(
          "################################### [END] ###################################"
        );
      }
    );
    
  • get balance

    こちらは、残高を取得するタスクです!!

    yarn getBalance --network holesky
    
  • callReadMethod

    こちらは、デフォルトで生成される Lock コントラクトの読み取り系メソッドを呼び出すタスクです。

    yarn callReadMethod --network holesky
    

    タスクファイルの中身は以下の通りです。

    import { task } from "hardhat/config";
    import { HardhatRuntimeEnvironment } from "hardhat/types";
    import { getContractAddress } from "../../helpers/contractJsonHelper";
    import { formatEther } from "viem";
    
    /**
     * 【Task】	call read method of sample contract
     */
    task("callReadMethod", "call read method of sample contract").setAction(
      async (taskArgs: any, hre: HardhatRuntimeEnvironment) => {
        console.log(
          "################################### [START] ###################################"
        );
    
        // get wallet client
        const [owner] = await hre.viem.getWalletClients();
        const publicClient = await hre.viem.getPublicClient();
        // get chain ID
        const chainId = (await publicClient.getChainId()).toString();
        // get contract name
        const contractName = `LockModule#Lock`;
        // get contract address
        const contractAddress = getContractAddress(chainId, contractName);
    
        console.log(`
                ${contractName} 's address is ${contractAddress}
            `);
    
        // create Contract instance
        const lock = await hre.viem.getContractAt(
          "Lock",
          contractAddress as `0x${string}`,
          {
            client: { wallet: owner },
          }
        );
    
        // call read method
        const unlockTime = await lock.read.unlockTime();
        const ownerAddress = await lock.read.owner();
        // get contract's balance
        const contractBalance = await publicClient.getBalance({
          address: contractAddress as `0x${string}`,
        });
    
        console.log(`
                unlockTimes : ${unlockTime}
                ownerAddress: ${ownerAddress}
                contractBalance: ${formatEther(contractBalance)} ETH
            `);
    
        console.log(
          "################################### [END] ###################################"
        );
      }
    );
    

    ポイントは、 getContractAddress メソッドですね!

    ignition で生成される json ファイルから指定したネットワーク・コントラクトのアドレスを取得してくるヘルパーメソッドを使っています!!

    import fs from "fs";
    import path from "path";
    
    /**
     * デプロイされたアドレス情報をjsonファイルから取得するヘルパーメソッド
     * @param chainId チェーンID
     * @param contractName  コントラクト名 <コントラクト名>Module#<コントラクト名>の形式で指定する。
     * @returns
     */
    export function getContractAddress(
      chainId: string,
      contractName: string
    ): string | undefined {
      try {
        // ファイルパスを構築
        const filePath = path.join(
          __dirname,
          "../",
          "ignition",
          "deployments",
          `chain-${chainId}`,
          "deployed_addresses.json"
        );
    
        // JSONファイルの内容を読み込み
        const fileContent = fs.readFileSync(filePath, "utf-8");
    
        // JSONをオブジェクトにパース
        const deployedAddresses = JSON.parse(fileContent);
    
        // 指定されたコントラクト名のアドレスを返す
        return deployedAddresses[contractName];
      } catch (error) {
        console.error("Error reading contract address:", error);
        return undefined;
      }
    }
    

    これでいちいちコントラクトアドレスをファイルに貼り付けたりすることが不要となっています!!

  • calWriteMethod

    こちらは、 Lock コントラクトの書き込み系のメソッドを呼び出すタスクファイルです!!

    yarn callWriteMethod --network holesky
    
    import { task } from "hardhat/config";
    import { HardhatRuntimeEnvironment } from "hardhat/types";
    import { getContractAddress } from "../../helpers/contractJsonHelper";
    import { formatEther } from "viem";
    
    /**
     * 【Task】	call write method of sample contract
     */
    task(
      "callWriteMethod",
      "call write method (withdraw) of sample contract"
    ).setAction(async (taskArgs: any, hre: HardhatRuntimeEnvironment) => {
      console.log(
        "################################### [START] ###################################"
      );
    
      // get wallet client
      const [owner] = await hre.viem.getWalletClients();
      const publicClient = await hre.viem.getPublicClient();
      // get chain ID
      const chainId = (await publicClient.getChainId()).toString();
      // get contract name
      const contractName = `LockModule#Lock`;
      // get contract address
      const contractAddress = getContractAddress(chainId, contractName);
    
      console.log(`
                ${contractName} 's address is ${contractAddress}
            `);
    
      // create Contract instance
      const lock = await hre.viem.getContractAt(
        "Lock",
        contractAddress as `0x${string}`,
        {
          client: { wallet: owner },
        }
      );
    
      // get contract's balance
      const beforeBalance = await publicClient.getBalance({
        address: contractAddress as `0x${string}`,
      });
    
      // call withdraw method
      const hash = await lock.write.withdraw();
    
      // get contract's balance
      const afterBalance = await publicClient.getBalance({
        address: contractAddress as `0x${string}`,
      });
    
      console.log(`
                beforeBalance: ${formatEther(beforeBalance)} ETH
                afterBalance: ${formatEther(afterBalance)} ETH
                tx Hash: ${hash}
            `);
    
      console.log(
        "################################### [END] ###################################"
      );
    });
    

類似サービスを提供している他のプロバイダーについて

この類のサービスでまずみなさんが頭に思い浮かべるのが、 AlchemyInfraQuickNodeAnkr などではないでしょうか?

https://www.alchemy.com/

https://www.infura.io/

https://www.quicknode.com/

https://www.ankr.com/docs/

Google Cloud や AWS からも同様のサービスが提供されていますよね!

https://aws.amazon.com/jp/managed-blockchain/

https://cloud.google.com/web3?hl=ja

最近だと Cabinet さんもノード系サービスの提供を開始しています。

https://cbnt.co.jp/

結構色々ありますよね!

Dapps 開発における各社の Node as a Service をわかりやすく比較してまとめてくれている記事があるのでそちらが非常におすすめです!!

https://www.pontech.dev/post/node-as-a-service

この中に Ginco 社のサービスは載っていませんが、日系企業からこの類のサービスが出てきたのは大きいですよね!

どこのものを採用するかは社内もしくはプロジェクトメンバー内で比較検討した後に最も適したものを選ぶということが良さそうです!

終わりに

今回は、 Ginco 社の API エンドポイントサービスと hardhat + viem + TypeScript でスマコンをデプロイする方法を試してみました!!

上述した通り制限はありますが、今なら無料で試せるので皆さんもぜひ試してみてはどうでしょうか?

今回はここまでになります!!

ありがとうございました!!!

参考文献

  1. Ginco One Platform Site
  2. GitHub - mashharuki/Ginco-One-Platform-Sample
  3. Ginco 公式サイト
  4. Ginco TechBlog - Kubernetes を使ったブロックチェーンノード運用
  5. Pontech Blog - Dapps 開発における Node as a Service の比較・まとめ
  6. AWS Managed Blockchain Service
  7. Goole Cloud Web3 ポータルサイト
GitHubで編集を提案

Discussion