Transaction #197

Hash baf8c2f4d977d0346869ac5dbf8501f521de298195b8236fb3ab911cfcd2e001
Status Success
Timestamp 1336 days ago - 9/21/2020, 7:49:15 PM UTC+0
Block 197
Stamps Used 412
Burned Fee 0.04120000 TAU
From 89dab819180ed3d1cd0ea04ff0cd33b87b90e99d5abea6321afe9e6835db7f9f 
Contract Name submission
Function Name submit_contract

Additional Info
SubBlock Number 1
Nonce 0
Processor a2ce0217d08e0cf5718d36fc3b7b59d7bb5e4c6e3140a04e02da1d28a6fea56f
Signature 8e54b2546578a1b3a8f80ffff35723983c59649471107a08a788d45502afc7fdac410b11c86257eb1f5060ac46194e2a2f03f801cfc742362da04e6df25f2c06
Stamps Supplied 1000
Stamps per TAU 100

Kwargs

code import currency owner = Variable() distributionAmount = Variable() games = Hash() gameNames = Hash() @construct def seed(initial_owner: str): owner.set(initial_owner) distributionAmount.set(0) @export def transfer_ownership(newOwner: str): assert owner.get() == ctx.caller, 'transfer_ownership can only be executed by the contract owner' owner.set(newOwner) @export def addGame(gameId: str, playercount: int, amount: int): assert owner.get() == ctx.caller, 'addGame can only be executed by the contract owner' assert games[gameId, 'amount'] is None, 'Game with ID ' + gameId + ' already exists' assert playercount > 0, 'playercount must be > 0' assert amount > 0, 'amount must be > 0' games[gameId, 'playercount'] = playercount games[gameId, 'players'] = [] games[gameId, 'amount'] = amount games[gameId, 'markedForRemoval'] = False games[gameId, 'round'] = 1 games[gameId, 'locked'] = False if gameNames['names'] is not None: names = gameNames['names'] names.append(gameId) gameNames['names'] = names else: gameNames['names'] = [gameId] @export def withdraw(gameId: str): sender = ctx.caller players = games[gameId, 'players'] if players is not None and sender in players: filteredList = list(filter(lambda p: p != sender, players)) games[gameId, 'players'] = filteredList currency.transfer( amount=games[gameId, 'amount'] * (len(players)-len(filteredList)) * 0.9999, to=sender ) @export def markGameForRemoval(gameId: str): assert owner.get() == ctx.caller, 'markGameForRemoval can only be executed by the contract owner' games[gameId, 'markedForRemoval'] = True @export def removeGame(gameId: str): assert owner.get() == ctx.caller, 'removeGame can only be executed by the contract owner' assert games[gameId, 'playercount'] is not None, 'Game with ID ' + gameId + ' does not exist' assert games[gameId, 'markedForRemoval'] == True, 'game with ID ' + gameId + ' is not marked for removal, please call markForRemoval first' assert games[gameId, 'locked'] == True, 'game with ID ' + gameId + ' is not yet locked, please wait until current jackpot is distributed' assert len(games[gameId, 'players']) == 0, 'game with ID ' + gameId + ' cannot be removed, because there are still players subscribed!' games[gameId, 'playercount'] = None games[gameId, 'amount'] = None games[gameId, 'markedForRemoval'] = None games[gameId, 'players'] = None games[gameId, 'winner'] = None games[gameId, 'round'] = None games[gameId, 'locked'] = None names = gameNames['names'] names.remove(gameId) gameNames['names'] = names @export def withdrawFees(receiver: str): assert owner.get() == ctx.caller, 'withdrawFees can only be executed by the contract owner' # Balance of the contract - summed amounts of all gameIds - base amount (to stay at the contract) BASE_AMOUNT = 20 totalSum = 0 if gameNames['names'] is not None: names = gameNames['names'] for name in names: players = games[name, 'players'] amount = games[name, 'amount'] totalSum += (len(players) * amount) # IMMER 20 TAU auf dem Contract belassen availableToWithdraw = currency.get_balance(ctx.this) - (totalSum + BASE_AMOUNT) assert availableToWithdraw > 0, 'Not enough funds for fee withdrawal. Available Fees ' + \ availableToWithdraw currency.transfer( amount=availableToWithdraw, to=receiver ) else: # No game available --> payout all up to the base amount (20) availableToWithdraw = currency.get_balance(ctx.this) - BASE_AMOUNT assert availableToWithdraw > 0, 'Not enough funds for fee withdrawal. Available Fees ' + \ availableToWithdraw currency.transfer( amount=availableToWithdraw, to=receiver ) @export def joinGame(gameId: str, amount: int): random.seed() assert games[gameId, 'playercount'] is not None, 'Game with ID ' + gameId + ' does not exist' assert games[gameId, 'locked'] == False, 'Game with ID ' + gameId + ' is locked' assert games[gameId, 'amount'] == amount, 'For joining this game, you need to send exactly ' + str(games[gameId, 'amount']) + ' TAU' # ctx.caller is the verified identity of the person who signed this transaction # we will keep this reference as the "sender" of the transaction sender = ctx.caller # Pay the smart contract currency.transfer_from( amount=amount, to=ctx.this, main_account=sender) players = games[gameId, 'players'] players.append(sender) # Every player shuffles the list, this makes predictions for attackers much more heavy # Because they cannot predict the block numbers of the other players random.shuffle(players) games[gameId, 'players'] = players if len(games[gameId, 'players']) >= games[gameId, 'playercount']: playerList = games[gameId, 'players'] random.shuffle(playerList) randomInt = random.randint(0, len(playerList) - 1) winner = playerList[randomInt] winnerAmount = games[gameId, 'playercount'] * games[gameId, 'amount'] * 0.998 currency.transfer( amount=winnerAmount, to=winner ) games[gameId, 'players'] = [] games[gameId, 'round'] += 1 games[gameId, 'winner'] = winner distributionAmount.set(distributionAmount.get() + winnerAmount) if games[gameId, 'markedForRemoval'] == True: games[gameId, 'locked'] = True return "finished"
constructor_args {"initial_owner":"89dab819180ed3d1cd0ea04ff0cd33b87b90e99d5abea6321afe9e6835db7f9f"}
name con_hopium

