## What is a dApp? - {%youtube CDQX8inMCt0 %} - When you create a webpage or application you are using a combination of technologies in order to create it - Blockchain can be used as a type of backend for these decentralized app's we intend to create, otherwise known as dApp's - Blockchain is basically a distributed database with custom business logic and an API - It provides a more publicly open, reliable and trustworthy backend for our applications - When reading through this documentation make sure to check out the code for my example DAO dAPP and interact with it to get a better understanding. - https://mumbai.polygonscan.com/ - This can be done using a metamask account on the Mumbai testnet (this is a blockchain which run's on Polygon which is based upon Ethereum) - Guide to Adding and Using Mumbai Testnet - https://blog.pods.finance/guide-connecting-mumbai-testnet-to-your-metamask-87978071aca8 ## Developing a dApp - When designing a dApp we must consider the technologies that will make up our development tech stack - Keep in mind that there are various combinations of different programs which are constantly being updated and developed to assist with dApp development - **Choosing a Chain** - Choosing a specific Chain is where we begin before writing our smart contract - For my application I chose the Polygon chain which run's on the leading programmable blockchain: Ethereum - After choosing a chain, I then used Polygon's Mumbai test network to test and develop my smart contract - **Types of dApp** - Just like regular applications you can create many types of apps using blockchain technology - Here are some examples - [Sport's Betting](https://www.youtube.com/watch?v=z4xpkLnQrl8&feature=emb_logo&ab_channel=Chainlink) - [NFT Trading](https://opensea.io/about) - [DAO](https://moralis.io/dao-smart-contract-example-dao-guide/) - Decentralized Autonomous Organization - Can be used to hold users (investors) cryptocurrency (money) and use it to grow the organization while users vote on changes to benefit their investment. - The Polygon network makes use of this through a proof-of-stake algorithm which is explained into detail here: https://docs.polygon.technology/docs/maintain/polygon-basics/what-is-proof-of-stake/#:~:text=Proof%20of%20Stake%20(PoS)%20is,transactions%20and%20create%20new%20blocks. - Essentially this algorithms and type of dApp depends on investors economic stake in the network - **What is a DAO?** - {%youtube KHm0uUPqmVE %} - When writing my own dApp I wanted to create a DAO which is known as a Decentralized Autonomous Organization - A DAO utilizes the blockchain in order to create an organization which is collectively owned and managed by it's member's - DAOs get to impose their rules, guidelines, and functionalities which are then followed by the member's - [Tyler Lewis also has a great explanation on this](https://hackmd.io/@cleanT/HJ7iLUZ9c) - For our research I tried to implement the Nomic game introduced to us. This game is a rules change rules game where the goal is to win while changing and voting on newly proposed rules - You can view and interact with my code on the Mumbai testnet with this link - https://mumbai.polygonscan.com/address/0x43E5e41932075DEd76073e3db1616cfa1364590B - **Developing Smart Contract** - To use the blockchain we must write a smart contract using a high-level language - The primary language we will work with is Solidity. Read through the documentation below: - https://docs.soliditylang.org/en/v0.8.16/ - **Steps** - Open an IDE - I recommend learning the basics on Remix IDE which is used for quick testing and writing of smart contracts - Specify License and Compiler - On the first few lines of your code you should import your license and compiler version - Declare Contract with Name - Variables - **Owner** - Records who proposed a rule - **nextProposal** - Records the next proposed rule - **validTokens** - Array of valid token's require to be held in order to interact with smart contract - **daoContract** - Stores the address of the valid NFT's - These NFT's were created on the Polygon network using OpenSea and the ERC-721 standard - Functions - These are the variables and functions I needed in order to create a DAO for a rules change rules type of game - Each user who hold a valid NFT can submit a rule change to be voted on. Members of the DAO can vote whether this rule is enacted. - **constructor()** - stores the owner as the user's metamask ID - connects smart contract to NFT OpenSea contract - so we can validate who has the correct NFT - **struct proposal** - each proposal has the following data - ID - exists (boolean) - description - deadline - votesUp - votesDown - canVote - maxVotes - voteStatus - countConducted (boolean) - passed (boolean) - **function checkProposalEligibility** - checks whether a proposal is eligible to be pushed to the blockchain - **function checkVoteEligibility** - checks whether a vote is eligible to be pushed to the blockchain - **function createProposal** - checks whether user is a NFT holder - **function voteOnProposal** - checks if proposal exists and is eligible - **function addTokenID** - adds an token address which can be used for authenticating whether an account can use the contract - **function countVotes** - counts the votes and sets the proposal as passed or denied ## Further Steps and Explanation - You now should have gained some experience writing simple smart contracts and exploring my Nomic DAO contract - Using other libraries and SDK's can fast track your progress, experience, and learning with developing solidity smart contract's - OpenZeppelin is a smart contract library which provides you template contracts to use that are reliable and also teach you the fundamentals - https://docs.openzeppelin.com/contracts/4.x/ - After finalizing a smart contract on the chain of your choosing, you can then push it to the blockchain. This process depends on the chain or whether you are using a private local chain for development. ## Scholarly Articles on Emerging Blockchain dApp Ideas - [Prediction Market Design](https://www.sciencedirect.com/science/article/pii/S016792361930257X?casa_token=QmhWIA4RtzcAAAAA:pUstIP6E0kkWBrQShEsDikTNqEs_drugpfOIQqrMaivwCs5U-_6yu6w5R5GzD4WmgwgzIDHUjg) - Dicusses the fundamentals arround how a prediction market is designed while applying these findings - [Blockchain Applications Overview](https://ieeexplore.ieee.org/abstract/document/8466786) - This paper seperates the scams and faults of early blockchain applications to dicsuss the potential that is still provided by vaious chains. - [Athlete Performance Prediction](https://ieeexplore.ieee.org/abstract/document/9371762) - Uses blockchain to assist in live HMM modeling and prediction of athletes performance. This is unique as blockchain is emerging as a more statistically accurate method of prediction/analysis with it's peer to peer dynamic. ## DAO Contract Contract Reference `````sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.7; interface IdaoContract { function balanceOf(address, uint256) external view returns (uint256); } contract Dao { address public owner; uint256 nextProposal; uint256[] public validTokens; IdaoContract daoContract; constructor(){ owner = msg.sender; nextProposal = 1; daoContract = IdaoContract(0x2953399124F0cBB46d2CbACD8A89cF0599974963); validTokens = [9895683931903500912008780101487947851536148848455757909882133560737025490945]; } struct proposal{ uint256 id; bool exists; string description; uint deadline; uint256 votesUp; uint256 votesDown; address[] canVote; uint256 maxVotes; mapping(address => bool) voteStatus; bool countConducted; bool passed; } mapping(uint256 => proposal) public Proposals; event proposalCreated( uint256 id, string description, uint256 maxVotes, address proposer ); event newVote( uint256 votesUp, uint256 votesDown, address voter, uint256 proposal, bool votedFor ); event proposalCount( uint256 id, bool passed ); function checkProposalEligibility(address _proposalist) private view returns ( bool ){ for(uint i = 0; i < validTokens.length; i++){ if(daoContract.balanceOf(_proposalist, validTokens[i]) >= 1){ return true; } } return false; } function checkVoteEligibility(uint256 _id, address _voter) private view returns ( bool ){ for (uint256 i = 0; i < Proposals[_id].canVote.length; i++) { if (Proposals[_id].canVote[i] == _voter) { return true; } } return false; } function createProposal(string memory _description, address[] memory _canVote) public { require(checkProposalEligibility(msg.sender), "Only NFT holders can put forth Proposals"); proposal storage newProposal = Proposals[nextProposal]; newProposal.id = nextProposal; newProposal.exists = true; newProposal.description = _description; newProposal.deadline = block.number + 100; newProposal.canVote = _canVote; newProposal.maxVotes = _canVote.length; emit proposalCreated(nextProposal, _description, _canVote.length, msg.sender); nextProposal++; } function voteOnProposal(uint256 _id, bool _vote) public { require(Proposals[_id].exists, "This Proposal does not exist"); require(checkVoteEligibility(_id, msg.sender), "You can not vote on this Proposal"); require(!Proposals[_id].voteStatus[msg.sender], "You have already voted on this Proposal"); require(block.number <= Proposals[_id].deadline, "The deadline has passed for this Proposal"); proposal storage p = Proposals[_id]; if(_vote) { p.votesUp++; }else{ p.votesDown++; } p.voteStatus[msg.sender] = true; emit newVote(p.votesUp, p.votesDown, msg.sender, _id, _vote); } function countVotes(uint256 _id) public { require(msg.sender == owner, "Only Owner Can Count Votes"); require(Proposals[_id].exists, "This Proposal does not exist"); require(block.number > Proposals[_id].deadline, "Voting has not concluded"); require(!Proposals[_id].countConducted, "Count already conducted"); proposal storage p = Proposals[_id]; if(Proposals[_id].votesDown < Proposals[_id].votesUp){ p.passed = true; } p.countConducted = true; emit proposalCount(_id, p.passed); } function addTokenId(uint256 _tokenId) public { require(msg.sender == owner, "Only Owner Can Add Tokens"); validTokens.push(_tokenId); } } `````