file icon

How are smart accounts created, controlled, and recovered?

The Radix Bablon Mainnet upgrade ships with a powerful “smart account” model in which the normal user account is actually a component, with a flexible control model that frees it from being tied to a single key for access.  However, that doesn’t mean that you have to make a special transaction to create your smart account before using it.  Let’s start by covering how that works.

Virtual components

Accounts are one of the native components that come built-in to Radix.  They exist in their own address space (every account address starts with account_, so they can never be confused for something else), and instantiating an account component works in a special way.  The network considers valid account addresses derived from public keys to be pre-existing—you can call any of the normal account methods on any account address, even one that has never been created, and the network will automatically instantiate it at that moment.

This means that you can generate an address completely offline, just like on networks that use a simple key-controls-address-forever model, and know that the associated smart account will be automatically created the moment it is needed.  For example, your wallet can generate an appropriate public key, map it to an address, and you can give that address to an exchange or a friend who is going to send you some tokens.  They can then call the deposit method as if an account was already present at that address, and the account will be just-in-time created before the deposit happens (this means that the first interaction with a never-before-used account carries a very small fee increase).

We call this concept “virtual components,” and so far there are two kinds: accounts and identities (an identity is the on-ledger component related to each persona).

Controlling accounts by signature or badge

Initially, accounts start out controlled by a single private key, the same one associated with the keypair that was used to generate the address.  An account can remain that way forever, if that’s what their owner wants.  It will still be a configurable smart account, but at this stage it isn’t recoverable if the associated key is lost and can’t be regenerated.

Each account provides a method which switches administrative control to a badge.  That is, privileged actions such as withdrawing tokens will no longer look for the presence of a particular signature…they’ll require that the appropriate badge be present instead.

Using a badge instead of a single signature to control the account allows the owner to then store that badge in another component, and have that component manage access to the badge, which opens the door to just about any control scheme you can imagine.

Naturally, a native component dedicated to the purpose of multi-factor control of such a badge is provided, and it’s at the heart of Babylon’s powerful recovery model.

Introducing the access controller

The access controller component was designed expressly for the purpose of providing safe, recoverable access for a single badge—like the one that controls an account (or an identity component, providing recoverable access for persona-based dApp logins).

Its operation is based around 3 roles: Primary (P), Recovery (R), and Confirmation (C).

Each role is defined by an AccessRule, which means each role can be configured to accept any combination you like of signatures and badges.  For example, P could be a rule that says “either signature Alpha or both of signatures Bravo and Charlie must be present.”  C could be a single signature.  R could be “either signature Delta or badge Echo must be present.”

The P role is what permits access to the stored badge.  P, by itself, is all that is necessary to produce a proof of the held badge.  So, if you’re using an access controller to secure your account, most of your transactions will start with a call to the access controller to get a proof of the account’s admin badge, with sufficient signatures present to meet the rules of P.  This proof will then entitle you to take tokens from your account.

The Radix Wallet offers a simple, guided process for users to set up their access controller role preferences, and automatically handle adding the right access controller calls to transactions involving their accounts.  You won’t have to think about it after you configure it once.

Recovery is simply the act of changing what the rules are behind each of the three roles.  Maybe because you’ve lost access to something, or maybe just because you want to update your control scheme.

Generally, recovery is a two-step process of “initiating” and then “confirming” the change.  When initiating a recovery, you specify “here’s what I want the updated rules to be for P, R, and C.” Either the P or R roles can be used to initiate a recovery.

Once a recovery has been initiated, either of the other two roles can confirm it, at which point the pending rule change will take immediate effect.

For example, let’s take a simple case where P is a single key held on your phone, C is a single key on a Yubikey, and R is a badge held by a recovery service provider.  Sadly, your phone falls into a passing black hole, and you have to buy a new one.  The new phone has a new key generated on it, and you’d like to make that key your new P.  Recovery takes two steps.

  1. The recovery service submits a transaction telling the access controller that you want P to be just your new phone key, C to remain the same, and R to remain the same.
  2. You submit a transaction telling the access controller to confirm the recovery, with the Yubikey signature (C) present.

That’s it.  You’re back in action with your new phone able to access your account again.

Of course, this is just one example setup.  You’re in charge of what factors you want to use for each role.  You might say P is a 2-of-2 multisig requiring a key on your phone plus a key from a Yubikey, C is a key which you have backed up a seed phrase for, and R is a key held on a hardware wallet you keep in a safe deposit box at a bank.  It’s completely customizable based on what your personal requirements are for useability, security, and recoverability.

