The Quadratic Dollar Homepage is a spin on the Million Dollar Homepage. While it also features a space for images on a webpage, it allows users to vote on how much space each image takes up. Moreover, it employs a quadratic and collusion-resistant voting mechanism on Ethereum called Minimal Anti-Collusion Infrastructure (MACI) to prevent bribery and scale images quadratically.
DEMO: https://www.youtube.com/watch?v=b6VonnS8e1M
Clone this repo. Install dependencies by running yarn or npm install:
git clone https://github.com/appliedzkp/qdh
cd qdh
yarn # or `npm install`Copy .env.sample and name it .env.
In .env set values for all the missing variables, such as MONGO_URL, AZURE_STORAGE_ACCOUNT_NAME,
AZURE_CONTAINER_NAME, AZURE_KEY, AZURE_CONNECTION_STRING. You can find detailed guides on setting up MongoDB and Azure Storage towards the end of this doc.
cp .env.sample .env
vim .env # set `MONGO_URL, AZURE_STORAGE_ACCOUNT_NAME, etc...`Your .env file should looks something like this:
NEXT_PUBLIC_MACI_ADDRESS=0x2C2B9C9a4a25e24B174f26114e8926a9f2128FE4
NEXT_PUBLIC_POAP_ADDRESS=0x22C1f6050E56d2876009903609a2cC3fEf83B415
NEXT_PUBLIC_STRAPI_URL=https://strapi-admin.quadratic.page
MONGO_URL=mongodb+srv://user:password@mongodb-ip-or-dns.com/database...
AZURE_STORAGE_ACCOUNT_NAME=qdh
AZURE_CONTAINER_NAME=qdh-user-images
AZURE_KEY=24f234f234f+24f243f+24f243f/24f234f234f2f24f==...
AZURE_CONNECTION_STRING=DefaultEndpointsProtocol=https...Now run yarn dev (or npm run dev)
If you are already running
yarn dev(ornpm run dev), make sure to kill the process and start it again. Next.js doesn't pick up.envchanges automatically. Hence you need to restart it manually.
On the output, you should see something like this:
Loaded env from /your-project-path/qdh/.env
ready - started server on 0.0.0.0:3000, url: http://localhost:3000Frontend is now accessible on http://localhost:3000
Now let's set up and deploy MACI on a local testnet.
In a separate terminal, clone MACI: https://github.com/appliedzkp/maci
Carefully follow everything in "Local development and testing": bootstrap MACI repo, install Rust, build zk-SNARKs, compile contracts... everything up to the "Demo" section.
Here is a summary of commands described in detail in the abovementioned guide:
git clone git@github.com:appliedzkp/maci.git
cd maci
npm i && npm run bootstrap && npm run build
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # to install Rust
cargo install zkutil --version 0.3.2 && zkutil --help
cd circuits
npm run buildBatchUpdateStateTreeSnark && npm run buildQuadVoteTallySnark
cd ../contracts
npm run compileSolFrom the same directory (maci/contracts) start a Ganache instance:
npm run ganacheIn a separate terminal, go to maci/cli directory and create a new MACI election:
node ./build/index.js create -d 0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3 \
-sk macisk.8715ab59a3e88a7ceec80f214ec24a95287ef2cb399a329b6964a87f85cf51c \
-e http://localhost:8545 \
-s 15 \
-o 60 \
-bm 4 \
-bv 4Once you've deployed MACI and created an election, you should have an output like this:
MACI: 0x2C2B9C9a4a25e24B174f26114e8926a9f2128FE4Now you have 15 seconds to go to the frontend http://localhost:3000 and sign up. Then you'll be able to start voting and interacting with MACI. If you didn't signup in time - restart ganache and redeploy MACI (steps above). Also, you can increase MACI signup deadline, by changing -s 15 to -s 30 seconds.
Don't forget to connect your Metamask to your local testnet locahost:8545 and import one of the test wallets into it.
You can find a detailed guide of this step and other MACI commands in the MACI Demonstration docs.
You can also watch & listen to these great in-depth presentations about MACI by Koh Wei Jie: Making Sense of MACI, ZKPodcast: MACI with Koh Wei Jie and Minimum Anti-Collusion Infrastructure (MACI)
The goal of the Admin Dashboard is to simplify moderation of uploaded images, supply basic initial configuration to the QDH frontend (e.g. MACI contract address on the mainnet) and upload tally.json once the vote results are tallied.
Setting up and running Admin Dashboard is not mandatory, but recommended. We've based it on an open source headless CMS, called Strapi.
You'll be able to find detailed instructions on how to run it in the repo's README, but we'll make a short overview here as well.
Clone the repo https://github.com/appliedzkp/qdh-admin and install dependencies with yarn (or npm install)
git clone https://github.com/appliedzkp/qdh-admin
cd qdh-admin
yarn # or `npm install`Copy .env.example and name it .env.
In .env set values for all the missing variables, such as MONGO_URL, AZURE_STORAGE_ACCOUNT_NAME,
AZURE_CONTAINER_NAME, AZURE_KEY, AZURE_CONNECTION_STRING with the same values as used above.
cp .env.example .env
vim .env # set `MONGO_URL`, `AZURE_STORAGE_ACCOUNT_NAME`, `AZURE_CONTAINER_NAME`, `AZURE_KEY`, `AZURE_CONNECTION_STRING`.Run yarn develop to start the server locally.
The api will be available at http://localhost:1337 and the admin panel at http://localhost:1337/admin
You might want to update NEXT_PUBLIC_STRAPI_URL=http://localhost:1337 in the .env in qdh frontend, so that your local frontend talks to your locally run Strapi Admin api. Don't forget to manually kill and start the frontend server. (Next.js doesn't automatically pick up .env file changes.)
This repo is ready for Vercel, Heroku and Dokku deployments. Make sure to export enviromental variables from .env to the platform you are deploying on.
Install Vercel CLI:
yarn global add vercel
# or
npm i -g vercelThen from your qdh/ directory run vercel to start the deployment process and follow the steps. Should work automagically:
vercelYou can also auto deploy to Vercel by importing your git repo: https://vercel.com/new
If you don't have heroku cli installed yet, install it: brew tap heroku/brew && brew install heroku on macOS or sudo snap install --classic heroku on Ubuntu 16+. Then run heroku login to link your Heroku CLI to your account.
Then from your qdh/ repo directory run the following:
heroku create qdh-frontend
heroku config:set $(cat .env | sed '/^$/d; /#[[:print:]]*$/d') --app qdh-frontend # this will pick up variables from .env and transport them to your heroku instance
heroku git:remote --app qdh-frontend
git push heroku masterIf name qdh-frontend is already taken, try the steps above with a different name.
Dokku is a Docker powered mini-Heroku.
Follow these instructions to install Dokku on your server. Make sure to add your pub ssh keys to the dokku deployment (not just to ~/.ssh/authorized_keys on your server). Once you do that, you should be able to run the following from your local machine:
ssh -t dokku@your-server-ip apps:create qdh-frontend
ssh -t dokku@your-server-ip config:set qdh-frontend $(cat .env | sed '/^$/d; /#[[:print:]]*$/d') # this will pick up variables from .env and transport them to your dokku instance
git remote add dokku dokku@your-server-ip:qdh-frontend
git push dokku master- Create a Storage account. Give it a name. For example
qdh - Go to Storage account > Overview
- Click on Containers. Create a new storage container. Let's name it
qdh-user-images. Make sure that the "Public access level" is set to Blob (anonymous access for blobs only) - Click on Settings > Access keys. Copy paste Account Name, Key and Connection String from there.
- Tada! You now have
AZURE_STORAGE_ACCOUNT_NAME,AZURE_CONTAINER_NAME,AZURE_KEY,AZURE_CONNECTION_STRING:
AZURE_STORAGE_ACCOUNT_NAME='qdh'
AZURE_CONTAINER_NAME='qdh-user-images'
AZURE_KEY='24f234f234f+24f243f+24f243f/24f234f234f2f24f==...'
AZURE_CONNECTION_STRING='DefaultEndpointsProtocol=https...'p.s. We'll eventually try to make this project cloud agnostic. Feel free to contribute!
- If you are are looking for a free & easy MongoDB hosting, try Mongo Atlas
- If you've used Dokku before, you can deploy mongo instance on it using dokku-mongo plugin.
- You can also deploy MongoDB on your IaaS or PaaS of choice.