Skip to content

alanarvelo/DHackathon

Repository files navigation

diagram

Welcome to Decentralized Hackathons!


This is the official DeHack repository holding:

  • smart contracts — back end
  • web application — front end

What is DeHack?

DeHack is a platform to create and manage decentralized hackathons based on smart contracts on Ethereum. Anyone can add a prize to a new competition and encourage participants to create and compete.

What can you do with DeHack?

Using DeHack you can:

  • Create a new hackathon
  • Collect the prize (bounty) of a hackathon
  • Submit a project to a hackathon
  • Vote for a project on a hackathon
  • Retrieve part of the prize from a hackathon

Note that hackathons, and all competitions, are group efforts where certain individuals have certain responsibilities. DeHack is no exception, below is a description of the roles an individual can have and the stages hackathons go through.


Description

The platform is based on two main contracts that have a factory-child relationship, the DHackathonFactory contract and the DHackathon, DHackathon standing for Decentralized Hackathon. Any externally owned account (EOA) can call the createDHackathon(string memory _name, uint256 _prize) function of the DHackathonFactory contract to instantiate and become the Admin of a newly minted DHackathon contract (more on Admin and roles below). The caller must specify what name and prize the DHackathon will have. The contract's balance will have to be greater or equal to the promised prize for the DHackathon contract to change to the Open stage (more on Open and stages below).

Roles

Each hackathon has 4 types of users: Admin, Participant, Judge everyone else (No role). Function access is restricted via modifiers to EOA's with the appropriate roles. Roles are exclusive, the same EOA can't hold two roles, e.g. the Admin can't be a judge, nor can a judge be a participant.

  • Admin: in charge of adding and removing judges, moving the contract through its stages (In Preparation, Open, In Voting, Closed, more on stages below) and adding funds for the prize.
  • Participant: submit a link to their project and withdraw a piece of the prize if they got any votes from judges.
  • Judge: review the submitted projects and vote for their elected winner.
  • Anyone: regiser as a participant (gaining participant role access, i.e. can participate in the hackathon by submitting a project) and submit funds for prize.

Each role has a dedicated panel to perform its actions. Below the interface of a DHackathon displaying all roles' panels.

sequence diagram

Stages

The stages of a hackathon are sequentially: In Preparation, Open, In Voting, Closed. The Admin is in charge of moving the hackathon through its stages. Function access is restricted so that the hackathon is in the expected stage when X is activity is about to happen. For example, Participants can only register on the In Preparation stage, and Judges can only vote on the In Voting stage. An explanation of what each role can do in each stage can be found below.

  • In Preparation: contract starts on this stage.
    • Admin: add and remove judges, and set the stage to Open.
    • Participant: deregister, abandoning their role.
    • Judge: -
    • No role: register as a participant.
  • Open: contract balance must be >= than the declared prize. At least 1 judge and 2 participants must have registered.
    • Admin: remove judges, and set the stage to inVoting.
    • Participant: can submit a project, and deregister.
    • Judge: -
    • No role: -
  • In Voting:
    • Admin: remove judges, and set the stage to Closed.
    • Participant: de-register.
    • Judge: can submit a vote.
    • No role: -
  • Closed: at least 1 vote must have been submitted.
    • Admin: -
    • Participant: can withdraw prize, if they have received votes.
    • Judge: -
    • No role: -

To further illustrate the sequential nature of stages:

sequence diagram

For a more techncial description of the above see design pattern decisions and avoiding common attacks.

Objective & Benefits

Objective: This project was born out of the ironic experiencee of participating in a blockchain & Web3 hackathon conducted in a centralized manner and the prize was delivered 2 weeks after in fiat money. The purpose therefore is to help transition hackathons and other competitions to a decentralized manner thus benefitting from the transparency, immediacy, and anti-tampering, capabilities provided by blockchain back-ends.

Benefits: Notice the Admin has no power on the selection of the winner or the delivery of the prize. To further decentralize this platform the stage changes can be time based and the election of judges can be done via voting. See the Design Considerations & Next Features section for more.

  • Transparency:
    • anyone, at any point, knows the same as everyone else.
    • anyone can participate
  • Anti-tampering:
    • actors are anonymous reducing unconcious biases and/or discrimination
    • votes are anonymous and automated reducing tampering possibilities
    • the prize is not controlled by a centralized authority
  • Immediacy:
    • the prize is immediately available to the voted winners

