ちょっと久しぶりにEthereum(Dapp)の勉強をしているので、いろいろナレッジを書き残していきたい。
こちらのTypeChainを参考にしています 👀
https://github.com/ethereum-ts/TypeChain
前提条件
Truffle v5.1.66 (core: 5.1.66)
Solidity - 0.6.2 (solc-js)
Node v14.15.3
Web3.js v1.2.9
Node.jsはv14だと、truffle unbox react が動かなかったりするので v12 でもいいと思う。
ディレクトリを作成し、各種ファイルをインストール
$ mkdir truffle-ts-demo
$ cd truffle-ts-demo
# package.jsonを作成
$ npm init --y
# 必要なパッケージをインストール
$ npm install truffle typechain @typechain/truffle-v5 typescript -D
$ npm install @types/bn.js @types/mocha @types/chai @types/web3 -D
package.jsonのscripts部分を以下のように変更する
"scripts": {
"generate-types": "typechain --target=truffle-v5 'build/contracts/*.json'",
"postinstall": "truffle compile && npm run generate-types",
"build-migration-files": "tsc -p ./tsconfig.migrate.json --outDir ./migrations",
"migrate": "npm run build-migration-files && truffle migrate",
"test": "npm run postinstall && truffle test"
},
build/contract/*.jsonからtypes(typescriptの型ファイル)を生成。testファイル等の型依存をこのファイルで管理する。
solidityのコンパイルを行い、型ファイルを生成する。solファイルの型を変更した場合は都度実行する必要がある。
マイグレーションを実行。migrationファイルもTypeScriptで記述されているため、一度jsファイルを作成し、そのファイルを元にマイグレーションを行う。
ビルドを実行し、テストを実行します。
tsconfig.jsonとマイグレーション用のtsconfig.migrate.jsonを作成する。
$ touch tsconfig.json tsconfig.migrate.json
tsconfig.jsonは以下のようにする。お好みで変えてもよい。
{
"compilerOptions": {
"target": "es2018",
"module": "commonjs",
"lib": ["ES2018", "DOM"],
"sourceMap": true,
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
},
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
tsconfig.migrate.jsonはマイグレーションファイルのトランスパイルに利用します。基本的には同じで対象のファイルの対象が異なることになります。
{
"extends": "./tsconfig.json",
"include": ["./migrations-ts/*.ts", "./types/**/*.ts"]
}
# まずディレクトリを作成します
$ mkdir contracts migrations-ts test
# truffleの設定ファイルを作成します。
$ touch truffle-config.js
truffle-config.jsはとりあえず最低限の設定をしておきます
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*"
}
},
compilers: {
solc: {
version: "0.6.2"
}
}
};
Migrations.solとそのマイグレーションファイルを作成します。
$ touch contracts/Migrations.sol
$ touch migrations-ts/1_initail_migration.ts
Migrations.solはtruffle initと同じ内容を記述します。1_initial_migration.tsはTypeScriptで以下の内容を記述します。
const Migrations = artifacts.require("Migrations");
module.exports = function (deployer) {
deployer.deploy(Migrations);
} as Truffle.Migration;
export {};
基本的にはjsと同じですが、`as Truffle.Migration` で型の担保を行っています。また、最後の行に`export {}`を付ける必要があります。(マイグレーションファイルをインポートさせないため、空のexportをする必要がある。)
この時点でTypeScriptのエラーが発生するが一旦無視してすすめる。
一度buildを実行し、typesを生成する。
npm run postinstall
`types/truffle-contracts/*.d.ts`が生成され、migrations-ts上のエラーが消える。
truffleのmigationコマンドはjsファイルしか読めないので、migration-ts
内のtsファイルをjs形式に変更します。
$ npm run build-migration-files
上記のコマンドが実行されると、`migirations`というjsファイルが入ったディレクトリができるので、以降、`truffle migrate`でマイグレーションする場合はそちらのファイルを参照することになります。
migration-ts内のファイルを更新した場合は都度上記のコマンドを実行しjsを更新することになります。(実際はmigrationファイルを更新する頻度は少ないですが)
マイグレーションを実行する場合はGanache等Ethereumのクライアントを立ち上げ、マイグレーションコマンド npm run migrate
を実行します。
とりあえず、テストが動作することを確かめるためテストファイルを追加します。
$ touch test/migration.test.ts
下記のようにします
const MigrationsContract = artifacts.require("Migrations");
contract("Migrations", () => {
it("has been deployed successfully", async () => {
const migrations = await MigrationsContract.deployed();
assert(migrations, "contracut was not deployed");
});
});
テストを実行し、動作することを確認します。
$ npm run test
typescriptでtruffleのテンプレート環境を作る部分を説明しました。
ファイルを更新するたびにコンパイルが必要だったりするので、なにかファイルをwatchする機能をつけたほうが効率ではあります、時間があればそのあたりも詰めていきたですね。