Multisignature Smart-Contract Wallets

Overview

BitGo enables multisignature wallets for account-based assets on programmable blockchains, such as Ethereum, using smart contracts. Like all Bitgo wallets, when you make multisignature smart-contract wallets, BitGo creates 3 keys (user, backup, and BitGo). In addition, the smart contracts enable creating multiple receive addresses, a feature that isn't native to most account-based assets. The 2-of-3 key scheme and the ability to create multiple receive addresses may appear similar to their UTXO counterparts. However, the mechanisms of how they work for smart-contract wallets differ.

Addresses

Multisignature smart-contract wallets utilize forwarder smart contracts to enable multiple receive addresses. The forwarder smart contract automatically consolidates native tokens received in your receive addresses to your base address. However, if you receive non-native tokens, such as ERC20 tokens, you must initiate a consolidation transaction to the base address yourself. Any of the 3 wallet keys can sign a consolidation transaction. Additionally, forwarders can only send funds to the base address of the wallet.

Depending on your use case, BitGo offers multiple forwarder versions. Version 0 forwarders deploy as soon as you create the address. Version 1 forwarders and above only deploy upon receiving assets, in either the forwarder or base address, enabling you to save on fees for wallets or addresses that aren't yet in use. BitGo uses the CREATE2 opcode to create the address, but doesn't broadcast the creation transaction until an indexer detects the address received assets.

Gas fees related to forwarders include the following:

  • Creating a forwarder address - free
  • Deploying a v0 forwarder address - 102,000 gwei
  • Receiving assets to a v1 or v2 forwarder address for the first time and thus deploying the address - 154,000 gwei
  • Transferring assets from a forwarder to the base address costs - 63,662 gwei.

Keys

Each key controls an address on the Ethereum blockchain. The user-key and backup-key addresses typically aren't funded, other than for disaster recovery. However, the BitGo-key address is funded, because it's the gas tank. You can shard each key using Shamir's Secret Sharing (SSS) to create more complicated key distributions. This is often done for the user key.

When you instantiate a multisignature smart-contract wallet, BitGo stores the 3 addresses in the allowedSigners array. Every method on the smart contract requires a certain number of allowed signers to prevent reverting. For example, sending a native token to another address using SendMultiSig requires 2-of-3 signatures, but flushing ERC20 tokens from a forwarder using flushForwarderTokens only requires 1 signature. This enables BitGo to flush ERC20 tokens from your forwarder addresses without your signature and is also why BitGo can't withdraw assets from your wallet.

Signing

The smart contract enables collecting 2-of-3 signatures all on a single on-chain transaction. Typically, the user key signs some fields, including, but not limited to:

  • Unique identifier for the chain
  • Amount
  • Final destination address
  • Any contract data being forwarded
  • Expire time
  • Contract sequence ID

This is done by creating a hash on those fields, and signing that hash. BitGo takes those fields, along with the hash and signature, and places them in the data section of an unsigned transaction. The unsigned transaction has a value of 0, and a destination of the base address of the wallet smart contract. BitGo adds a nonce to the unsigned transaction and sends it to the BitGo hardware security module (HSM) for final signing.

At this stage, Bitgo refers to the transaction as a half-signed, because 1-of-3 keys applied a signature. However, from a protocol level, it's an unsigned transaction that just contains cryptographic proof that 1-of-3 keys signed parts of the data section.

Lastly, BitGo uses the HSM to sign the transaction using the BitGo key, creating a fully signed transaction from both the perspective of BitGo and the protocol. BitGo then broadcasts the transaction to the base address of the wallet. The smart contract verifies the transaction was signed by 1-of-3 keys (typically the BitGo key) and that the operationHash was signed by another key (typically the user key).