State Changes

Contract con_hopium
Variable owner
New Value 89dab819180ed3d1cd0ea04ff0cd33b87b90e99d5abea6321afe9e6835db7f9f
 
Contract con_hopium
Variable distributionAmount
New Value 0
 
Contract con_hopium
Variable __code__
New Value import currency __owner = Variable(contract='con_hopium', name='owner') __distributionAmount = Variable(contract='con_hopium', name= 'distributionAmount') __games = Hash(contract='con_hopium', name='games') __gameNames = Hash(contract='con_hopium', name='gameNames') def ____(initial_owner: str): __owner.set(initial_owner) __distributionAmount.set(0) @__export('con_hopium') def transfer_ownership(newOwner: str): assert __owner.get( ) == ctx.caller, 'transfer_ownership can only be executed by the contract owner' __owner.set(newOwner) @__export('con_hopium') def addGame(gameId: str, playercount: int, amount: int): assert __owner.get( ) == ctx.caller, 'addGame can only be executed by the contract owner' assert __games[gameId, 'amount' ] is None, 'Game with ID ' + gameId + ' already exists' assert playercount > 0, 'playercount must be > 0' assert amount > 0, 'amount must be > 0' __games[gameId, 'playercount'] = playercount __games[gameId, 'players'] = [] __games[gameId, 'amount'] = amount __games[gameId, 'markedForRemoval'] = False __games[gameId, 'round'] = 1 __games[gameId, 'locked'] = False if __gameNames['names'] is not None: names = __gameNames['names'] names.append(gameId) __gameNames['names'] = names else: __gameNames['names'] = [gameId] @__export('con_hopium') def withdraw(gameId: str): sender = ctx.caller players = __games[gameId, 'players'] if players is not None and sender in players: filteredList = list(filter(lambda p: p != sender, players)) __games[gameId, 'players'] = filteredList currency.transfer(amount=__games[gameId, 'amount'] * (len(players) - len(filteredList)) * decimal('0.9999'), to=sender) @__export('con_hopium') def markGameForRemoval(gameId: str): assert __owner.get( ) == ctx.caller, 'markGameForRemoval can only be executed by the contract owner' __games[gameId, 'markedForRemoval'] = True @__export('con_hopium') def removeGame(gameId: str): assert __owner.get( ) == ctx.caller, 'removeGame can only be executed by the contract owner' assert __games[gameId, 'playercount' ] is not None, 'Game with ID ' + gameId + ' does not exist' assert __games[gameId, 'markedForRemoval' ] == True, 'game with ID ' + gameId + ' is not marked for removal, please call markForRemoval first' assert __games[gameId, 'locked' ] == True, 'game with ID ' + gameId + ' is not yet locked, please wait until current jackpot is distributed' assert len(__games[gameId, 'players'] ) == 0, 'game with ID ' + gameId + ' cannot be removed, because there are still players subscribed!' __games[gameId, 'playercount'] = None __games[gameId, 'amount'] = None __games[gameId, 'markedForRemoval'] = None __games[gameId, 'players'] = None __games[gameId, 'winner'] = None __games[gameId, 'round'] = None __games[gameId, 'locked'] = None names = __gameNames['names'] names.remove(gameId) __gameNames['names'] = names @__export('con_hopium') def withdrawFees(receiver: str): assert __owner.get( ) == ctx.caller, 'withdrawFees can only be executed by the contract owner' BASE_AMOUNT = 20 totalSum = 0 if __gameNames['names'] is not None: names = __gameNames['names'] for name in names: players = __games[name, 'players'] amount = __games[name, 'amount'] totalSum += len(players) * amount availableToWithdraw = currency.get_balance(ctx.this) - (totalSum + BASE_AMOUNT) assert availableToWithdraw > 0, 'Not enough funds for fee withdrawal. Available Fees ' + availableToWithdraw currency.transfer(amount=availableToWithdraw, to=receiver) else: availableToWithdraw = currency.get_balance(ctx.this) - BASE_AMOUNT assert availableToWithdraw > 0, 'Not enough funds for fee withdrawal. Available Fees ' + availableToWithdraw currency.transfer(amount=availableToWithdraw, to=receiver) @__export('con_hopium') def joinGame(gameId: str, amount: int): random.seed() assert __games[gameId, 'playercount' ] is not None, 'Game with ID ' + gameId + ' does not exist' assert __games[gameId, 'locked' ] == False, 'Game with ID ' + gameId + ' is locked' assert __games[gameId, 'amount' ] == amount, 'For joining this game, you need to send exactly ' + str( __games[gameId, 'amount']) + ' TAU' sender = ctx.caller currency.transfer_from(amount=amount, to=ctx.this, main_account=sender) players = __games[gameId, 'players'] players.append(sender) random.shuffle(players) __games[gameId, 'players'] = players if len(__games[gameId, 'players']) >= __games[gameId, 'playercount']: playerList = __games[gameId, 'players'] random.shuffle(playerList) randomInt = random.randint(0, len(playerList) - 1) winner = playerList[randomInt] winnerAmount = __games[gameId, 'playercount'] * __games[gameId, 'amount'] * decimal('0.998') currency.transfer(amount=winnerAmount, to=winner) __games[gameId, 'players'] = [] __games[gameId, 'round'] += 1 __games[gameId, 'winner'] = winner __distributionAmount.set(__distributionAmount.get() + winnerAmount) if __games[gameId, 'markedForRemoval'] == True: __games[gameId, 'locked'] = True return 'finished'
 
