まずはこちらをご覧ください(web3-jsのtsライブラリより)
export class Contract {
// 中略
methods: any;
// 中略
}
ばかな、、、anyだと。。。
ということで今回は型付けが超絶貧弱な web3-js を ethereum-ts/TypeChain というライブラリを使って型を付けていきます。
Blockchain Advent Calendar 記事どうしようどうしようと迷い続けて最終的に超ニッチな所に行き着きましたwすいません。
使っているもの
- web3: 1.x系
- typechain-target-web3-v1: 1.0.4
- typechain: 1.0.3
TypeChainとは?
ethereum-ts というグループ(開発者一人)が作っているSolidityから生成したコントラクトに型を付けてくれるライブラリのようです。
現在495スターで開発者一人でこれは素晴らしい。
使ってみる
truflleやethers.jsなどにも対応しているようですが、今回はフロントではweb3-jsを使っている想定で進めます。
また、コントラクトはtruffleを使って開発している想定です
インストール
$ cd /path/to/truffle-dapps-root
$ npm install --save-dev typechain
$ npm install --save-dev typechain-target-web3-v1
コントラクトの型定義ファイルをビルド
$ cd /path/to/truffle-dapps-root
$ npx npx typechain --target web3-v1 './build/**/*.json'
$ cd ./types/web3-v1-contracts
=> コントラクトの型定義ファイルができている
フロントエンドアプリで使用
次は上で作った型定義ファイルをフロントエンドアプリに持っていき読み込ませましょう。
キャストが必要ですが、これで web3-js の Contract タイプに対して自作のコントラクトの型をつけることができます。
例として使用するコントラクト
contract MyContract {
uint256 value;
function setValue(uint256 _value) external {
value = _value;
}
function getValue() external view returns (uint256) {
return value;
}
}
ビルドされた型定義ファイル
export class MyContract extends Contract {
constructor(
jsonInterface: any[],
address?: string,
options?: ContractOptions
);
clone(): MyContract;
methods: {
setValue(_value: number | string): TransactionObject<void>;
getValue(): TransactionObject<string>;
};
events: {
allEvents: (
options?: EventOptions,
cb?: Callback<EventLog>
) => EventEmitter;
};
}
フロントエンドアプリ
import { MyContract } from './path/to/MyContract'; // 生成した型定義ファイル
const createMyContract: MyContract = () => {
// apiについては
return new web3.eth.Contract(abi, address) as MyContract;
);
// methodsに対して型が付与されている!!!
createMyContract().methods.setValue(10).send({
from: window.web3.eth.defaultAccount,
});
createMyContract().methods.setValue(10).send({
from: window.web3.eth.defaultAccount,
});
createMyContract().methods.setValue().call();
タイプセーフなdappsライフを
型というものは素晴らしいものですね。
npmにパッケージとしてリリースして常に最新のビルドしたものを見ているようにしたり、シンボリックリンクでファイルを共有したり、すこし運用に工夫は必要ですが、これでdappsフロントエンドアプリのバグが減りそうです。
では良いお年を〜