🪝

Hooksの基本的なコード

2023/12/05に公開

Hooksとは

Hooksは、XRP Ledger(XRPL)プロトコルのスマートコントラクト機能です。この機能により、開発者は独自のロジックを実装することが可能になります。Hooksではアカウントから送信したトランザクションやアカウントが受信したトランザクションをトリガーにHookを呼び出してそのトランザクションの送信/受信を拒否したり、別のトランザクションを発行したり、State情報の追加・変更・削除などを行うことができます。

現在はXahau Networkで利用可能ですが、将来的にはXRP Ledgerのメインネットでも利用可能になることが期待されています。

https://xahau.network

この記事ではHooksで利用できる基本的なfunctionを紹介します。

functionの一覧は以下のリンクから確認することができます。

https://xrpl-hooks.readme.io/reference/hook-api-conventions

accept/rollback

accept

Hookを成功として終了し、全てのHookStateの変更をコミットします。

文字列や結果コードを返すことができます。

c
accept(SBUF("Success"), 100);
hookscript
accept("Success", 100)

rollback

Hookを拒否として終了し、全ての変更をロールバックします。

文字列や結果コードを返すことができます。

c
rollback(SBUF("Rejected!"), 100);
hookscript
rollback("Rejected!", 100)

トランザクション情報の取得

otxn_field

Hookの呼び出し元となったトランザクションの情報を取得することができます。

c
uint8_t otxn_acc[20];
otxn_field(SBUF(otxn_acc), sfAccount);

sfAccountの箇所には取得したいフィールドを指定します。

hookscript
const account_field = Tx.Account

Accountの箇所には取得したいフィールドを指定します。執筆時点ではhookscriptは開発段階であるため一部のフィールドのみ利用可能です。

Hook情報の取得

現在実行中のHookの情報を取得することができます。

hook_account

Hookの呼び出し元となったアカウントのIDを取得することができます。

アカウントアドレス(rアドレス)ではなく、アカウントIDであることに注意が必要です。アカウントIDからrアドレスを取得したい場合はutil_raddrを利用します。

c
uint8_t hook_acc[20];
hook_account(SBUF(hook_acc));
hookscript
const hook_accid = hook_account()

hook_param

Hookに設定されているパラメータを取得することができます。
このパラメータはアカウントへHookをインストールする時などに設定するものであり、Hookを変更可能な外部の管理アカウントのアドレスなどを指定します。
同じHookを別のアカウントにインストールする場合には、このパラメータを変更してそのアカウントのHookでは別の管理アカウントを設定するようなことができます。

トランザクションのHookParametersフィールドに設定されている値とは別の情報となります。

c
uint8_t param_aname[2] = {'F', 'A'};
uint8_t param_a[20];
hook_param(SBUF(param_a), SBUF(param_aname));
hookscript
const acc_param = new HookParam<Account>({
  name: "FA",
  // description: 'some description',
});

HookState

HookStateはHookの実行中に変更することができる状態を表します。key-value毎に1つのHookStateで表され、key情報を利用してHookStateを取得・変更することができます。

state

key情報からState情報を取得することができます。

サンプルコードの29はvalueの長さを表します。

c
uint8_t state_value[29];
state(SBUF(state_value), SBUF(hook_acc));
hookscript
const acc_key = new Account(hook_acc).toString()
const state_value = LocalState.getItem(acc_key, 29);

state_set

key情報からState情報を追加・変更・削除することができます。

c
int64_t value[1] = [0];
value[0] = 1;
state_set(SBUF(value), SBUF(hook_acc));
hookscript
let buffer = new ByteArray(1);
buffer[0] = 0;
let value_view = new ByteView(buffer, 0, 1); // 引数: ByteArray, offset, length
const acc_key = new Account(hook_acc).toString()
LocalState.setItem(acc_key, value_view);

HooksParameters

トランザクション送信時にHooksParametersフィールドを指定することでHookの呼び出し毎に異なるパラメータを指定することができます。

otxn_param

c
otxn_param(SBUF(otxn_param_value), SBUF(PARAM_NAME));
hookscript
// 執筆時点ではサポートされていません。

レジャーオブジェクトの取得

全てのレジャーオブジェクトは一意のキーを持ちます。そのキーを利用してレジャーオブジェクトを取得することができます。

util_keylet

c
uint8_t keylet[34];
util_keylet(SBUF(keylet), KEYLET_LINE, SBUF(hook_accid), SBUF(account_field), SBUF(currency_code))
hookscript
const keylet = Keylet.getTrustLine(new Account(hook_accid), new Account(account_field), currency_code)

まとめ

Hooksの基本的なfunctionを紹介しました。これらのfunctionを組み合わせることでHooksを利用したスマートコントラクトを実装することができます。
hookscriptではまだ一部のfunctionは利用できないものの、今後のアップデートにより利用可能となるでしょう。

Hooksのfuntionについてより詳細に知りたい場合は以下のリンクをご覧ください。

https://xrpl-hooks.readme.io/reference/hook-api-conventions

以下のリポジトリではHooksのサンプルコードが公開されています。

https://github.com/Transia-RnD/hooks-toolkit-ts/tree/main/contracts

https://github.com/XRPL-Labs/hookscript/tree/main/hook-api-examples

興味を持たれた方はXRP Ledger開発者のDiscordチャンネルへ是非お越しください!
日本語チャンネルもありますので、英語ができなくても大丈夫です!
https://xrpldevs.org

また、XRPL JapanのDiscordサーバもありますので、こちらもぜひご参加ください!
https://discord.gg/invite/xrpljapan

私のX/Twitterアカウントはこちら!

Discussion