Introducing TheButton.co — a Simple Ethereum Game
This is a take on the popular Reddit experiment the button, but with a few key differences. At the core, this button is based on an Ethereum smart contract. There’s a countdown timer — when the button is pressed the timer resets (just like the original). Anyone can press the button as many times as they want, but it costs ether to press it. The last presser wins the accumulated ether as a jackpot!
Rules of the game
The above TL; DR is a huge oversimplification, because it only scratches the surface. Firstly, funds deposited by pressing the button go into four distinctive “buckets”:
- Jackpot (currently 85%)
- Charity (currently 5%)
- Revenue for the devs (currently 9%)
- The rest goes to the next campaign (currently 1%)
As can be inferred, if the timer runs out, a campaign is finished. When that happens, the next button press will finalize that last campaign, and it will start a new one. Finalizing a campaign means that the accumulated ether will be split according to the pre-set fractions as described above.
Secondly, the price for pressing the button is not constant! There are two parameters which determine how the price changes: N, and the price multiplier. Currently N = 5, and the price multiplier is set to 6%, which means that the price will increase by 6% every 4 presses.
Lastly, a campaign has one more parameter that determines its behavior — the period (or what the timer resets to), which is currently set to 30 minutes.
If you’re familiar with the original button, then most of this will make sense, but if not, I highly recommend checking out the original subreddit. I’ve been learning solidity for the past year and I had been thinking about some simple and fun ideas which I could implement as dApps. Thinking about past simple and viral internet phenomena I quickly connected the dots and thought about how the button can be made into an Ethereum dApp. I’ve never done any web development before, so it was a major learning experience!
I have engineering background, but I’ve also just finished an MBA. I’ve been thinking a lot about what smart contracts can do for businesses, and my Accounting smart contract base is one of the ways I hope to contribute to developers and companies who intend to base their business on smart contracts. Another direction, which I hope more blockchain projects take and which I would like to contribute to, is thinking about giving back to society. We’re all obsessed with the technology we’re developing, or the prices of crypto and tokens we’ve bought, but not many of us have stopped to appreciate what we have, and to think about how we can help the disadvantaged in the world. This is why I’ve implemented a charity fraction in the button dApp, and I intend to add this to any future dApp projects I work on. Thinking about CSR is not only for already successful companies, I think it can be part of very young ventures as well (that topic can be a whole separate article on its own)!
The current charity beneficiary is Giveth.io — I have no association with them whatsoever. They are working on developing the future of giving on the Ethereum blockchain, and are one of the few charitable organizations that accept ETH as donations currently. They are completely transparent about how they spend their funding and will make it easy to donate to specific causes in the future.
Smart Contract Overview
For those of you who want to understand exactly what the smart contract does, I will explain it step by step here. The contract is deployed here
ButtonBase contract which contains all simple getters and setters and
TheButton which contains the core logic. The base contract inherits
DSAuth for ownership and
Accounting for accounting. Also using
DSMath for safe math.
A button campaign is contained in a struct:
All of the campaign parameters can be changed, but changing them only affects the next campaign, as the parameters are stored separately as internal variables. Parameters can be changed by the owner of the contract, but only to a certain extent, using these function modifiers:
limited modifier ensures that some supplied argument has hard-coded limits and the
timeLimitedone ensures that a function can only be called once in a while— useful when setting the button parameters or accounting fractions:
Setting the charity beneficiary is also
timeLimited — this does not by any means prevent the devs to cheat and steal the charity funds (by waiting out the period for setting the beneficiary), but it at least guarantees that we can’t do it whenever we want. We have no interest in cheating anyone out of their hard earned money, but we need some time to gain legitimacy and the trust of the community.
Winners’ funds are kept in a mapping:
mapping (address => Account) winners;
Withdrawing the jackpot is as easy as (using the proprietary accounting functions makes it easy to handle value):
Sending charity ETH:
Since the Accounting base keeps track of all known deposits and withdrawals, we have functions to redeem any surplus ETH (can be sent from a contract
selfdestruct) or ERC20 tokens:
The main contract contains the press logic:
Which boils down to this:
The button can be stopped, but that only prevents from starting a new campaign, and does not affect any running campaign. It also prevents from finalizing a campaign from the press function, that’s why there is a separate public
finalize function that allows anyone to finalize the last campaign.
Handling a press looks like this:
Starting a new campaign:
Finalizing a campaign:
DSMath makes it easy — it can treat numbers as wads (numbers with 18 decimal places), so if a fraction is set to 0.05*10¹⁸ (5% in wad), it’s a matter of multiplying the total balance with that fraction using the
wmul function to figure out how much to transfer to the given account.
For more, check out the official smart contract code verified on Etherscan.