Users can submit solutions using the submitSolution(_x1: uint256, _x2: uint256) method. The contract checks the submitted values against the problems constraints and saves/rejects them depending on whether the solution respects all of them. When the end of the competition is reached, the address that submitted the best solution can call claimBounty() to claim the Ether that is locked in the contract.
Implementation in Vyper
linear_optimization_problem_bounty.vy
# Author: Sören Steiger, twitter.com/ssteiger_# License: MIT# EVENTS:NewSolutionFound:event({_addressOfWinner: indexed(address), _solution: uint256})BountyTransferred:event({_to: indexed(address), _amount: wei_value})BountyIncreased:event({_amount: wei_value})CompetitionTimeExtended:event({_to: uint256})# STATE VARIABLES:owner:public(address)x1:public(uint256)x2:public(uint256)bestSolution:public(uint256)addressOfWinner:public(address)durationInBlocks:public(uint256)competitionEnd:public(uint256)claimPeriodeLength:public(uint256)# METHODS:@publicdef__init__(_durationInBlocks: uint256): self.owner = msg.sender self.bestSolution =0 self.durationInBlocks = _durationInBlocks self.competitionEnd = block.number + _durationInBlocks self.addressOfWinner = ZERO_ADDRESS# set claim periode to three days# assuming an average blocktime of 14 seconds -> 86400/14 self.claimPeriodeLength =6172@public@payabledef__default__():# return any funds sent to the contract address directlysend(msg.sender, msg.value)@privatedef_calculateNewSolution(_x1: uint256,_x2: uint256) -> uint256:# check new parameters against constraintsassert _x1 <=8assert _x2 <=12assert (3* _x1) + (2* _x2) <=100assert _x1 + _x2 <=24assert _x1 >0and _x2 >0# calculate and return new solutionreturn (3* _x1) + (2* _x2)@publicdefsubmitSolution(_x1: uint256,_x2: uint256) -> uint256: newSolution: uint256 newSolution = self._calculateNewSolution(_x1, _x2)assert newSolution > self.bestSolution# save the solution and it's values self.x1 = _x1 self.x2 = _x2 self.bestSolution = newSolution self.addressOfWinner = msg.sender log.NewSolutionFound(msg.sender, newSolution)return newSolution@publicdefclaimBounty():assert block.number > self.competitionEndif (self.addressOfWinner == ZERO_ADDRESS):# no solution was found -> extend duration of competition self.competitionEnd = block.number + self.durationInBlockselse:assert block.number < (self.competitionEnd + self.claimPeriodeLength)assert msg.sender == self.addressOfWinnersend(self.addressOfWinner, self.balance)# extend duration of competition self.competitionEnd = block.number + self.durationInBlocks log.BountyTransferred(self.addressOfWinner, self.balance)@public@payabledeftopUpBounty(): log.BountyIncreased(msg.value)@publicdefextendCompetition():# only if no valid solution has been submittedassert self.addressOfWinner == ZERO_ADDRESSassert block.number > (self.competitionEnd + self.claimPeriodeLength)# extend duration of competition self.competitionEnd = block.number + self.durationInBlocks# reset winner address self.addressOfWinner = ZERO_ADDRESS log.CompetitionTimeExtended(self.competitionEnd)