{"id":9623,"date":"2024-10-24T13:52:55","date_gmt":"2024-10-24T13:52:55","guid":{"rendered":"https:\/\/metaschool.so\/articles\/?p=9623"},"modified":"2024-10-25T04:06:44","modified_gmt":"2024-10-25T04:06:44","slug":"build-a-dapp-on-ethereum","status":"publish","type":"post","link":"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/","title":{"rendered":"How to Build a dApp on Ethereum: A Comprehensive Technical Guide 2024"},"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-dapp-on-ethereum\/#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-dapp-on-ethereum\/#Prerequisites\" title=\"Prerequisites\">Prerequisites<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#Development_Tools\" title=\"Development Tools\">Development Tools<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#Technical_Knowledge\" title=\"Technical Knowledge\">Technical Knowledge<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#Resources\" title=\"Resources\">Resources<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#1_Setting_Up_the_Development_Environment\" title=\"1. Setting Up the Development Environment\">1. Setting Up the Development Environment<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#Initial_Setup\" title=\"Initial Setup\">Initial Setup<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#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-9\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#Configuration_Setup\" title=\"Configuration Setup\">Configuration Setup<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#2_Writing_the_Smart_Contract\" title=\"2. Writing the Smart Contract\">2. Writing the Smart Contract<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#Contract_Development\" title=\"Contract Development\">Contract Development<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#3_Testing_the_Smart_Contract\" title=\"3. Testing the Smart Contract\">3. Testing the Smart Contract<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#4_Frontend_Development\" title=\"4. Frontend Development\">4. Frontend Development<\/a><ul class='ez-toc-list-level-3'><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#React_Setup_with_Web3_Integration\" title=\"React Setup with Web3 Integration\">React Setup with Web3 Integration<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#Creating_a_User_Interface_Component_of_the_dApp\" title=\"Creating a User Interface Component of the dApp\">Creating a User Interface Component of the dApp<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/metaschool.so\/articles\/build-a-dapp-on-ethereum\/#Smart_Contract_Deployment\" title=\"Smart Contract Deployment\">Smart Contract Deployment<\/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-dapp-on-ethereum\/#Best_Practices_for_Ethereum_Development\" title=\"Best Practices for Ethereum Development\">Best Practices for Ethereum Development<\/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-dapp-on-ethereum\/#Next_Steps_for_Learning\" title=\"Next Steps for Learning:\">Next Steps for Learning:<\/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-dapp-on-ethereum\/#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><a href=\"https:\/\/metaschool.so\/articles\/dapps-decentralised-applications\/\" data-type=\"link\" data-id=\"https:\/\/metaschool.so\/articles\/dapps-decentralised-applications\/\">Decentralized applications (dApps)<\/a> represent the cornerstone of Web3 technology, combining traditional web development with blockchain capabilities. Unlike conventional applications, dApps operate on a decentralized network\u2014specifically, the Ethereum blockchain\u2014providing transparency, immutability, and trustless execution of business logic through smart contracts. This comprehensive guide will walk you through building a full-stack Ethereum dApp, from smart contract development to frontend integration and deployment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Prerequisites\"><\/span>Prerequisites<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Before diving into development, ensure you have the following tools and knowledge:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Development_Tools\"><\/span>Development Tools<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/nodejs.org\/en\" data-type=\"link\" data-id=\"https:\/\/nodejs.org\/en\" target=\"_blank\" rel=\"noopener\">Node.js (v14.0.0 or later)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.npmjs.com\/package\/yarn\" data-type=\"link\" data-id=\"https:\/\/www.npmjs.com\/package\/yarn\" target=\"_blank\" rel=\"noopener\">npm or yarn package manager<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/metamask.io\/download\/\" data-type=\"link\" data-id=\"https:\/\/metamask.io\/download\/\" target=\"_blank\" rel=\"noopener\">Metamask browser extension<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/code.visualstudio.com\/\" data-type=\"link\" data-id=\"https:\/\/code.visualstudio.com\/\" target=\"_blank\" rel=\"noopener\">Code editor (VS Code recommended with Solidity extensions)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/git-scm.com\/\" data-type=\"link\" data-id=\"https:\/\/git-scm.com\/\" target=\"_blank\" rel=\"noopener\">Git for version control<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Technical_Knowledge\"><\/span>Technical Knowledge<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>JavaScript\/TypeScript fundamentals<\/li>\n\n\n\n<li>React.js framework basics<\/li>\n\n\n\n<li>Solidity programming language<\/li>\n\n\n\n<li>Basic understanding of blockchain concepts<\/li>\n\n\n\n<li>Familiarity with Web3 principles<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Resources\"><\/span>Resources<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Some ETH in your test wallet (using Sepolia other testnet faucets)<\/li>\n\n\n\n<li>Infura or Alchemy account for API access<\/li>\n\n\n\n<li>GitHub account for version control<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"1_Setting_Up_the_Development_Environment\"><\/span>1. Setting Up the Development Environment<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Initial_Setup\"><\/span>Initial Setup<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>First, let&#8217;s create a robust development environment with all the necessary tools and configurations:<\/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=\"# Create project directory\nmkdir ethereum-dapp\ncd ethereum-dapp\n\n# Initialize npm project\nnpm init -y\n\n# Install core dependencies\nnpm install --save-dev hardhat @nomiclabs\/hardhat-waffle ethereum-waffle chai @nomiclabs\/hardhat-ethers ethers @openzeppelin\/contracts dotenv\n\n# Install development tools\nnpm install --save-dev prettier prettier-plugin-solidity solhint\n\n# Initialize Hardhat project\nnpx hardhat init\" 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\">Create<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">project<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">directory<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">mkdir<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethereum<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">dapp<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">cd<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethereum<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">dapp<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"># <\/span><span style=\"color: #9CDCFE\">Initialize<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">npm<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">project<\/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>\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\">core<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">dependencies<\/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\">save<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">dev<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">hardhat<\/span><span style=\"color: #D4D4D4\"> @<\/span><span style=\"color: #9CDCFE\">nomiclabs<\/span><span style=\"color: #D4D4D4\">\/<\/span><span style=\"color: #9CDCFE\">hardhat<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">waffle<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethereum<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">waffle<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">chai<\/span><span style=\"color: #D4D4D4\"> @<\/span><span style=\"color: #9CDCFE\">nomiclabs<\/span><span style=\"color: #D4D4D4\">\/<\/span><span style=\"color: #9CDCFE\">hardhat<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/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\">dotenv<\/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\">development<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tools<\/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\">save<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">dev<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">prettier<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">prettier<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">plugin<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">solidity<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">solhint<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\"># <\/span><span style=\"color: #9CDCFE\">Initialize<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Hardhat<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">project<\/span><\/span>\n<span class=\"line\"><span style=\"color: #9CDCFE\">npx<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">hardhat<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">init<\/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>Create a well-organized project structure for your dApp:<\/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=\"ethereum-dapp\/\n\u251c\u2500\u2500 contracts\/\n\u251c\u2500\u2500 scripts\/\n\u251c\u2500\u2500 test\/\n\u251c\u2500\u2500 frontend\/\n\u251c\u2500\u2500 hardhat.config.js\n\u251c\u2500\u2500 .env\n\u2514\u2500\u2500 .gitignore\" 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\">ethereum<\/span><span style=\"color: #D4D4D4\">-<\/span><span style=\"color: #9CDCFE\">dapp<\/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\">\u251c\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">scripts<\/span><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u251c\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">test<\/span><span style=\"color: #D4D4D4\">\/<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u251c\u2500\u2500 <\/span><span style=\"color: #9CDCFE\">frontend<\/span><span style=\"color: #D4D4D4\">\/<\/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\">js<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u251c\u2500\u2500 .<\/span><span style=\"color: #9CDCFE\">env<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u2514\u2500\u2500 .<\/span><span style=\"color: #9CDCFE\">gitignore<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Configuration_Setup\"><\/span>Configuration Setup<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Create a Hardhat configuration file for your dApp:<\/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=\"require(&quot;@nomiclabs\/hardhat-waffle&quot;);\nrequire(&quot;@nomiclabs\/hardhat-ethers&quot;);\nrequire(&quot;dotenv&quot;).config();\n\nconst INFURA_PROJECT_ID = process.env.INFURA_PROJECT_ID;\nconst PRIVATE_KEY = process.env.PRIVATE_KEY;\n\nmodule.exports = {\n  solidity: {\n    version: &quot;0.8.19&quot;,\n    settings: {\n      optimizer: {\n        enabled: true,\n        runs: 200\n      }\n    }\n  },\n  networks: {\n    hardhat: {\n      chainId: 1337\n    },\n    sepolia: {\n      url: `https:\/\/sepolia.infura.io\/v3\/${INFURA_PROJECT_ID}`,\n      accounts: [`0x${PRIVATE_KEY}`],\n      gas: 2100000,\n      gasPrice: 8000000000\n    },\n    mainnet: {\n      url: `https:\/\/mainnet.infura.io\/v3\/${INFURA_PROJECT_ID}`,\n      accounts: [`0x${PRIVATE_KEY}`]\n    }\n  },\n  paths: {\n    sources: &quot;.\/contracts&quot;,\n    tests: &quot;.\/test&quot;,\n    cache: &quot;.\/cache&quot;,\n    artifacts: &quot;.\/frontend\/src\/artifacts&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: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;@nomiclabs\/hardhat-waffle&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;@nomiclabs\/hardhat-ethers&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;dotenv&quot;<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">config<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">INFURA_PROJECT_ID<\/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\">INFURA_PROJECT_ID<\/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\">PRIVATE_KEY<\/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\">PRIVATE_KEY<\/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\">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.19&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 style=\"color: #9CDCFE\">optimizer:<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">enabled:<\/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\">runs:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">200<\/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>\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\">hardhat:<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">chainId:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">1337<\/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\">sepolia:<\/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\">`https:\/\/sepolia.infura.io\/v3\/<\/span><span style=\"color: #569CD6\">${<\/span><span style=\"color: #4FC1FF\">INFURA_PROJECT_ID<\/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 style=\"color: #9CDCFE\">accounts:<\/span><span style=\"color: #D4D4D4\"> [<\/span><span style=\"color: #CE9178\">`0x<\/span><span style=\"color: #569CD6\">${<\/span><span style=\"color: #4FC1FF\">PRIVATE_KEY<\/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 style=\"color: #9CDCFE\">gas:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">2100000<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">gasPrice:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #B5CEA8\">8000000000<\/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\">mainnet:<\/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\">`https:\/\/mainnet.infura.io\/v3\/<\/span><span style=\"color: #569CD6\">${<\/span><span style=\"color: #4FC1FF\">INFURA_PROJECT_ID<\/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 style=\"color: #9CDCFE\">accounts:<\/span><span style=\"color: #D4D4D4\"> [<\/span><span style=\"color: #CE9178\">`0x<\/span><span style=\"color: #569CD6\">${<\/span><span style=\"color: #4FC1FF\">PRIVATE_KEY<\/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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">paths:<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">sources:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;.\/contracts&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">tests:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;.\/test&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">cache:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;.\/cache&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">artifacts:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&quot;.\/frontend\/src\/artifacts&quot;<\/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=\"2_Writing_the_Smart_Contract\"><\/span>2. Writing the Smart Contract<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Contract_Development\"><\/span>Contract Development<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Our smart contract is a simple storage system that lets users store and retrieve values but with important safety features added. We use OpenZeppelin&#8217;s contracts to handle basic security (like preventing reentrancy attacks) and ownership controls. The contract stores a value for each user&#8217;s address separately, tracks who has stored values, and lets the owner perform bulk operations if needed. When values change, the contract emits events so the value on the frontend of our dApp can update in real time.<\/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=\"\/\/ SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\nimport &quot;@openzeppelin\/contracts\/access\/Ownable.sol&quot;;\nimport &quot;@openzeppelin\/contracts\/security\/ReentrancyGuard.sol&quot;;\n\ncontract SimpleStorage is Ownable, ReentrancyGuard {\n    \/\/ State variables\n    uint256 private value;\n    mapping(address =&gt; uint256) private userValues;\n    mapping(address =&gt; bool) private hasStored;\n\n    \/\/ Events\n    event ValueChanged(address indexed user, uint256 newValue, uint256 timestamp);\n    event ValueReset(address indexed user, uint256 timestamp);\n\n    \/\/ Custom errors\n    error InvalidValue();\n    error NoValueStored();\n\n    \/\/ Modifiers\n    modifier validValue(uint256 _value) {\n        if (_value == 0) revert InvalidValue();\n        _;\n    }\n\n    \/\/ Main functions\n    function setValue(uint256 newValue) public validValue(newValue) nonReentrant {\n        value = newValue;\n        userValues[msg.sender] = newValue;\n        hasStored[msg.sender] = true;\n\n        emit ValueChanged(msg.sender, newValue, block.timestamp);\n    }\n\n    function getValue() public view returns (uint256) {\n        return value;\n    }\n\n    function getUserValue(address user) public view returns (uint256) {\n        if (!hasStored[user]) revert NoValueStored();\n        return userValues[user];\n    }\n\n    function resetValue() public onlyOwner {\n        value = 0;\n        emit ValueReset(msg.sender, block.timestamp);\n    }\n\n    \/\/ Batch operations\n    function setMultipleValues(address[] calldata users, uint256[] calldata values) \n        public \n        onlyOwner \n    {\n        require(users.length == values.length, &quot;Arrays length mismatch&quot;);\n\n        for (uint i = 0; i < users.length; i++) {\n            userValues[users[i]] = values[i];\n            hasStored[users[i]] = true;\n            emit ValueChanged(users[i], values[i], block.timestamp);\n        }\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: #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\">19<\/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\/access\/Ownable.sol&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;@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\">SimpleStorage<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">is<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">Ownable<\/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: #6A9955\">\/\/ State variables<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">private<\/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: #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\">uint256<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">userValues<\/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\">private<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">hasStored<\/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\">\/\/ Events<\/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\">ValueChanged<\/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\">user<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">newValue<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">timestamp<\/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\">ValueReset<\/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\">user<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">timestamp<\/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\">\/\/ Custom errors<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InvalidValue<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">NoValueStored<\/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\">\/\/ Modifiers<\/span><\/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\">validValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/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: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">_value<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">InvalidValue<\/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: #6A9955\">\/\/ Main functions<\/span><\/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\">setValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">newValue<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">validValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">newValue<\/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\">value<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">newValue<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">userValues<\/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\">newValue<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">hasStored<\/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\">ValueChanged<\/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\">newValue<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">block<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">timestamp<\/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\">getValue<\/span><span style=\"color: #D4D4D4\">() <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">view<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/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>\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\">getUserValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">user<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">view<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">returns<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">hasStored<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">user<\/span><span style=\"color: #D4D4D4\">]) <\/span><span style=\"color: #9CDCFE\">revert<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">NoValueStored<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">userValues<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">user<\/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\">resetValue<\/span><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\">value<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">;<\/span><\/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\">ValueReset<\/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\">block<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">timestamp<\/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: #6A9955\">\/\/ Batch operations<\/span><\/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\">setMultipleValues<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">calldata<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">users<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">uint256<\/span><span style=\"color: #D4D4D4\">[] <\/span><span style=\"color: #9CDCFE\">calldata<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">) <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">public<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">require<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">users<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">length<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;Arrays length mismatch&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: #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\">users<\/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\">userValues<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">users<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">]] = <\/span><span style=\"color: #9CDCFE\">values<\/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\">hasStored<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">users<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/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\">emit<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">ValueChanged<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">users<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">], <\/span><span style=\"color: #9CDCFE\">values<\/span><span style=\"color: #D4D4D4\">[<\/span><span style=\"color: #9CDCFE\">i<\/span><span style=\"color: #D4D4D4\">], <\/span><span style=\"color: #9CDCFE\">block<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">timestamp<\/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>\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=\"3_Testing_the_Smart_Contract\"><\/span>3. Testing the Smart Contract<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The test file checks if our contract works as intended by simulating real user interactions. We test three main things: that the contract deploys correctly with the right owner, that users can store and retrieve their values properly, and that only the owner can perform restricted operations like bulk updates. Each test uses different test accounts to simulate multiple users interacting with the contract.<\/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 { expect } = require(&quot;chai&quot;);\nconst { ethers } = require(&quot;hardhat&quot;);\n\ndescribe(&quot;SimpleStorage&quot;, function() {\n    let SimpleStorage;\n    let simpleStorage;\n    let owner;\n    let addr1;\n    let addr2;\n\n    beforeEach(async function() {\n        SimpleStorage = await ethers.getContractFactory(&quot;SimpleStorage&quot;);\n        [owner, addr1, addr2] = await ethers.getSigners();\n        simpleStorage = await SimpleStorage.deploy();\n        await simpleStorage.deployed();\n    });\n\n    describe(&quot;Deployment&quot;, function() {\n        it(&quot;Should set the right owner&quot;, async function() {\n            expect(await simpleStorage.owner()).to.equal(owner.address);\n        });\n\n        it(&quot;Should initialize with zero value&quot;, async function() {\n            expect(await simpleStorage.getValue()).to.equal(0);\n        });\n    });\n\n    describe(&quot;Transactions&quot;, function() {\n        it(&quot;Should set the value correctly&quot;, async function() {\n            await simpleStorage.connect(addr1).setValue(42);\n            expect(await simpleStorage.getValue()).to.equal(42);\n            expect(await simpleStorage.getUserValue(addr1.address)).to.equal(42);\n        });\n\n        it(&quot;Should emit ValueChanged event&quot;, async function() {\n            await expect(simpleStorage.connect(addr1).setValue(42))\n                .to.emit(simpleStorage, &quot;ValueChanged&quot;)\n                .withArgs(addr1.address, 42, await getBlockTimestamp());\n        });\n\n        it(&quot;Should revert with InvalidValue for zero input&quot;, async function() {\n            await expect(simpleStorage.setValue(0))\n                .to.be.revertedWithCustomError(simpleStorage, &quot;InvalidValue&quot;);\n        });\n    });\n\n    describe(&quot;Batch Operations&quot;, function() {\n        it(&quot;Should set multiple values correctly&quot;, async function() {\n            const users = [addr1.address, addr2.address];\n            const values = [42, 84];\n\n            await simpleStorage.setMultipleValues(users, values);\n\n            expect(await simpleStorage.getUserValue(addr1.address)).to.equal(42);\n            expect(await simpleStorage.getUserValue(addr2.address)).to.equal(84);\n        });\n    });\n});\n\nasync function getBlockTimestamp() {\n    const blockNumBefore = await ethers.provider.getBlockNumber();\n    const blockBefore = await ethers.provider.getBlock(blockNumBefore);\n    return blockBefore.timestamp;\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: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #4FC1FF\">expect<\/span><span style=\"color: #D4D4D4\"> } = <\/span><span style=\"color: #DCDCAA\">require<\/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: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #4FC1FF\">ethers<\/span><span style=\"color: #D4D4D4\"> } = <\/span><span style=\"color: #DCDCAA\">require<\/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>\n<span class=\"line\"><span style=\"color: #DCDCAA\">describe<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;SimpleStorage&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: #569CD6\">let<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">SimpleStorage<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">let<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">let<\/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: #569CD6\">let<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">addr1<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #569CD6\">let<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">addr2<\/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\">beforeEach<\/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: #9CDCFE\">SimpleStorage<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getContractFactory<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;SimpleStorage&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        [<\/span><span style=\"color: #9CDCFE\">owner<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">addr1<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">addr2<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getSigners<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">SimpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">deploy<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">deployed<\/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: #DCDCAA\">describe<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Deployment&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 set the right owner&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: #DCDCAA\">expect<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">owner<\/span><span style=\"color: #D4D4D4\">()).<\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">equal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">owner<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">address<\/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: #DCDCAA\">it<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Should initialize with zero value&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: #DCDCAA\">expect<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getValue<\/span><span style=\"color: #D4D4D4\">()).<\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">equal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/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>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">describe<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Transactions&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 set the value correctly&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: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">connect<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">addr1<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">setValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">42<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">expect<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getValue<\/span><span style=\"color: #D4D4D4\">()).<\/span><span style=\"color: #9CDCFE\">to<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">equal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">42<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">expect<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getUserValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">addr1<\/span><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 style=\"color: #DCDCAA\">equal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">42<\/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: #DCDCAA\">it<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Should emit ValueChanged event&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: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">expect<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">connect<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">addr1<\/span><span style=\"color: #D4D4D4\">).<\/span><span style=\"color: #DCDCAA\">setValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">42<\/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: #DCDCAA\">emit<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;ValueChanged&quot;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                .<\/span><span style=\"color: #DCDCAA\">withArgs<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">addr1<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">42<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">getBlockTimestamp<\/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: #DCDCAA\">it<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Should revert with InvalidValue for zero input&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: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">expect<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">setValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/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\">be<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">revertedWithCustomError<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #CE9178\">&quot;InvalidValue&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>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #DCDCAA\">describe<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Batch Operations&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 set multiple values correctly&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: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">users<\/span><span style=\"color: #D4D4D4\"> = [<\/span><span style=\"color: #9CDCFE\">addr1<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">addr2<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">address<\/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\">values<\/span><span style=\"color: #D4D4D4\"> = [<\/span><span style=\"color: #B5CEA8\">42<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #B5CEA8\">84<\/span><span style=\"color: #D4D4D4\">];<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">setMultipleValues<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">users<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">values<\/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\">expect<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getUserValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">addr1<\/span><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 style=\"color: #DCDCAA\">equal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">42<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">expect<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getUserValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">addr2<\/span><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 style=\"color: #DCDCAA\">equal<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">84<\/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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">});<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><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: #DCDCAA\">getBlockTimestamp<\/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\">blockNumBefore<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">provider<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getBlockNumber<\/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\">blockBefore<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">provider<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getBlock<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">blockNumBefore<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">blockBefore<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">timestamp<\/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=\"4_Frontend_Development\"><\/span>4. Frontend Development<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"React_Setup_with_Web3_Integration\"><\/span>React Setup with Web3 Integration<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Create a new React application with advanced Web3 integration for the frontend of the dApp. The useWeb3Contract hook handles all our blockchain interactions in one place. It connects to MetaMask, creates the contract instance, and provides functions our components can use to interact with the blockchain. When something goes wrong (like MetaMask not being installed or a transaction failing), it captures the error so we can show it to the user. This keeps all the complex blockchain logic separate from our UI 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=\"\/\/ src\/hooks\/useWeb3Contract.js\nimport { useState, useEffect, useCallback } from 'react';\nimport { ethers } from 'ethers';\nimport SimpleStorage from '..\/artifacts\/contracts\/SimpleStorage.sol\/SimpleStorage.json';\n\nexport function useWeb3Contract(contractAddress) {\n    const [contract, setContract] = useState(null);\n    const [provider, setProvider] = useState(null);\n    const [signer, setSigner] = useState(null);\n    const [error, setError] = useState(null);\n    const [loading, setLoading] = useState(true);\n\n    const initialize = useCallback(async () =&gt; {\n        try {\n            if (!window.ethereum) {\n                throw new Error(&quot;MetaMask not installed&quot;);\n            }\n\n            const provider = new ethers.providers.Web3Provider(window.ethereum);\n            const signer = provider.getSigner();\n            const contract = new ethers.Contract(\n                contractAddress,\n                SimpleStorage.abi,\n                signer\n            );\n\n            setProvider(provider);\n            setSigner(signer);\n            setContract(contract);\n            setError(null);\n        } catch (err) {\n            setError(err.message);\n        } finally {\n            setLoading(false);\n        }\n    }, [contractAddress]);\n\n    useEffect(() =&gt; {\n        initialize();\n    }, [initialize]);\n\n    const connectWallet = async () =&gt; {\n        try {\n            await window.ethereum.request({ method: 'eth_requestAccounts' });\n            await initialize();\n        } catch (err) {\n            setError(err.message);\n        }\n    };\n\n    return { contract, provider, signer, error, loading, connectWallet };\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: #6A9955\">\/\/ src\/hooks\/useWeb3Contract.js<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">useState<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">useEffect<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">useCallback<\/span><span style=\"color: #D4D4D4\"> } <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;react&#39;<\/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\">ethers<\/span><span style=\"color: #D4D4D4\"> } <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;ethers&#39;<\/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\">SimpleStorage<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;..\/artifacts\/contracts\/SimpleStorage.sol\/SimpleStorage.json&#39;<\/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: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">useWeb3Contract<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">contractAddress<\/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\">contract<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">setContract<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">useState<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">null<\/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\">provider<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">setProvider<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">useState<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">null<\/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\">signer<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">setSigner<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">useState<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">null<\/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\">error<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">setError<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">useState<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">null<\/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\">loading<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">setLoading<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">useState<\/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: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">initialize<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #DCDCAA\">useCallback<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> () <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">try<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (!<\/span><span style=\"color: #9CDCFE\">window<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ethereum<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #C586C0\">throw<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">new<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">Error<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;MetaMask not installed&quot;<\/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\">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: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">providers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">Web3Provider<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">window<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ethereum<\/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\">signer<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #9CDCFE\">provider<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getSigner<\/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\">contract<\/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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">contractAddress<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">SimpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">abi<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">signer<\/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: #DCDCAA\">setProvider<\/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: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">setSigner<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">signer<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">setContract<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">setError<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        } <\/span><span style=\"color: #C586C0\">catch<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">err<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">setError<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">err<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">message<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        } <\/span><span style=\"color: #C586C0\">finally<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">setLoading<\/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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }, [<\/span><span style=\"color: #9CDCFE\">contractAddress<\/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\">useEffect<\/span><span style=\"color: #D4D4D4\">(() <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">initialize<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }, [<\/span><span style=\"color: #9CDCFE\">initialize<\/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: #DCDCAA\">connectWallet<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> () <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">try<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">window<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">ethereum<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">request<\/span><span style=\"color: #D4D4D4\">({ <\/span><span style=\"color: #9CDCFE\">method:<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;eth_requestAccounts&#39;<\/span><span style=\"color: #D4D4D4\"> });<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">initialize<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        } <\/span><span style=\"color: #C586C0\">catch<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">err<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">setError<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">err<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">message<\/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>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">provider<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">signer<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">loading<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">connectWallet<\/span><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=\"Creating_a_User_Interface_Component_of_the_dApp\"><\/span>Creating a User Interface Component of the dApp<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The StorageInterface component is the main screen with which users interact with the dApp. It shows the currently stored value and has a form where users can input new values. When users submit the form, it calls our smart contract through the Web3 hook we created. While the transaction is processing, it shows a loading state, and if anything goes wrong, it displays an error message. It also handles connecting to MetaMask if users haven&#8217;t done that yet.<\/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=\"\/\/ src\/components\/StorageInterface.js\nimport React, { useState, useEffect } from 'react';\nimport { useWeb3Contract } from '..\/hooks\/useWeb3Contract';\n\nconst CONTRACT_ADDRESS = process.env.REACT_APP_CONTRACT_ADDRESS;\n\nfunction StorageInterface() {\n    const [value, setValue] = useState('');\n    const [storedValue, setStoredValue] = useState(null);\n    const [isLoading, setIsLoading] = useState(false);\n    const { contract, error, loading, connectWallet } = useWeb3Contract(CONTRACT_ADDRESS);\n\n    useEffect(() =&gt; {\n        if (contract) {\n            fetchStoredValue();\n        }\n    }, [contract]);\n\n    const fetchStoredValue = async () =&gt; {\n        try {\n            const value = await contract.getValue();\n            setStoredValue(value.toString());\n        } catch (err) {\n            console.error('Error fetching value:', err);\n        }\n    };\n\n    const handleSetValue = async (e) =&gt; {\n        e.preventDefault();\n        setIsLoading(true);\n\n        try {\n            const tx = await contract.setValue(value);\n            await tx.wait();\n            await fetchStoredValue();\n            setValue('');\n        } catch (err) {\n            console.error('Error setting value:', err);\n        } finally {\n            setIsLoading(false);\n        }\n    };\n\n    if (loading) return <div&gt;Loading...<\/div&gt;;\n    if (error) return (\n        <div&gt;\n            <p&gt;Error: {error}<\/p&gt;\n            <button onClick={connectWallet}&gt;Connect Wallet<\/button&gt;\n        <\/div&gt;\n    );\n\n    return (\n        <div&gt;\n            <h2&gt;Storage Interface<\/h2&gt;\n            <p&gt;Current Value: {storedValue ?? 'No value stored'}<\/p&gt;\n\n            <form onSubmit={handleSetValue}&gt;\n                <input\n                    type=&quot;number&quot;\n                    value={value}\n                    onChange={(e) =&gt; setValue(e.target.value)}\n                    placeholder=&quot;Enter a value&quot;\n                    disabled={isLoading}\n                \/&gt;\n                <button type=&quot;submit&quot; disabled={isLoading || !value}&gt;\n                    {isLoading ? 'Processing...' : 'Set Value'}\n                <\/button&gt;\n            <\/form&gt;\n        <\/div&gt;\n    );\n}\n\nexport default StorageInterface;\" 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\">\/\/ src\/components\/StorageInterface.js<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">React<\/span><span style=\"color: #D4D4D4\">, { <\/span><span style=\"color: #9CDCFE\">useState<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">useEffect<\/span><span style=\"color: #D4D4D4\"> } <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;react&#39;<\/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\">useWeb3Contract<\/span><span style=\"color: #D4D4D4\"> } <\/span><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;..\/hooks\/useWeb3Contract&#39;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4FC1FF\">CONTRACT_ADDRESS<\/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\">REACT_APP_CONTRACT_ADDRESS<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">function<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">StorageInterface<\/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\">value<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">setValue<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">useState<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;&#39;<\/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\">storedValue<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">setStoredValue<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">useState<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #569CD6\">null<\/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\">isLoading<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">setIsLoading<\/span><span style=\"color: #D4D4D4\">] = <\/span><span style=\"color: #DCDCAA\">useState<\/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: #569CD6\">const<\/span><span style=\"color: #D4D4D4\"> { <\/span><span style=\"color: #4FC1FF\">contract<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">error<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">loading<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #4FC1FF\">connectWallet<\/span><span style=\"color: #D4D4D4\"> } = <\/span><span style=\"color: #DCDCAA\">useWeb3Contract<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #4FC1FF\">CONTRACT_ADDRESS<\/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\">useEffect<\/span><span style=\"color: #D4D4D4\">(() <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">fetchStoredValue<\/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\">contract<\/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: #DCDCAA\">fetchStoredValue<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> () <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">try<\/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\">value<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getValue<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">setStoredValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">value<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">toString<\/span><span style=\"color: #D4D4D4\">());<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        } <\/span><span style=\"color: #C586C0\">catch<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">err<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/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\">error<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;Error fetching value:&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">err<\/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>\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: #DCDCAA\">handleSetValue<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">e<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">e<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">preventDefault<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #DCDCAA\">setIsLoading<\/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: #C586C0\">try<\/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\">tx<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">contract<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">setValue<\/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: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">tx<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">wait<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">fetchStoredValue<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">setValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;&#39;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        } <\/span><span style=\"color: #C586C0\">catch<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">err<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/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\">error<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&#39;Error setting value:&#39;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">err<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        } <\/span><span style=\"color: #C586C0\">finally<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #DCDCAA\">setIsLoading<\/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>\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\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">loading<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">div<\/span><span style=\"color: #808080\">&gt;<\/span><span style=\"color: #D4D4D4\">Loading...<\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">div<\/span><span style=\"color: #808080\">&gt;<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">div<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">p<\/span><span style=\"color: #808080\">&gt;<\/span><span style=\"color: #D4D4D4\">Error: <\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #569CD6\">}<\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">p<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">button<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">onClick<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #9CDCFE\">connectWallet<\/span><span style=\"color: #569CD6\">}<\/span><span style=\"color: #808080\">&gt;<\/span><span style=\"color: #D4D4D4\">Connect Wallet<\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">button<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">div<\/span><span style=\"color: #808080\">&gt;<\/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\">return<\/span><span style=\"color: #D4D4D4\"> (<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">div<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">h2<\/span><span style=\"color: #808080\">&gt;<\/span><span style=\"color: #D4D4D4\">Storage Interface<\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">h2<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">p<\/span><span style=\"color: #808080\">&gt;<\/span><span style=\"color: #D4D4D4\">Current Value: <\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #9CDCFE\">storedValue<\/span><span style=\"color: #D4D4D4\"> ?? <\/span><span style=\"color: #CE9178\">&#39;No value stored&#39;<\/span><span style=\"color: #569CD6\">}<\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">p<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">form<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">onSubmit<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #9CDCFE\">handleSetValue<\/span><span style=\"color: #569CD6\">}<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">input<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;number&quot;<\/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: #569CD6\">{<\/span><span style=\"color: #9CDCFE\">value<\/span><span style=\"color: #569CD6\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">onChange<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">e<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">setValue<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">e<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">target<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">value<\/span><span style=\"color: #D4D4D4\">)<\/span><span style=\"color: #569CD6\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">placeholder<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;Enter a value&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">disabled<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #9CDCFE\">isLoading<\/span><span style=\"color: #569CD6\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #808080\">\/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #808080\">&lt;<\/span><span style=\"color: #569CD6\">button<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;submit&quot;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">disabled<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #9CDCFE\">isLoading<\/span><span style=\"color: #D4D4D4\"> || !<\/span><span style=\"color: #9CDCFE\">value<\/span><span style=\"color: #569CD6\">}<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #9CDCFE\">isLoading<\/span><span style=\"color: #D4D4D4\"> ? <\/span><span style=\"color: #CE9178\">&#39;Processing...&#39;<\/span><span style=\"color: #D4D4D4\"> : <\/span><span style=\"color: #CE9178\">&#39;Set Value&#39;<\/span><span style=\"color: #569CD6\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">button<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">form<\/span><span style=\"color: #808080\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #808080\">&lt;\/<\/span><span style=\"color: #569CD6\">div<\/span><span style=\"color: #808080\">&gt;<\/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: #C586C0\">export<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">default<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">StorageInterface<\/span><span style=\"color: #D4D4D4\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1346\" height=\"910\" src=\"https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2024\/10\/image-11.png\" alt=\"dApp on ethereum\" class=\"wp-image-9645\" srcset=\"https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2024\/10\/image-11.png 1346w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2024\/10\/image-11-300x203.png 300w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2024\/10\/image-11-1024x692.png 1024w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2024\/10\/image-11-768x519.png 768w, https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2024\/10\/image-11-1320x892.png 1320w\" sizes=\"auto, (max-width: 1346px) 100vw, 1346px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">5. Deployment and Production<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Smart_Contract_Deployment\"><\/span>Smart Contract Deployment<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Create a deployment script with proper error handling and verification. Our deployment script handles the process of putting the smart contract on the blockchain. It first checks if we have enough ETH to deploy, then deploys the contract and waits for it to be confirmed. If we&#8217;re on a testnet, it also verifies the contract on Etherscan so users can read the source code. The script provides clear console messages about what&#8217;s happening during deployment.<\/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=\"\/\/ scripts\/deploy.js\nasync function main() {\n    try {\n        \/\/ Get network information\n        const [deployer] = await ethers.getSigners();\n        console.log(&quot;Deploying contracts with account:&quot;, deployer.address);\n\n        const balance = await deployer.getBalance();\n        console.log(&quot;Account balance:&quot;, ethers.utils.formatEther(balance));\n\n        \/\/ Deploy contract\n        const SimpleStorage = await ethers.getContractFactory(&quot;SimpleStorage&quot;);\n        const simpleStorage = await SimpleStorage.deploy();\n        await simpleStorage.deployed();\n\n        console.log(&quot;SimpleStorage deployed to:&quot;, simpleStorage.address);\n\n        \/\/ Verify contract on Etherscan\n        if (network.name !== &quot;hardhat&quot;) {\n            console.log(&quot;Waiting for block confirmations...&quot;);\n            await simpleStorage.deployTransaction.wait(6);\n\n            await hre.run(&quot;verify:verify&quot;, {\n                address: simpleStorage.address,\n                constructorArguments: [],\n            });\n        }\n    } catch (error) {\n        console.error(&quot;Deployment failed:&quot;, error);\n        process.exit(1);\n    }\n}\n\nmain()\n    .then(() =&gt; process.exit(0))\n    .catch((error) =&gt; {\n        console.error(error);\n        process.exit(1);\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: #6A9955\">\/\/ scripts\/deploy.js<\/span><\/span>\n<span class=\"line\"><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: #DCDCAA\">main<\/span><span style=\"color: #D4D4D4\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">try<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #6A9955\">\/\/ Get network information<\/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: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getSigners<\/span><span style=\"color: #D4D4D4\">();<\/span><\/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\">&quot;Deploying contracts with account:&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">deployer<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">address<\/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\">balance<\/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\">getBalance<\/span><span style=\"color: #D4D4D4\">();<\/span><\/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\">&quot;Account balance:&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">utils<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">formatEther<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">balance<\/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\">SimpleStorage<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">ethers<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">getContractFactory<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;SimpleStorage&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\">simpleStorage<\/span><span style=\"color: #D4D4D4\"> = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">SimpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">deploy<\/span><span style=\"color: #D4D4D4\">();<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">deployed<\/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\">&quot;SimpleStorage deployed to:&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">address<\/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\">\/\/ Verify contract on Etherscan<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">network<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">name<\/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: #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\">&quot;Waiting for block confirmations...&quot;<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">deployTransaction<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">wait<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">6<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">hre<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">run<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;verify:verify&quot;<\/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\">simpleStorage<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #9CDCFE\">address<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">constructorArguments:<\/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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    } <\/span><span style=\"color: #C586C0\">catch<\/span><span style=\"color: #D4D4D4\"> (<\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\">) {<\/span><\/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\">error<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #CE9178\">&quot;Deployment failed:&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">process<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">exit<\/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>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">main<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    .<\/span><span style=\"color: #DCDCAA\">then<\/span><span style=\"color: #D4D4D4\">(() <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">process<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">exit<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #B5CEA8\">0<\/span><span style=\"color: #D4D4D4\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    .<\/span><span style=\"color: #DCDCAA\">catch<\/span><span style=\"color: #D4D4D4\">((<\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\">) <\/span><span style=\"color: #569CD6\">=&gt;<\/span><span style=\"color: #D4D4D4\"> {<\/span><\/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\">error<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">error<\/span><span style=\"color: #D4D4D4\">);<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">process<\/span><span style=\"color: #D4D4D4\">.<\/span><span style=\"color: #DCDCAA\">exit<\/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><\/code><\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Best_Practices_for_Ethereum_Development\"><\/span>Best Practices for Ethereum Development<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>When developing on the Ethereum blockchain, following established best practices is crucial for creating secure and efficient applications. Start by ensuring you&#8217;re using the latest stable version of Solidity, as each new release brings important security patches and features that can enhance your smart contracts. Security should be at the forefront of your development process \u2013 implement proper access controls, use tested design patterns, and consider having your contracts audited before deployment to mainnet.<\/p>\n\n\n\n<p>Gas optimization is another critical aspect of Ethereum development, every operation in your smart contract costs gas, so optimizing your code can significantly reduce transaction costs for your users. Additionally, maintain a robust testing suite that covers all possible scenarios and edge cases. The Ethereum ecosystem is rapidly evolving, so staying connected with the community and keeping up with new developments will help you make informed decisions about your application&#8217;s architecture and features.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Next_Steps_for_Learning\"><\/span>Next Steps for Learning:<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Metaschool offers intensive, hands-on training in a structured web3 learning program. Metaschool\u2019s hands-on&nbsp;<a href=\"https:\/\/metaschool.so\/courses?blockchain=Ethereum\">Ethereum development courses<\/a>&nbsp;are offered for free. These self-paced and structured courses guide you to write Smart Contracts in Solidity, build NFTs, and teach you to&nbsp;<a href=\"https:\/\/metaschool.so\/courses\/create-your-own-ethereum-token-in-just-30-mins\">create your own Ethereum Token in 30 mins<\/a>&nbsp;with expert instruction and a guided learning environment.<\/p>\n\n\n\n<p>Developers at every stage of their learning journey will benefit from Metaschool\u2019s Ethereum blockchain track and learn to build dApps quickly.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/metaschool.so\/articles\/wp-content\/uploads\/2024\/08\/Screenshot-2024-08-01-at-2.11.54%E2%80%AFPM-1024x850.png\" alt=\"Learn Solidity on MetaSchool\" class=\"wp-image-7820\"\/><\/figure>\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>The Web3 ecosystem is constantly evolving, so staying updated with the latest developments and best practices is crucial for building successful dApps. As you continue your journey in Web3 development, several advanced topics are worth exploring to enhance your capabilities as a dApp developer. Diving into advanced smart contract patterns will help you write more sophisticated and secure contracts.<\/p>\n\n\n\n<p>Understanding Layer 2 scaling solutions like <a href=\"https:\/\/ethereum.org\/en\/developers\/docs\/scaling\/optimistic-rollups\/\" target=\"_blank\" rel=\"noopener\">Optimistic Rollups and ZK-Rollups<\/a> is becoming increasingly important as Ethereum scales to meet growing demand. Gas optimization techniques deserve special attention \u2013 learning how to write more efficient contracts can save your users significant costs in the long run. Familiarizing yourself with various token standards such as ERC20 for fungible tokens and ERC721 for NFTs will open up new possibilities for your applications. Additionally, exploring decentralized storage solutions like <a href=\"https:\/\/ipfs.tech\/\" data-type=\"link\" data-id=\"https:\/\/ipfs.tech\/\" target=\"_blank\" rel=\"noopener\">IPFS<\/a> will help you build truly decentralized applications where both logic and data storage exist outside traditional centralized servers.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":24,"featured_media":9642,"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":[17],"tags":[],"class_list":["post-9623","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blockchain"],"_links":{"self":[{"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts\/9623","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=9623"}],"version-history":[{"count":6,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts\/9623\/revisions"}],"predecessor-version":[{"id":9667,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/posts\/9623\/revisions\/9667"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/media\/9642"}],"wp:attachment":[{"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/media?parent=9623"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/categories?post=9623"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/metaschool.so\/articles\/wp-json\/wp\/v2\/tags?post=9623"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}