Skip to main content

URef Access Rights and Security Considerations

Understanding Access Rights

An Unforgeable Reference or URef is a key type used for storage on a Casper network. They can store any value other than Account and exist as a top-level entity. As such, no individual entity may own a URef, they can only hold the necessary AccessRights to interact with a given URef.

AccessRights determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:

uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-000

And this is the same URef with READ and ADD access rights.

uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-005

The following table outlines all possible AccessRights settings:

Access RightsSerialization
NONE0
READ1
WRITE2
READ_WRITE3
ADD4
READ_ADD5
ADD_WRITE6
READ_ADD_WRITE7
danger

Any access rights granted alongside a passed URef are irrevocable.

AccessRights and Purses

A Purse is a unique type of URef representing a token balance. Each Addressable Entity will have an associated URef that represents its main purse. Account and contract entities may have additional purses.

For URefs that represent a purse, access rights determine the ability to read or change the associated balance of tokens. The following table outlines what each operation allows in the context of a purse:

Global StateAction Monetary Action
AddDeposit (i.e. transfer to)
WriteWithdraw (i.e. transfer from)
ReadBalance check

Security Considerations for dApp Developers

When developing a dApp that interacts with tokens in any way, it will be necessary to work with various URef AccessRights for associated purse URefs.

This tutorial outlines our recommendations when transferring tokens to a contract.

When passing a URef to another entity in any way, ensure that you are only passing the URef with the appropriate AccessRights. The following example code shows the syntax for creating a URef with any given access rights combination. In this example, only the new_uref should be passed to another entity.

// 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);