Skip to content
Myra edited this page Aug 14, 2018 · 28 revisions

Introduction

  • A decentralized application running on the Ethereum blockchain, to empower real behavioral change driven by goal setting tied to financial incentivizes.
  • A Pledge contract is a binding agreement you sign with yourself to ensure that you follow through with your intentions, and it does this by utilizing the psychological power of loss aversion and accountability to drive behavior change.
  • By asking users to create a Pledge, dApptastic helps users define their goal (whatever it may be), acknowledge what it’ll take to accomplish it, and leverage the power of putting money on the line to turn that goal into a reality.

Glossary/Features

  • Pledge: A contract representation of a commitment to a goal defined by goal type, number of days, success threshold, pledge amount
  • Success Threshold: A user chosen value between 40-75%
    • If the number of days they successfully completed this daily goal is equal or above this rate, then the pledge is considered successful, and hence when the pledge is closed anytime after this rate is met, they will receive their pledge amount back into their account. Or else, they will lose it to the recipient account chosen at the time of pledge creation.
    • To incentivize against closing the pledge at the least percentage rate possible (i.e 40%), users will have the ability to customize their avatar attached to the profile on this platform. An increasing number of customization features will get unlocked if and only if they meet higher thresholds.

User Stories

Browse

  1. Any user opens up the web app. The user is shown the home page where they can view all ongoing and finished pledges currently on the platform. They can also see stats on total number of pledges, total amount pledged, total users, etc. The user is also show a login button in order to authenticate and create their own pledge.
  2. A user opens up the web app, and successfully authenticates using uPort for the first time. The profile tab shows some account info and an empty avatar. The user is redirected to their dashboard showing their name and location. The previous pledges section is empty, and the current pledges section prompts them to create a new pledge with various input fields - goalType, amount, pledgeLength, etc.

Pledge Creation/Updates

  1. A user successfully creates a pledge. The current pledge section shows details of their ongoing active pledge. The user will only be able to 'checkin' for the current day. The home page will update to include their pledge in the list, and the stats will be updated to account for the newly created pledge by this user. A user should not be able to create more than one active pledge at a time.
  2. A user wants to close an existing pledge. A user with an active pledge returns to the web app, and successfully authenticates using uPort. The user is redirected to the dashboard and clicks on 'Finish Pledge' on an active pledge. The contract should distribute the amount to the recipient/owner depending on the success % of the pledge, and mark the pledge as inactive. This pledge should then appear under 'Previous Pledges' in the dashboard. At this point, the user can create another active pledge.

Profile Changes

  1. A user can change their avatar attached to their profile by going to the Profile tab. After a successful transaction, they can see this new avatar update across the platform.

Tenents

  • An absolute minimum of on-chain computation and data usage
  • A user should not be able to manipulate storage vars/application state differently from the UI vs. from directly calling contract methods from backend.
  • A clear UI to notify users of any status changes in background processes.

Tech Stack

Database - Local blockchain, Ethereum’s Testnet Rinkeby blockchain.
Hosting - IPFS
Frontend - React/Redux/ReduxRouter with Webpack/Babel, Semantic-UI, Avataars
Domain name - tbd
Package Manager - NPM, ethPM
Programing language - Solidity 0.4.24
Frameworks - Trufffle
Development server - Node.js, ganache-cli
Transaction Signing - Metamask
Authentication - uPort

Design_Pattern_Decisions

Contracts

1. Single contact with structs

2. Factory/Child contracts - [IMPLEMENTED]

  • Considering this question - 'What are the concerns that contracts are dealing with?'
  • Users will have an ability to accept ether to their username; Each pledge will have a certain value tied to it; And keeping it all in one (potentially very complicated) contract seems to create a very nice large honey pot, and is much more difficult to audit.
  • If the users hold their money inside their own single pledge contract, then it would be easier to protect the amount, and provide a much more clear way to audit.
  • Child contracts are more expensive, but given the reasons above, I believe the implementation will be much more secure and auditable.

Storing Users

To keep track of pledges that belong to a single authenticated(by uPort) user.

1. uPort MNID

Originally, I thought this would be a string because I wanted to store the MNID, but as it's a known issue that the EVM doesn't handle string[] well (i.e - can't return string[] from a contract function) - I took the next approach.

2. Metamask address

Usually the address key is a MetaMask address from which the transaction happens. But since many wallet addresses can belong to the same user, this approach didn't make sense in a system where we are using uPort to authenticate.

3. uPort address - [IMPLEMENTED]

I chose the address key here to be the value returned by MNID.decode(). I'm thinking of storing the MNID from uPort as the ‘user address’ key, and not the actual wallet address. A pledge could only be modified if and only if the userNetworkSpecificAddress of the current authenticated user matches the userNetworkSpecificAddress of the creator of that Item.

Storing Checkins

To keep track of what days the user checked in for a given active ongoing pledge.

1. mapping(uint => bool) public checkins saved as storage variable

  • Pros:
    • Takes care of having only unique values by nature
  • Con:
    • Not able to loop over

2. uint8[] only containing the days that the user has checked in. Storage variable.

  • Pros:
    • lower gas costs
  • Cons:
    • Unordered/Unsorted
    • Possible to have duplicates, as prevention of duplicates would mean looping in the contract, which is not cost-effective.

3. bool[PLEDGE_DAYS_LENGTH]. Storage variable. [IMPLEMENTED]

  • Pros:
    • array is a restricted and known length, so we can still loop over without gas costs being too high
  • Cons:
    • tbd

Emergency Stop


Avoiding_Common_Attacks

Cost Analysis