Published in


A SmartContract best practice: Push, Pull, or Give?

In this post, I will talk about the trade off between writing secure smart contract and creating better user experiences. The blog post shows some code but hopefully it’s understandable even if you don’t write any code.

How long does it take for you to withdraw the payout?

The premise of my Dapp BlockParty is that “You will get deposit +more (aka. payout)if you attend”.

To receive the payout, however, you have to call the smart contract function withdraw(). You may be surprised how many people actually don’t take their money back.

The following chart shows how many days it takes for people to withdraw their payout. There have been nearly 100 people participated so far. Though more than half people withdrew within a day after the event was over, more than 10% of people didn’t take within seven days (and there are still people who haven’t taken the payout as I write this post).

The longest time it took to withdraw was 281 days

Why 7 days is important? Because the smart contract has a function called clear() which allows contract owner (me) to take all the left over and the default cooling period is set to 1 week .

You may ask “Why doesn’t the contract just send back to all the participants when the event is over?”.

Pull Over Push

Good question. That was actually my original implementation.

Replace payback to use withdraw” commit

However this had 2 problems so I changed the implementation.

  1. Sending ether back to all the participants could run out of gas.
  2. Sending ether to unknown addresses could lead to security vulnerabilities.

The second point is now best known as “Pull over Push” pattern and advocated by reputable blockchain organisations such as OpenZeppelin and Consensys.

Every Ether transfer implies potential code execution. The receiving address can implement a fallback function that can throw an error. Thus, we should never trust that a send call will execute without error. A solution: our contracts should favor pull over push for payments.

External calls can fail accidentally or deliberately. To minimize the damage caused by such failures, it is often better to isolate each external call into its own transaction that can be initiated by the recipient of the call. This is especially relevant for payments, where it is better to let users withdraw funds rather than push funds to them automatically. (This also reduces the chance of problems with the gas limit.) Avoid combining multiple send() calls in a single transaction.

By following these best practices, I changed payback to simply mark who entitles the payout and introduced withdraw() function which allows participants to take the payout.

However, now I have been getting different messages.

It’s true. Users should not really need to interact with smart contract more than they absolutely have to as people new to Smart contract tend to make mistakes.

So I asked in the exit survey whether users want smart contract to send the money back (with extra admin cost) and here is the response(response rate is about 20%).

I would say the result is a bit mixed. While over 50 % of people are up for the idea (26% yes + 15.8&5.3% yes if cheap), 30% of people rather do it by themselves.

Share or Give?

During Ethereum London November meetup, one of the participants also suggested something interesting.

Instead of sharing the no show deposits among participants, what if we donate? That’s actually a nice idea and I am a big fan of giving to a good cause (in fact my CodeUp asks participants to donate to local charity).

However, I have a bit of concern that donating the no show deposits to charity actually weaken people’s will to turn up because it goes to a good cause rather than random participants. Also, changing the payout distribution logic depending on events may dilute the unique and strong message BlockParty has.

The alternative idea

Then I came up another idea. Rather than changing the payout() logic to share or give, why don’t I change the clear() rule to take the money and send it back to a pre defined address. This can be either the participant’s address or other addresses such as me ( :-) ) or charity address.

This gives the maximum option for people to withdrawby themselves, admins to send the payout back (with fee), or give the money you are too lazy to take back to a good cause, while minimising the change on the smart contract itself.

I am quite excited by the idea but would like to hear everybody’s opinion before I go ahead and implement it. If you liked reading this post, I would appreciate if you can vote the following.





Recommended from Medium

How to Make Money From Cryptocurrency Without Investing, Trading, Mining or Staking

MUDA to launch AfroKingz NFT collection.

Animal Crossing Meets Minecraft’: Branch Raises $12.5M for Play-to-Earn Project

Tezos Blockchain cycle 487 stats

Recharge (RCG) Token Information

Asia’s First Tokenized Security Exchange Readies for Launch

Crypto-Guilds partners with to create level up system for web3 players

Recap of Discussion Activity with Prizes-Day 7

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


More from Medium

ERC721 NFT Standard: Tech overview

Storing and deploying NFT collection in ERC1155 token on Opensea marketplace.

The WNFT App

How to Create Your NFT on Ethereum Blockchain