Secure a Coldkey with a Multisig
A multisig (multiple signatories) wallet is a way of distributing responsibility for a coldkey across a set of wallets, referred to as signatories. Any signatory can propose a transaction, but the action must be agreed by some threshold of others before it will execute. Conventionally, a multisig is described as " out of ", where is the threshold number of signatories required to sign a transaction and is the total number of signatories. The signatories on a multisig may be seperate people, or a set of keys controlled by a single individual. This gives multisigs great versatility in providing security against single points of failure, including the loss of a single key or the decision of a team-mate to act irresponsibly.
A multisig account requires multiple signatories to approve a transaction before it is executed. This prevents a single point of failure, adding a strong layer of protection against malicious coldkey access. In Bittensor, this level of protection may be appropriate for very valuable wallets. This includes those with creator permissions over a subnet and those that control validator hotkeys with significant stake, but it can also include any individual wallet used for holding TAO and staking.
This page will guide the user through an example practice workflow of creating a multisig wallet and transferring TAO to and from it. For ease of practice, this entire workflow will be executed on a single workstation. However, in a realistic scenario, one or more operators would need to perform the steps on independent secure coldkey workstations in order to reap the full security benefits of a multisig configuration.
Prerequisites
- Install the latest version of BTCLI
- Acquire some Testnet TAO.
- Polkadot-JS: This tutorial will employ the Polkadot-JS browser app, which allows users to submit transactions to Polkadot-based chains, including Bittensor. To use your coldkey private keys with the Polkadot-JS app, you must install the wallet browser extension, which is available for Firefox or Chrome.
Provision and configure your workstation
A multisig depends on a set of pre-existing coldkeys, which will serve as the signatories for the multisig. In a realistic scenario, these coldkeys would belong to separate people--team-mates collectively managing a subnet or validator, for example, or family members managing a shared investment.
For this simple example, we will use a two of three multisig, meaning total number of signatories on the multisig is 3, and 2 signatures are required to authorize a transaction.
Keep security in mind
Coldkeys private keys and seed phrases for wallets with real (mainnet) TAO are critical secrets.
In a realistic scenario, using wallets with real (mainnet) TAO, it would be crucial to follow proper workstation security. This implies that each coldkey would be provisioned to its own secure coldkey workstation, as maintaining separate workstations for each coldkey is important for minimizing the risk that multiple of the keys are lost or leaked; storing or handling the keys together undermines the purpose of having multiple keys.
See Coldkey and Hotkey Workstation Security.
In the current practice scenario, using testnet TAO, we will forego full workstation security for ease, and handle all three keys on a single workstation, which can be an ordinary laptop rather than a secure workstation.
Configure the target network in the Polkadot-JS web app.
-
Visit the Polkadot-JS explorer web app.
-
Click the blockchain selector tab in the upper lefthand corner of the web page, next to Accounts. This is set to Polkadot main chain by default.
-
Scroll down and open Development at the bottom of the Chains menu, and paste the address for the Bittensor test chain into custom endpoint:
wss://test.finney.opentensor.ai:443
.You should see the page update and display live information about Bittensor testnet.
Create and import 3 coldkey pairs ("accounts") in the Polkadot-JS browser extension
Each of our 3 signatories needs a wallet. Either create them or re-use available test wallets.
-
Use
btcli
to create three coldkeys/wallets, or use practice wallets you already have access to. Alternatively, you can create wallets in the Polkadot-JS browser extension. -
Load each key into the Polkadot-JS wallet browser extension:
- Click to open the browser extension.
- Click +, then select Import account from pre-existing seed.
- Provide your seed phrase to regenerate your wallet's coldkey private key.
-
Configure your keys to use the custom network (Bittensor's test net). For each key/account:
- Click the menu (three dots) to configure the account.
- Open the network dropdown selector, and choose Allow use on any chain.
-
You may need to allow the PolkadotJS webapp to use specific wallets by clicking connect in the extension.
-
You may need to refresh the PolkadotJS webapp to show updated accounts information.
-
Confirm success by visiting the accounts page. You should see all three wallets/accounts listed as accounts available via browser extensions.
Create the multisig
In this step, we'll create the multisig wallet, specifying the signatory wallets.
-
Navigate to the accounts page.
-
Click + Multisig. In the add multisig modal:
- Select from the available signatories, which must be in your address book (if they are not, add them from the Accounts/Address book tab).
- Set the threshold.
- Set a name.
- Click create.
-
Use
btcli w regen_coldkeypub --wallet.name multisig
to add the wallet's public key to BTCLI. -
View its balance information with
btcli view dashboard --wallet.name multisig
.
Transfer TAO to the multisig wallet.
- Find the multisig wallet's coldkey public key on the accounts page, listed under multisig. Click on the wallet/account to open it's show modal, then click Copy by the account name and address/public key to copy it out.
- Use BTCLI to transfer testnet TAO to the mutlisig wallet.
- Run
btcli wallet transfer
. - Provide the multisig wallet's coldkey public key.
- Specify the amount. It's recommended to do a small transfer first to confirm the address, even with testnet TAO.
- Run
- To confirm the transfer, view the multisig wallet in the accounts page or the BTCLI dashboard. It should show the TAO from the transfer almost immediately.
Transfer TAO from the multisig
Let's try executing a sensitive operation with the multisig wallet: transferring TAO. Choose any destination wallet that you control. It can be one of the signatories. Note this wallet's balance, so you can confirm the transaction's ultimate success by seeing the increase in that balance.
To transfer TAO out of the multisig wallet requires a multisig transaction, meaning it must be approved by threshold of the total signatories. First, one wallet must propose the transaction. This proposal will exist on the blockchain where it can be signed by other signatories, which will execute the proposed transaction.
Note that the signatory that proposes a multisig action must make a deposit that will be returned upon approval or rejection of the transaction, the amount of which will be displayed in the multisig transaction modal. The wallet that will propose the multisig transaction must have a balance above this amount.
Propose the transfer
-
In the Polkadot-JS web app, click the Developer tab and select Extrinsics, or navigate to the extrinsics page at polkadot.js.org/apps/#/extrinsics.
-
Under using the selected account, select the multisig wallet. Note that the multisig wallet's TAO balance is displayed.
-
Under submit the following extrinsic:
- Select the
balances
module (from the lefthand dropdown menu). - Select
transferKeepAlive
.
- Select the
-
Under Id: AccountId, paste in the coldkey public key for the destination wallet.
-
Under value, put the amount of TAO to transfer. This amount must be available in the multisig wallet. A wallet with a test TAO balance sufficient to pay the fee
-
Copy out the encoded call data, which other signatories will need to sign the transaction.
-
Copy out the encoded call hash, which other signatories will need to confirm the details of the transaction.
-
Copy out the link under encoding details, which will allow other signatories to view the details of the transaction and confirm it against the encoded call hash.
-
Click Submit Transaction.
-
In the authorize transaction modal, select the signatory.
Note that this should be selected as a multisig signatory, not as a proxy account. You may need to toggle the Use a proxy for this call switch to Don't use a proxy for this call.
-
Select Multisig approval with hash (non-final approval), not Multisig message with call (for final approval).
-
Click Sign and Submit.
Approve the transaction
-
Return to the accounts page.
-
Find the multisig wallet, noting that it should now display a clickable element for view pending approvals. You can also click on the wallets three dot menu and select Multisig approvals.
-
The approval modal will display the encoded call hash, allowing signatories to confirm the identity of the proposed transaction, but it does not display details about the call.
To view details of the call, visit the link provided under encoding details when creating the transaction proposal.
cautionConfirm that the call hash in the details link matches the call hash in the transaction you are approving. This is the only way to be certain you are approving the correct transaction.
-
Select the approving signatory, which cannot be the signatory who proposed the transaction.
-
If you are the final approver, enter the encoded call data, which was provided when the transaction was created, and is displayed at the top of the page at the encoding details link.
-
Set the toggle to Multisig message with call (for final approval).
-
Click Approve, which will open the signing modal.
-
Confirm the information and click Sign and Submit.
Confirm success
Check the multisig wallet's balance, which should have decreased by the transfer amount, and the destination wallet, which should have increased.