Demo

A walkthrough of platform usage can be found in the demo videos on Youtube.


Design Considerations & Next Features

Moving hackathon through stages

Currently, the Admin is reponsible for moving the DHackathon contract, which represents a hackathon in the Ethereum blockchain, through its stages by calling the functions: openDHackathon(), toVotingDHackathon(), and closeDHackathon(). Given that at creation, each DHackathon contract gets a createdOn property, these stage changes can be time based. The contract can last a fixed number of days on each stage, or the user can define the length of each stage at creation.

To do: Make stage transitions, from In Preparation to Open, Open to In Voting, and In Voting to Closed, time or date based.

Project submission

Project submissions are currently simple, a url string is all the is required from the participants in the submitProject(string memory _url) function. This url is expected to be a github link to the project's repository, and there is nothing currently stopping participants from making updates to their projects past the Open stage. Though, github does timestamp each commit. More sophisticated ways of submitting and storing a project can be devised. A simple addition would be to timestamp when the project's url at submission, though how will this prevent particpants from updating the url's content is still unclear. Hashing may be the way, though help is required here.

The projects struct is below:

struct Project {
        string url;
        uint128 votes;
        bool withdrewPrize;
    }
mapping (address => Project) public projects;

To do: timestamp projects at submission and require a hash of its content.

Voting mechanism

Currently each judge has one vote to grant to one participant, the vote is += 1 for the elected participant votes count. The judges can only call the submitVote(address _electedWinner) function once. More complex voting mechnism where the DHackathon can have judging criterias or themes to be evaluated on and judges can vote different amounts to different participants on different criterias. These would allow for calculating a podium, i.e. select the winners as a 1st, 2nd, and 3rd place, which more closely resembles centralized hackathons.

To do: add judging criterias and calculate winners podium-style (1st, 2nd, 3rd place).

Prize division

Withdrawal design pattern is used here, winners must call the withdrawPrize function to receive their portion of the prize. The prize is divided equally by the number of votes given out by judges and awarded to participants based on the number of votes received. On code:

/// Inside the closeDHackathon function
prizePortion = address(this).balance.div(numJudgesWhoVoted);
...
/// Inside the withdrawPrize function
uint256 amount = winner.votes.mul(prizePortion);

To do: code a more complex and customizable prize distribution mechanism according to improved voting logic.

Participants and teams

Currently participants are represented by EOA's only. Would be great to add functionality for having teams that consist of several EOA's, submit a projects together and share the prize. Other options are to have participants get approved or charge a fee for participating (similar to a betting format).

To do: add teams functionality.

Adding and removing Judges

Another of the big responsibilities of the Admin is to select the judges. However, on the In Preparation period, there can be a voting process for the community, particpants and No roles, to vote for who they want their judge to be, based on the theme of the DHackathon aligning with that individual's expertise. The EOA of that individual must be known.

To do: allow judge selection via voting process of the community.

Sponsor role

A Sponsor role can be assigned to anyone who submits funds or who submits more then X funds. The sponsor role could have tiers depending on the donation. Companies, will be interested in the publicity and functionality of the Sponsor role if it is designed to be appealing enough for them.

To do: add a Sponsor role for EOA's that submit funds and add relevant functionality.

Extend to any type of competition

As can be seen, hackathons are just one kind of competition that can be decentralized. Roles, Admin, Participant, Judge are agnosticly named so these contracts functionality can be easily expnded to other types of competitions. Competitions need not be online, they can have a physical component and still benefit from decentralized registration, prize funding, judge selection, voting, and prize disbursal.

Any sort of tournament: poker, esports, ping pong, or art competitions can leverage this workflow.

To do: generalize functionality to provide registration, prize funding, judge selection, voting, and prize disbursal to any type of competition.

Other To-do's:

  • Host the front-end on IPFS
  • Add capability for the Ethereum Name Service (ENS)
  • Auth & signing with Uport and Blockstack
  • Add Loading Bar

Getting Started

Below is a technical explanation of how to copy the project and run a local version of it in your machine. If you just want to play with the live, finished platform find it here DeHack. If you want to study & improve the platform by getting a local copy, please read on.

Prerequisities

