前回のethers.jsでBIP39のニーモニックフレーズとBIP44準拠のHDWalletを使うに続き、今回はENS(Ethereum Name Service)の機能を使ってみます。
バージョン
- node.js v10.16.3
- npm 6.10.3
- ethers.js 4.0.45
ethers.jsとは(再掲)
公式のFeaturesには以下のように書いています。 What is ethers.js — ethers.js 4.0.0 documentation
- 秘密キーをクライアントサイドに安全かつ確実に保管する
- JSONウォレットのインポートとエクスポート(Geth、Parity、crowdsale)
- BIP39ニーモニックフレーズ(12ワードのバックアップフレーズ)およびHDウォレット(英語、イタリア語、日本語、韓国語、簡体字中国語、繁体字中国語 etc)のインポートとエクスポート
- ABIv2やHuman-Readable ABIなど、任意のコントラクトABIからJavaScriptオブジェクトを作成する
- JSON-RPC、INFURA、Etherscan、またはMetaMaskを介してEthereumノードに接続する
- Ethereum Name Service(ENS)の名前解決
- 小さなサイズ(圧縮で~88kb;非圧縮で284kb)
- Ethereum機能に対応する包括的な機能
- 広範なドキュメント
- 広範なテストケース
- 完全なTypeScript対応
- MITライセンス(全ての依存関係を含む)で自由に使える完全なオープンソースである
今回はEthereum Name Service(ENS)の名前解決を使ってみます。
ENSとは
ethereum上でドメイン名とアドレスとを名前解決するプロトコルです。SolidityでENSプロトコルは定義されており、.eth(ドメイン名)と0x***(アドレス)とがマッピングされています。WebのDNSのようにドメイン名とIPアドレスをマッピングするようなもののアナロジーで考えてもらえればと思います。
ENSの詳しい仕組みはnoteにまとめていますので詳細はこちらをご覧ください。
ethers.jsからEthereumブロックチェーンに接続する方法
ethers.jsではENSの名前解決機能が提供されていますが、ENSを取得するためにはEthereumブロックチェーンに接続する必要があります。ethers.jsで提供されているproviderを用いて様々な手段で接続することができます。
providerは以下が用意されています。
- getDefaultProvider
INFURAまたはEtherscanから接続
- EtherscanProvider
Etherscanから接続
- InfuraProvider
INFURAから接続
- JsonRpcProvider
JSON-RPCで接続。GethやParityなどを接続先として想定
- Web3Provider
Web3providerで接続。MetamaskなどはWeb3 providerエンジン
- IpcProvider
IPCを経由したJSON-RPCで接続。GethやParityなどを接続先として想定
また、FallbackProviderという「任意のProviderを設定し、一度失敗しても接続をリトライして試行する」というオプションも用意されています。
Providers — ethers.js 4.0.0 documentation
今回はInfuraProviderを利用します。Infura に登録してログインすると、PROJECT IDを始めとしたキーが表示されます。
InfuraProviderの場合は接続先ネットワークと、projectIdを以下のように設定します。(ドキュメントではapiAccessTokenと書いてありますがprojectIdです)
const ethers = require('ethers'); projectId = "xxxxx"; // infura provider = new ethers.providers.InfuraProvider(network = "homestead", projectId);
なお、実はprojectIdを入れなくてもデフォルトのprojectIdが使われるのでEthereumには接続できますが、出来るだけ自分のProjectIDを使った方が良いでしょう。
ENSの名前解決をしてアドレスを導き出す
今回はethereum創設者のvitalikが保持するENSであるvitalik.ethを名前解決してみます。以下コードでENSの名前解決を行います。ethereum創設者であるVitalikが所持するvitalik.eth
から名前解決してアドレスを導き出してみます。
const ethers = require('ethers'); projectId = "xxxxx"; // infura provider = new ethers.providers.InfuraProvider(network = "homestead", projectId); provider.resolveName("vitalik.eth").then(function(address) { console.log("Address: " + address); });
ens.jsとして保存し、実行すると
$ node ens.js Address: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
がvitalik.ethのアドレスであることが分かりました。
アドレスからENSを導き出す
先ほど導き出した0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
から
const ethers = require('ethers'); projectId = "xxxx"; provider = new ethers.providers.InfuraProvider(network = "homestead", projectId); provider.resolveName("vitalik.eth").then(function(address) { console.log("Address: " + address); }); provider.lookupAddress("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045").then(function(ens){ console.log("ENS: " + ens); });
ens.jsとして保存し、実行すると
$ node ens.js Address: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 ENS: vitalik.eth
となり、アドレスからENSを引けました。
まとめ
ethers.jsで簡単にENSの機能を使うことができます。OpenSeaもENS対応したりなど、これからENSが普及していくと考えられるので利用したい機能です。