Account
Unlike other blockchains, accounts in Radix are components. These components are instantiated from the native-account blueprint.
Each account component contains an owner, and the component is able to manage resources, lock XRD for transaction payments, and more.
Additionally, each account also has a special role called the Securify role, which is able to modify the account's authorization model.
It is also important to note that the identity native blueprint is a simpler version of the native-account blueprint, so the threat model for that would be a subset of the threat model presented here.
Let us look into the most security-critical functions and methods that the native-account blueprint exposes.
Function: on_virtualize()
The function signature is on_virtualize(input: OnVirtualizeInput, api: &mut Y)
.
This function is called when a Radix address is interacted with (say, a deposit is sent to it) while there is no instantiated account component on that address. The OnVirtualizeInput
argument type is as follows:
The variant_id
is used to determine whether the rid
is a SECP256K1 public key or an ED25519 public key. This function then calls create_virtual()
, which is used to create and instantiate a native-account component at the address specified by address_reservation
(which is the address that was interacted with).
When creating the account, an owner badge is created. The owner badge is a nonfungible resource that has the byte format of [entity_type, public_key_hash]
, where entity_type
determines whether the account is using a SECP256K1 public key or an ED25519 public key.
The owner badge is put into the account's metadata, along with the public key hash.
Radix uses an off-chain authentication method known as ROLA (Radix Off Ledger Authentication). A user can use this to prove that that they own the private key to the public key for a specific virtual account.
Function: create()
The function signature is create(api: &mut Y)
.
This method is used to create an account component. It follows the same flow as create_virtual()
, described in the threat model for on_virtualize()
in the subsection above.
Function: create_advanced()
The function signature is create_advanced(owner_role: OwnerRole, address_reservation: Option<GlobalAddressReservation>, api: &mut Y)
.
This has the same flow as the create()
function, except that it also allows to specify a fixed or updatable owner role as well as a predefined address reservation for the account component.
Method: lock_fee()
The method signature is lock_fee(amount: Decimal, api: &mut Y)
.
This method fetches the account's XRD vault, and locks a fee from it. It is intended to be used to pay for transaction fees. The core details behind transaction fees are covered in the transaction-flow threat model, which you can find in section ref↗.
This method is only callable by the owner of this account.
Method: lock_contingent_fee()
The method signature is lock_contingent_fee(amount: Decimal, api: &mut Y)
.
This method does the same thing as lock_fee()
, except that it locks a contingent fee. Contingent fees are fees that are only used if the transaction completes successfully.
This method is only callable by the owner of this account.
Method: add_authorized_depositor()
The method signature is add_authorized_depositor(badge: ResourceOrNonFungible, api: &mut Y)
.
This method is used to add a nonfungible resource (which acts as a badge in this case) as an authorized depositor. This then allows anyone holding that nonfungible resource to deposit resources into this account.
This method is only callable by the owner of this account.
Method: try_deposit_or_refund()
The method signature is try_deposit_or_refund(bucket: Bucket, authorized_depositor_badge: Option<ResourceOrNonFungible>, api: &mut Y)
.
This method is callable by anyone on every account. It is intended to be used to deposit resources into an account.
The resources that are deposited come from the bucket
argument. If this account is not accepting deposits of the resource within the bucket
, then the authorized_depositor_badge
is checked to ensure that the depositor has been authorized to deposit into this account.
If the depositor is not authorized, then the bucket
is refunded to the caller (i.e., it is returned by this function).
Method: try_deposit_or_abort()
The method signature is try_deposit_or_abort(bucket: Bucket, authorized_depositor_badge: Option<ResourceOrNonFungible>, api: &mut Y)
.
This method calls try_deposit_or_refund()
. The difference is that if the deposit fails, then the entire transaction is reverted.