Additional features of the access controller

There are a couple more important actions that the R role can perform that we haven’t discussed yet.

First is the “lock the Primary role” action.  R can instantly disable or re-enable the P role’s normal ability to access the stored badge.  This effectively means that the account is locked, since only the P role can access the badge that lets you do things like withdraw tokens or present badges held in your account.  It’s intended for cases where you believe P may be compromised, and you want to take immediate action to prevent anything bad happening while you update your security rules.

For example, you check your pocket and realize your phone has been stolen, and it was able to provide P on its own.  Probably the thief won’t be able to unlock it, but just in case, you’d like to remove any risk.  You have previously given a badge which can act as R to a friend, so you get in touch with them and tell them to lock P.  Now you’re safe, and you have all the time you need to get a new phone and initiate a recovery to establish a brand new P.  (Or, maybe it turns out your phone just fell out of your pocket, and you find it an hour later.  Call up your friend and tell them to unlock P, and you’re back to normal.)

It’s important to note that this doesn’t mean you’re in trouble if your R role gets compromised and the attacker uses it to lock your P role.  Even when locked out from accessing the stored badge, P can still participate in recovery operations, so you can use the two roles you still control (P and C) to initiate a recovery and change your R to something new.

Second is the “timed recovery” action, also known as “recovery of last resort.”  While normal recovery operations require 2 out of the 3 roles to complete, there is always the worst case scenario where you’ve lost both your P and your C.  To do this, the access controller lets you recover with only R – but with a delay so that you have time to cancel the recovery if the R role is compromised.

“Timed recovery” can only be initiated by R, and will be automatically confirmed once a customizable time delay has passed.  It can be canceled at any time by any role.  Think of things like having a 6 month timer, and having an R held by an attorney with instructions to activate it in the event of your death, so that your family can recover access to your assets.  You’re free to disable this feature if you don’t want it, in which case recovery will always require two of the three roles.

But wait, there’s more!

The Radix Wallet handles the access controller configuration for your smart accounts and identities, which means safe control and recovery is just a few taps away without having to worry about the mechanics of the associated operations.  But the flexibility of the access controller makes it a powerful tool for much more than just wallets and user accounts.

Developers can use the access controller to easily create flexible control schemes to grant access to things like admin badges for their components, allowing for multiple people to be authorized (and later de-authorized, if needed!) without having to share private keys around.

Did you sell your successful Web3 app to another company?  No more wrangling over key transfer, no more buyers wondering if the seller really did destroy all their backups of the key…just “change the locks” on the access controller and the old key is useless.

Best of all, applications no longer have to bake complicated and inflexible signature schemes into their code to permit administrator access…just issue a badge, pop it into an access controller, and you’re free to change the rules however you like down the road.

Scrypto and the Radix Engine finally make practical the proper separation of concerns that has become ubiquitous in the rest of the software development world, but has been extraordinarily difficult to achieve on distributed ledgers.  The logic that defines your authorization and user roles can be entirely separate from your business logic, and easily updatable independent of that business logic.  Less to think about, less to implement, less to have to plan ahead of time.  Fewer bugs, fewer hacks, happier users & developers!


So if I delegate some/all of my Recovery role to friends or services, that means they can access my account?

No!  Only the Primary (P) role has that power.

Can I split up the Recovery role among multiple parties?

Absolutely.  The Scrypto AccessRules which are used to define the roles are extraordinarily flexible, so it’s possible to set up pretty much anything you like.  For example, would you like a seriously complicated R rule that could be met by:

  • 2-of-2 keys which you have backed up the seed phrases for, or
  • A key held on a single Yubikey, or
  • 3-of-5 badges being present which you have handed out to 5 different friends?

You can capture all that, together, in a single rule!  Devs can dream up all kinds of schemes, and easily put them into practice.  However, designing an intuitive user interface that can handle an infinite space of rule configurations is not practical, so the Radix Wallet will offer a user-friendly, guided workflow that lets users choose from a variety of sensible security patterns.

What if I get a new hardware device and want to add it to my control scheme?

Even when you haven’t lost something, changing the control rules is handled via the same recovery flow…you just include whatever key your new device can produce in the new rules.

Why is the access controller separate from the smart account?

It’s a terrifically useful pattern for multisig and recovery, and there was no reason to limit that power just to accounts. In fact, the same access controller will be used to offer multi-factor recovery of Persona-based logins, by controlling an on-ledger identity component that is similar to the account component.

Independent components which can be combined in a transaction to produce more powerful behavior is what programmability on Radix is all about!

Further reading: