DEV Community

Cover image for Token Payout based on Private Information: Golf Barbecue Coin (GBC)
datadr1ven
datadr1ven

Posted on

Token Payout based on Private Information: Golf Barbecue Coin (GBC)

Midnight Network Challenge: Protect That Data

This is a submission for the Midnight Network "Privacy First" Challenge - Protect That Data prompt

What I Built

My golf friends and I want each other to improve. And so while we play our own games, and keep track of our own (private) stats, we incentivize two quantities, by penalizing two related events. To keep track of our penalties, we created, and have used for the past year, an ERC-20 token with a funny name. We chose this name, because at the end of summer, we required each other to use our accumulated token balances, to pitch in for an end of season get together.

Using this token requires quite a bit of manual effort, and we prefer a workflow where each of us can enter our (private) hole details, and have the token balance update automatically based on penalty events (which can be computed from the private hole details). This seems like a perfect use case for Midnight/Compact, and falls into the category of proving eligibility for token payout without disclosing personal information.

This was a difficult project for me, as I was on my own (in the sense that I'm couldn't find documentation/examples) in implementing a witness based on changing private state. I am proud of accomplishing this in a basic form, although I'm sure the implementation leaves a lot to be desired. Over the next few months, I plan to finish all of the TODOs, and transition the prototype to production.

Demo

All of the code I developed is here. The repository contains a compact contract called gbc.compact, an api/cli bootstrapped by create-midnight-app in boilerplate/contract-cl, and a UI in boilderplate/gbc-ui.

Here is a video of the UI in action, which displays the (public) GBC balances, as a function of (private) hole data input.

In the video below you can see a deployed gbc contract being invoked, with the witness being based on private dynamic data (user provided hole results). I need help wiring actual contract calls up to my UI, and this part of the project is left as a TODO.

How I Used Midnight's Technology

  • Utilized the compact language in writing gbc.compact
  • The super awesome helper create-midnight-app generated cli scaffold from the gbc contract. Extending the scaffold was nontrivial, as it made overly simplistic assumptions (such as a static witness)
  • Spent a significant amount of time attempting to write a UI that actually interacts with a deployed contract. Tried two main approaches, 1) adapting the example-bboard UI, which uses modules such as the Midnight DApp Connector API, and 2) attempting to use OpenZeppelin's UI builder. In the end, I was unsuccessful with both approaches. A simple tutorial here would've helped a lot

Another TODO before going production will (likely) be to incorporate OpenZeppelin's FungibleToken compact contract, as the current token-like capabilities in gbc.compact are rudimentary at best. A simple tutorial here also would've helped a lot.

Data Protection as a Core Feature

To achieve this prototype required implementing a witness based on changing private state. Specifically, as a user enters their result for a particular golf hole, this private information informs the witness latestResult(), so that the contract circuit nextHole() can be invoked, and the appropriate balance bookkeeping ledger quantities can be updated.

Set Up Instructions / Tutorial

As described in the README,

start by running npm install at the top level directory

  • for the contract
  1. run npm install from boilerplate/contract
  2. run npm run compact from boilerplate/contract
  3. run npm run build from boilerplate/contract
  • for the cli
  1. run npm install' from boilerplate/contract-cli
  2. run npm run build
  3. run either npm run standalone or npm run testnet-remote (the latter requires starting a proof server via docker)
  • for the ui
  1. run npm install from boilerplate/gbc-ui
  2. run npm run dev from boilerplate/gbc-ui
  3. point a browser at localhost:5173

Top comments (0)