Interacting with the Proxy Precompile¶
Introduction¶
The Proxy Precompile on Moonbeam allows accounts to set proxy accounts that can perform specific limited actions on their behalf, such as governance, staking, or balance transfers.
If a user wants to provide a second user access to a limited number of actions on their behalf, traditionally the only method to do so would be by providing the first account's private key to the second. However, Moonbeam includes native proxy functionality in the runtime, which enables proxy accounts. Proxy accounts should be used due to the additional layer of security that they provide, where many accounts can perform actions for a main account. This is best if, for example, a user wants to keep their wallet safe in cold storage but still wants to access parts of the wallet's functionality like governance or staking.
The Proxy Precompile can only be called from an Externally Owned Account (EOA) or by the Batch Precompile.
To learn more about proxy accounts and how to set them up for your own purposes without use of the Proxy Precompile, view the Setting up a Proxy Account page.
The Proxy Precompile is located at the following address:
0x000000000000000000000000000000000000080b
0x000000000000000000000000000000000000080b
0x000000000000000000000000000000000000080b
Note
There can be some unintended consequences when using the precompiled contracts on Moonbeam. Please refer to the Security Considerations page for more information.
The Proxy Solidity Interface¶
Proxy.sol is an interface through which Solidity contracts can interact with the Proxy Pallet. You do not have to be familiar with the Substrate API since you can interact with it using the Ethereum interface you're familiar with.
The interface includes the following functions:
addProxy(address delegate, ProxyType proxyType, uint32 delay) - registers a proxy account for the sender after a specified number of delay blocks (generally zero). Will fail if a proxy for the caller already exists
delegate- address of the account to be registered as a proxyproxyType- ProxyType enumeration specifying the type of proxy to be registereddelay- uint32 number of blocks before the proxy registration becomes active
removeProxy(address delegate, ProxyType proxyType, uint32 delay) - removes a registered proxy for the sender
delegate- address of the proxy account to be removedproxyType- ProxyType enumeration of the proxy type to be removeddelay- uint32 delay value of the proxy to be removed
removeProxies() - removes all of the proxy accounts delegated to the sender
None.
proxy(address real, address callTo, bytes callData) - dispatches callData to callTo on behalf of real using the caller's registered proxy rights
real- address of the account the call will be executed forcallTo- address receiving the proxied call (subject to dispatch limitations)callData- call data to forward to the destination
proxyForceType(address real, ProxyType forceProxyType, address callTo, bytes callData) - dispatches callData on behalf of real while enforcing the provided proxy type instead of inferring it
real- address of the account the call will be executed forforceProxyType- ProxyType value that must match the caller's registered proxy typecallTo- address receiving the proxied call (subject to dispatch limitations)callData- call data to forward to the destination
isProxy(address real, address delegate, ProxyType proxyType, uint32 delay) - returns a boolean, true if the delegate address is a proxy of type proxyType, for address real, with the specified delay
real- address of the account that might be represented by the proxydelegate- address of the potential proxy accountproxyType- ProxyType enumeration of the proxy type to checkdelay- uint32 delay value to check
The proxyType parameter is defined by the following ProxyType enum, where the values start at 0 with the most permissive proxy type and are represented as uint8 values:
enum ProxyType {
Any,
NonTransfer,
Governance,
Staking,
CancelProxy,
Balances,
AuthorMapping,
IdentityJudgement
}
Proxy Types¶
There are multiple types of proxy roles that can be delegated to accounts, which are represented in Proxy.sol through the ProxyType enum. The following list includes all of the possible proxies and the type of transactions they can make on behalf of the primary account:
- Any — allows the proxy account to dispatch the
Governance,Staking,Balances, andAuthorMappingactions permitted by the runtime filter; arbitrary smart contract targets are not allowed, and balance transfers are limited to EOAs without contract code - NonTransfer — allows transactions through the
Governance,StakingandAuthorMappingprecompiles, where themsg.valueis checked to be zero; no contract calls outside those precompiles are permitted - Governance - the governance proxy will allow the proxy account to make any type of governance related transaction (includes both democracy or council pallets)
- Staking - the staking proxy will allow the proxy account to make staking related transactions through the
StakingPrecompile, including calls to theAuthorMappingPrecompile - CancelProxy - the cancel proxy will allow the proxy account to reject and remove delayed proxy announcements (of the primary account). Currently, this is not an action supported by the Proxy Precompile
- Balances - allows only plain balance transfers to EOAs with no contract code and does not support calling contracts or precompiles
- AuthorMapping - this type of proxy account is used by collators to migrate services from one server to another
- IdentityJudgement - the identity judgement proxy will allow the proxy account to judge and certify the personal information associated with accounts on Polkadot. Currently, this is not an action supported by the Proxy Precompile
Proxy Dispatch Limitations¶
Moonbeam applies an EVM call filter to proxy dispatches. The key rules are as follows:
- Only EOAs (or the Batch Precompile) can call the Proxy Precompile; contracts cannot
- Not a general “call any contract as the real account” path—non-precompile contract calls are rejected
- Governance, Staking, and AuthorMapping calls must target their respective precompiles with
msg.value = 0 - Balances proxy calls only allow plain value transfers to EOAs with no contract code (not to contracts or precompiles)
CancelProxyis not dispatched through the Proxy Precompile
Interact with the Solidity Interface¶
The following section will cover how to interact with the Proxy Precompile from Remix. Please note that the Proxy Precompile can only be called from an EOA or by the Batch Precompile.
Checking Prerequisites¶
The below example is demonstrated on Moonbase Alpha, however, similar steps can be taken for Moonbeam and Moonriver. You should:
- Have MetaMask installed and connected to Moonbase Alpha
- Have an account with some DEV tokens. You can get DEV tokens for testing on Moonbase Alpha once every 24 hours from the Moonbase Alpha Faucet
- Have a second account that you control to use as a proxy account (funding optional)
Remix Set Up¶
To get started, get a copy of Proxy.sol and take the following steps:
- Click on the File explorer tab
- Copy and paste the file contents into a Remix file named
Proxy.sol
Compile the Contract¶
- Click on the Compile tab, second from top
- Then to compile the interface, click on Compile Proxy.sol
Access the Contract¶
- Click on the Deploy and Run tab, directly below the Compile tab in Remix. Note: you are not deploying a contract here, instead you are accessing a precompiled contract that is already deployed
- Make sure Injected Provider - Metamask is selected in the ENVIRONMENT drop down
- Ensure Proxy.sol is selected in the CONTRACT dropdown. Since this is a precompiled contract there is no need to deploy, instead you are going to provide the address of the Precompile in the At Address field
- Provide the address of the Proxy Precompile for Moonbase Alpha:
0x000000000000000000000000000000000000080band click At Address - The Proxy Precompile will appear in the list of Deployed Contracts
Add a Proxy¶
You can add a proxy for your account via the Proxy Precompile if your account doesn't already have a proxy. In this example, you will add a balances proxy to an account by taking the following steps:
- Expand the Proxy Precompile contract to see the available functions
- Find the addProxy function and press the button to expand the section
- Insert your second account's address as the delegate,
5as proxyType, and0as delay - Press transact and confirm the transaction in MetaMask
Note
When constructing the transaction in Remix, the proxyType is represented as a uint8, instead of the expected enum ProxyType. In Solidity, enums are compiled as uint8, so when you pass in 5 for proxyType, you indicate the sixth element in the ProxyType enum, which is the balances proxy.
Check a Proxy's Existence¶
You can determine whether or not an account is a proxy account for a primary account. In this example, you will insert the parameters of the previously added proxy to determine if the proxy account was successfully added:
- Find the isProxy function and press the button to expand the section
- Insert your primary account's address as real, your second account's address as delegate,
5as proxyType, and0as delay - Press call
If everything went correctly, the output should be true.
Dispatch a Proxy Call¶
Once you've registered a proxy, you can forward a call on behalf of the real account. In Remix, expand the Proxy Precompile contract and open proxy (or proxyForceType if you want to force the proxy type). The following example will use a Balances proxy (or Any with Balances allowed) to send value to an EOA with no contract code, keeping callData as 0x for a plain transfer. Remember that the runtime limits described in Proxy Dispatch Limitations apply.
Ensure MetaMask is connected to the delegate/proxy account (the one authorized via addProxy), not the primary account, before dispatching. Then, take the following steps:
- In Remix, set the amount to send in the VALUE field. Double-check the VALUE units (wei vs ether) before sending.
- Enter the address of the account being proxied.
- Enter the callTo address (this is the receiving account).
- Enter
0xfor call data. - Press Transact to dispatch the call.
Remove a Proxy¶
You can remove a proxy from your account via the Proxy Precompile. In this example, you will remove the balances proxy previously added to your delegate account by taking the following steps:
- Expand the Proxy Precompile contract to see the available functions
- Find the removeProxy function and press the button to expand the section
- Insert your second account's address as the delegate,
5as proxyType,0and as delay - Press transact and confirm the transaction in MetaMask
After the transaction is confirmed, if you repeat the steps to check for a proxy's existence, the result should be false.
And that's it! You've completed your introduction to the Proxy Precompile. Additional information on setting up proxies is available on the Setting up a Proxy Account page and the Proxy Accounts page on Polkadot's documentation. Feel free to reach out on Discord if you have any questions about any aspect of the Proxy Precompile.
| Created: February 3, 2022






