## 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);
}
}
`````