Giter VIP home page Giter VIP logo

multi-sig's Introduction

🚩 Challenge 6: πŸ‘› Multisig Wallet

readme-6

πŸ‘©β€πŸ‘©β€πŸ‘§β€πŸ‘§ A multisig wallet is a smart contract that acts like a wallet, allowing us to secure assets by requiring multiple accounts to "vote" on transactions. Think of it as a treasure chest that can only be opened when all key parties agree.

πŸ“œ The contract keeps track of all transactions. Each transaction can be confirmed or rejected by the signers (smart contract owners). Only transactions that receive enough confirmations can be "executed" by the signers.

🌟 The final deliverable is a multisig wallet where you can propose adding and removing signers, transferring funds to other accounts, and updating the required number of signers to execute a transaction. After any of the signers propose a transaction, it's up to the signers to confirm and execute it. Deploy your contracts to a testnet, then build and upload your app to a public web server.

πŸ’¬ Meet other builders working on this challenge and get help in the Multisig Build Cohort telegram.


πŸ“œ Quest Journal 🧭

In this challenge you'll have access to a fully functional Multisig Wallet for inspiration, unlike previous challenges where certain code sections were intentionally left incomplete.

The objective is to allow builders to create their unique versions while referring to this existing build when encountering difficulties.

πŸ₯… Goals:

  • Can you edit and deploy the contract with a 2/3 multisig with two of your addresses and the buidlguidl multisig as the third signer? (buidlguidl.eth is like your backup recovery.)
  • Can you propose basic transactions with the frontend that sends them to the backend?
  • Can you β€œvote” on the transaction as other signers?
  • Can you execute the transaction and does it do the right thing?
  • Can you add and remove signers with a custom dialog (that just sends you to the create transaction dialog with the correct calldata)

βš”οΈ Side Quests:

  • Multisig as a service
    Create a deploy button with a copy-paste dialog for sharing so anyone can make a multisig at your URL with your frontend.

  • Create custom signer roles for your Wallet
    You may not want every signer to create new transfers, only allow them to sign existing transactions or a mega-admin role who will be able to veto any transaction.

  • Integrate this MultiSig wallet into other Scaffold ETH-2 builds
    Find a Scaffold ETH-2 build that could make use of a Multisig wallet and try to integrate it!


πŸ‘‡πŸΌ Quick Break-Down πŸ‘›

This is a smart contract that acts as an offchain signature-based shared wallet amongst different signers that showcases use of meta-transaction knowledge and ECDSA recover().

If you are unfamiliar with these concepts, check out all the ETH.BUILD videos by Austin Griffith, especially the Meta Transactions one!

❗ OpenZepplin's ECDSA Library provides an easy way to verify signed messages, in this challenge we'll be using it to verify the signatures of the signers of the multisig wallet.

At a high-level, the contract core functions are carried out as follows:

Offchain: β›“πŸ™…πŸ»β€β™‚οΈ - Generation of a packed hash (bytes32) for a function call with specific parameters through a public view function . - It is signed by one of the signers associated to the multisig, and added to an array of signatures (bytes[] memory signatures)

Onchain: β›“πŸ™†πŸ»β€β™‚οΈ

  • bytes[] memory signatures is then passed into executeTransaction as well as the necessary info to use recover() to obtain the public address that ought to line up with one of the signers of the wallet.
    • This method, plus some conditional logic to avoid any duplicate entries from a single signer, is how votes for a specific transaction (hashed tx) are assessed.
  • If it's a success, the tx is passed to the call(){} function of the deployed MetaMultiSigWallet contract (this contract), thereby passing the onlySelf modifier for any possible calls to internal txs such as (addSigner(),removeSigner(),transferFunds(),updateSignaturesRequired()).

Cool Stuff that is Showcased: 😎

  • Showcases how the call(){} function is an external call that ought to increase the nonce of an external contract, as they increment differently from user accounts.
  • Normal internal functions, such as changing the signers, and adding or removing signers, are treated as external function calls when call() is used with the respective transaction hash.
  • Showcases use of an array (see constructor) populating a mapping to store pertinent information within the deployed smart contract storage location within the EVM in a more efficient manner.

Checkpoint 0: πŸ“¦ Environment πŸ“š

Before you begin, you need to install the following tools:

Then download the challenge to your computer and install dependencies by running:

git clone https://github.com/scaffold-eth/se-2-challenges.git challenge-6-multisig
cd challenge-6-multisig
git checkout challenge-6-multisig
yarn install

in the same terminal, start your local network (a blockchain emulator in your computer):

yarn chain

in a second terminal window, πŸ›° deploy your contract (locally):

cd challenge-6-multisig
yarn deploy

in a third terminal window, start your πŸ“± frontend:

cd challenge-6-multisig
yarn start

πŸ“± Open http://localhost:3000 to see the app.

In a fourth terminal window:

❗ This command is only required in your local environment (Hardhat chain).

yarn backend-local

When deployed to any other chain, it will automatically use our deployed backend (repo) from https://backend.multisig.holdings:49832/.

πŸ‘©β€πŸ’» Rerun yarn deploy --reset whenever you want to deploy new contracts to the frontend, update your current contracts with changes, or re-deploy it to get a fresh contract address.

πŸ” Now you are ready to edit your smart contract MetaMultiSigWallet.sol in packages/hardhat/contracts


Checkpoint 1: πŸ“ Configure Owners πŸ–‹

