Proxy Accounts
The Accounts Tab in the Polkadot-JS UI cannot handle complex proxy setups (e.g. a proxy -> multisig -> an anonymous proxy which is part of another multisig). These complex setups must be done using the Extrinsics Tab directly.
We recommend to use the Westend Testnet if you are testing features for the first time. By performing the complex proxy setups on the testnet, you can comfortably replicate the procedure on the main networks.
Much like controller accounts in staking, proxies allow users to use an account (it can be in cold storage or a hot wallet) less frequently but actively participate in the network with the weight of the tokens in that account. Proxies can be viewed as a more powerful and flexible version of a controller account, i.e. proxies are allowed to perform a limited amount of actions related to specific substrate pallets on behalf of another account. The video below contains more information about using proxies.
Why use a Proxy?โ
Proxies are helpful because they let you delegate efficiently and add a layer of security. Rather than using funds in a single account, smaller accounts with unique roles can complete tasks on behalf of the main stash account. Proxies can be hotter than the initial account, which can be kept cold, but the weight of the tokens in the colder account can be used by the hotter accounts. This increases the security of your accounts by minimizing the number of transactions the cold account has to make. This also drives attention away from the stash account, although it is possible to determine the relationship between the proxy and the proxied account.
From the security perspective, we can imagine proxies as bodyguards of a VIP, loyal and ready to risk their lives to ensure the VIP's protection. But proxies are also useful in other contexts such as efficient account management at the corporate level. They also provide an elegant solution to change signatories within multi-signature accounts, and they can be used within proxy calls and nested proxy calls. In this page we will explore all these interesting use cases of proxies within the Polkadot ecosystem.
Shown below is an example of how you might use these accounts. Imagine you have one stash account as your primary token-holding account and don't want to access it very often, but you want to participate in staking to earn staking rewards. You could set one of your existing accounts as a staking proxy for that stash account. The stash account is also the controller here, but it does not matter because you will always use your staking proxy to sign staking-related transactions.
If you just use a controller that is not a staking proxy, the stash account will still have to sign for some staking-related transactions such as bond more funds and change controller account (Figure left). But if you have a staking proxy, everything will be signed by the proxy, making the stash account even more isolated (Figure right). In other words, the account assigned as a staking proxy of the stash can participate in staking on behalf of that stash. If the proxy is compromised, it doesn't have access to transfer-related transactions, so the stash account could just set a new proxy to replace it.
Creating multiple proxy accounts that act for a single account, lets you come up with more granular security practices around how you protect private keys while still being able to actively participate in a network.
The maximum number of proxies allowed for a single account is .
Creating Proxyโ
To create a proxy account read this support article.
Proxy Typesโ
You can set up a proxy account via the proxy pallet. When you set a proxy, you must choose a type of proxy for the relationship. Polkadot offers:
- Any
- Non-transfer
- Governance
- Staking
- Identity Judgement
- Cancel
- Auction
When a proxy account makes a transaction, Polkadot filters the desired transaction to ensure that the proxy account has the appropriate permission to make that transaction on behalf of the cold account. For example, staking proxies have permission to do only staking-related transactions.
For the latest information on the calls and pallets that can be fully accessed by proxies, check the source code in the runtime folder on the Polkadot repository
Any Proxyโ
As implied by the name, a proxy type of Any allows the proxy account to make any transaction, including balance transfers. In most cases, this should be avoided as the proxy account is used more frequently than the cold account and is therefore less secure.
Non-transfer Proxyโ
Proxies that are of the type Non-transfer are accounts that allow any type of transaction except balance transfers (including vested transfers). Hence, this proxy does not have permission to access calls in the Balances and XCM pallet.
Governance Proxyโ
The Governance type will allow proxies to make transactions related to governance (i.e., from the Democracy, Phragmen Election, Treasury, Bounties, Tips, Utility and Child Bounties pallets).
See Governance for more information on governance proxies or watch our technical explainer video that explores this concept.
Staking Proxyโ
Visit the Advanced Staking Concepts page for more detailed information about staking proxies.
The Staking type allows staking-related transactions. Do not confuse a staking proxy with the controller account. Within the staking pallet, some transactions must come from the stash account, while others must come from the controller account. The stash account is meant to stay in cold storage, while the controller account makes day-to-day transactions like setting session keys or deciding which validators to nominate. The stash account still needs to make some transactions such as bonding extra funds or designating a new controller account. A proxy doesn't change the roles of stash and controller accounts but does allow the stash to be accessed even less frequently than using a controller account.
The staking proxy can fully access Staking, Session, Utility and Fast Unstake pallets.
Use a non-transfer instead of a staking proxy to participate in nomination pools. The staking proxy is not enabled to make successful calls to the nomination pools pallet.
Identity Judgement Proxyโ
The Identity Judgement proxies are in charge of allowing registrars to make judgments on an
account's identity. If you are unfamiliar with judgment and identities on chain, please refer to
this page. This proxy can only access provide_judgement
call from
the Identity pallet along with the calls from the Utility pallet.
Cancel Proxyโ
Proxies that are of the type Cancel allow accounts to reject and remove any time-delay proxy
announcements. This proxy can only access reject_announcement
call from the Proxy pallet.
Auction Proxyโ
Proxies that are of the type Auction are accounts that allow transactions pertaining to parachain auctions and crowdloans. The Auction proxy account can sign those transactions on behalf of an account in cold storage. If you already set up a Non-transfer proxy account, it can do everything an Auction proxy can do. Before participating in a crowdloan using an Auction proxy, it is recommended that you check with the respective parachain team for any possible issues pertaining to the crowdloan rewards distribution. Auction proxy can access Auctions, Crowdloan, Registrar and Slots pallets.
Removing Proxyโ
Read the section "Removing Proxies" on this support page to learn how to remove proxies.
How to view your Proxyโ
To view your proxy, just go on the Accounts menu in the Polkadot-JS UI, next to the proxied account you will notice a blue icon. Hover on it, and you will see Proxy overview. Click on it and you will be presented with a list of all proxies for that account.
Additionally, you can head over to the Chain State tab (underneath the Developer menu) on Polkadot-JS Apps. If you've created your proxy on a Kusama account, it is required to change your network accordingly using the top left navigation button. On this page, the proxy pallet should be selected, returning the announcements and proxies functions. The proxies function will allow you to see your created proxies for either one account or for all accounts (using the toggle will enable this). Proxy announcements are what time lock proxies do to announce they are going to conduct an action.
Proxy Depositsโ
Proxies require deposits in the native currency (i.e. DOT or KSM) to be created. The deposit is required because adding a proxy requires some storage space on-chain, which must be replicated across every peer in the network. Due to the costly nature of this, these functions could open up the network to a Denial-of-Service attack. To defend against this attack, proxies require a deposit to be reserved while the storage space is consumed over the lifetime of the proxy. When the proxy is removed, so is the storage space, and therefore the deposit is returned.
The required deposit amount for n
proxies is equal to:
ProxyDepositBase
+ ProxyDepositFactor
* n
where the ProxyDepositBase
is the required amount to be reserved for an account to have a proxy
list (creates one new item in storage). For every proxy the account has, an additional amount
defined by the ProxyDepositFactor
is reserved as well (appends 33 bytes to storage location). The
ProxyDepositBase
is
and the ProxyDepositFactor
is
.
Time-delayed Proxyโ
We can add a layer of security to proxies by giving them a delay time. The delay will be quantified
in blocks. Polkadot has approximately 6
seconds of block time. A delay value of 10 will mean ten blocks, which equals about one minute
delay. The proxy will announce its intended action using the proxy.announce
extrinsic and will
wait for the number of blocks defined in the delay time before executing it. The proxy will include
the hash of the intended function call in the announcement. Within this time window, the intended
action may be canceled by accounts that control the proxy. This can be done by the proxy itself
using the proxy.removeAnnouncement
extrinsic or by the proxied account using the the
proxy.rejectAnnouncement
extrinsic. Now we can use proxies knowing that any malicious actions can
be noticed and reverted within a delay period. After the time-delay, the proxy can use the
proxy.proxyAnnounced
extrinsic to execute the announced call.
See this video tutorial to learn how you can setup and use time-delayed proxies. The video goes through the example below.
Let's take for example the stash account Eleanor that has a controller Charly. Eleanor does not fully trust Charly, and as a consequence sets him as a time-delayed staking proxy. In this way, if Charly submits an extrinsic to change the controller to Bob, such extrinsic can be rejected by Eleanor. Bob can be even more malicious than Charly and change the reward destination to another account he only controls. Remember that Eleanor added Charly as proxy, but she might not want to add Bob as a controller. This implies that Eleanor monitors Charly, and that within the time-delay she can spot the announced extrinsic. Eleanor can check all the proxy call announcements made by her account's proxies on-chain. On Polkadot-JS UI, go to Developer > Storage > Proxy > Announcements to check the hashes for the calls made by the proxy accounts and the block height at which they are enabled for execution.
If you try to use proxy.proxyAnnounced
to execute the call within the time-delay window you will
get an error "Proxy unannounced" since the announcement will be done after the time delay. Also note
that regular proxy.proxy
calls do not work with time-delayed proxies, you need to announce the call
first and then execute the announced call on a separate transaction.
Proxy callsโ
Proxy calls are used by proxies to call proxied accounts. These calls are important for example in the case of pure proxies, as any attempt to sign transactions with a pure proxy will fail. For more details see the dedicated section about anonymous proxies.
Nested Proxy Callsโ
As the term suggests, nested proxy calls are proxy calls within proxy calls. Such calls are needed if there are proxied accounts that are proxies themselves. In the example diagram below, Alice has a stash account that has a staking proxy account, P-C. P-C is a pure proxy, a proxied account originally spawned by Charly that is now an any proxy of P-C and signs everything on its behalf.
For example, to bond more funds, Charly needs to submit a prox.proxy
extrinsic to P-C, which in
turn submits a proxy.proxy
extrinsic to Alice including for example a staking.bondExtra
extrinsic, specifying the number of extra tokens that need to be bounded. If Charly wants to leave,
a new account can take his place as any proxy (before Charly leaves!). There is no need to change
the staking proxy account. Also, Alice is the only one who can remove P-C as a staking proxy, and
P-C can only perform staking-related tasks. For example, P-C cannot send funds out from Alice's
account.
Proxy calls can be done using the Extrinsic Tab in the Polkadot-JS UI. Nested proxy calls can be
done by calling each proxy.proxy
extrinsic separately, or in some cases by just calling the last
proxy.proxy
extrinsic. In the diagram above, submitting the proxy call from P-C to Alice will
automatically ask for Charly's signature. Thus one proxy call will trigger the second one because
Charly's is the only any proxy of P-C, and P-C cannot sign anything. While if we want to use Bob's
account we will need to submit all three proxy calls.
Anonymous Proxy (Pure Proxy)โ
Read carefully the text below and before performing any action using anonymous proxies on Polkadot, experiment on the Westend testnet.
Anonymous proxies are very different from other proxy types. The proxies we described so far are existing accounts assigned as proxies by a primary account. These proxies act on behalf of the primary account, reducing the exposure of the primary account's private key. Remember, the more often we use an account's private key to sign transactions, the more we expose that key to the internet, increasing the visibility of that account. The purpose of a proxy is thus to draw the attention of potential attackers away from the primary account, as proxies' private keys will be used most of the time to perform actions on behalf of the primary account.
Anonymous proxies are new accounts that are created (not assigned) by a primary account. That primary account then acts as any proxy on behalf of the anonymous proxy. Anonymous proxies are keyless non-deterministic accounts as they do not have a private key but they have an address that is randomly generated. Also, in some sense, nobody owns an anonymous proxy as nobody has a private key to control them.
Anonymous proxies are not anonymous because they have an address that is spawned by a primary account acting as any proxy. Even if the any proxy changes, it is still possible to find who generated the anonymous proxy by going backward using a block explorer. There was thus the need to change the name of anonymous proxy. People suggested keyless accounts since they do not have a private key and are proxied accounts. However, multisig accounts are also keyless (but deterministic). Moreover, even if anonymous proxies are proxied accounts, they can still act as proxies and control other accounts via proxy calls (see multisig example below). Thus, the name that has been chosen is pure proxy. If you want to know more about the reasoning behind renaming of pure proxies, see the discussion in this PR or the discussion on Polkadot forum.
From now on we will thus use the term pure proxy instead of anonymous proxy.
Create and Remove Pure Proxyโ
To create a pure proxy see this support article, or watch this technical explainer video.
The procedure for removing a pure proxy is different from the one used to remove other proxies. Visit the section "Removing an Anonymous Proxy" on this support article, or watch this technical explainer video.
Learn more about pure proxies from our technical explainer video.
Use of Pure Proxyโ
The use of the pure proxy is strictly bound to the relationship between the pure proxy and the any proxy. Note that the any proxy does not necessarily be the one who created the pure proxy in the first place. Hence, pure proxies are not really owned by somebody, but they can be controlled. Once that relationship between the pure proxy and its any proxy is broken, the pure proxy will be inaccessible (even if visible on the Polkadot-JS UI). Also, pure proxies are non-deterministic, meaning that if we lose one pure proxy, the next one we create from the same primary account will have a different address.
Pure proxies cannot sign anything because they do not have private keys. However, although they do
not have private keys and cannot sign any transaction directly, they can act as proxies (or better,
proxy channels) within proxy.proxy
calls (proxy calls). For example, it is possible to have pure
proxies within a multisig. Using proxy calls, it is possible to use the any proxy to call the
pure proxy, which in turn will do a multisig call. More about this later on.
Once you remove the relationship with any proxy, the pure proxy will be inaccessible. Also, pure proxies cannot sign for anything.
Why Pure Proxy?โ
Despite their complexity and associated dangers, pure proxies have important benefits that we discuss below.
Enhanced Securityโ
Pure proxies cannot be stolen because they do not have private keys. The only accounts that have full access to the pure proxies are any proxies. Security can be further increased if the any proxy is a multi-signature account.
Simplified and Secure Account Management at a Corporate Levelโ
You can see this video tutorial that goes through this scenario. The tutorial requires some familiarity with the Extrinsic Tab of the Polkadot-JS UI.
Probably the greatest benefit of using pure proxies is the management of complex account relationships at a corporate level. Let's take for example 3 accounts belonging to Charlie, Dan and Eleanor working for Company X. Charlie holds funds belonging to Company X, but he wants to leave the company and transfer the economic responsibility to Eleanor. Dan is a staking proxy of Charlie.
Without Pure Proxy, Charlie must (see left side of the Figure below):
- Remove Dan as a staking proxy, this step requires 1 signature
- Stop nominating and unbound all funds , this step requires 2 signatures
- Transfer the funds to Eleanor, this step requires 1 signature
Then Eleanor adds Dan as a staking proxy (1 signature). The whole process requires 5 signatures. Here we are presenting a simple example, in fact, with multi-signature accounts and multiple proxies the procedure would be more time-consuming and labor-intensive.
With Pure Proxy (see right side of the Figure above), Charlie must add Eleanor as any proxy of the pure proxy, and remove himself (or Eleanor can remove him). The process requires just 2 signatures (1 signature to add the new any proxy and 1 signature the remove the old one). The funds remain in the pure proxy, and it is not necessary to stop nominating or unbond funds. Also, any proxy relationships with the pure proxy stay in place. Thus, if we use the pure proxy, with an increasing number of proxies we will always have to sign twice (not necessarily true in multi-signature accounts). While if we are not using the pure proxy, the more the proxies the more signatures we need to detach them from the old stash and attach them to the new stash (see Figure below).
Multi-signature Account Managementโ
Pure proxies are useful to efficiently manage multi-signature (multisigs) accounts. In fact, multisigs are deterministic, which means that once a multisig is created the signatories cannot be changed. If one of the signatories wants to leave the multisig, a new multisig must be created. This is inconvenient, especially at corporate-level management where the chance of replacing someone within a multisig can be high. Pure proxies allow keeping the same multisig when the signatories change.
Scenario One: One Anonymous Proxy within a Multisigโ
You can see this video tutorial that goes through this scenario. The tutorial requires some familiarity with the Extrinsic Tab of the Polkadot-JS UI.
It is possible to put a pure proxy within a multisig, and then transactions will be signed by the
any proxy on behalf of the pure proxy (proxied account). Let's take for example the diagram
below. Alice, Bob and Anon are part of the multisig ABC, a multisig account with threshold 2. P-C is
a pure proxy spawned by Charlie, who now acts as any proxy and thus signs anything on behalf of
P-C. The pure proxy cannot sign directly because it does not have a private key. So, for example,
to send funds from the multisig to Dan, Charly needs to submit a proxy.proxy
extrinsic to P-C,
which in turn will submit a multisig.asMulti
extrinsic to ABC containing the call data for the
balances.transferKeepAlive
extrinsic about the transfer of some funds from ABC to Dan. Alice can
then approve the transfer by submitting a multisig.asMulti
extrinsic also containing the call data
for the balances.transferKeepAlive
extrinsic about the transfer of some funds from ABC to Dan.
If Charly wants to leave the multisig, a new any proxy can be added to P-C and Charly can be removed (by himself or by the new any proxy). Note that the multisig also contains Bob that in this specific example does not do anything.
To use a pure proxy within a multisig you need to use the Extrinsic Tab and generate a
proxy.proxy
extrinsic. If you try to sign a multisig transaction using the pure proxy you will
be prompted with a warning. Remember, you cannot sign something directly if you do not have a
private key.
Scenario Two: Multisig made of Anonymous Proxiesโ
You can see this video tutorial that goes through this scenario. The tutorial requires some familiarity with the Extrinsic Tab of the Polkadot-JS UI.
The diagram below shows a multisig that is made only with pure proxies (P-A, P-B and P-C). In this situation Alice, Bob or Charly can leave the multisig at any time without the requirement of creating a new multisig. If for example, Bob leaves the multisig the procedure will require somebody else to be added as any proxy to P-B, and then Bob can remove himself (or the new any proxy can remove Bob).
In the diagram above, Alice submits the proxy.proxy
extrinsic to P-A, which in turn submits the
multisig.asMulti
extrinsic containing the balances.transferKeepAlive
extrinsic about the
transfer of some tokens from ABC to Dan. Then, Charly does the same to confirm the transaction. Note
that Charly will need to pay for some weight, for the computation that is necessary to execute the
transaction.