# Get & Set Value 2.0 | Web3.0 dApp Dev 0x05 **Published by:** [Web3dAppDevCamp](https://paragraph.com/@apecoder/) **Published on:** 2021-11-23 **URL:** https://paragraph.com/@apecoder/get-set-value-2-0-web3-0-dapp-dev-0x05 ## Content In our 1.0 version, we created a simple Get & Set value dApp and its contract and deploy that onto Github-Pages. Now, we can upgrade the 1.0 version. It will become much cooler with economic model!0x01 Make contracts folder sub Repo of the projectIn the repo, we can see that the contracts folder actually stores another repo. Here we used the submodule feature of git. For smart contract, the benefit of doing this is that for the same dApp, we may have different contract versions. For NFT project, we may have the regular version, whitelist version, upgradeable version and etc. If we set contracts as submodule, we will be able to switch contracts inside the folder directly. Here are some git commands for submodule:# add submodule for this folder git submodule add submodule-repository-URL # example: # git submodule add https://github.com/leeduckgo/set-purpose-contracts.git # clone the submodule when cloning repo git clone --recurse-submodules repository-URL # manually clone specified submodules git submodule update --init folder-path # example: # git submodule update packages/hardhat/contracts --init 0x02 add access control to setPurposeOn basis of PurposeHandler, we can use require statements to add access control to setPurpose . When the caller of the contract is not the assigned owner in the constructor function, an error will occur and the following code will not be executed.pragma solidity >=0.8.0 <0.9.0; //SPDX-License-Identifier: MIT import "hardhat/console.sol"; contract PurposeHandler { //event SetPurpose(address sender, string purpose); string public purpose = "Building Unstoppable Apps"; address public owner = 0x7EF99B0E5bEb8ae42DbF126B40b87410a440a32a; // replace with your own address constructor() { // owner = msg.sender; } function setPurpose(string memory newPurpose) public { // about msg.sender: // https://cryptozombies.io/en/lesson/2/chapter/3 // about require: // https://cryptozombies.io/en/lesson/2/chapter/4 require( msg.sender == owner, "NOT THE OWNER!"); purpose = newPurpose; console.log(msg.sender,"set purpose to",purpose); //emit SetPurpose(msg.sender, purpose); } } **TIPS: ** More about msg.sender: https://cryptozombies.io/en/lesson/2/chapter/3 More about require: https://cryptozombies.io/en/lesson/2/chapter/4Go back to set-purpose root directory. Start local network, deploy the contract, and start the dApp:export SKIP_PREFLIGHT_CHECK=true # config environment variable yarn chain # Start local blockchain network yarn deploy # Deploy contract yarn start # run dApp image-20211029132355937Open up http://localhost:3000 in browser. When Owner is making transaction:set_purpose_v0x02When address other that Owner is making transaction:set_purpose_v0x02-wrongTIPS: If address have errors related to Nonce, just reset the Nonce: Metamask > Settings > Advanced > Reset AccountAuthors: leeduckgo msfew ## Publication Information - [Web3dAppDevCamp](https://paragraph.com/@apecoder/): Publication homepage - [All Posts](https://paragraph.com/@apecoder/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@apecoder): Subscribe to updates - [Twitter](https://twitter.com/Web3dAppCamp): Follow on Twitter