Contract con_hopium
Variable __compiled__
New Value e3000000000000000000000000050000004000000073ea000000640064016c005a0065016402640364048d025a0265016402640564048d025a0365046402640664048d025a0565046402640764048d025a06650764089c016409640a84045a086509640283016507640b9c01640c640d840483015a0a6509640283016507650b650b640e9c03640f6410840483015a0c650964028301650764119c0164126413840483015a0d650964028301650764119c0164146415840483015a0e650964028301650764119c0164166417840483015a0f650964028301650764189c016419641a840483015a106509640283016507650b641b9c02641c641d840483015a1164015300291ee9000000004eda0a636f6e5f686f7069756dda056f776e65722902da08636f6e7472616374da046e616d65da12646973747269627574696f6e416d6f756e74da0567616d6573da0967616d654e616d65732901da0d696e697469616c5f6f776e6572630100000000000000010000000200000043000000731800000074006a017c008301010074026a016401830101006400530029024e72010000002903da075f5f6f776e6572da03736574da145f5f646973747269627574696f6e416d6f756e7429017209000000a900720d000000da00da045f5f5f5f09000000730400000000010a01720f0000002901da086e65774f776e6572630100000000000000010000000200000043000000732400000074006a01830074026a036b027316740464018301820174006a057c00830101006400530029024e7a3d7472616e736665725f6f776e6572736869702063616e206f6e6c792062652065786563757465642062792074686520636f6e7472616374206f776e65722906720a000000da03676574da03637478da0663616c6c6572da0e417373657274696f6e4572726f72720b00000029017210000000720d000000720d000000720e000000da127472616e736665725f6f776e6572736869700e000000730600000000020601100172150000002903da0667616d654964da0b706c61796572636f756e74da06616d6f756e7463030000000000000004000000040000004300000073d400000074006a01830074026a036b027316740464018301820174057c0064026602190064006b087336740464037c00170064041700830182017c0164056b04734674046406830182017c0264056b04735674046407830182017c0174057c00640866023c00670074057c00640966023c007c0274057c00640266023c00640a74057c00640b66023c00640c74057c00640d66023c00640a74057c00640e66023c007406640f190064006b0972c67406640f19007d037c036a077c00830101007c037406640f3c006e0a7c0067017406640f3c006400530029104e7a3261646447616d652063616e206f6e6c792062652065786563757465642062792074686520636f6e7472616374206f776e657272180000007a0d47616d652077697468204944207a0f20616c72656164792065786973747372010000007a17706c61796572636f756e74206d757374206265203e20307a12616d6f756e74206d757374206265203e20307217000000da07706c617965727346da106d61726b6564466f7252656d6f76616ce901000000da05726f756e64da066c6f636b6564da056e616d65732908720a0000007211000000721200000072130000007214000000da075f5f67616d6573da0b5f5f67616d654e616d6573da06617070656e642904721600000072170000007218000000721e000000720d000000720d000000720e000000da0761646447616d651500000073220000000002060110010a011601100110010c010c010c010c010c010c010c0108010a010a02722200000029017216000000630100000000000000030000000500000003000000737600000074006a01890074027c006401660219007d017c0164006b09727288007c016b06727274037404870066016402640384087c01830283017d027c0274027c00640166023c0074056a0674027c0064046602190074077c01830174077c028301180014007408640583011400880064068d0201006400530029074e721900000063010000000000000001000000020000001300000073080000007c0088006b03530029014e720d0000002901da01702901da0673656e646572720d000000720e000000da083c6c616d6264613e3000000073000000007a1a77697468647261772e3c6c6f63616c733e2e3c6c616d6264613e72180000007a06302e3939393929027218000000da02746f290972120000007213000000721f000000da046c697374da0666696c746572da0863757272656e6379da087472616e73666572da036c656eda07646563696d616c290372160000007219000000da0c66696c74657265644c697374720d00000029017224000000720e000000da0877697468647261772b000000730e000000000206010c01100116010c010401722e000000630100000000000000010000000400000043000000732600000074006a01830074026a036b0273167404640183018201640274057c00640366023c006400530029044e7a3d6d61726b47616d65466f7252656d6f76616c2063616e206f6e6c792062652065786563757465642062792074686520636f6e7472616374206f776e657254721a0000002906720a0000007211000000721200000072130000007214000000721f00000029017216000000720d000000720d000000720e000000da126d61726b47616d65466f7252656d6f76616c360000007306000000000206011001722f000000630100000000000000020000000400000043000000730c01000074006a01830074026a036b027316740464018301820174057c0064026602190064006b097336740464037c001700640417008301820174057c0064056602190064066b027356740464077c001700640817008301820174057c0064096602190064066b027376740464077c001700640a170083018201740674057c00640b660219008301640c6b02739a740464077c001700640d170083018201640074057c00640266023c00640074057c00640e66023c00640074057c00640566023c00640074057c00640b66023c00640074057c00640f66023c00640074057c00641066023c00640074057c00640966023c007407641119007d017c016a087c00830101007c01740764113c006400530029124e7a3572656d6f766547616d652063616e206f6e6c792062652065786563757465642062792074686520636f6e7472616374206f776e657272170000007a0d47616d652077697468204944207a0f20646f6573206e6f74206578697374721a000000547a0d67616d652077697468204944207a3c206973206e6f74206d61726b656420666f722072656d6f76616c2c20706c656173652063616c6c206d61726b466f7252656d6f76616c206669727374721d0000007a44206973206e6f7420796574206c6f636b65642c20706c65617365207761697420756e74696c2063757272656e74206a61636b706f74206973206469737472696275746564721900000072010000007a3f2063616e6e6f742062652072656d6f7665642c206265636175736520746865726520617265207374696c6c20706c61796572732073756273637269626564217218000000da0677696e6e6572721c000000721e0000002909720a0000007211000000721200000072130000007214000000721f000000722b0000007220000000da0672656d6f766529027216000000721e000000720d000000720d000000720e000000da0a72656d6f766547616d653d00000073280000000002060110010a0116010a0116010a0116010e0116010c010c010c010c010c010c010c0108010a0172320000002901da08726563656976657263010000000000000008000000040000004300000073d600000074006a01830074026a036b027316740464018301820164027d0164037d0274056404190064006b0972a07405640419007d0378347c0344005d2c7d0474067c046405660219007d0574067c046406660219007d067c0274077c0583017c06140037007d027138570074086a0974026a0a83017c027c01170018007d077c0764036b047390740464077c0717008301820174086a0b7c077c0064088d0201006e3274086a0974026a0a83017c0118007d077c0764036b0473c4740464077c0717008301820174086a0b7c077c0064088d0201006400530029094e7a377769746864726177466565732063616e206f6e6c792062652065786563757465642062792074686520636f6e7472616374206f776e6572e9140000007201000000721e000000721900000072180000007a344e6f7420656e6f7567682066756e647320666f7220666565207769746864726177616c2e20417661696c61626c65204665657320290272180000007226000000290c720a00000072110000007212000000721300000072140000007220000000721f000000722b0000007229000000da0b6765745f62616c616e6365da0474686973722a00000029087233000000da0b424153455f414d4f554e54da08746f74616c53756d721e000000720500000072190000007218000000da13617661696c61626c65546f5769746864726177720d000000720d000000720e000000da0c776974686472617746656573550000007322000000000206011001040104010c0108010a010c010c0114010c0108011401100210011401723a000000290272160000007218000000630200000000000000080000000600000043000000739a01000074006a018300010074027c0064016602190064006b097328740364027c001700640317008301820174027c0064046602190064056b027348740364027c001700640617008301820174027c006407660219007c016b02737474036408740474027c0064076602190083011700640917008301820174056a067d0274076a087c0174056a097c02640a8d03010074027c00640b660219007d037c036a0a7c028301010074006a0b7c03830101007c0374027c00640b66023c00740c74027c00640b66021900830174027c006401660219006b059001729674027c00640b660219007d0474006a0b7c048301010074006a0d640c740c7c048301640d180083027d057c047c0519007d0674027c0064016602190074027c006407660219001400740e640e830114007d0774076a0f7c077c06640f8d020100670074027c00640b66023c0074027c006410660205001900640d370003003c007c0674027c00641166023c0074106a1174106a1283007c0717008301010074027c0064126602190064136b0290017292641374027c00640466023c00641453006400530029154e72170000007a0d47616d652077697468204944207a0f20646f6573206e6f74206578697374721d000000467a0a206973206c6f636b656472180000007a30466f72206a6f696e696e6720746869732067616d652c20796f75206e65656420746f2073656e642065786163746c79207a0420544155290372180000007226000000da0c6d61696e5f6163636f756e7472190000007201000000721b0000007a05302e393938290272180000007226000000721c0000007230000000721a00000054da0866696e69736865642913da0672616e646f6dda0473656564721f0000007214000000da03737472721200000072130000007229000000da0d7472616e736665725f66726f6d72360000007221000000da0773687566666c65722b000000da0772616e64696e74722c000000722a000000720c000000720b000000721100000029087216000000721800000072240000007219000000da0a706c617965724c697374da0972616e646f6d496e747230000000da0c77696e6e6572416d6f756e74720d000000720d000000720e000000da086a6f696e47616d656b0000007338000000000208010a0116010a0116010a0108011a01060112010c010a010a010c011e010c010a011401080220010e010c0114010c01120112010c01724600000029127229000000da085661726961626c65720a000000720c000000da0448617368721f0000007220000000723f000000720f000000da085f5f6578706f72747215000000da03696e747222000000722e000000722f0000007232000000723a0000007246000000720d000000720d000000720d000000720e000000da083c6d6f64756c653e01000000732800000008010c01040108010c010c030e0506011006060114150601100a0601100606011017060110150601
 
Contract con_hopium
Variable __owner__
New Value null
 
Contract con_hopium
Variable __submitted__
New Value 2020,9,21,19,49,16,0
 
Contract currency
Variable balances
Key 89dab819180ed3d1cd0ea04ff0cd33b87b90e99d5abea6321afe9e6835db7f9f
New Value 979.400000000000000000