{"id":12202,"date":"2025-02-05T15:36:35","date_gmt":"2025-02-05T15:36:35","guid":{"rendered":"https:\/\/metaschool.so\/articles\/?p=12202"},"modified":"2025-02-09T15:36:54","modified_gmt":"2025-02-09T15:36:54","slug":"build-a-multisig-wallet-on-zksync-era","status":"publish","type":"post","link":"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/","title":{"rendered":"Building a MultiSig Wallet on ZKSync Era: A Complete Guide 2025"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_56_1 ez-toc-wrap-left counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title \" >Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Introduction\" title=\"Introduction\">Introduction<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#What_is_a_MultiSig_Wallet\" title=\"What is a MultiSig Wallet?\">What is a MultiSig Wallet?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Why_the_ZKsync_Era\" title=\"Why the ZKsync Era?\">Why the ZKsync Era?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Project_Setup\" title=\"Project Setup\">Project Setup<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Project_Structure\" title=\"Project Structure\">Project Structure<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Installing_Dependencies\" title=\"Installing Dependencies\">Installing Dependencies<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Understanding_the_Contract_Components\" title=\"Understanding the Contract Components\">Understanding the Contract Components<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#State_Variables\" title=\"State Variables\">State Variables<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Transaction_Structure\" title=\"Transaction Structure \">Transaction Structure <\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Events_and_Modifiers\" title=\"Events and Modifiers\">Events and Modifiers<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Core_Functionality_Implementation\" title=\"Core Functionality Implementation\">Core Functionality Implementation<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Constructor\" title=\"Constructor\">Constructor<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Submitting_Transactions\" title=\"Submitting Transactions\">Submitting Transactions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Confirmation_and_Execution\" title=\"Confirmation and Execution\">Confirmation and Execution<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Deploying_to_ZKSync_Era\" title=\"Deploying to ZKSync Era\">Deploying to ZKSync Era<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Hardhat_Configuration\" title=\"Hardhat Configuration\">Hardhat Configuration<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Deployment_Script\" title=\"Deployment Script\">Deployment Script<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Testing_the_Wallet\" title=\"Testing the Wallet\">Testing the Wallet<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Interacting_with_the_MultiSig_Wallet_A_Command-Line_Interface\" title=\"Interacting with the MultiSig Wallet: A Command-Line Interface\">Interacting with the MultiSig Wallet: A Command-Line Interface<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Understanding_the_CLI_Tool\" title=\"Understanding the CLI Tool\">Understanding the CLI Tool<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Example_Usage\" title=\"Example Usage:\">Example Usage:<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Security_Considerations\" title=\" Security Considerations\"> Security Considerations<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/metaschool.so\/articles\/build-a-multisig-wallet-on-zksync-era\/#Conclusion\" title=\"Conclusion\">Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Introduction\"><\/span>Introduction<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Security\u00a0in the world of Web3\u00a0is\u00a0not\u00a0a feature\u00a0but\u00a0a\u00a0given. Multi-signature\u00a0wallets\u00a0probably\u00a0represent one of the\u00a0robust\u00a0ways\u00a0to\u00a0secure\u00a0one&#8217;s\u00a0digital assets,\u00a0where\u00a0the\u00a0need\u00a0for several\u00a0parties to approve transactions\u00a0is baked into their design. Today, we\u00a0will\u00a0build a secure MultiSig wallet on ZKSync Era,\u00a0which\u00a0combines\u00a0multisignature\u00a0security\u00a0with\u00a0Layer 2 scaling\u00a0efficiency. But before we dive\u00a0deep\u00a0into the code, let&#8217;s\u00a0first\u00a0understand what we\u00a0are\u00a0going to build\u00a0and why each component matters.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_is_a_MultiSig_Wallet\"><\/span>What is a MultiSig Wallet?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>A multisig wallet is like\u00a0the\u00a0digital\u00a0equivalent\u00a0of having a safe\u00a0with multiple keyholders.\u00a0 Consider\u00a0this as like\u00a0a corporate treasury where no\u00a0one\u00a0person should have complete control over the funds. Instead of\u00a0needing\u00a0just one signature to\u00a0validate\u00a0a transaction, a multisig wallet requires a\u00a0predetermined\u00a0number of authorized signatures before any transaction can\u00a0execute.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"774\" src=\"https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/image-4.png\" alt=\"Working of MultiSig wallet explained\" class=\"wp-image-12204\" srcset=\"https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/image-4.png 1200w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/image-4-300x194.png 300w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/image-4-1024x660.png 1024w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/image-4-768x495.png 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><figcaption class=\"wp-element-caption\">Image by sCrypt <\/figcaption><\/figure>\n\n\n\n<p>For\u00a0instance, in a\u00a0three-owner\u00a0multisig\u00a0wallet\u00a0that\u00a0requires\u00a0two signatures\u00a0before funds can be transferred, any two\u00a0of the\u00a0owners\u00a0would\u00a0have to\u00a0agree\u00a0on\u00a0such\u00a0a\u00a0transfer. This significantly\u00a0limits\u00a0the\u00a0risks\u00a0of:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Unauthorized transactions<\/li>\n\n\n\n<li>Single points of failure<\/li>\n\n\n\n<li>Internal fraud<\/li>\n\n\n\n<li>Key compromise <\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Why_the_ZKsync_Era\"><\/span>Why the ZKsync Era?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>ZKSync Era is a Layer 2 scaling solution that offers several advantages for our MultiSig implementation: <\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Cost Efficiency: Transactions cost significantly less than on Ethereum mainnet<\/li>\n\n\n\n<li>Speed: Faster transaction confirmation times<\/li>\n\n\n\n<li>Security: Inherits Ethereum&#8217;s security through ZK rollup technology<\/li>\n\n\n\n<li>EVM Compatibility: Allows us to use familiar Solidity patterns and tools. <br><br>We have a very fun course on ZKsync. Learn to build a<a href=\"https:\/\/metaschool.so\/courses\/build-music-streaming-dapp-zksync\" data-type=\"link\" data-id=\"https:\/\/metaschool.so\/courses\/build-music-streaming-dapp-zksync\"> Decentralized Music Streaming and Tipping Platform on ZKsync<\/a>. <\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"666\" src=\"https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/Screenshot-2025-02-09-at-11.25.29-PM-1024x666.png\" alt=\"\" class=\"wp-image-12317\" srcset=\"https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/Screenshot-2025-02-09-at-11.25.29-PM-1024x666.png 1024w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/Screenshot-2025-02-09-at-11.25.29-PM-300x195.png 300w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/Screenshot-2025-02-09-at-11.25.29-PM-768x499.png 768w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/Screenshot-2025-02-09-at-11.25.29-PM-1536x999.png 1536w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2025\/02\/Screenshot-2025-02-09-at-11.25.29-PM-2048x1332.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Project_Setup\"><\/span>Project Setup<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Let&#8217;s start by setting up our development environment. Create a new project directory:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"mkdir zksync-multisig\ncd zksync-multisig\nnpm init -y\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">mkdir<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">zksync<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">multisig<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">cd<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">zksync<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">multisig<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">npm<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">init<\/span><span style=\"color: #D4D4D4\"> -<\/span><span style=\"color: #9CDCFE\">y<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Project_Structure\"><\/span>Project Structure<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Our project will follow this structure. We will first create a directory named zksync-multisig, inside which we have a contracts folder, a deploy folder, scripts , and configuration files for hardhat, typescript, a package.json, and a .env file.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"zksync-multisig\/\n\u251c\u2500\u2500 contracts\/\n\u2502   \u2514\u2500\u2500 MultiSigWallet.sol\n\u251c\u2500\u2500 deploy\/\n\u2502   \u2514\u2500\u2500 deploy.ts\n\u251c\u2500\u2500 scripts\/\n\u2502   \u2514\u2500\u2500 compile.ts\n\u251c\u2500\u2500 hardhat.config.ts\n\u251c\u2500\u2500 tsconfig.json\n\u251c\u2500\u2500 package.json\n\u2514\u2500\u2500 .env\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">zksync<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">multisig<\/span><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u251c\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">contracts<\/span><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u2502   \u2514\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">MultiSigWallet<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">sol<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u251c\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">deploy<\/span><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u2502   \u2514\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">deploy<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ts<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u251c\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">scripts<\/span><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u2502   \u2514\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">compile<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ts<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u251c\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">hardhat<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">config<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ts<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u251c\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">tsconfig<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">json<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u251c\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">package<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">json<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u2514\u2500\u2500 .<\/span><span style=\"color: #9CDCFE\">env<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Installing_Dependencies\"><\/span>Installing Dependencies<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Install the necessary packages:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"npm install --save-dev @matterlabs\/hardhat-zksync-deploy @matterlabs\/hardhat-zksync-solc @openzeppelin\/contracts zksync-web3 ethers hardhat @types\/node @types\/chai typescript ts-node dotenv\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">npm<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">install<\/span><span style=\"color: #D4D4D4\"> --<\/span><span style=\"color: #9CDCFE\">save<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">dev<\/span><span style=\"color: #D4D4D4\"> @<\/span><span style=\"color: #9CDCFE\">matterlabs<\/span><span style=\"color: #D4D4D4\">\/<\/span><span style=\"color: #9CDCFE\">hardhat<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">zksync<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">deploy<\/span><span style=\"color: #D4D4D4\"> @<\/span><span style=\"color: #9CDCFE\">matterlabs<\/span><span style=\"color: #D4D4D4\">\/<\/span><span style=\"color: #9CDCFE\">hardhat<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">zksync<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">solc<\/span><span style=\"color: #D4D4D4\"> @<\/span><span style=\"color: #9CDCFE\">openzeppelin<\/span><span style=\"color: #D4D4D4\">\/<\/span><span style=\"color: #9CDCFE\">contracts<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">zksync<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">web3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">hardhat<\/span><span style=\"color: #D4D4D4\"> @<\/span><span style=\"color: #9CDCFE\">types<\/span><span style=\"color: #D4D4D4\">\/<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\"> @<\/span><span style=\"color: #9CDCFE\">types<\/span><span style=\"color: #D4D4D4\">\/<\/span><span style=\"color: #9CDCFE\">chai<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">typescript<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ts<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">dotenv<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Each package serves a specific purpose:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<ul class=\"wp-block-list\">\n<li><code>@matterlabs\/hardhat-zksync-deploy<\/code>: Enables deployment to ZKSync<\/li>\n\n\n\n<li><code>@matterlabs\/hardhat-zksync-solc<\/code>: Compiles contracts for ZKSync<\/li>\n\n\n\n<li><code>@openzeppelin\/contracts<\/code>: Provides secure, audited contract components<\/li>\n\n\n\n<li><code>zksync-web3<\/code>: Facilitates interaction with ZKSync network<\/li>\n<\/ul>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Understanding_the_Contract_Components\"><\/span>Understanding the Contract Components<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Let&#8217;s break down our MultiSig wallet contract into its core components. Each piece serves a specific security or functional purpose.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"State_Variables\"><\/span>State Variables<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"\/\/ SPDX-License-Identifier: MIT\npragma solidity ^0.8.17;\n\nimport &quot;@openzeppelin\/contracts\/security\/ReentrancyGuard.sol&quot;;\n\ncontract MultiSigWallet is ReentrancyGuard {\n    address[] public owners;\n    mapping(address =&gt; bool) public isOwner;\n    uint public numConfirmationsRequired;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\">\/\/ SPDX-License-Identifier: MIT<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">pragma<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">solidity<\/span><span style=\"color: #D4D4D4\"> ^<\/span><span style=\"color: #B5CEA8\">0.8<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #B5CEA8\">17<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;@openzeppelin\/contracts\/security\/ReentrancyGuard.sol&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">MultiSigWallet<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ReentrancyGuard<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">owners<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">mapping<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">isOwner<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">numConfirmationsRequired<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Here&#8217;s why each state variable matters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>owners<\/code>: Stores the list of wallet owners&#8217; addresses<\/li>\n\n\n\n<li><code>isOwner<\/code>: Provides O(1) lookup to verify if an address is an owner<\/li>\n\n\n\n<li><code>numConfirmationsRequired<\/code>: Defines how many owners must confirm a transaction<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Transaction_Structure\"><\/span>Transaction Structure <span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"    struct Transaction {\n        address to;\n        uint value;\n        bytes data;\n        bool executed;\n        uint numConfirmations;\n    }\n\n    Transaction[] public transactions;\n    mapping(uint =&gt; mapping(address =&gt; bool)) public isConfirmed;\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">struct<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Transaction<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">value<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bytes<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">executed<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">numConfirmations<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">Transaction<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">transactions<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">mapping<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">mapping<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\">)) <\/span><span style=\"color: #9CDCFE\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">isConfirmed<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>This structure is crucial because:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>It tracks all transaction details including recipient, value, and execution status<\/li>\n\n\n\n<li>The nested mapping <code>isConfirmed<\/code> prevents double confirmations<\/li>\n\n\n\n<li>The array <code>transactions<\/code> maintains an ordered history of all proposals<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Events_and_Modifiers\"><\/span>Events and Modifiers<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"    event Deposit(address indexed sender, uint amount, uint balance);\n    event SubmitTransaction(\n        address indexed owner,\n        uint indexed txIndex,\n        address indexed to,\n        uint value,\n        bytes data\n    );\n\n    modifier onlyOwner() {\n        require(isOwner[msg.sender], &quot;not owner&quot;);\n        _;\n    }\n\n    modifier txExists(uint _txIndex) {\n        require(_txIndex < transactions.length, &quot;tx does not exist&quot;);\n        _;\n    }\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">event<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">Deposit<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">indexed<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">sender<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">amount<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">balance<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">event<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">SubmitTransaction<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">indexed<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">owner<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">indexed<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">txIndex<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">indexed<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">value<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bytes<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    );<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">modifier<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">onlyOwner<\/span><span style=\"color: #D4D4D4\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">isOwner<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">msg<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">sender<\/span><span style=\"color: #D4D4D4\">], <\/span><span style=\"color: #CE9178\">&quot;not owner&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">_<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">modifier<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">txExists<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">transactions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;tx does not exist&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">_<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Events and modifiers enhance our contract by:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Providing transparent transaction tracking<\/li>\n\n\n\n<li>Implementing access control<\/li>\n\n\n\n<li>Ensuring transaction validity<\/li>\n\n\n\n<li>Preventing execution of non-existent transactions<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Core_Functionality_Implementation\"><\/span>Core Functionality Implementation<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Constructor\"><\/span>Constructor<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"    constructor(address[] memory _owners, uint _numConfirmationsRequired) {\n        require(_owners.length &gt; 0, &quot;owners required&quot;);\n        require(\n            _numConfirmationsRequired &gt; 0 &amp;&amp;\n                _numConfirmationsRequired <= _owners.length,\n            &quot;invalid number of required confirmations&quot;\n        );\n\n        for (uint i = 0; i < _owners.length; i++) {\n            address owner = _owners[i];\n            require(owner != address(0), &quot;invalid owner&quot;);\n            require(!isOwner[owner], &quot;owner not unique&quot;);\n\n            isOwner[owner] = true;\n            owners.push(owner);\n        }\n\n        numConfirmationsRequired = _numConfirmationsRequired;\n    }\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">constructor<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_owners<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_numConfirmationsRequired<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_owners<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;owners required&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">_numConfirmationsRequired<\/span><span style=\"color: #D4D4D4\"> &gt; <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\"> &amp;&amp;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">_numConfirmationsRequired<\/span><span style=\"color: #D4D4D4\"> &lt;= <\/span><span style=\"color: #9CDCFE\">_owners<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #CE9178\">&quot;invalid number of required confirmations&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        );<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\"> &lt; <\/span><span style=\"color: #9CDCFE\">_owners<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">; <\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">++) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">owner<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_owners<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">owner<\/span><span style=\"color: #D4D4D4\"> != <\/span><span style=\"color: #DCDCAA\">address<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">), <\/span><span style=\"color: #CE9178\">&quot;invalid owner&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(!<\/span><span style=\"color: #9CDCFE\">isOwner<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">owner<\/span><span style=\"color: #D4D4D4\">], <\/span><span style=\"color: #CE9178\">&quot;owner not unique&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">isOwner<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">owner<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">owners<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">push<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">owner<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">numConfirmationsRequired<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">_numConfirmationsRequired<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>The constructor implements crucial validation:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ensures there&#8217;s at least one owner<\/li>\n\n\n\n<li>Validates the number of required confirmations<\/li>\n\n\n\n<li>Prevents duplicate owners<\/li>\n\n\n\n<li>Rejects zero addresses<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Submitting_Transactions\"><\/span>Submitting Transactions<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"    function submitTransaction(\n        address _to,\n        uint _value,\n        bytes memory _data\n    ) public onlyOwner {\n        uint txIndex = transactions.length;\n\n        transactions.push(\n            Transaction({\n                to: _to,\n                value: _value,\n                data: _data,\n                executed: false,\n                numConfirmations: 0\n            })\n        );\n\n        emit SubmitTransaction(msg.sender, txIndex, _to, _value, _data);\n    }\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">submitTransaction<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_to<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_value<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">bytes<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">memory<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">onlyOwner<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">txIndex<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">transactions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">transactions<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">push<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">Transaction<\/span><span style=\"color: #D4D4D4\">({<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">to:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_to<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">value:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_value<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">data:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_data<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">executed:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">numConfirmations:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">0<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            })<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        );<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">emit<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">SubmitTransaction<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">msg<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">sender<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">txIndex<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_to<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_value<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_data<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>This function:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Creates new transaction proposals<\/li>\n\n\n\n<li>Initializes confirmation count to zero<\/li>\n\n\n\n<li>Emits an event for off-chain tracking<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Confirmation_and_Execution\"><\/span>Confirmation and Execution<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"    function confirmTransaction(\n        uint _txIndex\n    ) public onlyOwner txExists(_txIndex) notExecuted(_txIndex) notConfirmed(_txIndex) {\n        Transaction storage transaction = transactions[_txIndex];\n        transaction.numConfirmations += 1;\n        isConfirmed[_txIndex][msg.sender] = true;\n\n        emit ConfirmTransaction(msg.sender, _txIndex);\n    }\n\n    function executeTransaction(\n        uint _txIndex\n    ) public onlyOwner txExists(_txIndex) notExecuted(_txIndex) nonReentrant {\n        Transaction storage transaction = transactions[_txIndex];\n\n        require(\n            transaction.numConfirmations &gt;= numConfirmationsRequired,\n            &quot;cannot execute tx&quot;\n        );\n\n        transaction.executed = true;\n\n        (bool success, ) = transaction.to.call{value: transaction.value}(\n            transaction.data\n        );\n        require(success, &quot;tx failed&quot;);\n\n        emit ExecuteTransaction(msg.sender, _txIndex);\n    }\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">confirmTransaction<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">onlyOwner<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">txExists<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">notExecuted<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">notConfirmed<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">Transaction<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">storage<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">transaction<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">transactions<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">transaction<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">numConfirmations<\/span><span style=\"color: #D4D4D4\"> += <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">isConfirmed<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">][<\/span><span style=\"color: #9CDCFE\">msg<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">sender<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">emit<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">ConfirmTransaction<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">msg<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">sender<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">executeTransaction<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">uint<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    ) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">onlyOwner<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">txExists<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">notExecuted<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">nonReentrant<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">Transaction<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">storage<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">transaction<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">transactions<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">transaction<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">numConfirmations<\/span><span style=\"color: #D4D4D4\"> &gt;= <\/span><span style=\"color: #9CDCFE\">numConfirmationsRequired<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #CE9178\">&quot;cannot execute tx&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        );<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">transaction<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">executed<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        (<\/span><span style=\"color: #9CDCFE\">bool<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">success<\/span><span style=\"color: #D4D4D4\">, ) = <\/span><span style=\"color: #9CDCFE\">transaction<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">call<\/span><span style=\"color: #D4D4D4\">{<\/span><span style=\"color: #C8C8C8\">value<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #9CDCFE\">transaction<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">value<\/span><span style=\"color: #D4D4D4\">}(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">transaction<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">data<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        );<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">success<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;tx failed&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">emit<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">ExecuteTransaction<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">msg<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">sender<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">_txIndex<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>These functions implement:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Secure transaction confirmation tracking<\/li>\n\n\n\n<li>Reentrancy protection during execution<\/li>\n\n\n\n<li>Proper state updates<\/li>\n\n\n\n<li>Event emission for transparency<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Deploying_to_ZKSync_Era\"><\/span>Deploying to ZKSync Era<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Hardhat_Configuration\"><\/span>Hardhat Configuration<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Create: <code>hardhat.config.ts<\/code><\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"import &quot;@matterlabs\/hardhat-zksync-deploy&quot;;\nimport &quot;@matterlabs\/hardhat-zksync-solc&quot;;\n\nmodule.exports = {\n  zksolc: {\n    version: &quot;1.3.5&quot;,\n    compilerSource: &quot;binary&quot;,\n    settings: {},\n  },\n  defaultNetwork: &quot;zkSyncTestnet&quot;,\n  networks: {\n    zkSyncTestnet: {\n      url: &quot;https:\/\/sepolia.era.zksync.dev&quot;,\n      ethNetwork: &quot;sepolia&quot;,\n      zksync: true,\n      verifyURL: &quot;https:\/\/explorer.era.zksync.dev\/contract_verification&quot;\n    },\n  },\n  solidity: {\n    version: &quot;0.8.17&quot;,\n  },\n};\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;@matterlabs\/hardhat-zksync-deploy&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;@matterlabs\/hardhat-zksync-solc&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #4EC9B0\">module<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4EC9B0\">exports<\/span><span style=\"color: #D4D4D4\"> = {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">zksolc:<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">version:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;1.3.5&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">compilerSource:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;binary&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">settings:<\/span><span style=\"color: #D4D4D4\"> {},<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">defaultNetwork:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;zkSyncTestnet&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">networks:<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">zkSyncTestnet:<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">url:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;https:\/\/sepolia.era.zksync.dev&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">ethNetwork:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;sepolia&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">zksync:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">verifyURL:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;https:\/\/explorer.era.zksync.dev\/contract_verification&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">solidity:<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">version:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;0.8.17&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">};<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Deployment_Script\"><\/span>Deployment Script<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Create: <code>deploy\/deploy.ts<\/code> <br><br>Note: You can get the test sepolia tokens here: <a href=\"https:\/\/faucet.triangleplatform.com\/zksync\/sepolia\" target=\"_blank\" rel=\"noopener\">https:\/\/faucet.triangleplatform.com\/zksync\/sepolia<\/a><\/p>\n<\/blockquote>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"import { Wallet } from &quot;zksync-web3&quot;;\nimport * as ethers from &quot;ethers&quot;;\nimport { HardhatRuntimeEnvironment } from &quot;hardhat\/types&quot;;\nimport { Deployer } from &quot;@matterlabs\/hardhat-zksync-deploy&quot;;\n\nexport default async function (hre: HardhatRuntimeEnvironment) {\n  const wallet = new Wallet(&quot;<YOUR_PRIVATE_KEY&gt;&quot;);\n  const deployer = new Deployer(hre, wallet);\n\n  \/\/ Load contract artifact\n  const artifact = await deployer.loadArtifact(&quot;MultiSigWallet&quot;);\n\n  \/\/ Deploy contract\n  const owners = [wallet.address]; \/\/ Add more owners as needed\n  const requiredConfirmations = 1;\n\n  const multiSigWallet = await deployer.deploy(artifact, [owners, requiredConfirmations]);\n\n  console.log(`MultiSig wallet deployed to ${multiSigWallet.address}`);\n}\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">Wallet<\/span><span style=\"color: #D4D4D4\"> } <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;zksync-web3&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">*<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">as<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;ethers&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">HardhatRuntimeEnvironment<\/span><span style=\"color: #D4D4D4\"> } <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;hardhat\/types&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">Deployer<\/span><span style=\"color: #D4D4D4\"> } <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;@matterlabs\/hardhat-zksync-deploy&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">export<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">default<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">hre<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4EC9B0\">HardhatRuntimeEnvironment<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">wallet<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">Wallet<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;&lt;YOUR_PRIVATE_KEY&gt;&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">deployer<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">Deployer<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">hre<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">wallet<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #6A9955\">\/\/ Load contract artifact<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">artifact<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">deployer<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">loadArtifact<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;MultiSigWallet&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #6A9955\">\/\/ Deploy contract<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">owners<\/span><span style=\"color: #D4D4D4\"> = [<\/span><span style=\"color: #9CDCFE\">wallet<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\">]; <\/span><span style=\"color: #6A9955\">\/\/ Add more owners as needed<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">requiredConfirmations<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">multiSigWallet<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">deployer<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">deploy<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">artifact<\/span><span style=\"color: #D4D4D4\">, [<\/span><span style=\"color: #9CDCFE\">owners<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">requiredConfirmations<\/span><span style=\"color: #D4D4D4\">]);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">console<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">log<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">`MultiSig wallet deployed to <\/span><span style=\"color: #569CD6\">${<\/span><span style=\"color: #9CDCFE\">multiSigWallet<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #569CD6\">}<\/span><span style=\"color: #CE9178\">`<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Testing_the_Wallet\"><\/span>Testing the Wallet<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Let&#8217;s create a basic test script to verify our wallet&#8217;s functionality:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"import { expect } from &quot;chai&quot;;\nimport { Wallet, Provider } from &quot;zksync-web3&quot;;\nimport * as hre from &quot;hardhat&quot;;\nimport { Deployer } from &quot;@matterlabs\/hardhat-zksync-deploy&quot;;\n\ndescribe(&quot;MultiSigWallet&quot;, function () {\n    it(&quot;Should deploy and execute a transaction&quot;, async function () {\n        \/\/ Test implementation\n    });\n});\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">expect<\/span><span style=\"color: #D4D4D4\"> } <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;chai&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">Wallet<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">Provider<\/span><span style=\"color: #D4D4D4\"> } <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;zksync-web3&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">*<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">as<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">hre<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;hardhat&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">Deployer<\/span><span style=\"color: #D4D4D4\"> } <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;@matterlabs\/hardhat-zksync-deploy&quot;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">describe<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;MultiSigWallet&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> () {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">it<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Should deploy and execute a transaction&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> () {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Test implementation<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    });<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">});<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Interacting_with_the_MultiSig_Wallet_A_Command-Line_Interface\"><\/span>Interacting with the MultiSig Wallet: A Command-Line Interface<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>To make our MultiSig wallet more accessible and easier to interact with, we&#8217;ve created a CLI tool that simplifies common operations. This script provides a user-friendly interface for submitting, confirming, and executing transactions, as well as viewing transaction details.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Understanding_the_CLI_Tool\"><\/span>Understanding the CLI Tool<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The CLI script is built using TypeScript and leverages the <code>zksync-web3<\/code> and <code>ethers<\/code> libraries for blockchain interaction. It provides a menu-driven interface with six primary functions:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Submit new transactions<\/li>\n\n\n\n<li>Confirm pending transactions<\/li>\n\n\n\n<li>Execute transactions that have met confirmation requirements<\/li>\n\n\n\n<li>View detailed transaction information<\/li>\n\n\n\n<li>Check the total transaction count<\/li>\n\n\n\n<li>Exit the application<\/li>\n<\/ol>\n\n\n\n<p>Here&#8217;s how to set up and run the CLI tool:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"# First, create a .env file with your private key\necho &quot;WALLET_PRIVATE_KEY=your_private_key_here&quot; &gt; .env\n\n# Install dependencies if you haven't already\nnpm install zksync-web3 ethers dotenv\n\n# Save the script as multisig-cli.ts\n# Run using ts-node\nts-node multisig-cli.ts\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\"># <\/span><span style=\"color: #9CDCFE\">First<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">a<\/span><span style=\"color: #D4D4D4\"> .<\/span><span style=\"color: #9CDCFE\">env<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">file<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">with<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">your<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">key<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">echo<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;WALLET_PRIVATE_KEY=your_private_key_here&quot;<\/span><span style=\"color: #D4D4D4\"> &gt; .<\/span><span style=\"color: #9CDCFE\">env<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"># <\/span><span style=\"color: #9CDCFE\">Install<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">dependencies<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">you<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">haven<\/span><span style=\"color: #CE9178\">&#39;t alread<\/span><span style=\"color: #F44747\">y<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">npm<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">install<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">zksync<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">web3<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">dotenv<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"># <\/span><span style=\"color: #9CDCFE\">Save<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">the<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">script<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">as<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">multisig<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">cli<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ts<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"># <\/span><span style=\"color: #9CDCFE\">Run<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">using<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">ts<\/span><span style=\"color: #D4D4D4\">-node<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">ts<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">node<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">multisig<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">cli<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ts<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Let&#8217;s examine how the script works. At its core, the script establishes a connection to ZKSync Era&#8217;s Sepolia testnet and initializes a contract instance using your wallet:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"const provider = new Provider(&quot;https:\/\/sepolia.era.zksync.dev&quot;);\nconst wallet = new Wallet(process.env.WALLET_PRIVATE_KEY || &quot;&quot;, provider);\nconst multiSig = new ethers.Contract(MULTISIG_ADDRESS, MULTISIG_ABI, wallet);\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">provider<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">Provider<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;https:\/\/sepolia.era.zksync.dev&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">wallet<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">Wallet<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">process<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">env<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #4FC1FF\">WALLET_PRIVATE_KEY<\/span><span style=\"color: #D4D4D4\"> || <\/span><span style=\"color: #CE9178\">&quot;&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">provider<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">multiSig<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Contract<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4FC1FF\">MULTISIG_ADDRESS<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">MULTISIG_ABI<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">wallet<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>When you run the script, you&#8217;ll be presented with a menu of options. Each option corresponds to a specific MultiSig wallet function. For example, when submitting a new transaction, the script will:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Prompt for the recipient&#8217;s address<\/li>\n\n\n\n<li>Ask for the amount in ETH<\/li>\n\n\n\n<li>Submit the transaction to the blockchain<\/li>\n\n\n\n<li>Provide the transaction hash for tracking<\/li>\n<\/ol>\n\n\n\n<p>The script includes error handling and user-friendly prompts, making it an ideal tool for both testing and production use. Whether you&#8217;re an owner needing to confirm transactions or an administrator monitoring wallet activity, the CLI provides a straightforward interface for all essential MultiSig operations.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Example_Usage\"><\/span>Example Usage:<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"ZKSync Era MultiSig Wallet CLI\n===============================\n1. Submit Transaction\n2. Confirm Transaction\n3. Execute Transaction\n4. View Transaction Details\n5. Get Transaction Count\n6. Exit\n\nEnter your choice (1-6):\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #9CDCFE\">ZKSync<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Era<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">MultiSig<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Wallet<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">CLI<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">===============================<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B5CEA8\">1.<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Submit<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Transaction<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B5CEA8\">2.<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Confirm<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Transaction<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B5CEA8\">3.<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Execute<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Transaction<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B5CEA8\">4.<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">View<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Transaction<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Details<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B5CEA8\">5.<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Get<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Transaction<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Count<\/span><\/span>\n<span class=\"line\"><span style=\"color: #B5CEA8\">6.<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Exit<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">Enter<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">your<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">choice<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">):<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>This tool is particularly useful for wallet owners who prefer command-line interfaces or need to automate certain interactions with the MultiSig wallet. It&#8217;s built with security in mind, using environment variables for sensitive data and providing clear feedback for all operations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Security_Considerations\"><\/span><br>Security Considerations<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>When implementing your MultiSig wallet, consider these security aspects:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Owner Management<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Implement secure methods for adding\/removing owners<\/li>\n\n\n\n<li>Consider timelock for owner changes<\/li>\n<\/ul>\n\n\n\n<p>2. Transaction Safety<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add transaction expiration<\/li>\n\n\n\n<li>Implement cancellation mechanisms<\/li>\n\n\n\n<li>Consider gas limits<\/li>\n<\/ul>\n\n\n\n<p>3. Access Control<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Carefully manage owner permissions<\/li>\n\n\n\n<li>Implement role-based access if needed<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>On\u00a0ZKSync\u00a0Era, your\u00a0MultiSig wallet\u00a0development\u00a0will\u00a0bring\u00a0together\u00a0the best\u00a0from\u00a0both worlds:\u00a0substantial\u00a0security\u00a0thanks\u00a0to\u00a0many\u00a0signatures and\u00a0fast\u00a0transactions,\u00a0courtesy\u00a0of\u00a0Layer 2 scaling. We\u00a0have\u00a0implemented\u00a0a secure\u00a0and\u00a0extensible implementation\u00a0to\u00a0base\u00a0your\u00a0digital\u00a0asset\u00a0management\u00a0on\u00a0in a decentralized context\u00a0.<br><br>Bear\u00a0in\u00a0mind\u00a0that\u00a0with smart contracts,\u00a0security\u00a0should\u00a0be\u00a0number\u00a0one\u00a0on\u00a0your\u00a0checklist. Always:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Thoroughly test your implementation<\/li>\n\n\n\n<li>Consider having your code audited<\/li>\n\n\n\n<li>Start with small amounts when testing in production<\/li>\n\n\n\n<li>Monitor your contract for any unusual activity<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>The complete code for this project is available on GitHub, and you can find a deployed example on the ZKSync Era Sepolia testnet at 0x3f3EdA70B1732644F5C8EA8c88D7De978ecF791f. <\/p>\n<\/blockquote>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":24,"featured_media":12322,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[343],"tags":[],"class_list":["post-12202","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-solidity"],"_links":{"self":[{"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts\/12202","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/users\/24"}],"replies":[{"embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/comments?post=12202"}],"version-history":[{"count":11,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts\/12202\/revisions"}],"predecessor-version":[{"id":12321,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts\/12202\/revisions\/12321"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/media\/12322"}],"wp:attachment":[{"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/media?parent=12202"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/categories?post=12202"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/tags?post=12202"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}