あいさつ
教育学部一年です。
東京の会社にリモートでインターンをしてます。
今回はその業務関連で勉強したことをまとめます。
多くのバグに衝突し、その対処法を逐次書くのでテンポは非常に悪いです。必要なところだけを適宜読み抜くようにしてください。
ほんと、バグがいっぱいで辛かった……
やること
NEMの公式チュートリアルの冒頭から、TypeScriptのサンプルコードを実行するところまでです。
環境(執筆時)
Windows 10
TypeScript Version 3.3.4000
Node.js v8.11.3
nem2-cli @0.11.0
nem2-sdk @0.11.1
npm @6.9.0
ts-node @8.0.3
環境設定
Node.jsはインストールしておいてください。
npm i npm
npm init
npm i -g nem2-cli nem2-sdk typescript rxjs js-joda ts-node utf8
アカウント作成
まず、NEMアカウントを作成します。
今回は会社の上司がオンラインでNodeを建ててくれたので、そちらを使います。
(通常はローカルで環境を作りそこでテストするのが王道のようです。)
>nem2-cli profile create
しかし、まずここからエラーに衝突します。幸先悪いですね。
Error1: アカウント作成エラー
Error Provide a valid NEM2 Node URL. Example: http://localhost:3000
エラーに記述があるとおりのURLや、Private KEYなど様々確認するのですが、どうやら違う様子。
解決
Profile stored correctly
default->
Network: MIJIN_TEST
Url: http://~
Address: SCJY~
PublicKey: 63FD~
PrivateKey: 783E~
端的に言って、これはいつの間にか解決していました。
しかし、エラーの原因をいろいろ探していた経験を鑑みると、ホームディレクトリに.nem2rc.json
ファイルが存在しなかったのが第一の原因のように思います。
同様のことにぶち当たった方は、ホームディレクトリに.nem2rc.json
ファイルを作成し、{}
とだけ記入して保存してみてください。
話をチュートリアルに戻し、アカウント情報を取得してみます。
>nem2-cli account info
Account: SCJY~
-------------------------------------------------------
Address: SCJY~
at height: 1
PublicKey: 0000~
at height: 0
Importance: 0
at height: 0
Mosaics
650b00d30620b86a: 409090909
MosaicIDが650b~のモザイクがすでに付与されていますね。
ここで、チュートリアルを進めるため、別アカウントも作成しておきます。
>nem2-cli account generate --network MIJIN_TEST --save --url http://~ --profile buyer
New Account: SAXS~
Public Key: 8CF5~
Private Key: 8BF8~
Stored buyer profile
Monitor類の作成
モニタリング用のコマンドプロンプトを3つ用意し、それぞれnem2-cli monitor status
, nem2-cli monitor unconfirmed
, nem2-cli monitor confirmed
を実行しておきます。
最初のコマンドはエラーを表示してくれます。二番目のが「正常に予約された処理」。三番目のは「正常に終了した処理」を表示します。
モザイク作成
チュートリアル通りです。
すでにトークンが付与されていましたが、新しく作ってみます。
>nem2-cli transaction mosaic --amount 1000000 --supplymutable --divisibility 0 --duration 1000
Do you want mosaic to be transferable? [y/n]: n
Do you want mosaic to have levy mutable? [y/n]: y
Transaction announced correctly
Hash: A2D3~
Signer: 63FD~
Your mosaic id is:
Hex: 10a5abae76de8603
Uint64: [ 1994294787 279292846]
モザイク送信
これもチュートリアル通り。
最初に登録したdefaultアカウントから、buyerアカウントへモザイクを送信しています。
まずは、もともと作ってあったモザイクの方から。
>nem2-cli transaction transfer --recipient SAXS~ --mosaics @cat.currency::10 --message "Hello NEM" --profile default
Transaction announced correctly
Hash: 969E65EBFF15827A34B2C949D9AC6F7299A62DA04F372FB272952A6DA8AAD0BE
Signer: 63FD~
buyerアカウント情報を取得してみましょう。
>nem2-cli account info --profile buyer
Account: SAXS~
-------------------------------------------------------
Address: SAXS~
at height: 16561
PublicKey: 0000~
at height: 0
Importance: 0
at height: 0
Mosaics
650b00d30620b86a: 0.00001
モザイクは正常に送信されていますね。
作った方のモザイクも送信してみます。
>nem2-cli transaction transfer --recipient SAXS~ --mosaics 10a5abae76de8603::10 --message "Hello buyer" --profile default
Transaction announced correctly
Hash: B830~
Signer: 63FD~
同じく、defaultアカウントからbuyerアカウントへの送信です。
アカウント情報を確認してみます。
>nem2-cli account info --profile buyer
Account: SAXS~
-------------------------------------------------------
Address: SAXS~
at height: 16561
PublicKey: 0000~
at height: 0
Importance: 0
at height: 0
Mosaics
10a5abae76de8603: 10
650b00d30620b86a: 0.00001
650b~以外のモザイクが取得できていますね!
TypeScriptサンプルコードの実行
さて、ここからがひどい泥沼だったのですが……
まず、NEMアプリを記述したTSコードを実行するには、Node.js上で実行する必要があります。
手段は二通り。
-
~.ts
ファイルを直接ts-node
コマンドで実行 -
~.ts
ファイルを~.js
ファイルにコンパイルし、node
コマンドで実行
結論から言うと、1は断念し、2はうまくいきました。
こちらがソースコード。
import {
Account, Address, Deadline, UInt64, NetworkType, PlainMessage, TransferTransaction, Mosaic, MosaicId,
TransactionHttp
} from 'nem2-sdk';
const transferTransaction = TransferTransaction.create(
Deadline.create(),
Address.createFromRawAddress('SC7A~'),
[new Mosaic(new MosaicId([ 1994294787, 279292846 ]), UInt64.fromUint(1))], // Replace with your mosaicId
PlainMessage.create('enjoy your ticket'),
NetworkType.MIJIN_TEST
);
const privateKey = process.env.PRIVATE_KEY;
const account = Account.createFromPrivateKey(privateKey, NetworkType.MIJIN_TEST);
const signedTransaction = account.sign(transferTransaction);
const transactionHttp = new TransactionHttp('http://~');
transactionHttp.announce(signedTransaction).subscribe(
x => console.log(x),
err => console.log(err)
);
チュートリアルサイトのコードを貼り合わせてMosaicIDとかを変更しただけですね。
実行前に、環境変数にPRIVATE_KEY
を登録しておくのもお忘れなく。
では方針1「ts-node
で直接実行」を試してみます。
>ts-node ./~/test.ts
C:\~\index.ts:226
return new TSError(diagnosticText, diagnosticCodes)
^
TSError: ⨯ Unable to compile TypeScript:
~/test.ts:4:8 - error TS2307: Cannot find module 'nem2-sdk'.
4 } from 'nem2-sdk';
~~~~~~~~~~
~/test.ts:14:20 - error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
14 const privateKey = process.env.PRIVATE_KEY;
~~~~~~~
at createTSError (C:~\index.ts:226:12)
at getOutput (C:~\index.ts:335:40)
at Object.compile (C:~\index.ts:368:11)
at Module.m._compile (C:~\index.ts:414:43)
at Module._extensions..js (module.js:663:10)
at Object.require.extensions.(anonymous function) [as .ts] (C:~\index.ts:417:12)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
だめみたいですね。
じゃあ方針2「一度コンパイルしてから実行」も試してみます。
>tsc ./~/test.ts
~/MultisigAccountGraphInfo.d.ts(8,48): error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
~/Observable.d.ts(89,59): error TS2585: 'Promise' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
~/types.d.ts(41,84): error TS2304: Cannot find name 'Iterable'.
~/types.d.ts(45,6): error TS2585: 'Symbol' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later.
C:~\index.ts(14,20): error TS2580: Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.
あらら……
Error2: TSファイルが実行できない
エラーコード通りにtsconfigを設定するも解決せず。
まぁエラーの一部は.tsファイルの存在するディレクトリでnpm i nem2-sdk
やってなかったとかいう超初歩的なものだったのですが…笑
tsconfig設定とかをいろいろ調べ回った挙げ句、原因は「型定義ファイルがインストールされていない」、「管理者権限でないとコンパイラが環境変数を読みにいけない」ということでした。
解決
TSファイルのあるディレクトリでnpm i nem2-sdk @types/core-js @types/node
を実行します。
次に、管理者モードでコマンドプロンプトを開き、tsc
コマンドでTSファイルをコンパイル。
そうしたら、非管理者モードのコマンドプロンプトに戻ってnode ~.ts
を実行。
管理者モードではPOSTメソッドが許可されていないらしいので、実行そのものは非管理者モードでないといけないようです。(おそらく、ts-nodeがうまくいかないのはこのため……)
>node ./~/test.js
TransactionAnnounceResponse {
message: 'packet 9 was pushed to the network via /transaction' }
以上、TSサンプルコードの実行は見事達成できました。
終わりに
以下蛇足ですが感想など。
前半からエラー(しかも環境依存ぽい)に苦しまされ続けたので、非常に疲れました。右も左もわからない中でもがくハメになり、NEMコミュニティの皆様の助言の数々は(直接の解決には至らずとも)貴重なマイルストーンとなり、とても感謝しています。
ともかくも良い勉強になりましたね。またできることが一つ増えた。
次回からはNEMの新機能などに深く突っ込んだ記事を書いていく所存です。
最後になりましたが、いろいろご指導くださった @daoka さんに感謝申し上げます。これからも頑張っていきます。