JKになりたい

何か書きたいことを書きます。主にWeb方面の技術系記事が多いかも。

RaidenNetworkを動かしてみたメモ

概要

RaidenNetworkはERC20に準拠したトークンをオフチェーンで高速に送受金できるような仕組みです。
BitCoinでいう「LignthingNetwork」のEthereum版に相当します。
低コスト、スケーラブル、プライバシーが保護される、といった特徴があります。

RaidenNetworkではグローバルコンセンサスは必要ありません。
on chainにdepositしたトークンによって完全に担保されたbalance proofと呼ばれる 、電子署名とhash locked transfer技術によって達成されます。


(PaymentChannelの概念図 https://raiden.network/101.html から転載)

AとBでやりとりする時は、その間に「Payment Channel」と呼ばれる一時的なチャネルを作成しそこでやりとりします。
ここでのやり取りは実際のブロックチェーンに関与せず、一瞬で送受金することが可能です。
ただし、やり取り可能な限度額はon-chainにdepositした額までという制約があります。
また、このchanelを「生成する時」と「閉じる時」には実際のブロックチェーンに書き込む必要があります。

また、Raiden Networkは以下のようにPaymentChannelのネットワークを構築することが可能です。

以下だと例えば、AからDに送金するためにA->B->E->Dという経路で送金が可能になります。


この送金に手数料はかかりません。ただし、ネットワークの仲介者が手数料を取ろうと思えば取ることも可能です。
問題点が、A->B->E->Dのルートで送金する際、全てのPaymentChannelで送金額以上のdepositをしておく必要があるということです。
この性質のため、Raiden Networkは多額の送金には向いていません。

一方で、少額取引(micro payment)には非常に有用です。

RaidenNetworkを動かしてみる

起動

  • installする
    macならhomebrewで入ります
brew tap raiden-network/raiden
brew install raiden

今回入れたのはv0.11.0です(2018/10/05にv0.12がリリースされています)

  • Ropstenテストネットワークに接続
    Ropsten以外だと、raiden起動時にThe chosen ethereum network id '3' differs from the ethereum client '15'. Please update your settings.って怒られました。
    現状はRopstenでしか動かせないようです。

なので今回はInfura経由ノード経由で接続したいと思います

raiden --keystore-path  ~/.ethereum/testnet/keystore --eth-rpc-endpoint "https://ropsten.infura.io/v3/<yourToken>"

上記コマンドを実行する前に、~/.ethereum/testnet/keystore秘密鍵を設置しておく必要があります。
Metamaskで登録してあるアカウントを書き出そうと思ったんですけど、keystoreのjsonファイルを出力することはできないようです。

そこで、nakajoさんが公開されているhdwallet-to-keystoreを利用します。

$ hd2keystore "north hoge hoge ......" password >> ~/.ethereum/testnet/keystore/account1.json
$ hd2keystore -i 1 "north hoge hoge ......" password >> ~/.ethereum/testnet/keystore/account2.json

送受信を試すので、2つのアドレスを登録しておきましょう。
これでOKです。raiden networkを起動します。

起動してしばらくすると、

The Raiden API RPC server is now running at http://127.0.0.1:5001/

APIサーバが立ち上がります。アドレスを選択する画面になりますので、いずれかを選択します。

起動後、リクエストが通る事を確認します。

$curl -i http://localhost:5001/api/1/address
{"our_address": "0xxxxxxxxxxxxxxxxxxxx"}

これで準備完了です!

ERC20トークンの送受金

まず、トークンをraiden networkに登録する必要があります。
とりあえず既に登録されていないか確認しておきましょう。

curl -i http://localhost:5001/api/1/tokens | grep 0xxxxxxx

登録済みでなければ、トークンを登録します。
公式ドキュメントに

For the Raiden Red Eyes release, it will not be possible to register more than one token, due to security reasons in order to minimise possible loss of funds in the case of bugs.

と書いてある通り、1つのトークンしか登録できないようで注意が必要です。

また、公式ドキュメントではhexアドレスを指定しているようですが、EIP55に基づいてエンコードしないと

{"errors": ["invalid endpoint", "Not a valid EIP55 encoded address."]}

とエラーが帰ってくるので注意が必要です。

全て小文字のhexアドレスしか持っていない場合は、https://ropsten.etherscan.io でそのアドレスを入れる事で、簡単にEIP55準拠のアドレスを取得することができます。

curl -i -X PUT http://localhost:5001/api/1/tokens/0xxxxxxxx -H 'Content-Type: application/json'
HTTP/1.1 201 CREATED
mimetype: application/json
Content-Type: application/json
Content-Length: 71
Date: Thu, 11 Oct 2018 06:04:24 GMT

{"token_network_address": "0xxxxxxxx"}

トークンの登録が完了しました。

Payment Channelを開く

トークンの登録が完了したので、Paymentchannelを開きます

curl -i -X PUT http://localhost:5001/api/1/channels -H 'Content-Type: application/json' --data-raw '{"balance": 1000, "partner_address": "0xxxxxxxxxxxxxxx", "settle_timeout": 500, "token_address": "0xxxxxxxxxxxxx"}'
HTTP/1.1 201 CREATED
mimetype: application/json
Content-Type: application/json
Content-Length: 325
Date: Thu, 11 Oct 2018 06:28:11 GMT

{"partner_address": "0xxxxxxxxxxxxxxxxx", "settle_timeout": 500, "balance": 0, "channel_identifier": 1, "reveal_timeout": 10, "token_address": "0xxxxxxxxxxxxxxx", "token_network_identifier": "0xxxxxxxxxxxxx", "state": "opened", "total_deposit": 0}

これでPayment Channelが開きました

Depositする

最初のアドレスがトークンアドレス、2つ目が参加者のアドレスです

curl -i -X PATCH http://localhost:5001/api/1/channels/0xxxxxxxxxxxx/0xxxxxxxxxxxxxx-H 'Content-Type: application/json' --data-raw '{"total_deposit": 10000}'
HTTP/1.1 200 OK
mimetype: application/json
Content-Type: application/json
Content-Length: 333
Date: Thu, 11 Oct 2018 06:40:43 GMT

{"partner_address": "0xxxxxxxxxx", "settle_timeout": 500, "balance": 10000, "channel_identifier": 1, "reveal_timeout": 10, "token_address": "0xxxxxxxxxxxxxx", "token_network_identifier": "0xxxxxxxxxxxxxx", "state": "opened", "total_deposit": 10000}

これで最初のユーザはDepositが完了しました。

もう1人のユーザもDepositする必要がありますので、やっていきます。
まず、もう1人のユーザを選択してraidenを立ち上げます。

raiden --keystore-path  ~/.ethereum/testnet/keystore --api-address 127.0.0.1:5002 --eth-rpc-endpoint "https://ropsten.infura.io/v3/*******"

depositします

$ curl -i -X PATCH http://localhost:5002/api/1/channels/0x12c6a63eb028e6dEE546b60f54460F8e008baf34/0x31253350aFc5b923F88ED45e89721A3f3c64d21F -H 'Content-Type: application/json' --data-raw '{"total_deposit": 12000}'

トークンのやり取りをする

パートナーにERC20トークンを送金してみます。
1つ目のアドレスはトークンのアドレス。2つ目はパートナーのアドレスです。

curl -i -X POST http://localhost:5001/api/1/payments/0x12c6a63eb028e6dEE546b60f54460F8e008baf34/0x0aB9FF4b4A8D98ae78f87062874e6F652152f59D -H 'Content-Type: application/json' --data-raw '{"amount": 40}'
HTTP/1.1 200 OK
mimetype: application/json
Content-Type: application/json
Content-Length: 242
Date: Thu, 11 Oct 2018 09:02:51 GMT

{"amount": 40, "target_address": "0x0aB9FF4b4A8D98ae78f87062874e6F652152f59D", "identifier": 164889477444762312, "token_address": "0x12c6a63eb028e6dEE546b60f54460F8e008baf34", "initiator_address": "0x31253350aFc5b923F88ED45e89721A3f3c64d21F"}

残高を確認してみます。

5001

$ curl -X GET http://127.0.0.1:5001/api/1/channels
[{"partner_address": "0x0aB9FF4b4A8D98ae78f87062874e6F652152f59D", "settle_timeout": 500, "total_deposit": 12000, "reveal_timeout": 10, "token_network_identifier": "0xe764B50C97166C71626AB3CB5B18bd01eDe1ef80", "balance": 11960, "channel_identifier": 1, "token_address": "0x12c6a63eb028e6dEE546b60f54460F8e008baf34", "state": "opened"}]P

5002

$ curl -X GET http://127.0.0.1:5002/api/1/channels
[{"token_network_identifier": "0xe764B50C97166C71626AB3CB5B18bd01eDe1ef80", "token_address": "0x12c6a63eb028e6dEE546b60f54460F8e008baf34", "reveal_timeout": 10, "total_deposit": 12000, "settle_timeout": 500, "channel_identifier": 1, "partner_address": "0x31253350aFc5b923F88ED45e89721A3f3c64d21F", "balance": 12040, "state": "opened"},

40トークン増加・減少していることがわかります。

トークンの引き出し(Payment ChannelのClose)

curl -i -X PATCH http://localhost:5001/api/1/channels/0x12c6a63eb028e6dEE546b60f54460F8e008baf34/0x0aB9FF4b4A8D98ae78f87062874e6F652152f59D -H 'Content-Type: application/json' --data-raw '{"state": "closed"}'
$ curl -i -X PATCH http://localhost:5001/api/1/channels/0x12c6a63eb028e6dEE546b60f54460F8e008baf34/0x0aB9FF4b4A8D98ae78f87062874e6F652152f59D -H 'Content-Type: application/json' --data-raw '{"state": "closed"}'
HTTP/1.1 200 OK
mimetype: application/json
Content-Type: application/json
Content-Length: 333
Date: Thu, 11 Oct 2018 09:44:48 GMT

{"partner_address": "0x0aB9FF4b4A8D98ae78f87062874e6F652152f59D", "settle_timeout": 500, "total_deposit": 12000, "reveal_timeout": 10, "token_network_identifier": "0xe764B50C97166C71626AB3CB5B18bd01eDe1ef80", "balance": 11960, "channel_identifier": 1, "token_address": "0x12c6a63eb028e6dEE546b60f54460F8e008baf34", "state": "closed"}

settle_timeoutがpayment channelがcloseしてから、チャンネルが解決する(メインのブロックチェーンに資産を戻す)までに必要なブロック数になります。 デフォルトでは500のようですね。短くしておけば良かったです・・。

statusがclosedになっている事がわかります

 curl -X GET http://127.0.0.1:5001/api/1/channels
[{"partner_address": "0x0aB9FF4b4A8D98ae78f87062874e6F652152f59D", "settle_timeout": 500, "total_deposit": 12000, "reveal_timeout": 10, "token_network_identifier": "0xe764B50C97166C71626AB3CB5B18bd01eDe1ef80", "balance": 11960, "channel_identifier": 1, "token_address": "0x12c6a63eb028e6dEE546b60f54460F8e008baf34", "state": "closed"}]P

もう片方のノードを参照しても、同じくclosedになっています。

$ curl -X GET http://127.0.0.1:5002/api/1/channels
[{"token_network_identifier": "0xe764B50C97166C71626AB3CB5B18bd01eDe1ef80", "token_address": "0x12c6a63eb028e6dEE546b60f54460F8e008baf34", "reveal_timeout": 10, "total_deposit": 12000, "settle_timeout": 500, "channel_identifier": 1, "partner_address": "0x31253350aFc5b923F88ED45e89721A3f3c64d21F", "balance": 12040, "state": "closed"},

settle_timeoutの分だけ待つと、statusがclosedからsettleに変わり、トークンが戻ってきます。

以下はトークンのTransferイベントログです。depositした12000トークンに40トークン送受金した額が反映されて、メインチェーンに戻ってきていることが確認できます。

f:id:sakata_harumi:20181012133353p:plain

まとめ

トークンの登録から、PaymentChannelの確立、送金出金まで一通り試すことができました。

App版のチュートリアルも公式は提供しているので、そちらでも動作を体験することができます。

現在はRopstenテストネットワークで開発版が動いている状態なので検証にしか使えませんが、将来的に採用していきたい技術だと思います。
ただこれ、(勘違いだったら恐縮なのですが)1アドレスにつき1つのraidn nodeを立ち上げないといけないっぽいんですよね。
立ち上がるのも若干時間がかかったりと、なかなかユーザに使ってもらうようにするのは実装が難しそうです。