I have been working on a dApp where a user can create contests and set attributes of contest like contest start date, end date, no of players, entrance fees etc. There can be N no of contests running parallelly. There will be a third party API call every 5 minutes for each player which would calculate some score of each player.

The contest will automatically end at the defined end date and the winner is decided by the score calculated by third-party API call. Anyone can join the contest. So, we have contests data and players data.

I am not sure of the contract structure for the same. Do I have to keep all the data on the contract, or I can put some data off Blockchain as well like calling third-party API and calling contract on contract end date? And would multiple contests would run on the same contract, or do I need to redeploy the contract for each contest?

Any help would be appreciated. Thanks

2 Answers 2


I don't want to give too many details, as I think with a little bit of effort, you could write it out yourself. Just giving some tips. Others are welcome to pitch in with suggestions, better way to model this etc.

A good way to proceed might be to have a struct called Contest (defined inside a smart contract ContestHost), which has the intrinsic properties associated with a contract (name, description, entryFee, startblock, endblock, array of contestants, current staked ether, isActive, etc). Since there is no built in concept of dates etc, you can think of substituting it with a startBlock and targetBlock concept. Look at the below AuctionHouse sample to understand this better.

This struct Contest would be used by a contract (say ContestHost) which has an array of Contests and a mapping between Contest and some particular property (to make it efficient to access each contest).

This contract should have a function to start a contest (returns a unique uint id), one to join a contest by sending ether and address, and maintain a total stakes for each contest.

Finally, you can look at these links to get a better idea.

Auction House: https://github.com/dob/auctionhouse/blob/master/contracts/AuctionHouse.sol

SCHEDULING OF TRANSACTIONS FOR DELAYED EXECUTION IN THE FUTURE: This could help execute "ContestClose" transaction at targetBlock. https://www.ethereum-alarm-clock.com/

Random Number Generation (some say it is slow, but it is guaranteed to be random): https://github.com/randao/randao

Withdrawal pattern for safe payout: https://solidity.readthedocs.io/en/v0.4.24/common-patterns.html#withdrawal-from-contracts

UPDATE: Also, you have mentioned that there might be a off-chain third-party API function that you need to call every 5 minutes, to update the status of each player. You should consider using a side-chain to host your entire smart contract (such as Matic Network, which is a Proof-Of-Stake side chain which is 100% compatible with the Ethereum mainnet and just requires ONE line of change for the deployed network provider).

The costs can come down significantly (100 times around) so this can make it very economical, and once ETH2.0 becomes fully functional (or considering that a Cardano side-chain for solidity code might come up very shortly), you can then move it onto the relevant mainnet.

  • Thanks for the Help Bharat. It makes sense to me what you have suggested but I still have a doubt that how this contract will hold money, as there will be separate money pool for every contest. Jul 24, 2018 at 12:12
  • Welcome... If you found my answer useful, please do upvote it. It all depends on your need-based design. If you are ok with holding the aggregate pool of money and defining tight functions only through which said money can be paid out, then above approach is fine. If you indeed want to have explicit pool of money per contest, then you could adopt the approach of deploying a smart contract PER contest and that way you could ensure that money of each contract is safely within the contract. If the ContestHouse contract is clearly defined, there should be no problem in either approach. Jul 24, 2018 at 14:15
  • Okay. I am moving with deploying a smart contract per contest. And it's architecture is comparatively easy to define. Now, my concern is should I write all the logic on the contract i.e executing the contract on its end date and calling a third party API every 5-minute or I should do these on Node API? Basically, for each player, we have to calculate some data from third-party API, and I think calling third party API from the contract would cost high, Please suggest. Jul 26, 2018 at 4:18
  • Not sure what you mean by calling a third party api every 5 minutes... What is it you're trying to achieve? Could you elaborate in your original post, so that it reflects this requirement better? Jul 26, 2018 at 4:21
  • Sure, Bharat. Updated Jul 26, 2018 at 4:52

You have to think why you want to use blockchain for this. For educational purposes? For fun? Because you can? Or is there some concrete reason like "I want this to be fully decentralized and immutable"?

The app would be easier and cheaper to make outside blockchain. So if you're asking which parts you should write & code in normal database and outside blockchain, then my answer is "all of it".

But if you want to do it inside the blockchain then I suggest you go all in. Write all the logic and data storage inside the contract(s). It won't be very cheap (in terms of gas usage)but it's doable.

I'd also suggest not deploying new contracts for each new contests as that'd be an overkill. Just write a contract which contains all the logic and data structure - that way creating a new contest won't be so expensive.

  • Thanks for sharing your thoughts. I want to create a dApp because I need to automatic transfer of winning amount to the winner by keeping some amount of money as commision. And as per your suggestion if I put all the login in contract, how would contract closes one contest on its end time by keeping other contests running? Jul 20, 2018 at 6:01
  • You can just keep a boolean flag inside the contest structure such as isRunning and once it's set to false the contest is no longer active. Jul 20, 2018 at 6:10
  • One way to really optimize your "per-contest contract" deployment costs could be to use the proxy pattern where you deploy just one "logic" contract and then all the per-contest contracts delegate calls to this logic contract so that they only store the data aspects and the implementation logic is outsourced to the single logic contract. A little complex but doable and will save a hell of a lot of gas and code storage. Here's a link to an excellent article on how to do exactly this using the proxy pattern.blog.gnosis.pm/solidity-delegateproxy-contracts-e09957d0f201 Dec 16, 2020 at 9:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.