Rustを使ったグローバルステートへの読み書き
下記の例では、Casperネットワーク上のグローバルステートにプログラミング言語のRustを用いて読み書きする方法についての概要をお伝えしています。
基本的に、Casperエコシステムでは、ストレージに3つの意味を持たせています。それらは、runtime::put_key と storage::write(alongside storage::new_uref as explained below) 、 storage::dictionary_put です。この格納された値は、runtime::get_key と storage::read、storage::dictionary_get を使用して読みとれます。各メソッドが特有の方法でデータを格納していることとその違いへの理解は大切です。
関数についての説明
runtime::put_key / runtime::get_key
put_key と get_key 両方の関数は、Hash Typesの理解とシリアライゼーション規格に書かれてあるように、CasperのKeyタイプを参照しています。この鍵は、KeyタイプとしてURefに格納されています。
storage::write / storage::read
storage::write は、事前に(storage::new_uref によって)生成されたURefに、指定された値を書き込みます。put_keyとは異なり、この値は上記にリストされたKeyタイプの1つではないが、潜在的にCLTypesのいづれかになります。storage::readは、これらの値を関連したURefから取得する方法を提供しています。
storage:dictionary_put / storage::dictionary_get
Casperネットワーク上の殆どのデータストレージにとって、辞書はNamedKeysより効率よく、ガスコストも低くなります。各辞書の項目は独立して存在しており、参照目的のために単一の辞書シードURefを共有します。
辞書に関する他情報は、辞書への理解をご確認ください。
コードのサンプル
put_key と storage::writeのサンプル
このコードサンプルは、新しいコントラクトを作成し、runtime::put_key関数を使用してグローバルステートにコントラクトハッシュを格納します。
格納された値が初期化されると、storage::write関数が既存の値をtrueに上書きします。その時、URefは現在のコンテキストにMY_STORED_VALUE_UREFという名前のNamedKey として格納されます。
// Store contract hash under a Named key CONTRACT_HASH
runtime::put_key(CONTRACT_HASH, contract_hash.into());
// Store !MY_STORED_VALUE (false) as init value/type into a new URef
let my_value_uref = storage::new_uref(!MY_STORED_VALUE);
// Store MY_STORED_VALUE (true) under the URef value
storage::write(my_value_uref, MY_STORED_VALUE);
// Store the Uref under a Named key MY_STORED_VALUE_UREF
let my_value_key: Key = my_value_uref.into();
runtime::put_key(MY_STORED_VALUE_UREF, my_value_key);
}get_key と storage::readのサンプル
このサンプルは、storage::readを用いて事前に格納されたMY_STORED_VALUE_UREFに対してランタイム引数ARG_MY_STORED_VALUEを比較する前に、get_key関数を用いて取得したCONTRACT_HASHにて上記のコードサンプルを補完します。
let my_stored_value_uref: URef = runtime::get_key(MY_STORED_VALUE_UREF)
.unwrap_or_revert()
.into_uref()
.map(|uref| URef::new(uref.addr(), AccessRights::default()))
.unwrap_or_revert()
.into_read();
let my_actual_stored_value: bool = storage::read(my_stored_value_uref).unwrap().unwrap();
// Compare my stored value with runtime arg
let my_expected_stored_value: bool = runtime::get_named_arg(ARG_MY_STORED_VALUE);
if my_actual_stored_value != my_expected_stored_value {
// We revert if my stored value is not what is expected from caller argument
runtime::revert(UserError::StoredValueError);
}
runtime::print(&my_actual_stored_value.to_string());
}dictionary_put と dictionary_getのサンプル
ストレージの辞書の使用例は、辞書への理解の辞書へのエントリーの書込みにてご確認いただけます。
名前付き鍵の追加の関数
以下の関数は、名前付き鍵を使う際にも興味深そうです。
- list_named_keys – 現在のコンテキストの名前付き鍵を返します
- has_key – 鍵が現在のコンテキストの名前付き鍵に存在している場合は、trueを返します
- remove_key – 現在のコンテキストから指定のNamedKeyを削除します