The platform runs on the following version of these frameworks.

  • node v8.12.0
  • npm@6.4.1
  • truffle@5.0.32
  • ganache-cli@6.6.0

NodeJS as a compilation engine to run scripts.

NPM, as a package manager.

Check if you have node and npm by typing in your terminal:

$ node -v
$ npm -v

If you don't yet have them, you can install them from here. Npm typically comes with NodeJS, but make sure you have them both.

Truffle for everything related to writing, testing, compiling, and deploying smart contracts.

Ganache-CLI to create a private blockchain to work during development (port 8545). I also utilized Ganache-GUI extensively,thus it will be set-up for you at port 9545.

Truffle and ganache-cli can be installed by running these commands in your terminal. Ganache-GUI can be downloaded from here.

$ npm install -g truffle
$ npm install -g ganache-cli

Note that we have installed the latest version of these packages, not the exact ones I utilized. Due to backwards compatibility, this should be fine. If you encounter any issue with these packages while developing, uninstall them and install the exact version that was used, shown above.

Metamask to interact with the dApp. It is a browser extension and can be easily installed following these steps.

Running the project

Clone the repository to your local machine by:

$ git clone https://github.com/alanarvelo/DHackathon.git

Smart Contracts — Back end

Once finished you can get into the project's root path (cd into it) by running:

$ cd DHackathon

This is the project's root path, where all the back-end code resides, mainly within ./contracts, ./tests, and truffle-config.js. All of the front-end code is within the ./app folder.

The back-end is strucutured as shown in the image below: data and dependencies diagram

As you can see, we used OpenZeppelin's contracts as building blocks for our own, so lets install them in your local machine. Simply run the below command from the root path.

npm install

openzeppelin-solidity is the only package that should have installed.

React files — Front end

Open another terminal, let's call this the front-end terminal. This terminal should open on the root path, to get inside the front-end files do:

$ cd app

From here (you should now be on <your-home-folders>/DHackathon/app), install all the front-end dependencies, mainly React, Truffle's Drizzle, and web3 by typing:

$ npm install

Ganache-cli private blockchain

To start a private blockchain, open yet another terminal, let's call it the ganche-cli terminal, and type:

$ ganache-cli

This command will create a new local blockchain and start listening on port 8545. Note you must import the generated accounts, via their private keys, to the MetaMask browser extension, to intereact with the platform when it is running in the local blockchains of ganache-gli or Ganache-GUI.

Making them work together

Go back to the original terminal (the one that is on the root path, <your-home-folders>/DHackathon, the first one, the one we didn't give a name to) and run:

truffle compile

To compile the smart contracts.

truffle migrate

To send the compiled smart contracts to any blockchain that is listening on port 8545, i.e. our ganache-cli private blockchain. If you have trouble in the future, the flag --reset comes handy on this command.

Now go back to the front-end terminal and do:

npm run start

This should start a development server, and open a web browser to http://localhost:3000/.

Here is where MetaMask comes in. Make sure you have MetaMask installed as an extension on that web browser. Open Metamask click on the top center where it says Networks, then click on Custom RPC, and paste HTTP://127.0.0.1:8545 on the New RPC URL field. MetaMask is now connected to your ganache-cli private blockchain. You should now be able to locally with the platform.

Likely, you will need to import some of the accounts recently created by ganache-cli to your Metamask extension to start calling web3 functions in the DApp.

Tests

Tests can be run by typing in the terminal. This should work anywhere, but go to the first terminal, the one where you ran truffle compile and truffle migrate

truffle test

That's it! Here an example of what should display in your terminal. tests passing

Deployment to external networks

The platform can be deployed to Rinkeby, Ropsten, other testnets, as well as to ethereum's Mainnet. In fact, it already has, see the deployed addresses here.

To deploy it yourself create a file called .env and add your Infura api key (or project id) and mnemonic as follows.

MNEMONIC=
INFURA_API_KEY=

Important: the file must have the extension be simply called .env so it is ignored by .gitignore preventing you from accidentally disclosing your mnemonic and thus your private keys. No need to use quotes to denote strings in for the values.

To deploy to testnets or mainnet, run:

truffle deploy --network <yourPreferedNetwork>

Authors

  • Alan Arvelo

If you have any question or feedback reach me at alanarvelo@gmail.com.


About

This is the official DeHack repository. A smart contracts platform to create and manage hackathons on Ethereum.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published