try catch and ...release
ページ
ホーム
Chromeアプリ開発Tips
公開アプリ
Ubuntu
Linuxコマンド
#!/bin/bash
ブロックチェーンと暗号通貨
2017年6月1日木曜日
Ripple: Gatewayのアセット発行とユーザ間の支払いの流れ
RippleでGatewayになる手順です。 Gatewayは独自アセットを発行したり、ユーザが保有するアセットの償還要求に応じたりします。 Gatewayが発行したアセットは、ユーザ間で自由にやり取りできます。 Gatewayはユーザ間のアセット送金毎に手数料を徴収することもできます。
## 目次 + [前提](#premise) + [アセット発行から送金まで](#issue-send-asset) + [Gatewayとしてセットアップ](#setup-as-gateway) + [トランザクションへの署名 (sign) と伝播 (submit)](#sign-and-submit) + [アセット名を伝える](#advertise-asset) + [Trust Lines を張る](#expand-trustline) + [アセットを発行する](#issue-asset) + [ユーザ間でアセットのやり取り](#asset-payment) + [アセット送金手数料の設定](#set-transfer-fee) + [アセットの償還](#redeem-asset) + [ハマりポイント](#trap) + [DefaultRipple と NoRipple](#defaultripple-noripple) + [意外と重要な noripple_check](#important-noripple-check) + [参考](#refs) ## 前提 (premise) - 発行アセット名: **"XXX"** - 登場人物 + **issuer** (アセット発行者) アドレス: <issuer_address> + **user1** (ユーザ1) アドレス: <user1_address> + **user2** (ユーザ2) アドレス: <user2_address> - Ripple **TestNet** を利用 **TIPS:** - テストアカウントは[こちら](https://ripple.com/build/ripple-test-net/)で作成 - TestNetのエンドポイント: > WEBSOCKETS: wss://s.altnet.rippletest.net:51233 > REST SERVER: https://api.altnet.rippletest.net:5990 > RPC PORT: 51234 - 残高などのチェックは以下の REST API を使うと便利: `https://api.altnet.rippletest.net:5990/v1/accounts/<アドレス>/balances` ## アセット発行から送金まで (issue-send-asset) ### 1) Gatewayとしてセットアップ (setup-as-gateway) issuer が Gateway として振る舞うには、**顧客ユーザとの関係を構築する前**に、以下の手順が必要になります: - `DefaultRipple` flag を **ON** にする。 これによって *Rippling* が可能になり、顧客ユーザたちはissuerが発行したアセットを互いに取引できるようになります。 実際のやり方としては、issuerが次のような`"TransactionType": "AccountSet"`な tx (トランザクション) オブジェクトを`SetFlag: 8`で投げればOK: ``` { "Account": "
", "TransactionType": "AccountSet", "SetFlag": 8, // DefaultRippleをON! "Flags": 0, "Fee": "15000", "LastLedgerSequence": 8007750, // 最新のledger_index + 3 ぐらい "Sequence": 12 // issuerのaccount_infoの"Sequence" } ``` ※ `LastLegerSequence` と `Sequence` は自分の環境に読み替えてください。 #### 署名 (sign) と伝播 (submit) (sign-and-submit) トランザクションは全て、前述のような tx オブジェクトに秘密鍵で署名 (sign) して伝播 (submit) させます。以下は、ローカル上で秘密鍵で sign した後の tx オブジェクト (signed_txhex) を submit しています: ``` $ curl -X POST -d '{ "method": "submit", "params": [ { "tx_blob": "
" } ] }' https://api.altnet.rippletest.net:51234 ``` 参考: [Is it still possible to issue your own assets on Ripple?](https://bitcoin.stackexchange.com/questions/50759/is-it-still-possible-to-issue-your-own-assets-on-ripple) ### 2) アセット名を伝える (advertise-asset) issuer は、自分が発行するアセット名 *XXX* を顧客ユーザ user1, user2 に伝えます。 ### 3) Trust Lines を張る (expand-trustline) 顧客ユーザ user1, user2 は、issuer とそのアセット名 *XXX* に対して *Trust Lines* を張ります。Trust Lines を張ることで、顧客ユーザは issuer が発行したアセット *XXX* をやり取りすることが可能になります。 Trust Line を張るには、それぞれの顧客ユーザが以下のように`"TransactionType": "TrustSet"`なトランザクションを`"Flags": 262144`で投げます: ``` { "TransactionType": "TrustSet", "Account": "
", "Fee": "12", "Flags": 262144, "LimitAmount": { "currency": "XXX", "issuer": "
", "value": "100" }, "LastLedgerSequence": 8007750, // 最新のledger_index + 3 ぐらい "Sequence": 12 // user1のaccount_dataの"Sequence" } ``` 上記は user1 のトランザクションです。user2 の分も忘れずに実行しておきましょう。 Trust Lines 状況の確認: `https://api.altnet.rippletest.net:5990/v1/accounts/
/trustlines` ### 4) アセットを発行する (issue-asset) 顧客ユーザに対し、アセットを発行してみましょう。 以下の例では、 issuer が user1 に対して 100 XXX を発行しています: ``` { "TransactionType" : "Payment", "Account" : "
", "Destination" : "
", "Amount" : { "currency" : "XXX", "value" : "100", "issuer" : "
" }, "Fee": "10", "Flags": 2147483648, // デフォルトの tfFullyCanonicalSig フラグ "LastLedgerSequence": 8007750, // 最新のledger_index + 3 ぐらい "Sequence": 12 // issuerのaccount_dataの"Sequence" } ``` アカウント残高などの確認: `https://api.altnet.rippletest.net:5990/v1/accounts/
/balances` ### 5) ユーザ間でアセットのやり取り (asset-payment) 顧客ユーザ同士でアセットを送金してみましょう。 以下の例では、user1 が uesr2 に対して 100 XXX 送金しています: ``` { "TransactionType" : "Payment", "Account" : "
", "Destination" : "
", "Amount" : { "currency" : "XXX", "value" : "100", "issuer" : "
" }, "Fee": "10", "Flags": 2147483648, // デフォルトの tfFullyCanonicalSig フラグ "LastLedgerSequence": 8007750, // 最新のledger_index + 3 ぐらい "Sequence": 12 // user1のaccount_dataの"Sequence" } ``` この後、user2の残高を見ると以下のようになっています (rest API の `/v1/accounts/
/balances` で確認): ``` { "success": true, "ledger": 1616729, "validated": true, "balances": [ { "value": "10000.03299", "currency": "XRP", "counterparty": "" }, { "value": "100", // <= +100 "currency": "XXX", "counterparty": "
" } ] } ``` 一方のissuerの残高は以下のようになっています: ``` { "success": true, "ledger": 1616689, "validated": true, "balances": [ { "value": "9999.99676", "currency": "XRP", "counterparty": "" }, { "value": "0", "currency": "XXX", "counterparty": "
" }, { "value": "-100", // <= -100 "currency": "XXX", "counterparty": "
" } ] } ``` ## アセット送金手数料の設定 (set-transfer-fee) issuerは発行したアセットのユーザ同士のやり取りで送金手数料(Transfer Fee)を徴収できます。 デフォルトでは手数料率(`TransferRate`)はゼロになっていますが、これは自由に設定することができます。参考:[transfer-fee/#rippled](https://ripple.com/build/transfer-fees/#rippled) 例えば、issuerが`TransferRate`を`1100000000` (10%) に設定するには以下のようなトランザクションを投げます: ``` { "TransferRate": 1100000000, // 10%に設定 "TransactionType": "AccountSet", "Account": "
", "Flags": 2147483648, "Fee": "10000", } ``` それでは、user2 から user1 に 50 XXX 送金してみましょう。そのまま 50 XXX を送金しても `tecPATH_PARTIAL` エラーが発生します。送金するにはissuerへの手数料込み(+10%)の 55 XXX を送金する必要があります: ``` { "TransactionType" : "Payment", "Account" : "
", "Destination" : "
", "Amount" : { "currency" : "XXX", "value" : "50", // 送金額(手数料抜き) "issuer" : "
" }, "SendMax" : { "currency" : "XXX", "value" : "55", // 送金額(手数料込み) issuerが設定した送金手数料率10%を掛けた額 "issuer" : "
" }, "Fee": "10", "Flags": 2147483648, // デフォルトの tfFullyCanonicalSig フラグ "LastLedgerSequence": 8007750, // 最新のledger_index + 3 ぐらい "Sequence": 12 // user2のaccount_dataの"Sequence" } ``` 送金後、それぞれの残高は以下のようになります: issuer: ``` { "success": true, "ledger": 1617729, "validated": true, "balances": [ { "value": "9999.99675", "currency": "XRP", "counterparty": "" }, { "value": "-50", // "0" => "-50" "currency": "XXX", "counterparty": "
" }, { "value": "-45", // "-100" => "-45" (50 XXX 送金したuser2から10%の手数料(5 XXX)を徴収) "currency": "XXX", "counterparty": "
" } ] } ``` user1: ``` { "success": true, "ledger": 1617736, "validated": true, "balances": [ { "value": "9999.969508", "currency": "XRP", "counterparty": "" }, { "value": "50", // "0" => "50" "currency": "XXX", "counterparty": "
" } ] } ``` user2: ``` { "success": true, "ledger": 1617733, "validated": true, "balances": [ { "value": "10000.03299", "currency": "XRP", "counterparty": "" }, { "value": "100", // "100" => "45" (送金額 50 XXX と その 10% の手数料 5 XXX が引かれている) "currency": "XXX", "counterparty": "
" } ] } ``` ## アセットの償還 (redeem-asset) アセットをissuerへ返還してみましょう。issuerへのアセットの返還には送金手数料は掛かりません。 以下の例では、 user2 が issuer にアセット XXX を全額(45 XXX)返還しています: ``` { "TransactionType" : "Payment", "Account" : "
", "Destination" : "
", "Amount" : { "currency" : "XXX", "value" : "45", // 送金額(手数料抜き) "issuer" : "
" }, "SendMax" : { "currency" : "XXX", "value" : "45", // 送金額(手数料込み) issuerへの返還には手数料が不要! "issuer" : "
" }, "Fee": "10", "Flags": 2147483648, // デフォルトの tfFullyCanonicalSig フラグ "LastLedgerSequence": 8007750, // 最新のledger_index + 3 ぐらい "Sequence": 12 // user2のaccount_dataの"Sequence" } ``` ## ハマりポイント (trap) #### DefaultRipple と NoRipple (defaultripple-noripple) アカウント作成後、トラストラインを張る前には必ず、それぞれのアカウントに `DefaultRipple` と `NoRipple` の設定を行う必要があります。そのアカウントの役割が **gateway** なのか **user** なのかで必要な設定が違います: **Issuer** (Gateway) の場合: - `DefaultRipple`: **Enabled** - `NoRipple`: **Disabled** **User** の場合: - `DefaultRipple`: **Disabled** - `NoRipple`: **Enabled** **DefaultRippleのEnabling** `AccountSet` トランザクションで `SetFlag` に `asfDefaultRipple` を立てると Enable になります。: ``` { TransactionType: "AccountSet", Account: "
", // DefaultRippleの有効化が必要になるのはissuer ... SetFlag: 8, // asfDefaultRipple } ``` **NoRippleのEnabling/Disabling** `TrustSet` トランザクションで `Flags` に `tfSetNoRipple` (Enabling) を立てると Enable になり、 `tfClearNoRipple` (Disabling) フラグを立てると Disable になります: issuerの場合: ``` { TransactionType: "TrustSet", Account: '
', ... Flags: 262144, // tfClearNoRipple (issuerにはNoRipple無効化) } ``` userの場合: ``` { TransactionType: "TrustSet", Account: '
', ... Flags: 131072, // tfSetNoRipple (userにはNoRipple有効化) } ``` #### 意外と重要な noripple_check (important-noripple-check) ちゃんとトラストラインを張っているにもかかわらず、ユーザ同士でのアセットの送受信が上手くいかない(例えば、`tecPATH_DRY` エラーが出るなどの)時は、[先ほど](#defaultripple-noripple)の `DefaultRipple` または `NoRipple` の設定がミスっている可能性を疑いましょう。 調査するために
と
それぞれに `noripple_check` を行ってみます。 まずは
の `noripple_check` から行ってみます。以下のリクエストパラメータで `noripple_check` API を叩きます: ``` $ curl -X POST -d '{ "method": "noripple_check", "params": [ { "account": "
", "ledger_index": "current", "limit": 2, "role": "gateway", // issuer なので "gateway" をセット "transactions": true } ] }' https://api.altnet.rippletest.net:51234 ``` もし
の `noripple_check` で **`problems: [ 'You should clear the no ripple flag on your XXX line to
'],`** のようなレスポンスが含まれている場合は、これを解消する必要があります。(そもそも issuer が user の発行したアセット XXX にトラストラインを張ってしまっていることが問題なのですが!) まずは Gateway としてのお作法として、念のためもう一度 defaultRipple を有効にしておきます。具体的には `AccountSet` APIのリクエストパラメータ `SetFlag` に `asfDefaultRipple` フラグをセットします: ``` { TransactionType: 'AccountSet', Account: '
', Fee: '10', Flags: 2147483648, SetFlag: 8 // asfDefaultRipple } ``` そして、
の XXX へ張ってしまっているトラストラインを解消: ``` { TransactionType: "TrustSet", Account:
, LimitAmount: { issuer: '
', currency: 'XXX', value: '0', // ゼロ! }, Flags: 262144, // tfClearNoRipple, Fee: .... } ``` issuer側はこれだけ。 参考:[Unable to remove "no_ripple" flag from trustline](https://forum.ripple.com/viewtopic.php?f=2&t=15554) もしこれでもエラーが消えない場合は、ユーザ側
でも`noripple_check` してみます: ``` $ curl -X POST -d '{ "method": "noripple_check", "params": [ { "account": "
", "ledger_index": "current", "limit": 2, "role": "user", // ユーザなので "user" をセット "transactions": true } ] }' https://api.altnet.rippletest.net:51234 ``` もしレスポンスに **`problems: [ 'You should probably set the no ripple flag on your XXX line to
' ]`** のようなメッセージが含まれていたら、それがエラーの原因である可能性が大。なのでそちらも解消しておく必要があります。 一旦 `tfClearNoRipple` フラグをセットして noripple を解消しておきます: ``` { TransactionType: 'AccountSet', Account: '
', Fee: '10', Flags: 2147483648, SetFlag: 262144, // tfClearNoRipple ... } ``` そして、改めて
から XXX+issuer へのトラストラインを張り直します: ``` { TransactionType: 'TrustSet', Account: '
', LimitAmount: { issuer: '
', currency: 'XXX', value: '1000000' }, Flags: 131072, Fee: '10', LastLedgerSequence: 217180, Sequence: 26, ... } ``` これで、もう一度 `noripple_check` で確認すると problems が解消しているはず。これで
での対応は以上です。 もし他のユーザでも同じような problems が発生してる場合は、同じ手順で対処します。アセットのやり取りをする予定のユーザ全てにこれらを実施することで、ユーザ同士の XXX+issuer なアセット送受信が可能になります。 それでは、実際に送金してみましょう。 まずは
から
へ100単位をアセット(XXX+issuer)送金してみましょう: ``` { TransactionType: 'Payment', Account: '
', Destination: '
', Amount: { currency: 'XXX', value: '100', issuer: '
' }, SendMax: { currency: 'XXX', value: '100', issuer: '
' }, Flags: 2147483648, Fee: '10', Memos: [ { Memo: [Object] } ], LastLedgerSequence: 217402, Sequence: 16, ... } ``` 次に
から
へ30単位をアセット(XXX+issuer)送金: ``` { TransactionType: 'Payment', Account: '
', Destination: '
', Amount: { currency: 'XXX', value: '30', issuer: '
' }, SendMax: { currency: 'XXX', value: '30', issuer: '
' }, Flags: 2147483648, Fee: '10', Memos: [ { Memo: [Object] } ], LastLedgerSequence: 217954, Sequence: 19, ... ```
の `account_lines` を見てみると、ちゃんと増えていることがわかります: ``` $ curl -X POST -d '{ "method": "account_lines", "params": [ { "account": "
", "strict": true, "ledger_index": "current", "queue": true } ] }' https://api.altnet.rippletest.net:51234 { "account": "
", "ledger_current_index": 217956, "lines": [ { "account": "
", "balance": "30", // 増えた! "currency": "XXX", "limit": "100000", "limit_peer": "0", "no_ripple": true, "quality_in": 0, "quality_out": 0 }, ... ``` 以上です。 ## 参考 (refs) - [rippled | Ripple](https://ripple.com/build/rippled-apis/) - [Becoming a Ripple Gateway | Ripple](https://ripple.com/build/gateway-guide/) - [Ripple Forum](https://forum.ripple.com/)
0 件のコメント:
コメントを投稿
次の投稿
前の投稿
ホーム
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