Uniswap V3 発売直前記念🎉DEXシステムトレードの手引き
こんにちは。金の亡者の紫藤かもめ(@shidokamo)です。今週の推し漫画は「悪魔のメムメムちゃん」です。今回は、いつもの記事と違って、非常にテクニカルな内容ですが、DEXシステムトレードをやってみたい人に参考になるような記事を書いてみました。
DEXシステムトレードって?
Uniswap などの DEX のトレードをプログラムで自動売買することです。
それって儲かるの?
うまく歪みを見つければ、SUGOKU儲かるらしいです。僕は損しかしていません。とほほ。
なんで儲かるの?
背景としては、
- DEX の仕様、仕組みを詳細に理解している人はほとんどいない(0.1%もいないでしょう)。
- DEX を手動で使う人が多い。
- しかし DEX は大流行している。
- DEX の取引の自動化は割と難しい。
という状況が収益機会の発生要因の一部になるかなと思います。
この先も儲かるの?
DeFi 流行のトレンドは、この先数年は拡大が続くと睨んでいます。そして、DEX は DeFi の大動脈なんですよね。そう言った意味で、この先もまだまだ取引機会を発見できるかと思います。
まあ DeFi ってやればわかりますけど、すごく楽しいですよね単純に。
手動でトレードしてはだめなの?
仕組みの関係上、手動で最適な注文を入れるのは不可能に近いです。ここはCEXと大きく異なる点です。理由は、
- そもそもUniswapのUIは現在はレートの配信の遅延がとんでもなく大きいです(体感的には分単位だと思います)。昔はもっと早かったと思うのですが、ユーザが増えたので対応しきれないのでしょう。
- 手動で最適なガス代を即座に設定するのは不可能です。
- UIから注文をすると、何度もクリックを繰り返す必要があります。
- 指値注文はありません。
プログラムを用いて自動で注文を入れる優位性は大きいです。
それって難しいの?
かなり難しいです。Ethereum 周りの細かい仕様、処理を完全に理解して適切に処理してやる必要があります。その一助としてこの記事を書いてみました。
Ethereum というのは、ルールしかなくて、ルールの中では何をやってもいいという世界です。なので、隙を見せたらすぐに皆さんの財産を Ethereum 世界のルールに則って奪われると思ってください。現実世界では違法でも、Ethereum 世界ではルール違反ではないからです。
実際私はそそっかしいカスプログラマなので運が悪いので、しめて100万円以上やられてます。とほほ。最近もコードに一箇所ミスがあってフロントランニングで一撃数千ドル抜かれたのは笑いました。具体的にいうと、とあるメソッドにObject.toString()の文字列を渡すべきところを誤ってObjectそのものを渡してしまったらトランザクションの中身が一部おかしくなってそういう事になっちゃいました!へへ…運が悪いな〜運が!
売れないトークンなんてものを買わされたこともありました。これは敵ながら天晴れでしたね〜。
皆さんは本記事の手引きを参考にして慎重に進めてください!
ひとつひとつとにかく慎重にやっていけば、大きく損することはないでしょう。
「完璧に理解した!」と上級者ムーブをすると私のようなことになります。
プログラミング初心者でもできる?
実際のシステムトレードは、プログラミングを中心としたシステム構築・問題解決にかなり自信がある人以外はやめたほうがいいです。凝ったことをやり始めると、下手するとひとつの間違いで大きな資金を一気に失う可能性があるからです。
実際のシステムトレードは、腕に覚えがある人が挑戦してください。
ただ、以下で紹介していることは、基本的にテストネットで試すことが出来ます。
シリアスなトレードは行わずに単純に色々と調べて動かしてもみたいということであれば、全く問題はないので是非やってみてください。
Uniswap を極めよう
DEXと書きましたが、要は Uniswap です。DEXとは Uniswap であると言ってもいいくらいの流動性が Uniswap に集まっています。
ネットワーク効果が大きいので、この先も Uniswap にお金が集まり続けるでしょう。まずは、Uniswap を極めるのが良いかと思います。
Uniswap には、V1、V2、V3 とありますが、ひとまず V2 を完璧に使いこなすための簡単な手引きを以下に書きました。V1 は使う必要ないです。V3 はまだ早いです。
Uniswap V2 トレードの特徴は?
Uniswap V2 に代表される現在主流の AMM のトレードは以下のような際立った特徴を持ちます。
- 全ての取引、情報取得を Ethereum のブロックチェーンと直接やりとりします。
- 口座開設は不要です。
- KYCは不要です。
- アカウントという概念はありませんが、強いて言えばアカウントがいくらでも作れる取引所のような感じです。
- BAN されることはありません。
- 専用APIのようなものはありません。例えば現在のトークンの価格を取得するには Ethereum のノードに問い合わせをします。
- 裏を返せば、APIのレートリミットのようなものに悩まされることはありません。
- マッチングが不連続で発生します。Ethereumのブロックが生成されるごとに、取り込まれたトランザクションがマッチングします。
- 全ての注文は、IOC(Immediate Or Cancel)のような性質を持ちます。
- 参加者全員の取引履歴が全て公開されています。
- 手数料が高いです(一律0.3%)。これは流動性提供のインセンティブを与えるために仕方のないところではあります。(手数料に大口取引割引みたいなものがないので非常に公平ではあります。)
本記事での説明の内容
以下、段々とテクニカルな内容になりますが、本記事では要点のみを紹介します。
調べればすぐわかるような点については省略をして簡潔に記載しています。ちゃんと書いたら本一冊書けるくらいの内容なので、中身はそれなりに濃いです。
Uniswap で遊ぶ
Uniswap V2 をとりあえず使って遊んでみましょう(使ったことがない人もまだまだいますよね)。最初はテストネットでやってみましょう。テストネットなら失敗してもノーダメージですから安心してください。
- Uniswap V2 には、テストネットのコントラクトがあります。 Ropsten, Kovan, Rinkeby, Goerli 全部のテストネットにコントラクトがあると思います。
- まず、テストネットの ETH を faucet からもらいましょう。
- 次に、Metamask をテストネットにつないで Uniswap にアクセスしてみてください。当然ですが、フィッシングサイトには注意してください。
Uniswap : https://app.uniswap.org/
- 以下のスクリーンショットのように、画面上部にテストネットに接続していることが示されます。(この場合、'Ropsten' に接続していると表示されています)
- ここで、テストネットの ETH を DAI などにスワップなどしてみましょう。 トークンの値段はめちゃくちゃですが気にしないでください。
- 流動性提供など試せることはなんでもやってみましょう。
Uniswap V2 の仕組みの基本を理解する
色々記事はあるかと思いますが、自分はキョロナッツさん(@kyoronut)の記事で最初勉強をしました。DeFi の最先端を追っておられる方ですが、基本的な情報をわかりやすく紹介して頂いてとてもありがったかったですね。DeFi神です。
https://alis.to/lisalisa/articles/anLYvOqDwWqb
https://alis.to/lisalisa/articles/3Y1kdkAprEYo
- 最初は読んでも意味がわからないと思いますが、この先の手順でEtherscanで他人のトランザクションを観察したり、自分でスワップをして前後でプールの状態がどう変わるかなど手を動かすと理解が進むと思います。
- 最終的に、一番目の記事が完璧に理解できないくらいの理解度だとまだメインネットで実際のトレードはしないほうがいいです。テストネットで試しながら理解していきましょう。
参考書の紹介:Mastering Ethereum
さて以降では、実際に手を動かしてトランザクションのデータの意味を理解して、自分でトランザクションを発行する必要があるわけですが、細かい部分を理解するために先に参考書を紹介しておきます。
Andreas M. Antonopoulos 氏と Gavin Wood 氏の書いた名著 "Mastering Ethereum" を参考書籍にするのが良いと思います。GitHub 上でバージョン管理されている本なので GitHub で無料で読めちゃいます。オライリーから書籍も出てます。御二人ともいわば暗号通貨界の殿堂入り選手です。
とりあえず全部読む必要はないです。何か基本的なことを調べるときに使うとやっぱりちゃんと書いてあります。
https://github.com/ethereumbook/ethereumbook
スマコンやトランザクションに触れてみる
Ethereum 上でスマートコントラクトに対するトランザクションがどういうデータを使って処理されているか雰囲気をつかんでみましょう。
- ERC20 トークンの移動を Metamask からやってみましょう。トランザクションを手動で発行してみるってことですね。
- これももちろんテストネットで出来ます。
- Etherscan に行って、どんなデータがトランザクションとして送られているか観察しましょう。(テストネット用の Etherscan を使うことに注意してください)
- 下のような感じのデータから各種の値の意味を勉強してみるといいと思います。(念の為:自分とはなんの関係もない適当に拾ったトランザクションです。)
- Nonce の意味なんかも理解しておきましょう。"Mastering Ethereum" に載ってます。これを読んで理解できないようだとまだ先に進まないほうがいいです。
https://ropsten.etherscan.io/tx/0x6c0dbd919097ca1349a932294b1d15b834092fda39cb5e6c3526869566d83ff2
ERC20トークン(コントラクト)の仕様を理解する
Uniswap でスワップするものは全て、ERC20トークンと呼ばれるものです(基本的なERC20の仕様にいくつか機能を加えたようなものも多いです)。こいつの仕様をしっかり理解しておきましょう。
- 特に Decimals については絶対に理解しておくことをおすすめします。
- メソッドも頭に入れておくといいですね。
- とりあえずプログラムを使わなくてもEtherscan上で、メソッドを呼べるのでこれを使ってみると良いと思います。
- 例えば、Etherscan 上で以下の USDC のコントラクトに行って、balanceOf(address) というメソッドを呼んでみましょう。
https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#readProxyContract
- 引数にアドレスを渡してやると balance を得ることができます。
- 試しに Vitalik のアドレスを入れて USDC の残高を見てみました。
- 帰ってきた値を見て、Vitalik は 804 万ドルも USDC を持っているのか!と思ってしまった人はしっかりと勉強いたしましょう。
プログラミング環境について
この辺りから、GUIではなくプログラムで処理を行っていくことになりますのでまず簡単に必要な環境などについて紹介します。
- Node.js (JavaScript) でプログラムを書くことになります。書けない人はまず書けるようになりましょう。
- 現状 Node.js 以外でやるのは非常にツラいです。ライブラリなどは基本的に全部 JavaScript で書かれていると思ってください。
- もし、JavaScript を一切書いたことがない人でも一から勉強したほうが全然早いくらいの環境です。
- JavaScript を勉強する場合は、JavaScript は歴史的経緯から非常に仕様が複雑だということを考慮に入れて、最新のちゃんとした参考書で勉強しましょう。色々と参考書はありますが、以下の本はおすすめです。サイトで PDF を買えます。また、一度買うと毎年更新した最新の本を配信してくれるという実に良心的なサービスをやっています。
https://exploringjs.com/impatient-js/
- JavaScript の非同期処理の挙動について特にちゃんと理解しておきましょう。 同期処理、非同期処理をちゃんと使い分けられるようにするのが重要です。JavaScritpt の非同期処理はトレードとの相性が非常に良いので、使いこなせるようになるとすごく好きになれると思います。
- Node.js をインストールして一通り使えるようになるところが第一歩です。
web3.js を使ってみる
web3.js は、Ethereum のノードとやり取りをしたりするためのAPIライブラリです。割と低級な処理を行うためのライブラリですが、現状ではまだまだ web3 を割と使い倒す必要があります。
- トランザクションの問い合わせなんかをしてみましょう。
- web3.utils は特に頻繁に使うライブラリなのでひとつひとつ理解してみるといいかと思います。
- トランザクションを取得して、中身のデータをダンプして様子をみてみる、web3.utils で値を操作するみたいなことをやると、泥臭いですが結局は近道かもしれません。
ethers を使ってみる
ethers は、web3.js よりももう少し高級なインターフェースを提供するライブラリです。
- 公式のサンプルコードをみるとどんなことができるのかわかると思います。
- これも使えるようになっておくと便利ですのでざっと眺めておきましょう。
- ethers で、ERC20トークンのコントラクトのメソッドを叩いたりして実際にコントラクトとやりとりしてみると良いです。公式にサンプルがあると思います。Etherscan 上でコントラクトのメソッドを呼び出した結果と比較しましょう。
- メジャーなERC20トークン(USDC、USDT、WBTC、UNI)などは一通りコントラクトとやりとりしてみると良いかと思います。
- 2021年現在の最新バージョンは v5.0 です。ネットのサンプルコードは古いバージョンのものを使っていることがよくあるので注意してください。
トランザクションを発行してみる
プログラムから簡単なトランザクションを作って秘密鍵で署名してノードに送ってみましょう。テストネットで思う存分やりこみましょう。
- 自分は、'@ethereumjs/tx' というライブラリを使っています。
- ちゃんと公式ドキュメントをみて、使い方を学習しましょう。とりあえず Legacy tx で良いです。
https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx
- 雑にメインネットでがんがんトランザクションを発行して火傷した自分としては、テストネットで訓練をするのがとにかく大切だということを再度強調させていただきます。
- まずは、ETHを送金したり、ERC20を送金したりしてみると良いかと思います。
- トランザクションに意図的に誤った情報を入れるとどうなるか、どのような Receipt が帰ってくるか、Gasの設定を間違えるとどうなるかなど色々と研究されると良いかと思います。
- Metamask からトランザクションを発行した場合を正解例として使い、プログラムからトランザクションを発行した場合と違いがないようにできたか確認しましょう。
Uniswap SDK をインストールして使ってみる
Uniswap SDK はUniswap チームが公式に出している Node.js の有難いライブラリです。
レポジトリ:https://github.com/Uniswap/uniswap-v2-sdk
Quick Start:https://uniswap.org/docs/v2/javascript-SDK/quick-start/
Reference:https://uniswap.org/docs/v2/SDK/getting-started
- これは Uniswap からの情報取得やトランザクションを発行するための前処理を楽にしてくれるものです。
- 例えば、あるペアプールの現在の Reserve の量を取得したり、執行価格の計算などをしてくれます。この計算を自分でやるのは絶対にやめましょう。
- レポジトリに簡潔なテストコードがあるので、これをみて使い方を理解するのが一番良いです。
- まずは、SDK を使って、ペアプールの情報を取得したりしてみましょう。
- この SDK は、数値型周りの仕様が特に難解なので出来るだけ手を動かしてちゃんと理解したほうがいいです。ここを曖昧にしていると後で絶対に間違いを入れて損失を出します。Object の中身をダンプしてどんなデータを保持しているか見てみたりするのは良いと思います。
Swap トランザクションを発行する
さて、この辺りでようやく実際のスワップトランザクションを発行する準備はできたかなと思います。
以下のトランザクションをひとつづつ発行してみましょう。Approve の挙動をみるためには新しいアドレスを使うと良いと思います。
- ETH -> Token のスワップトランザクション
- Approve トランザクション
- Token -> ETH のトランザクション
- Token -> Token のスワップトランザクション
より複雑な処理を試す
基本的なスワップが行えるようになったら以下のようなこと研究してみるといいかなと思います。
- Uniswap のコントラクトの全部のスワップメソッドを試してみましょう。(ExactOutput と ExactInput の全ての組み合わせ)
- Slippage(MinimumOutput, MaxInput) を変更して挙動をみましょう。
- 無効なトランザクションをたくさん発行してみましょう。
- 複数のルートを使ってトレードしてみましょう。
- 複数のルートから最適なレートを取得しましょう。
- 複数の bot からトランザクションを同時に発行して競合した場合の挙動を観察しましょう。
- Buy -> Approve -> Sell あるいは、Approve -> Buy -> Approve -> Sell などの一連のトランザクションを自動で発行してみましょう。それぞれがエラーになった場合の処理を適切に行いましょう。
(発展編)自分のノードを建てる
色々やっていると、Ethereum のノードとやり取りをするってことは、自分でノードを建てちゃうのが一番良いってことじゃね?という発想になるかと思います。
- プールの状態の問い合わせ、トランザクションの発行など色々な処理をノードとやりとりするので自分でノードを作ったほうがパフォーマンス、安定性がいいと私は思っています。
- Infura とかの有料プランでもまあ大丈夫な気がしますが使ったことがないのでよくわかりません。Infura は2020年11月に大規模障害を起こしたことがあり、その原因が、Ethereum クライアント(geth)の更新を半年以上行っていませんした〜というめちゃくちゃなやつだったので信用していません。
https://blog.infura.io/infura-mainnet-outage-post-mortem-2020-11-11/
-
もしノードを建てる場合は、以下の点に注意してください。 自分は GCP を使っています。AWS か GCP がいいでしょう。ハードウェアスペックに問題がある場合永遠に最初の同期が終わりません。
-
十分なネットワーク帯域を準備(自宅でやる場合以外は問題ないでしょう)
-
SSD必須。出来れば複数台を接続して並列書き込み速度を向上させる。書き込み、読み込み速度をちゃんと測定してテストしてください。
-
メモリも多めに
-
スクリプト等で、簡単にクライアントの更新ができるようにしておく。クライアントの更新も平常時にちゃんとテストしておく。
- 当然ですがファイアウォールは適切に設定しましょう。
-
- ちなみに、自分で Ethereum のノードを建てても Uniswap SDK などを使う時にちゃんと PROVIDER を自分のノードに指定しないと意味ないので注意してください。(忘れがち)
その他
いくつかの Ethereum ハードフォークが予定されています。ライブラリの更新や情報収集など怠らないようにしていきましょう。
個別の質問には答える余裕がないので自己解決でお願いします!
ちなみにこの記事の内容は基礎的なことができるようになりましょうって感じで、DEXガチ勢はコントラクトを絡めて三角裁定をやってたりするんでなかなか大変ですねはい。https://etherscan.io/tx/0x75b9abc48d00398f8f8a68a4ca00dfe4392205ac234ce9ab280d87aed3a470a9
まとめ
まあそんな感じで楽しんでください〜