前提・実現したいこと
下記書籍に沿って、スマートコントラクトを実装したDAppsの開発演習をしています。
「試して学ぶ スマートコントラクト開発(マイナビ出版)」
実際にropstenネットワークにコントラクトコードをデプロイし、トランザクションの発行まで確認したのですが、イベントの発火が行われません。イベントが発火するとブラウザ常に新しいトークルームが生成されるというものになっています。
発生している問題・エラーメッセージ
トランザクションとイベントの監視を、Go言語によって行なっています。
エラーメッセージは出ていないのですが、Go言語の無限ループがされていないように見えます。
ソースコードとログを下記に記載いたします。
もしくはtopics["RoomCreated"]が入ってきていないのではないかと思っています。
何かご意見ありましたら参考にさせていただきたく投稿いたしました
solidityによるコントラクトコードです。
solidity
1contract RoomFactory is Destructible, Pausable { 2 3 event RoomCreated( 4 address indexed _creator, 5 address _room, 6 uint256 _depositedValue 7 ); 8 9 function createRoom() external payable whenNotPaused { 10 address newRoom = (new Room).value(msg.value)(msg.sender); 11 emit RoomCreated(msg.sender, newRoom, msg.value); 12 } 13}
Go言語によるイベント監視コードです。
想定では、for文直下のlog.Println("イベント検知中")により、ログに「イベント監視中」が無限に出続けるのではないかと考えています。
go
1func main() { 2 3 log.Println("Starting Event Server!!") 4 db := connectDB() 5 defer db.Close() 6 7 // ③Ethereumネットワークに参加中のノードに接続 8 client, err := ethclient.Dial(os.Getenv("GETH_URL")) 9 // client, err := ethclient.Dial("ws://127.0.0.1:8545") 10 if err != nil { 11 log.Fatalf("err: %v\n", err) 12 } 13 14 // ④Solidityで定義したイベントをハッシュ化する 15 topics := map[string]common.Hash{ 16 "RoomCreated": crypto.Keccak256Hash([]byte("RoomCreated(address,address,uint256)")), 17 } 18 log.Println("solidityで定義したイベントをハッシュ化する", topics) 19 20 // ⑤どのコントラクトのどのTopicを対象にイベントを検知処理するか設定 21 query := ethereum.FilterQuery{ 22 Addresses: []common.Address{common.HexToAddress(os.Getenv("ROOM_FACTORY_ADDRESS"))}, 23 Topics: [][]common.Hash{{ 24 topics["RoomCreated"], 25 }}, 26 } 27 log.Println("どのコントラクトのどのTopicを対象にイベントを検知処理するか設定:", query) 28 29 // ⑥client.SubscribeFilterLogsでコントラクトとの接続を開始 30 event := make(chan types.Log) 31 sub, err := client.SubscribeFilterLogs(context.Background(), query, event) 32 if err != nil { 33 log.Fatal(err) 34 } 35 log.Println("コントラクトとの接続:", event, sub, err) 36 37 roomFactoryAbi, err := abi.JSON(strings.NewReader(string(bindings.RoomFactoryABI))) 38 if err != nil { 39 log.Fatal(err) 40 } 41 log.Println("roomFactoryAbiをオブジェクト化:", roomFactoryAbi, err) 42 43 // ⑦イベント検知のための無限ループ 44 45 for { 46 47 log.Println("イベント検知中") 48 49 // ⑧select文を使ってチャネルの監視を行い、コントラクトとの接続が切断された場合はエラーメッセージを返す 50 select { 51 52 case err := <-sub.Err(): 53 log.Println("イベントエラー") 54 log.Println(err) 55 close(event) 56 57 case vLog := <-event: 58 log.Println("Topicsのエラー") 59 if len(vLog.Topics) == 0 { 60 log.Println("Topicsが存在しません") 61 } 62 63 // ⑩イベントを検知した場合はeventチャンネルを通じてイベントデータを返す。 64 log.Println("イベント検知準備") 65 66 switch vLog.Topics[0] { 67 case topics["RoomCreated"]: 68 var roomCreatedEvent RoomCreatedEvent 69 log.Println("イベントを検知") 70 if err := roomFactoryAbi.Unpack(&roomCreatedEvent, "RoomCreated", vLog.Data); err != nil { 71 log.Printf("Failed unpack: %v\n", err) 72 continue 73 } 74 75 // データベースに新しいデータを登録する処理 76 room := Room{ 77 Address: roomCreatedEvent.Room.Hex(), // デプロイされた新しいルームのコントラクトアドレス 78 CreateTxHash: vLog.TxHash.Hex(), // Transaction Hash 79 OwnerAddress: common.BytesToAddress(vLog.Topics[1].Bytes()).Hex(), // デプロイしたユーザーのアドレス 80 WeiBalance: roomCreatedEvent.DepositedValue.Uint64(), // デプロイ時に指定したDeposit額 81 EventCode: getEventCode(4), // イベントコード 82 OwnerID: 1, // ダミー 83 } 84 85 if err := db.Create(&room).Error; err != nil { 86 log.Printf("Failed create room: %v\n", err) 87 } 88 89 break 90 } 91 } 92 } 93} 94
試したこと
イベント監視コードのログです
ログに「イベント検知中」が一回しか出ていません。
なので、イベント監視のコードが常時監視していないのではないかと思っています。
test_event | 2019/09/05 02:56:37 Starting Event Server!! test_event | 2019/09/05 02:56:37 データベースに接続 test_event | 2019/09/05 02:56:38 solidityで定義したイベントをハッシュ化する map[RoomCreated:[104 73 247 164 9 173 151 211 156 95 250 7 75 247 101 51 11 241 165 116 218 153 212 196 131 17 150 236 215 126 168 218]] test_event | 2019/09/05 02:56:38 どのコントラクトのどのTopicを対象にイベントを検知処理するか設定: {<nil> <nil> <nil> [[125 137 92 95 62 226 4 96 16 225 156 245 254 164 133 206 67 15 12 205]] [[[104 73 247 164 9 173 151 211 156 95 250 7 75 247 101 51 11 241 165 116 218 153 212 196 131 17 150 236 215 126 168 218]]]} test_event | 2019/09/05 02:56:39 コントラクトとの接続: 0xc000075680 &{0xc000414680 0xb37700 {0xa5d340 0xc000075680 18} eth 0x1feed340575875d6fe33bb68948a66c4 0xc0000757a0 {{0 0} 0} 0xc000075740 {{0 0} 0} 0xc0004476e0} <nil> test_event | 2019/09/05 02:56:39 roomFactoryAbiをオブジェクト化: {function () returns() map[createRoom:function createRoom() returns() destroy:function destroy() returns() destroyAndSend:function destroyAndSend(address _recipient) returns() owner:function owner() constant returns(address) pause:function pause() returns() paused:function paused() constant returns(bool) renounceOwnership:function renounceOwnership() returns() transferOwnership:function transferOwnership(address _newOwner) returns() unpause:function unpause() returns()] map[OwnershipRenounced:event OwnershipRenounced(address indexed previousOwner) OwnershipTransferred:event OwnershipTransferred(address indexed previousOwner, address indexed newOwner) Pause:event Pause() RoomCreated:event RoomCreated(address indexed _creator, address _room, uint256 _depositedValue) Unpause:event Unpause()]} <nil> test_event | 2019/09/05 02:56:39 イベント検知中
なにかヒントになることがありましたらご教示頂けますと助かります。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/05 06:05
2019/09/05 12:52
2019/09/05 19:03