πŸ” The first step for this multisig wallet is to configure the owners, who will be able to propose, sign and execute transactions.

πŸ—οΈ This is done in the constructor of the contract, where you can pass in an array of addresses that will be the signers of the wallet, and a number of signatures required to execute a transaction.

πŸ› οΈ Modify the contract constructor arguments at the deploy script 00_deploy_meta_multisig_wallet.ts in packages/hardhat/deploy. Just set the first signer using your frontend address.

πŸ”„ Will need to run yarn deploy --reset to deploy a fresh contract with the first signer configured.

You can set the rest of the signers in the frontend, using the "Owners" tab:

multisig-1

In this tab you can start your transaction proposal to either add or remove owners.

πŸ“ Fill the form and click on "Create Tx".

multisig-2

This will take you to a populated transaction at "Create" page:

multisig-3

Create & sign the new transaction, clicking in the "Create" button:

multisig-4

You will see the new transaction in the pool (this is all offchain).

You won't be able to sign it because on creation it already has one signature (from the frontend account).

Click on the ellipsses button [...] to read the details of the transaction.

multisig-5

⛽️ Give your account some gas at the faucet and execute the transaction.

β˜‘ Click on "Exec" to execute it, will be marked as "Completed" on the "Pool" tab, and will appear in the "Multisig" tab with the rest of executed transactions.

multisig-6a

multisig-6b

Checkpoint 2: Transfer Funds πŸ’Έ

πŸ’° Use the faucet to send your multisig contract some funds. You can find the address in the "Multisig" and "Debug Contracts" tabs.

Create a transaction in the "Create" tab to send some funds to one of your signers, or to any other address of your choice:

multisig-7

πŸ–‹ This time we will need a second signature (remember we've just updated the number of signatures required to execute a transaction to 2).

multisig-8

Open another browser and access with a different owner of the multisig. Sign the transaction with enough owners:

multisig-9

(You'll notice you don't need ⛽️gas to sign transactions).

Execute the transaction to transfer the funds:

multisig-10


Checkpoint 3: πŸ’Ύ Deploy your contracts! πŸ›°

πŸ“‘ Edit the defaultNetwork to your choice of public EVM networks in packages/hardhat/hardhat.config.ts

πŸ” You will need to generate a deployer address using yarn generate This creates a mnemonic and saves it locally.

πŸ‘©β€πŸš€ Use yarn account to view your deployer account balances.

⛽️ You will need to send ETH to your deployer address with your wallet, or get it from a public faucet of your chosen network.

πŸš€ Run yarn deploy to deploy your smart contract to a public network (selected in hardhat.config.ts)

πŸ’¬ Hint: You can set the defaultNetwork in hardhat.config.ts to sepolia OR you can yarn deploy --network sepolia.

πŸ’¬ Hint: For faster loading of the Multisig tabs, consider updating the fromBlock passed to useScaffoldEventHistory (in the different components we're using it) to blocknumber - 10 at which your contract was deployed. Example: fromBlock: 3750241n (where n represents its a BigInt). To find this blocknumber, search your contract's address on Etherscan and find the Contract Creation transaction line.


Checkpoint 4: 🚒 Ship your frontend! 🚁

✏️ Edit your frontend config in packages/nextjs/scaffold.config.ts to change the targetNetwork to chains.sepolia or any other public network.

πŸ’» View your frontend at http://localhost:3000 and verify you see the correct network.

πŸ“‘ When you are ready to ship the frontend app...

πŸ“¦ Run yarn vercel to package up your frontend and deploy.

Follow the steps to deploy to Vercel. Once you log in (email, github, etc), the default options should work. It'll give you a public URL.

If you want to redeploy to the same production URL you can run yarn vercel --prod. If you omit the --prod flag it will deploy it to a preview/test URL.

🦊 Since we have deployed to a public testnet, you will now need to connect using a wallet you own or use a burner wallet. By default πŸ”₯ burner wallets are only available on hardhat . You can enable them on every chain by setting onlyLocalBurnerWallet: false in your frontend config (scaffold.config.ts in packages/nextjs/)

Configuration of Third-Party Services for Production-Grade Apps.

By default, πŸ— Scaffold-ETH 2 provides predefined API keys for popular services such as Alchemy and Etherscan. This allows you to begin developing and testing your applications more easily, avoiding the need to register for these services. This is great to complete your SpeedRunEthereum.

For production-grade applications, it's recommended to obtain your own API keys (to prevent rate limiting issues). You can configure these at:

  • πŸ”·ALCHEMY_API_KEY variable in packages/hardhat/.env and packages/nextjs/.env.local. You can create API keys from the Alchemy dashboard.

  • πŸ“ƒETHERSCAN_API_KEY variable in packages/hardhat/.env with your generated API key. You can get your key here.

πŸ’¬ Hint: It's recommended to store env's for nextjs in Vercel/system env config for live apps and use .env.local for local testing.


Checkpoint 5: πŸ“œ Contract Verification

Run the yarn verify --network your_network command to verify your contracts on etherscan πŸ›°


πŸ‘©β€β€οΈβ€πŸ‘¨ Share your public url with friends, add signers and send some tasty ETH to a few lucky ones πŸ˜‰!!

πŸƒ Head to your next challenge here.

πŸ’¬ Problems, questions, comments on the stack? Post them to the πŸ— scaffold-eth developers chat

multi-sig's People

Contributors

bhavyagor12 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.