URefのアクセス権限とセキュリティへの考慮

アクセス権への理解

Unforgeable Reference(偽造困難参照)はたまた URefとは、 Casperネットワーク上のストレージに使用される鍵の型のことです。Accout以外のいかなる値も格納でき、上位レベルのエンティティとして存在します。その様に、個々のアカウントでURefを保有することはなく、対象のURefとのやり取りに必要なAccessRightsの保有のみ可能です。
AccessRights は、Casperネットワーク上のエンティティがどの様にURefとやり取りするのかを決定します。URefのアドレスを結合した後、シングルバイトサフィックスとして表示されます。例としては、以下がアクセス権を持っていないURefの一例となります。

uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-000

そして、こちらはREADとADDのアクセス権を持った同じURefになります。

uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-005

下記テーブルは、全てのパターンのAccessRights設定の概要となります。

アクセス権シリアライゼーション
NONE0
READ1
WRITE2
READ_WRITE3
ADD4
READ_ADD5
ADD_WRITE6
READ_ADD_WRITE7

⚠危険⚠
渡されたURefと共に付与されたいずれのアクセス権も変更不可となります。

AccessRights とパース(お財布)

パース(お財布)は、トークン残高を表示するURefのユニークな型のことです。各Addressable Entityには、メインパースを表すURefが紐づいています。アカウントとコントラクトは、追加のパースを持っている場合もあります。

パースを表すURefの場合、アクセス権によって紐づいているトークン残高の変更や読取りの可否が決まります。下記テーブルは、パースのコンテキスト内で許可されている各オペレーションの概要です。

グローバルステートトークン周りのアクション
Add入金 (i.e. transfer to)
Write引き出し (i.e. transfer from)
Read残高確認

dApp開発者のためのセキュリティ

いずれの方法でもトークンをやり取りするdAppを開発する際は、対象のパースURef 用に様々なURef AccessRightsについて考慮する必要がでてきます。

このチュートリアルでは、コントラクトにトークンを転送する場合の推奨についてお伝えしています。

URefを他のエンティティに渡すいかなる場合でも、適したAccessRightsを付与したURefのみを渡していることを確認してください。下記サンプルコードは、どのアクセス権の組み合わせにおいてもURefを作成できるシンタックスをお見せしています。この場合は、new_urefのみが他のエンティティに渡すことができるようになっています。

// This example will create a version of the original URef with access rights stripped entirely.
let new_uref = uref.with_access_rights(AccessRights::NONE);
// This example will create a version of the original URef with only READ access rights.
let new_uref = uref.with_access_rights(AccessRights::READ);
// This example will create a version of the original URef with only WRITE access rights.
let new_uref = uref.with_access_rights(AccessRights::WRITE);
// This example will create a version of the original URef with both READ and WRITE access rights.
let new_uref = uref.with_access_rights(AccessRights::READ_WRITE);
// This example will create a version of the original URef with only ADD access rights.
let new_uref = uref.with_access_rights(AccessRights::ADD);
// This example will create a version of the original URef with both READ and ADD access rights.
let new_uref = uref.with_access_rights(AccessRights::READ_ADD);
// This example will create a version of the original URef with both ADD and WRITE access rights.
let new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);
// This example will create a version of the original URef with full access rights.
let new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);