Going Dutch - A Smart Contract for supper dates on the blockchain

  • Posted on: 2 September 2017
  • By: Jackson

Use Case

My buddy, Mark and I have been hanging out on supper dates for the past 18 years. Sometimes he pays first and I forget to pay him back. The reverse happens at other times. We don't trust each other to maintain an Excel file to capture the records. I mean, look, what if Mark doctors the Excel file when I am not looking. This is obviously a great candidate for blockchain - now our records becomes immutable and the history of our misspending are forever etched in the blockchain.

This is what I set out to achieve in my Go-Dutch contract:

  1. We have a pool of funds for supper dates and draw from the pool every time we eat.
  2. Sometimes I contribute more and sometimes Mark does. We both need to know how much each of us have been contributing to the pool.
  3. Sometimes we contribute for each other, like when I tell Mark that it is my treat today.
  4. We also need to know how much is left in the pool of funds.
  5. And obviously, when we spend, we need to deduct our spending from the pool.

Setting Up

I start geth and wait while it syncs with the block

geth --testnet --syncmode "fast" --rpc --rpcapi db,eth,net,web3,personal --cache=1024  --rpcport 8545 --rpcaddr 0.0.0.0 --rpccorsdomain "*" --bootnodes "enode://20c9ad97c081d63397d7b685a412227a40e23c8bdc6688c6f37e97cfbc22d2b4d1db1510d8f61e6a8866ad7f0e17c02b14182d37ea7c3c8b9c2683aeb6b733a1@52.169.14.227:30303,enode://6ce05930c72abc632c58e2e4324f7c7ea478cec0ed4fa2528982cf34483094e9cbc9216e7aa349691242576d552a2a56aaeae426c5303ded677ce455ba1acd9d@13.84.180.240:30303"

And then I create my directory for this use case and initialize truffle. Truffle pulls in everything I need to write the smart contract

mkdir godutch
cd godutch
truffle init webpack

Finally, I write the contract. You can find godutch.sol in my Git repository.

sudo pico godutch.sol

I change 2_deploy_contracts.js in /migration to initialize it to work between 2 buddies, Jack and Mark. It could include Ignatius, Daniel and Roger too, but these folks haven't been eating with us for a while. The contract does allow for multiple buddies to pool supper funds together.I have been increasing the gas to deploy this contract for a while now. It seems to get hungrier as the day passes. As I improve this, I will attempt to use web3.eth.estimateGas() but this will do for now.

var godutch = artifacts.require("./godutch.sol");
module.exports = function(deployer) {
  deployer.deploy(godutch, ['Jack', 'Mark'], {gas: 1000000});
};

Then I compile my godutch contract.

sudo truffle compile

Finally I deploy it.

sudo truffle migrate

It's time to execute the contract. I will start up the truffle console to do this.

sudo truffle console

Executing the Smart Contract

Solidity does not support decimals. So we can't quite contribute, say $2.50. Our contributions will be whole numbers and $2.50 will be represented as 250. 

Mark has started by contributing $0.40 to the pool. He's cheap. 

godutch.deployed().then(function(contractInstance) {contractInstance.contribute('Mark', 40).then(function(v) {console.log(v)})})

And then I contribute $0.30. I am cheaper.

godutch.deployed().then(function(contractInstance) {contractInstance.contribute('Jack', 30).then(function(v) {console.log(v)})})

Let's check if this has been recorded to the block. Yes, it says 70. We now have $0.70 in our pool of supper fund.

godutch.deployed().then(function(contractInstance) {contractInstance.whatIsOurPool().then(function(v) {console.log(v)})})
 
truffle(development)> { [String: '70'] s: 1, e: 1, c: [ 70 ] }

We figured that supper isn't a reality with $0.70 in the funds. So Mark contributed another $1.40 and I contributed $4.30. And then we check how much we now have. $6.40...a good start.

godutch.deployed().then(function(contractInstance) {contractInstance.contribute('Mark', 140).then(function(v) {console.log(v)})})
  
godutch.deployed().then(function(contractInstance) {contractInstance.contribute('Jack', 430).then(function(v) {console.log(v)})})
  
godutch.deployed().then(function(contractInstance) {contractInstance.whatIsOurPool().then(function(v) {console.log(v)})})

truffle(development)> { [String: '640'] s: 1, e: 2, c: [ 640 ] }

And then we spent $2.30 to share a slice of cake. And then we check how much is left in our supper pool. $4.10.

godutch.deployed().then(function(contractInstance) {contractInstance.spend(230).then(function(v) {console.log(v)})})
  
godutch.deployed().then(function(contractInstance) {contractInstance.whatIsOurPool().then(function(v) {console.log(v)})})

truffle(development)> { [String: '410'] s: 1, e: 2, c: [ 410 ] }

Let's check how much I contributed in total. $4.60.

godutch.deployed().then(function(contractInstance) {contractInstance.totalContrib('Jack').then(function(v) {console.log(v)})})

truffle(development)> { [String: '460'] s: 1, e: 2, c: [ 460 ] }

And Mark? $1.80. He better balance this up, that freeloader.

godutch.deployed().then(function(contractInstance) {contractInstance.totalContrib('Mark').then(function(v) {console.log(v)})})

truffle(development)> { [String: '180'] s: 1, e: 2, c: [ 180 ] }

As I am just testing using the truffle console, all that happened above were executed by just a single Ethereum account. In a real-life scenario, Mark would have made his contribution with his Ethereum account, and me, with my Ethereum account. For now, I could show the total contributions made by this single account, and how much contributions it has made on behalf of Mark and Jack. Here, the total contribution of both supper buddies is $6.40, out of which $4.60 came from Jack and $1.80 came from Mark.

godutch.deployed().then(function(contractInstance) {contractInstance.friendDetails('0x4071274E327B5C6381dd68312d67503d0Ab735F8').then(function(v) {console.log(v)})})
  
truffle(development)> [ { [String: '640'] s: 1, e: 2, c: [ 640 ] },
  [ { [String: '460'] s: 1, e: 2, c: [Object] },
    { [String: '180'] s: 1, e: 2, c: [Object] } ] ]

What's Next

The smart contract is done. The next step is to build a truffle web app that will execute these calls via a slick Web UI. Then both Mark and Jack could execute transactions on the contract with their own accounts - but that's the job of another day.

If you are reading this and thinks there's a better way to write this smart contract, please feel free to buzz me. 

Add new comment