ブロックチェーンと連携する際の注意点まとめ
はじめに
ブロックチェーンと連携して動作するようなアプリケーションを作成する場合、ワンダフルなエッジケースが大量に存在します。この記事では、これらの注意点をサクッとまとめます。
独学と経験則の部分が多いので、間違った箇所があるかもしれませんが、コメントなどで指摘して頂けるとありがたいです。あわよくば、この記事をはじめとして様々なTipsが集まればなと思います。
当日20時から急いで書いているので誤字脱字が多いかも
1. たまにトランザクションが消滅する
基本的なブロックチェーンでは、一次的に矛盾するブロック(=異なる歴史)が同時に存在することがあります。この場合、どちらの歴史が正しいかは、確率的に決定されます。そして、確率で敗れた側の歴史に記録されたトランザクションは無効化され、事実上存在しなかったことになります。
取引所に例えると、ユーザーの入金が無かったことにされたり、ユーザーに出金が届かなかったりします。これでは商売あがったりですね。
この問題が顕著なのはPolygonで毎日大体500件ほどのトランザクションが消滅しているようです。ネットワーク全体のトランザクションが日に約500万件なので、一万分の一ぐらいの確率で発生するようです。
では、どうすればいいでしょうか?
一般的な対策は、確率が収束するのを待つことです。主要な取引所では、入金の際に数ブロック待つことで、その後の残高への反映が行われますが、これは上記の理由によるものだと思います。
また、出金する際も同様で、発行したトランザクションが消滅しないか確認し、消滅していた場合はリトライするなどの対策が必要です。
2. ガス代の推定がうまくいかない
Polygonのような、ガス代の桁が違うチェーンで何も考えずにトランザクションを実行すると、なかなかブロックチェーンに取り込まれなかったり、エラーが返ってきたりします。
ガス代推測アルゴリズムを使うか、チェーンが提供するAPIを利用するなどして、いい感じなガス代を設定したうえでトランザクションを投げましょう。
いい感じのガス代を計算する方法については、次のリポジトリなどでまとめられています。(RainbowWalletも参考にしているらしい?)
3. トランザクションが詰まる
Ethereumなどのチェーンは直前のnonceのトランザクションが実行されるまで、次のトランザクションは実行されません。
ethersなどでトランザクションを実行すると、まだ取り込まれていないトランザクションも考慮したnonceが設定されます。
なので、ガス代が少ないなどの理由でなかなかトランザクションが取り込まれないと、後続のすべてのトランザクションも実行されない、というような事態に陥ります。
4. RPCが遅れる
ブロックチェーンのデータを取得する際、JSON RPCを使用することが一般的ですが、このRPCの同期が遅れることがあります。その結果、ユーザーがフロントエンドで行ったトランザクションが、バックエンドで確認した際には未実行のように見えることがあります。
viem(たしかethersも)などのライブラリでは、トランザクションを取得するために何度かリトライする機能がデフォルトで提供されています。そのため、この問題はそれほど心配する必要はないかもしれません。
実際にchainlistなどでチェーンごとのRPC同期状況を見てみると、一部のRPCは数ブロック分遅れていることがわかると思います。
終わりに
本当にサクッとまとめました。まだいくつか書き忘れている気がしますが、アドベントカレンダーに間に合わないので見切り発車します。
今後も僕の知見が深まり次第、この記事に追記していく予定です。
Discussion