GoFundYourself (the dapp)
GoFundYourself Profile Page - upload to IPFS Part 1
GoFundYourself Profile Page - upload to IPFS Part 2
Solidity Smart Contract - Part 1 (KeeperCompatible)
Solidity Smart Contract - Part 2 (AggregatorV3Interface)
Polygonscan Verification - Contract Source Code Verified (Exact Match)
The Team (the heart)
GoFundYourself Figma Diagrams
✨ An IRL tokenization platform to turn your hopes, dreams, and desires into fundable NFTs on the Polygon blockchain using Chainlink, IPFS, Moralis, and NFT.Storage.
https://www.pats.cool/case-studies Pat Santiago, creator of PatNFT, successfully tokenized himself using a fundable NFT to get himself to ETHDenver. As a team, we decided to build a platform to make it easy for anyone, anywhere, to tokenize their human capital to make their dreams come true. We wanted to scale his concept for maximum social impact.
What if anyone could contribute to good-will projects, volunteer endeavors, or social good initiatives? Just in the US, Americans gave $471.44 billion in 2020 (a 5.1% increase from 2019), according to the National Philanthropic Trust. But this is just one country, and there is limited data about how much funding really goes on to fund social impact projects. With GoFundYourself, funding endeavors are on-chain and verifiable, transparent, and open to all. More people can receive education, more people can build substantial programs and projects, and substantial opportunities can be unlocked for people, regardless of geography or region, for social good and social impact.
Raising capital is hard, takes many months to a year, and is not guaranteed. With GoFundYourself, you pitch your idea to make the world a better place and get funded by a network of people who want to support you and your dreams.
What it does
Users who wish to receive funding for their project initiate a token sale. Owners of these tokens can redeem them for a listed service from the project creator at a later date.
These projects then are minted onto the blockchain and through an event listener, are culminated into a feed for users to see, support, or fund such proposals and projects.
Not only can you see what other projects are available to fund, but you can also list your own project through the platform. We wanted to create a dialogue between funders and fundees, all on the blockchain, through innovative, and cutting-edge, technology.
How we built it
[ x ] Chainlink Keepers - Checks if the token agreement for work / job has expired, and updates the smart contract’s specific value for that Job to “expired”. Our Solidity smart contract leverages the KeeperCompatibleInterface from Chainlink to do so.
[ x ] Chainlink Price Feed - Allows users to send in a Wrapped ETH and MATIC (on Mumbai Testnet) to check against their currently approved USD maximum $ per project tier level (starting with $55 and multiplying by 5 each successful time). Our Solidity smart contract leverages the AggregatorV3Interface from Chainlink to do so.
[ x ] NFT.storage && IPFS - immutably stores a project as an IPFS hashed blob on NFT.storage, so that people are held accountable to their commitments and for improved transparency. NFT.storage uses Filecoin agreements to provide long-term storage persistence as an indelible record. Our workToken smart contract points to the https gateway as a tokenURI. We also have a separate function that saves the profile picture as IPFS.
[ x ] Polygon - In order to make this application more accessible to more people around the world, especially those with limited financial resources, we used Polygon. Poly leverages layer 2 solution to keep the low gas fee. In addition, Polygon is the cleanest-energy blockchain available, so it made sense to build with it for our project given we wanted to have a social impact implementation, not just in the mission, but in the technology decisions we made as well.
[ x ] Moralis - Moralis support in the Discord, ease of use for the 1 free server, and a developer friendly experience for making a decentralized application like this possible, was Marvelous. We leveraged several Moralis hooks, such as the MetaMask authenticate hook to log in, the user management system using the Moralis database, storing of public user and project classes for querying ease, and the ability to save the IPFS hash for user pictures back into each User’s data fields dynamically. Building our dapp with Moralis was an obvious choice to ensure we can track the safety, security, and ease of use of our application more directly, while we tailor unique user experiences for our users directly. This would not be possible with just JWT tokens. We wanted to build our app for scale, and the moralis-react SDK is optimal for this.
[ x ] NextJS + Typescript + Styled-Components + Material-UI - The GoFundYourself dapp is built with NextJS, a React-optimized front-end framework created by Vercel, in the front-end, and TypeScript was added in the back-end for functions. For styling, the styled-components and Material-UI frameworks and libraries were incorporated to speed up development while providing a strong UX for users.
[ x ] Netlify - The GoFundYourself dapp is deployed via a CI/CD pipeline from GitHub based on our
prod branch to Netlify. Netlify stores our environmental variables and API keys securely, while allowing us to distribute our dapp for the world at no cost.
Challenges we ran into
How do we keep the users safe? We want to keep the users private information secure in the database, and keep a permanent and immutable record of their work/job/funding agreements using NFT and NFT.Storage. One technique we designed into our Smart Contract is a tiered level system, so that each project must sell and redeem all workTokens from that project before moving on to the next level. That way, if there is a malicious fundraiser, it’s more difficult to move to larger sums of money. On the user side, profile pictures, as in your wallet’s PFP, is something that we thought should be public and decentralized by design, just like your wallet address string. As such, we implemented an IPFS file storage solution using an async await function to do this. There are other user attributes like bio, name, etc. that would be saved to the private user’s file…and publicly queryable but not on the blockchain. This mix of decentralized and centralized data attributes we thought was a better trade off than everything being one or the other, especially allowing people to update/change attributes more or less frequently.
We designed our front-end to visually display information about the users. We call this a reputation system. We have full transparency and immutability. People looking to fund a project can see the user's track record (total projects started, complete and incomplete %), they will also be able to see the track record of others who are funding the project (how many projects have they funded, complete funded projects %).
Whether or not to build a calendar booking system? We think that it would be a great feature, and something that a Chainlink API call or a verification system could confirm. Originally we thought that each NFT would be exchangeable for an “hour” of time/work.
How to come up with a proof of reputation algorithm if we had more time? We want each user to have a reputation score (RS). The RS will be calculated through a function involving the number of projects the user has completed (affected by project tier), the number of incomplete projects started by the user, total projects funded by the user, and the number of complete projects the user has funded (affected by project tier) .
RS = F(p, e, v) + F(tf, q, v)
RS = User Reputation Score
p = complete projects started by user
e = incomplete projects started by user
tf = total funded projects by user
q = complete projects funded by user
v = project tier
We currently do not have enough data to finetune the proof of reputation algorithm, and we want to decide on this later, please leave us feedback at email@example.com.
How to upload files/metadata to IPFS for a user in Moralis This was the first time that many developers on our team were using IPFS/Filecoin in any capacity. We of course had heard of IPFS, but actually using IPFS in a development capacity was very new. One of the specific struggles we encountered was how to allow a user to upload a file from the front end, store it on IPFS, wait for a _ipfs hash to come back, and then save that on behalf of the user.
This took us several hours of debugging but we finally figured out how to do this, saving it on IPFS and then saving that _ipfs link to that User’s metadata in Moralis. It was a very empowering moment when we figured it out, but there were a lot of things we need to learn about that were challenging, such as saving data or a file as local state, run a function that can take that local state and upload it to IFPS, preview the uploaded image, and then allow the user to then receive that data back and use it on behalf of their user’s account.
How to create a scalable smart contract in Solidity One of the core issues on the Solidity smart contract side was how “NFTs” or a “coin” works for our use case, and how the Solidity smart contract actually works with wallets for authenticated users. We were considering creating a coin, instead of an NFT, initially, and we struggled to envision which was the “better” solution for our use case. We ended up picking an NFT because of the ability to store metadata and enable event tracking.
However, we spent quite a lot of time testing out both coin (ERC20) and NFT (ERC721 vs. ERC1155) approaches to see which one made the most sense. Even more, we needed to do a lot of test driven development to debug errors we were receiving in Remix/Hardhat about the smart contract and how it was operating. This was challenging because we did not know the right answer when we started the hackathon. However, we believe we were able to nail down the right solution in the end.
Managing the scope for a hackathon vs. post-hackathon scale When we were working on the Solidity smart contract and the dapp UX, something we brushed up against was the need to curb the expectations of the “app we want to launch” with the “app we can build right now.” Scales of magnitude came up frequently, and we had to scope down our vision into practical, operationalizable, buildable elements now, knowing we can update it after the hackathon.
When we were working on our hackathon project, our minds were racing about what we “could do,” so we had lots of conversations and discussions about what we “can/should do right now.” This actually led to a lot of great developments, and a good part of the reason why we are so excited to keep building on this after the hackathon judging.
Accomplishments that we're proud of
We were able to complete a project that can share Pat’s “tokenize myself” idea with the world.
“I made my first GitHub commit” - Pat
Brian, who worked on the front-end/back-end, learned how async functions work for pinning files on IPFS. This was a really great learning experience from the development side learning how "async await" actually works when you store an item in local state, and then pass that into a mechanism that uploads to IPFS...you then "wait" for that response to come back as an _ipfs hash and then our function saves that hash link as an object in the user.
Riley, who worked on our smart contract, learned how to implement test-driven-development for the Solidity smart contracts he wrote into our GoFundYourself dapp. This was a really great learning experience for him as he got to see exactly how skilled he was with "new skills" for him, while also collaborating with the entire team to implement Chainlink, smart contracts, and decentralization on Polygon.
Tippi, who worked as our product manager for our team, gained a lot of great experience with Chainlink and was there as we implemented various elements of decentralized oracles, price feeds, and API concepts of Chainlink into our smart contracts and concepts for GoFundYourself. He learned what it means to hold the actual situation of a complex human and technical system in his mind and heart, and help each teammate see the big picture and get unstuck when they need help.
Will, who was our first-test user for the project, joined the team and figured out our implementation flow. He poked holes in the project and allowed us to think critically of our project to make it stronger and further developed for a release post-hackathon. His edge cases were instrumental for seeing where we could stretch this idea further. Will also created team’s multi-signature ETH wallet using Gnosis Safe – this was his first time doing this, as well as for many of our team’s first times with multi-sig wallets, so this was a big accomplishment for learning about collaborative, team-based authentication and ownership.
Overall, we all successfully used git and GitHub to fork, branch, and merge our codes together. We all usually are used to working on projects individually, so we are all proud of our collaborations and ability to work together across multiple time-zones and geographies to build GoFundYourself. Moreover, we all had fun and did a ton of learning over the course of the hackathon.
What we learned
- How to use Chainlink’s KeeperCompatibleInterface to implement a way to check if the token agreement for work / a job has expired, and update the smart contract’s specific value for that Job to “expired”.
- How to use Chainlink’s AggregatorV3Interface to allow users to send a Wrapped ETH and MATIC (on Mumbai Testnet) to check against their currently approved USD max $ per project tier level (starting with $55 and multiplying by 5 each successful time).
- How to upload to IPFS using NFT.storage for decentralized file storage for a dapp.
- What it looks like to upload a file from the front-end to IFPS and what you “get back”.
- How users can update their metadata and properties in a Moralis database.
- How to leverage and implement Moralis’ moralis-react SDK npm package and use various web3 hooks provided by Moralis in the dapp.
- How to deploy a smart contract via Hardhat to Polygon.
- The similarities between the Ethereum blockchain (that our team was more familiar with) and the Polygon blockchain (Layer 2) that we became more familiar with over this hackathon, as well as how easy Polygon is to build on, deploy to, and implement in our app.
- What happens when you deploy a contract and allow users to interact with that smart contract.
- What test driven development looks like for Solidity smart contracts and TypeScript front-end calls.
- How to better use styled components and Material-UI design libraries on the front-end.
- How to store files locally in the browser before uploading them and how state works in NextJS
- Better understanding of Solidity nuances and how it connects to Chainlink.
- The importance of Time Management.
- How to work together as a team and collaborate across time-zones.
- How to create a Gnosis safe for a multi-sig wallet.
- Validation about GoFundYourself from the people we have been speaking about it with.
- The need for a protocol like GoFundYourself and why we need to continue working on this post-hackathon.
What's next for GoFundYourself
Tomorrow on Saturday, May 28, we are meeting with a securities lawyer friend from CityDAO to ask some of the challenging questions we’ve been thinking about (see our Google Doc).
Next week, we will begin syncing the front-end and smart contract to the Figma designs when Brian, Riley, and the team have more time to expand the smart contract. We also will be optimizing the UX further based on the user-feedback we received thus far.
We are also working on several grant applications to secure funds to build out our team more and scale our dapp and protocol in a way that allows us to get audited (to increase security), and flow better for our users (to increase UX), and ensure the protocol can scale for our use-case (to increase adoption).
Starting at the beginning of June, we will begin a large marketing push to onboard more members onto our platform. We will be hosting Clubhouse rooms and Twitter spaces to hype up GoFundYourself, increase our member base, start user-testing for those early adopters, and get ready for our contract to be audited so that we can eventually push to mainnet.