def Main(operation, args): """ :Entry point of Core_NA SmartContract: """ trigger = GetTrigger() if trigger == Verification(): # check if the invoker is the owner of this contract is_owner = CheckWitness(ROOT_ADMIN) # If owner, proceed if is_owner: return True return False elif trigger == Application(): if operation == 'init': initialized = storage_load("Core_NASC_initialized") if not initialized: return init() root_na = storage_load("root_NA") if root_na: return DynamicAppCall(root_na, operation, args) else: Notify("DynamicAppCall failed.") return False
def getTotalStaked(): """ Gets the total amount of tokens that are currently staked in the contract. :return: (int) Current amount of staked tokens """ tokenContract = getStakingContract() contractAddress = GetExecutingScriptHash() args = [contractAddress] balance = DynamicAppCall(tokenContract, 'balanceOf', args) return balance
def delegate_verify(context, wallet, args): name = args[0] provider = Get(context, name) if not provider: Notify(UNEXISTING_PROVIDER) return False Notify(['[DELEGATE-VERIFY] caller:', wallet, 'provider', provider]) result = DynamicAppCall(provider, 'verifyClaim', [wallet]) if not result: Notify('[DELEGATE-VERIFY] access denied') return False return True
def completeStake(args): """ Complete the stake specified by `stakeID` If the staking period is complete, this returns the staked tokens to the user, and dispatches a `complete` event Note that since this method can return tokens ONLY back to the address that originally staked the tokens, it can be called by anyone. :param args (list): a list with the first item being the address in question and the second being the stakeID :return: (bool): success """ stakes = getStakesForAddr(args[0]) stakeID = args[1] stake = stakes[stakeID] if not stake: raise Exception("Could not find stake") addr = stake['addr'] amount = stake['amount'] now = GetTime() if stake['endTime'] > now: raise Exception("Not eligible to unstake yet") if stake['complete']: raise Exception("Stake already completed") # transfer back to user args = [GetExecutingScriptHash(), addr, amount] transferOfTokens = DynamicAppCall(getStakingContract(), 'transfer', args) if transferOfTokens: stake['completed'] = True stakes[stakeID] = stake addrStakeKey = concat(STAKE_ADDR_KEY, addr) Put(ctx, addrStakeKey, Serialize(stakes)) OnStakeComplete(stakeID, addr) return True return False
def Main(test, args): if test == 1: # test_invalid_array_index" x = args[1] elif test == 2: # test_negative_array_indexing x = args[-1] elif test == 3: # test_invalid_type_indexing x = test[1] elif test == 4: # test_invalid_appcall invalid_contract = b'\x0bA\xfe\xecy\x9e\x12\x8fi\xa2.\xf8\x92T7X@\x93\x9f\xd0' DynamicAppCall(invalid_contract, [])
def sc_call(alias_info, operation, args): """ :param alias_info: :param operation: \n:param args []: \n:returns True if success or False if failed: \ntryes to resolve alias_info and pass call to resolved smartcontract \nin case of sub_nas support alias_info is array [alias, sub_nas] """ two = 2 # this is interesting, contract fails if [acc_alias, 4] query_args = [alias_info, two] sc = na_call("na_query", query_args) if sc: return DynamicAppCall(sc, operation, args) else: Notify( "SC call failed. Possible reasons: no exists or expired, not in provided NA." ) return False
def transfer_to_smart_contract(ctx, t_from, args, is_mint): """Transfers a token to a smart contract and triggers the receiving contract's onNFTTransfer event. :param StorageContext ctx: current store context :param byte[] t_from: transfer from address (who is sending the NFT) :param list args: 0: byte[] t_to: transfer to address (who is receiving the NFT) 1: bytes t_id: token id 2: extra_arg (optional) :param bool is_mint: whether or not the token is being minted :return: transfer success :rtype: bool """ t_to = args[0] t_id = args[1] if len(t_from) != 20 or len(t_to) != 20: Notify(INVALID_ADDRESS_ERROR) return False # invoke the onNFTTransfer operation of the recipient contract, # if it returns False, then reject the transfer success = DynamicAppCall(t_to, 'onNFTTransfer', args) if success is False: Notify('transfer rejected by recipient contract') return False # need to check funds again in case a transfer or approval # change happened inside the onTokenTransfer call # the `is_mint` check is needed because you can't get the token # owner for a token that hasn't finished being minted yet if is_mint is False: t_owner = Get(ctx, t_id) if t_owner != t_from: Notify('insufficient funds') return False Log('transfer accepted by recipient contract') return True
def Main(operation, args): # The trigger determines whether this smart contract is being # run in 'verification' mode or 'application' trigger = GetTrigger() if trigger == Verification(): return False # 'Application' mode elif trigger == Application(): """ TODO: Description & HOWTO Example: sc build_run cc-workshop-game/master.py True True True 0710 05 Register [b'cf4741b5ef169d7170bfe725c5d36e7e177185e3'] sc build_run cc-workshop-game/master.py True True True 0710 05 Player [b'cf4741b5ef169d7170bfe725c5d36e7e177185e3'] sc build_run cc-workshop-game/master.py True True True 0710 05 Battle [b'cf4741b5ef169d7170bfe725c5d36e7e177185e3', b'7311e3cd33bbbec5b8fc6a146580c9121e849cf8'] """ if operation == 'CleanUp': # Input data - contract hash Delete(ctx, "Players") return True elif operation == 'Register': # Input data - contract hash without leading "0x" put_serialized(ctx, 'Players', args[0]) return True elif operation == 'Battle': player_1 = args[0] player_2 = args[1] competition = args[2] competition_step = args[3] players_list = get_serialized(ctx, "Players") if player_1 == player_2: print("Error: Suiside is not accepted.") return False if not is_in_list(players_list, player_1): print("Error: Player 1 is not registred.") return False if not is_in_list(players_list, player_2): print("Error: Player 2 is not registred.") return False # Start Battle players = concat(player_1, player_2) battle_data = concat(get_height_hash(),players) battle_id = hash160(battle_data) # Set Users data started_data_p1 = { 'hp': 10, 'repair_drone': 1, 'missile': 1 } started_data_p2 = { 'hp': 10, 'repair_drone': 1, 'missile': 1 } players_data = { player_1: started_data_p1, player_2: started_data_p2 } battle_round = 1 # Start BATTLE (15 rounds) params = [] name_player_1 = DynamicAppCall(byte_swap(player_1), 'Name', params) name_player_2 = DynamicAppCall(byte_swap(player_2), 'Name', params) player1_name_struct = {'hash': player_1, 'name': name_player_1} player2_name_struct = {'hash': player_2, 'name': name_player_2} OnBattlePlayers(player1_name_struct, player2_name_struct) while ( players_data[player_1]['hp'] > 0 and players_data[player_2]['hp'] > 0 and battle_round < 16 ): serialized_players_data = Serialize(players_data) params = [ battle_id, battle_round, serialized_players_data ] battle_round += 1 serialized_action_player_1 = DynamicAppCall(byte_swap(player_1), 'OnBattle', params) serialized_action_player_2 = DynamicAppCall(byte_swap(player_2), 'OnBattle', params) action_player_1 = Deserialize(serialized_action_player_1) action_player_2 = Deserialize(serialized_action_player_2) # PLAYER 1 players_data = battle_round_actions(players_data, action_player_1, action_player_2, player_1, player_2) # PLAYER 2 players_data = battle_round_actions(players_data, action_player_2, action_player_1, player_2, player_1) round_story = { 'battle_round': battle_round, player_1: action_player_1, player_2: action_player_2 } OnBattleRound(battle_id, battle_round, player_1, player_2, action_player_1, action_player_2, players_data[player_1]['hp'], players_data[player_2]['hp'] ) if players_data[player_1]['hp'] > players_data[player_2]['hp']: winner = player_1 loser = player_2 else: winner = player_2 loser = player_1 params_result = [] onWin = DynamicAppCall(byte_swap(winner), 'OnWin', params_result) onLose = DynamicAppCall(byte_swap(loser), 'OnLose', params_result) OnBattleResult(battle_id, winner, competition, competition_step) return True elif operation == 'Report': return True elif operation == 'Player': params = [ ] players_list = get_serialized(ctx, "Players") if is_in_list(players_list, args[0]): params = [ ] name = DynamicAppCall(byte_swap(args[0]), 'Name', params) print("Player name:") print(name) return name else: print("Error: Need to register") return False return False
def na_call(operation, args): """ :param operation: :param args [ [alias_name, sub_nas],... ]: \nhandles NA service calls """ nargs = len(args) if nargs < 1: msg = "Not enough arguments provided for service call." Notify(msg) return return_value(False, msg) else: sub_nas = False alias = args[0] if not alias: return False if sub_nas: if len(alias) > 1: sub_nas = alias[1] elif len(alias) == 0: Notify("Alias name not provided.") return False alias_name = alias[0] if not alias_name: Notify("Alias name not provided.") return False else: alias_name = alias if not alias_name: return False if sub_nas: target = na_query(sub_nas, 2) script_hash = GetExecutingScriptHash() if target != script_hash: # do not pass in case we are target if target: return DynamicAppCall(target, operation, args) else: msg = concat("Failed to resolve: ", sub_nas) Notify(msg) return return_value(False, msg) args = list_slice(args, 1, nargs) print(operation) if operation == 'na_register': return na_register(alias_name, args) elif operation == 'na_renew': return na_renew(alias_name, args) elif operation == 'na_update_target': return na_update_target(alias_name, args) elif operation == 'na_transfer': return na_transfer(alias_name, args) elif operation == 'na_delete': return na_delete(alias_name, args) elif operation == 'na_query': return na_query(alias_name, args) elif operation == 'na_alias_data': return na_alias_data(alias_name, args) elif operation == 'na_offer_sell': return offer_sell(alias_name, args) elif operation == 'na_cancel_sale_offer': return cancel_sale_offer(alias_name, args) elif operation == 'na_offer_buy': return offer_buy(alias_name, args) elif operation == 'na_cancel_buy_offer': return cancel_buy_offer(alias_name, args)
def Main(hash, operation, a, b): res = DynamicAppCall(hash, operation, a, b) return res
def stakeTokens(args): """ Stakes the given amount of tokens for a user with the given duration This must be called by the owner of the tokens to be staked. :param args (list): a list with the items [address, amountToStake, durationToStake] :return: (bool): success """ addr = args[0] amount = sanitizeAmount(args[1]) duration = args[2] tx = GetScriptContainer() txHash = tx.Hash if not isWhitelisted(addr): raise Exception("Address must be whitelisted") if not CheckWitness(addr): raise Exception("Must be signed by staker addr") if duration < 1 or duration > 24: raise Exception("Invalid duration") rate = calculateRate(duration) stakeId = concat(txHash, addr) if Get(ctx, stakeId) > 0: raise Exception("Already stake for this transaction and address") args = [addr, GetExecutingScriptHash(), amount] transferOfTokens = DynamicAppCall(getStakingContract(), 'transferFrom', args) if transferOfTokens: now = GetTime() end = now + (duration * SECONDS_PER_MONTH) stake = { 'addr': addr, 'stakeId': stakeId, 'rate': rate, 'amount': amount, 'duration': duration, 'startTime': now, 'endTime': end, 'complete': False } addrStakeKey = concat(STAKE_ADDR_KEY, addr) currentStakes = Get(ctx, addrStakeKey) if len(currentStakes) < 1: currentStakes = {} else: currentStakes = Deserialize(currentStakes) currentStakes[stakeId] = stake Put(ctx, stakeId, 1) Put(ctx, addrStakeKey, Serialize(currentStakes)) OnStake(stakeId, addr, amount, rate, now, end) return True raise Exception("Could not transfer tokens to staking contract")