villagerHの日記

勉強したことや苦労した事などを書き綴ります

コントラクト自身のアドレス

まだ完全じゃないですが体調がよくなり始めたので作業の方も再開し始めました。

フロント側を作っている最中にコントラクトの拡張を何度か行ったのですが
そういえばtruffleでのテスト用ファイルを全く更新していなかったことを思い出して更新しました。

ちなみにですが
Truffleにはtestフォルダにテスト用のsolidityファイルを用意するとテストを行える機能があるようです。
解説してくださってるサイトがあるのでそれを参考にしつつ作ってます。


メインの方のコントラクトですがCryptoZombiesを参考にしつつ作っており

  • 任意のワードからユニットを生成してmsg.senderで呼び出し元のアドレスを保存
  • 保存されたユニットのIDを取得するメソッドにアドレスを渡すとそのアドレスのIDが取得できる

という形になってます。

このIDを取得するメソッドへのアドレスをテスト側のコントラクトで以下の形で呼び出してました。

uint[] memory unitids = unitFactory.getUnitIdByOwner(msg.sender);

しかしユニットを作ってからやっているのに何度やってもunitidsの中身が0でうまく取得できません。

eventでログを出しながらやったところCreate時に保存されているアドレスとgetUnitIdByOwnerで渡した時のアドレスが違っていることがわかりました。

よくよく考えれば当たり前なのですがテスト側でmsg.senderしてしまうとテスト側の呼び出し元のアドレスになってしまうんですね。

テストコントラクト(msg.sender=アドレスA)⇨メインコントラクト(msg.sender=アドレスA)

こうなるのかと思って実装してましたが正しくは以下の形です。

テスト呼び出し元(自身のアドレス=アドレスB)⇨テストコントラクト(自身のアドレス=アドレスA, msg.sender=アドレスB)⇨メインコントラクト(msg.sender=アドレスA)

わかりづらい図で申し訳ないですがざっくりこんな感じです。

で、テストのコントラクト自身のアドレスを取得するにはどうすればいいのかというとthisを使えばいいようです。

uint[] memory unitids = unitFactory.getUnitIdByOwner(address(this));

これで無事に意図している挙動になってテストが無事にできました。