Ginco One Platformを使ってスマコンをデプロイしてみよう!
はじめに
みなさん、こんにちは!
今回は、Ginco 社が提供しているブロックチェーン用の API エンドポイントサービスを使ってスマコンをデプロイしてみましたのでその内容を共有したいと思います!
制限がありますが、今は無料で使えるようになっています!
Ginco 社について
Ginco 社はウォレットやインデクサーなど Web3 アプリ開発に必須となる Web3 インフラ機能を提供している会社です。
先日国際的なセキュリティ認証の証として知られる SOC2 Type-Ⅱ を取得されたことが発表されてたりしています。
インドにも会社を設立したりしている勢いのある会社です!
Progmat や Chainalysis 社とも協業を発表しています。
テックブログも非常に面白い記事ばかりなのでおすすめです。
個人的には Kubernetes を使ったブロックチェーンノード運用 の記事が面白かったです!
他にもオンラインウェビナーや月次のレポートを配信していたりと情報発信も積極的に行っています!
Ginco One Platform を使ってスマコンをデプロイしてみた!
Ginco 社は今年に入って Alchemy のようにブロックチェーンネットワークにアクセスするための API エンドポイントを提供してくれるポータルサイトを展開しています。
利用制限がありますが、 Alchemy で使っているみたいにメールアドレスでユーザー登録した後に無料で API エンドポイントを使うことができます!!
今回はその 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
の最新バージョンを使っていたり、 ignition や viem も使っています!!
-
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] ###################################" ); });
類似サービスを提供している他のプロバイダーについて
この類のサービスでまずみなさんが頭に思い浮かべるのが、 Alchemy や Infra 、 QuickNode 、 Ankr などではないでしょうか?
Google Cloud や AWS からも同様のサービスが提供されていますよね!
最近だと Cabinet さんもノード系サービスの提供を開始しています。
結構色々ありますよね!
Dapps 開発における各社の Node as a Service をわかりやすく比較してまとめてくれている記事があるのでそちらが非常におすすめです!!
この中に Ginco 社のサービスは載っていませんが、日系企業からこの類のサービスが出てきたのは大きいですよね!
どこのものを採用するかは社内もしくはプロジェクトメンバー内で比較検討した後に最も適したものを選ぶということが良さそうです!
終わりに
今回は、 Ginco 社の API エンドポイントサービスと hardhat + viem + TypeScript でスマコンをデプロイする方法を試してみました!!
上述した通り制限はありますが、今なら無料で試せるので皆さんもぜひ試してみてはどうでしょうか?
今回はここまでになります!!
ありがとうございました!!!
Discussion