Dapper Labs
Published in

Dapper Labs

Designing Dapper

How we built our smart contract wallet

  • there was the process of backing up a key or seed phrase (usually accompanied by frightening warnings about the catastrophic consequences should you ever lose it),
  • the challenge of understanding the mechanics of gas, and
  • figuring out why on Earth in-game (and on-chain) actions sometimes took a minute and sometimes took an hour.
  • Client-side wallets — Wallets that store keys on the user’s device (eg. Metamask)
  • Server-side wallets — Wallets that store keys on the service provider’s server (eg. Coinbase)

When a system is designed so that a single mistake results in unrecoverable compromise or loss, it’s not a matter of if this will happen, but when.

  1. No single point of failure — The design should expect and be resilient to user error (eg. key loss, key compromise, etc.)
  2. End user is always in control — The user should always be in control of what’s in their wallet; Dapper Labs should never have access to or control over their assets
  3. Ease-of-use — The wallet should be easy, intuitive, and fun to use

Smart Contracts vs Direct-Keyed Accounts

The difference with Dapper

  1. Authorization enables deciding which devices have access to your account and which ones don’t — did you lose the phone containing your Dapper wallet? No problem, just revoke that device.
  2. Transacting is, well, transacting, but with some superpowers—you can perform multiple distinct actions within one transaction, and cosigner keys enable powerful security features.
  3. Recovery is your wallet’s last line of defence— it allows you to get back into your wallet, even if you lose all the other keys to your account.

Dapper’s authorization system

function setAuthorized(address _authorizedAddress, uint256 _cosigner)

Dapper’s transactions

  • An operation is a single user action executed by the wallet (this maps to the notion of a transaction in direct-keyed account wallets).
  • An invocation is an ordered list of operations to be executed together in a single function call to the wallet contract.
  • A transaction is what the term typically means when speaking generally about Ethereum. To sum up, a transaction contains 0 or more invocations and an invocation contains 1 or more operations.
function invoke0(bytes calldata data)function invoke1CosignerSends(uint8 v, bytes32 r, bytes32 s, uint256 nonce, address authorizedAddress, bytes calldata data)function invoke1SignerSends(uint8 v, bytes32 r, bytes32 s, bytes calldata data)function invoke2(uint8[2] calldata v, bytes32[2] calldata r, bytes32[2] calldata s, uint256 nonce, address authorizedAddress, bytes calldata data)
<revert 1byte>[<target 20bytes><value 32 bytes><datalen 32 bytes><data variable bytes>][…]

Dapper’s recovery mechanism

function setRecoveryAddress(address _recoveryAddress)function emergencyRecovery(address _authorizedAddress, uint256 _cosigner)
function recoverGas(uint256 _version, address[] calldata _keys)


Escape Hatch

Dapper makes it safe and easy to access blockchain-based fun

PS: Want to dig into the code? Check out our open-source repo!



The serious business of fun and games on the blockchain. New Flow blockchain blog: https://www.onflow.org/blog

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store