Skip to main content

実践・白紙練習:ゼロから手打ち

Counter 白紙練習 第三弾:callTx で increment を呼び出す

第二弾でデプロイした Counter 契約に CLI から接続し、increment を callTx で呼び、ledger を読んで round が増えたことを確認するまでの実験ノート。findDeployedContract → callTx.increment() → queryContractState → Counter.ledger。これで「契約・コンパイル・デプロイ・呼び出し」が一周します。


第二弾 で、Counter 契約をローカル Midnight に置きました。第三弾は、いよいよ最後のピース、呼び出しです。

置いた契約の increment ボタンを、CLI から実際に押します。そして ledger を読んで、round が増えたことを確認します。これで合言葉が一周します。

このページも実験ノートです。「いま何を確認しているか」「どこでログがズレたか」「どの段階で成功と言えるか」を、順番に残します。

1. 第三弾の現在地

ここまでの流れを整理します。

人間語でいうと——

今回いちばん大事な、3つの言葉の違いをはっきりさせます。

2. .midnight-state.json を確認する

呼び出すには、まず「どの契約を呼ぶのか」が必要です。それが Contract Address。第二弾の最後に recordDeployment(...).midnight-state.json に保存しましたね。中身を見ます。

例:

3. increment.ts を作る

第三弾の主役は increment.ts です。第二弾の deploy.ts の隣に作ります。

役割の違いを、はっきりさせておきます。

最終的な構成はこうなります。

4. まずは Contract Address を読むだけ

第二弾と同じく、いきなり callTx には進みません。まず .midnight-state.json からアドレスを読めるかだけ確認します。

cli/src/increment.ts の最初の形:

実行:

期待ログ:

この段階での成功:

まだ呼び出しではありません。でも「どの契約を呼ぶか」が手に入りました。

5. 手打ちミス例:activeNetwork に deployment が入ってしまう

実際に、こんな表示になることがありました。

active network: のところに、"undeployed" ではなく deployment の中身が出ています。これは、こう書いてしまったとき。

正しい形:

これは壊れたのではなく、次の確認ポイントです。「変数の中身が予想とちがったら、まず console.log で覗く」——実験ノートの基本動作です。

6. network / wallet / DUST を準備する

呼び出すにも、第二弾の deploy.ts と同じく network / wallet / DUST が必要です。increment.ts にも同じ準備を入れます。

必要な import:

main() の中、Contract Address を読んだに追加します。

この段階では、まだ increment は呼びません。目的は「呼び出し前の準備ができるか」の確認だけ。

成功ログ例:

この段階での成功:

7. ログ順の整理

作業中、.midnight-state.json を読む処理が後ろにも残ってしまい、ログが二重に出ました。

「契約アドレスを読む → wallet 準備」の順なのに、アドレス読みが wallet の後にも残っていたのが原因です。正しい流れはこう。

念のため、保存されたネットワークと、いま解決したネットワークが一致するかも確認します。

8. 呼び出し方を既存サンプルから学ぶ

既存サンプル(kodomo01.app/src/cli.ts)では、デプロイ済み契約への接続に findDeployedContract を使い、circuit をこう呼んでいました。

Counter には storeMessage はありません。あるのは increment。だからこうなります。

ここ、第一弾からの伏線が回収されます。

ledger circuit callTxcallTx が、ついに姿を現しました。

9. providers を作る(createProviders)

呼び出しにも providers が要ります(第二弾と同じ顔ぶれ)。今回は createProviders(...) という関数にまとめます。main() の外に置きます。

それぞれの役わり(第二弾のおさらい):

10. デプロイ済み Counter に接続する

wallet.stop()に、デプロイ済み契約への接続を追加します。

成功ログ:

ここで初めて、デプロイ済み契約に接続できました。まだボタンは押していませんが、機械の前に立った状態です。

11. increment を callTx で呼ぶ

接続できたら、ついに increment を呼びます。

成功ログ:

人間語で:

Transaction ID と Block height は、呼ぶたびに変わります。increment を呼ぶたびに新しいトランザクションがブロックに入るからです。あなたの手元の値が上の例と違っても、まったく問題ありません。

12. ledger を読む

呼び出しが成功したら、本当に round が増えたか確認します。サンプル(HelloWorld)の読み取りはこうでした。

Counter 版はこう。

最初の出力:

これはエラーではありません

13. [Getter] の中身を取り出す

{ round: [Getter] } と出たのは、roundgetter(取り出し用の関数)だから。明示的に ledgerState.round を表示します。

成功ログ:

読みやすく出すなら:

ここで初めて、ledger の round を読めました。まとめると——

14. ログ位置を整理する

実作業中、DUST ready for increment!最後にも出てしまいました。

DUST ready for increment! は本来、呼び出しのに出るログです。正しい順番はこう。

コード上の正しい位置:

もし DUST ready for increment! が最後にも出るなら、どこかに重複して残っています。探して、後ろの方を消します。

2つ出たら、後ろの1つを消せばOK。

15. wallet.stop() の位置

wallet.stop() は、呼び出しと読み取りが終わった後に置きます。

悪い例(呼び出し前に止めている):

正しい位置:

16. RPC-CORE Normal Closure ログについて

途中で、こんなログが出ることがあります。

17. 第三弾の最終成功ログ

全部つなげて実行すると、こんな流れになります(これが第三弾の完成形)。

人間向けに訳すと:

18. 第三弾の最終まとめ

到達点をチェックで振り返ります。

三部作を、ひとことで。

✍️ 白紙練習(何度でも反復)

答えを開く前に、自分の手から出してみましょう。一周を「言葉で言える」ことが、いちばんの力です。

白紙練習

デプロイ済みの Counter を呼び出して round を読むまでの流れを、順番に書いてみよう。

クイズ

deployContract / findDeployedContract / callTx.increment() のちがいは?

クイズ

Compact で export circuit increment() と書いたものは、TypeScript 側でどう呼ぶ?

クイズ

ledger を読むと round が [Getter] と表示された。これはエラー? どう中身を取り出す?

クイズ

wallet.stop() を呼ぶ位置はどこ? なぜ?

クイズ

RPC-CORE ... Normal Closure のログが出た。どう扱う?

今日の呪文

今日の勝利条件

締め

次回予告(第四弾候補)

一周できたら、次は「読むだけ」を切り出してみましょう。

さらにその先(改造10本ノック と地続きです):

でも、あせらず。まずは今日の一周を、何度でも噛みしめてください。

つぎに読むページ