How I built a decentralized Ethereum app for the Super Bowl
Crypto is everywhere now, but I always wondered if people were just going to trade it, or actually use it for something productive.
When I heard that the creator of Ethereum was just a guy working on Bitcoin that wanted to attach code to blockchain transactions, I had to learn more. I also heard the buzz word “decentralized app” (or dApp for short), but I never really could explain what one was.
My attempt to explain how Ethereum is different than Bitcoin.
So, what type of code would be transferred alongside a money transaction? With Ethereum, you write something called a “smart contract”. I had trouble wrapping my head around this until I saw an actual example in code.
Let’s look at a very simple contract:
An inbox contract. Imagine if it cost money to send an email…
Even if you know nothing about Solidity, the language of smart contracts, you can see above that we are initializing a class called Inbox
with a string called message
. It looks like we can setMessage
, and that’s about it.
When you call setMessage
, you’re changing data in the contract, and any time you do that, you have to send a transaction to the Ethereum network.
So decentralized apps are just apps that interact directly with the blockchain.
Sending Money with Contracts
Let’s look at another contract to see how money is moved around:
A lottery contract. Make that money move.
In this one, there is an enter
function that has payable
in the definition. This function expects there to be a value associated with the transaction (in this case 0.1 ETH). Next, there is an address[]
array that we push
the msg.sender
(the player) into. Finally, the pickWinner
function chooses a random entry in the players
array, and pays them out the balance in the contract with transfer()
.
The cool thing about Solidity contract is that you compile it to be understood by Javascript, and you can write tests with Mocha:
All of this, by the way, was taught to me by Stephen Grider, who has a class on Udemy called Ethereum & Solidity: The Complete Developer’s Guide.
Deploying a contract to the Ethereum network is pretty easy too:
Once a contract is deployed, you can use the web3
library to interact with it from a React app.
I had an idea to build an app for the super bowl.
The Big Game Contract
Here’s the idea for the app:
- 12 players
- Each player can choose a team (either “birds”, or “pats”)
- Each player must send 0.015 ETH (about $20) to enter
- If your team wins, you split the pot with everyone else who chose that team
Let’s dive into the contract function by function to understand how this could work.
Let’s get this party started!
We initialize BigGame
with a manager
(the person who deploys the contract, me), two address[]
arrays to represent each team, and a playerIndex
mapping of address => uint
. Thin of the playerIndex
mapping as a hash of every single Ethereum address, initialized to zero.
When players enter, I’ll update their playerIndex
so I can display their status on the web page.
+-------------+---------------------+
| playerIndex | status |
+-------------+---------------------+
| 0 | Not entered |
| 1 | Entered birds |
| 2 | Entered pats |
| 3 | Entered birds, won |
| 4 | Entered pats, won |
| 5 | Entered pats, lost |
| 6 | Entered birds, lost |
| 9 | Refund everybody |
+-------------+---------------------+
Yes, if something goes wrong, I have a function that will refund everybody.
One more thing to note: restricted
is a function modifier that we’ll use later on the pickWinner
function. This only lets the manager
pick a winner.
Let’s check out of the meat and potatoes of the contract, the enter
function:
Notice payable
in the function definition. The key here is transfer
, which takes the payout for the winning team (calculated with this.balance / teamName.length
), and transfer
s an even amount to each player.
Let’s check out the pickWinner
function:
Fingers crossed!
This cycles through the list of players in the winning team and transfer
s the payout equally (this.balance / teamName.length
) and sets the playerIndex
. Solidity doesn’t allow you to compare two strings natively, so I had to create a function to do that.
Finally, let’s take a look at the refundEverybody
function:
Just in case, ya know?
Using delete
essentially resets those address arrays if I wanted to try again.
That’s basically it. The next challenge was to build a React app that talked to the blockchain and interacted with the contract. Here’s what it looks like before entering:
playerIndex
is 0 still
And when you click the “enter” button:
Rinkeby is a test network for Ethereum.
The app uses Metamask, which is a Chrome extension to let you interact with the Ethereum blockchain in your browser. Think of it as a wallet you can use on websites. Once the transaction is submitted, you have to wait a little while (20–30 seconds) for the miners to confirm the transaction. Once there are block confirmations, you’ll get back a transaction hash. Here’s the one I got back when I took this screenshot.
When you refresh the page (I know), you should see that you’re entered:
Fingers crossed!
Remember the manager
variable above? When I switch back to the original Metamask account that I deployed the contract with, I can see a special Manager Tools section:
It’s tempting to never use the middle button.
Let’s see what the page looks like when I pick a winner:
Now the payouts are zero’d out and I noticed some extra ETH in my account. It would have been cool to show the final payout, but I didn’t have time.
It’s crazy to think this website doesn’t have a database; it relies on the contract’s data changing when people enter or pick a winner.
Conclusion
It was awesome learning about dApps and contracts, and I hope to keep building more.
By the way, the Big Game contract is deployed to the main Ethereum network now.
If you want to check out the full contract, check out the Github repo.
If you’re interested in the tech stack, I used:
- React for components (create-react-app)
- Bulma for CSS framework
- Redux for data layer (reduxForm was considered)
- Mocha and granache for testing (also Remix)
- solc to compile the Solidity to Javascript
- web3 library with Infura hosts for talking with the Ethereum network
- Docker for containerization
- Zeit’s Now for deployments
If you want to see any of the web page source, hit me up on Twitter!