def update_board_round(board_id): owner_key = get_owner_key(board_id) content_key = get_content_key(board_id) endtime_key = get_endtime_key(board_id) highest_bidder_key = get_highest_bidder_key(board_id) highest_bid_key = get_highest_bid_key(board_id) next_content_key = get_next_content_key(board_id) period = Get(ctx, get_period_key(board_id)) current_timestamp = get_current_timestamp() round_end = current_timestamp + period # update Info Put(ctx, endtime_key, round_end) new_owner = Get(ctx, highest_bidder_key) Put(ctx, owner_key, new_owner) new_content = Get(ctx, next_content_key) Put(ctx, content_key, new_content) Put(ctx, highest_bid_key, 0) print('Update Round Completed') return True
def vote(args): """ Vote for a proposal :param args: list of arguments [PROPOSAL_ID, VOTE] :return: bool, result of the execution """ if len(args) != 2: return False # get proposal from storage proposal_id = args[0] proposal_storage = Get(ctx, proposal_id) # check proposal existence if not proposal_storage: print("Proposal not found") return False # get caller address references = GetScriptContainer().References if len(references) < 1: return False caller_addr = references[0].ScriptHash # check if address already voted if Get(ctx, concat(proposal_id, caller_addr)): print('Already voted') return False # Deserialize proposal array proposal = Deserialize(proposal_storage) # iterate authorized address index = 0 while index < len(proposal[3]): if proposal[3][index] == caller_addr: authorized = True break index += 1 if not authorized: print('Not allowed to vote') return False # increment vote counter if args[1] == 1: print('Yes!') proposal[1] = proposal[1] + 1 else: print('No!') proposal[2] = proposal[2] + 1 # serialize proposal and write to storage proposal_storage = Serialize(proposal) Put(ctx, proposal_id, proposal_storage) # mark address as voted Put(ctx, concat(proposal_id, caller_addr), True) return True
def do_token_data(ctx, t_id): """Returns the specified token's id, properties and uri data as a dict :param StorageContext ctx: current store context :param bytes t_id: token id :return: dictionary of id, property, and uri keys mapped to their corresponding token's data :rtype: dict """ # `token_key` may seem a bit redundant, however I realized that # smart contract developers need an easy way to get an # integer/bytes data type for the token id to make getting/adding # extra data pertaining to a particular token id easier. # Otherwise, they would have to parse the uri or properties key to # get the token id and then convert that to an integer (which I'm # not sure can be done in neo-boa) or do a call to tokensOfOwner # keys # token_key = concat('token/', t_id) prop_key = concat('properties/', t_id) uri_key = concat('uri/', t_id) token_data = { concat('token/', t_id): t_id, prop_key: Get(ctx, prop_key), uri_key: Get(ctx, uri_key) } return token_data
def removeSubaccountAsMaster(executionerPublicKey, domainName, SubaccountHash): if not CheckWitness(executionerPublicKey): return False #check if owner and domains exists if not existDomainAndOwnerWithHash(executionerPublicKey, domainName): return False SubaccountKey = createSubMainKey(domainName, SubaccountHash) if existSubaccount(SubaccountKey): ctx = GetContext() subdomainName = Get(ctx, createSubRootNameKey(SubaccountKey)) if subdomainName is not None: Delete(ctx, createSubNameKey(SubaccountKey, subdomainName)) Delete(ctx, createSubRootNameKey(SubaccountKey)) #get subdomain subdomainName = Get(ctx, createSubRootNameKey(SubaccountKey)) subsKeyValue = concat(subdomainName, ":") subsKeyValue = concat(subsKeyValue, SubaccountHash) #remove from all subs hashesKey = createSubsKey(domainName) removeHashFromHashes(hashesKey, subsKeyValue, ";") Delete(ctx, SubaccountKey) Delete(ctx, createMasterApprovedKey(SubaccountKey)) Delete(ctx, createSubApprovedKey(SubaccountKey)) #remove from all scripthash subdomains tr = concat("s:", domainName) removeDomainFromStorage(SubaccountKey, tr) return True return False
def transfer(t_from, t_to, amount): ctx = GetContext() assert len(t_from) == 20, "Invalid from address" assert len(t_to) == 20, "Invalid to address" if t_from == t_to: Notify("Transferring to self. Nothing changes.") return True from_val = Get(ctx, t_from) if from_val == amount: Delete(ctx, t_from) else: difference = from_val - amount Put(ctx, t_from, difference) if from_val < amount: return False to_value = Get(ctx, t_to) to_total = to_value + amount Put(ctx, t_to, to_total) Notify("Transfer successful.") return True
def buyCat(from_acc, animal, amount): if not CheckWitness(from_acc): Notify("Not the owner, can't buy") return False tmplist = Get(ctx, from_acc + "CAT") if len(tmplist) != 0: delist = Deserialize(tmplist) Notify(delist) delist.append(animal) Notify(delist) Put(ctx, from_acc + "CAT", Serialize(delist)) else: Put(ctx, from_acc + "CAT", Serialize([animal])) Notify(Serialize([animal])) current_balance = Get(ctx, from_acc) if current_balance <= amount: Notify("Insufficient funds") return False to_balance = Get(ctx, TOKEN_OWNER) to_balance += amount Put(ctx, TOKEN_OWNER, to_balance) current_balance -= amount if current_balance != 0: Put(ctx, from_acc, current_balance) else: Delete(ctx, from_acc) OnTransfer(from_acc, TOKEN_OWNER, amount) return True
def pay_in_token(ctx, t_from, t_to, amount): if amount < 0: return False elif amount == 0: return True if len(t_to) != 20 or len(t_from) != 20: return False if t_from == t_to: print("transfer to self!") return True from_balance = Get(ctx, t_from) if from_balance < amount: print("insufficient funds") return False elif from_balance == amount: Delete(ctx, t_from) else: difference = from_balance - amount Put(ctx, t_from, difference) to_balance = Get(ctx, t_to) to_total = to_balance + amount Put(ctx, t_to, to_total) OnTransfer(t_from, t_to, amount) return True
def removePendingTransaction(executionerPublicKey, domainName, idPendingTransaction): if not CheckWitness(executionerPublicKey): return False #if owner or Subaccount and domains exist if not existDomainAndOwnerOrSubaccountWithHash(executionerPublicKey, domainName): return False #check if exist transaction if existPendingTransaction(domainName, idPendingTransaction) is None: return False #create root pending transaction key = createPendingTransactionKey(domainName, idPendingTransaction) ctx = GetContext() transactionAttr = Get(ctx, createAttributesKey(key)) price = Get(ctx, createPriceKey(key)) #recreate unique pending transaction tr = createTransactionHash(idPendingTransaction, transactionAttr, price) Delete(ctx, key) Delete(ctx, createExecutedKey(key)) Delete(ctx, createAttributesKey(key)) Delete(ctx, createPriceKey(key)) #remove from domains/pendingTransactions keyAllPending = createPendingTransactionsKey(domainName) removeHashFromHashes(keyAllPending, tr, "|") return True
def GetUserPublications(args): user = args[0] context = GetContext() publications_key = concat('publications', user) publications = Get(context, publications_key) user_publications = [] if not publications: return [True, user_publications] publications = Deserialize(publications) # Go through each user publication and get details for i in range(0, len(publications)): publication_key = concat(publications_key, sha1(publications[i])) publication = Get(context, publication_key) publication = Deserialize(publication) # Append only if publication is active if publication[5]: user_publications.append(publication) return [True, user_publications]
def check_winner(game_id): context = GetContext() game_key_prefix = concat('game.', game_id) winner_key = concat(game_key_prefix, '.winner') winner = Get(context, winner_key) if winner: return winner answer1_key = concat(game_key_prefix, '.answer1') answer1 = Get(context, answer1_key) if not answer1: return -1 answer2_key = concat(game_key_prefix, '.answer2') answer2 = Get(context, answer2_key) if not answer2: return -1 player_index = get_winner_index(answer1, answer2) if player_index == 0: winner = 'draw' else: player_key = concat('.player', int_to_str(player_index)) winner = Get(context, concat(game_key_prefix, player_key)) Put(context, winner_key, winner) delete_game(game_id) return winner
def give_user_gas(ad_id, reciever_id, reciever_ad_count): reciever_info = list(length=5) ad_data = list(length=8) ad_id = args[0] reciever_id = args[1] reciever_ad_count = args[2] if reciever_ad_count < 1: return 'User did not view any ads' ad_data = deserialize_bytearray(Get(ctx, ad_id)) ad_gas_amount = ad_data[7] reciever_info = Get(ctx, reciever_id) ad_gas_amount = ad_gas_amount / 2 reciever_info[3] = ad_gas_amount reciever_info[4] = reciever_info[4] + 1 Delete(ctx, reciever_id) data_serialized = serialize_array(reciever_info) Put(ctx, reciever_id, data_serialized) if transfer: Notify(' Transaction approved') update_gas = update_gas(ad_id, ad_gas_amount) if update_gas: Notify("Gas amount on acc updated ") return True return False
def DoTransferFrom(t_from, t_to, amount): if amount <= 0: return False context = GetContext() allowance_key = concat(t_from, t_to) available_to_to_addr = Get(context, allowance_key) if available_to_to_addr < amount: Log("Insufficient funds approved") return False from_balance = Get(context, t_from) if from_balance < amount: Log("Insufficient tokens in from balance") return False to_balance = Get(context, t_to) # calculate the new balances new_from_balance = from_balance - amount new_to_balance = to_balance + amount new_allowance = available_to_to_addr - amount # persist the new balances Put(context, allowance_key, new_allowance) Put(context, t_to, new_to_balance) Put(context, t_from, new_from_balance) Log("transfer complete") # dispatch transfer event DispatchTransferEvent(t_from, t_to, amount) return True
def do_bid(board_id, bidder, bid, content): if bid <= 0: return False # Bid is Valid highest_bid = Get(ctx, get_highest_bid_key(board_id)) if bid > highest_bid: # pay to system if not pay_in_token(ctx, bidder, CONTRACT_OWNER, bid): print('Bid failed') return False # refund last bidder last_bidder = Get(ctx, get_highest_bidder_key(board_id)) if not pay_in_token(ctx, CONTRACT_OWNER, last_bidder, highest_bid): print('Refund Last Bidder Failed') return False Put(ctx, get_highest_bid_key(board_id), bid) Put(ctx, get_highest_bidder_key(board_id), bidder) Put(ctx, get_next_content_key(board_id), content) return True else: print('Bid Smaller than Current Bid') return False
def Main(operation, args): if operation == 'totalSupply': return Get(ctx, TOTAL_SUPPLY_KEY) if operation == 'name': return TOKEN_NAME if operation == 'symbol': return TOKEN_SYMBOL if operation == 'decimals': return TOKEN_DECIMALS if operation == 'balanceOf': if len(args) == 1: return Get(ctx, args[0]) if operation == 'transfer': if len(args) == 3: return transfer(args[0], args[1], args[2]) if operation == 'init': return init() return False
def GetNewPublications(): context = GetContext() publications = Get(context, 'new_publications') new_publications = [] if not publications: return [True, new_publications] publications = Deserialize(publications) # Go through each new publication and get details for i in range(0, len(publications)): user = publications[i][0] name = publications[i][1] publications_key = concat('publications', user) publication_key = concat(publications_key, sha1(name)) publication = Get(context, publication_key) publication = Deserialize(publication) # Append only if publication is active if publication[5]: new_publications.append(publication) return [True, new_publications]
def Main(method, *arr): context = GetContext() #updateBalance #arr[Account, amount] if method == 0: Put(context, arr[0], arr[1]) return "BalanceUpdated" #getBalance #arr[Account] if method == 1: val = Get(context, arr[0]) return val #sendPayment #arr[SenderAccount, ReceiverAccount, amount] if method == 2: bal1 = Get(context, arr[0]) bal2 = Get(context, arr[1]) amount = arr[2] bal1 -= amount bal2 += amount Put(context, arr[0], bal1) Put(context, arr[1], bal2) return "PaymentSend"
def start_play(player1, player2, answer_hash): context = GetContext() if not CheckWitness(player1): Log('Not authorized') return 0 players_key = concat(concat(player1, '.'), player2) game_id = Get(context, players_key) if not game_id: game_id = get_new_game_id() game_key_prefix = concat('game.', game_id) player1_key = concat(game_key_prefix, '.player1') player2_key = concat(game_key_prefix, '.player2') answer_hash1_key = concat(game_key_prefix, '.answer_hash1') players_reverse_key = concat(concat(player2, '.'), player1) Put(context, player1_key, player1) Put(context, player2_key, player2) Put(context, answer_hash1_key, take(answer_hash, 32)) Put(context, players_key, game_id) Put(context, players_reverse_key, game_id) else: game_key_prefix = concat('game.', game_id) player2_key = concat(game_key_prefix, '.player2') answer_hash2_key = concat(game_key_prefix, '.answer_hash2') player2 = Get(context, player2_key) answer_hash2 = Get(context, answer_hash2_key) if answer_hash2 or player2 != player1: return game_id Put(context, answer_hash2_key, take(answer_hash, 32)) return game_id
def DoMatch(src_order_key, dst_order_key, course): """ Method for the dApp owner to match exchange requests Input data: all not matched requests. Output data: matched pairs """ # Check if the method is triggered by the oracle for this exchange context = GetContext() src_order_data = Get(context, src_order_key) oracle = src_order_data[12] src_deposit_amount = src_order_data[10] dst_order_data = Get(context, dst_order_key) dst_deposit_amount = dst_order_data[10] if not CheckWitness(oracle): Log("Must be oracle to notice results") return False # refund deposit of the source wallet t1 = DoTransfer(DEPOSIT_WALLET, QUARK_WALLET, src_deposit_amount) # refund deposit of the source wallet t2 = DoTransfer(DEPOSIT_WALLET, QUARK_WALLET, dst_deposit_amount) if t1 and t2: DispatchExchangeEvent(src_order_key) DispatchExchangeEvent(dst_order_key) return True return False
def DoTransfer(t_from, t_to, amount): if amount <= 0: Log("Cannot transfer negative amount") return False from_is_sender = CheckWitness(t_from) if not from_is_sender: Log("Not owner of funds to be transferred") return False if t_from == t_to: Log("Sending funds to self") return True context = GetContext() from_val = Get(context, t_from) if from_val < amount: Log("Insufficient funds to transfer") return False if from_val == amount: Delete(context, t_from) else: difference = from_val - amount Put(context, t_from, difference) to_value = Get(context, t_to) to_total = to_value + amount Put(context, t_to, to_total) DispatchTransferEvent(t_from, t_to, amount) return True
def Main(operation): # create an array stuff = ['a', 3, ['j', 3, 5], 'jk', 'lmnopqr'] # serialize it to_save = Serialize(stuff) Put(ctx, 'serialized', to_save) if operation == 1: return to_save elif operation == 2: to_retrieve = Get(ctx, 'serialized') return to_retrieve elif operation == 3: to_retrieve = Get(ctx, 'serialized') deserialized = Deserialize(to_retrieve) return deserialized elif operation == 4: to_retrieve = Get(ctx, 'serialized') deserialized = Deserialize(to_retrieve) return deserialized[2] return False
def Main(operation, args): """ Main definition for the smart contracts :param operation: the operation to be performed :type operation: str :param args: list of arguments. args[0] is always sender script hash args[1] is always domain args[2] (optional) is either target or other address args[3] (optional) is target (if args[2] is address) :param type: str :return: byterarray: The result of the operation """ # Common definitions user_hash = args[0] domain = args[1] domain_owner_key = concat(domain, ".owner") domain_target_key = concat(domain, ".target") owner = b'#\xba\'\x03\xc52c\xe8\xd6\xe5"\xdc2 39\xdc\xd8\xee\xe9' # This doesn't require authentication if operation == 'GetDomain': return Get(GetContext(), domain_target_key) # Everything after this requires authorization authorized = CheckWitness(user_hash) if not authorized: Log("Not Authorized") return False Log("Authorized") if operation == 'RegisterDomain': if (CheckWitness(owner)): address = args[2] Put(GetContext(), domain_owner_key, address) if len(args) == 4: target = args[3] Put(GetContext(), domain_target_key, target) return True if operation == 'SetDomainTarget': domain_owner = Get(GetContext(), domain_owner_key) if (CheckWitness(domain_owner)) or (CheckWitness(owner)): # License the product target = args[2] Put(GetContext(), domain_target_key, target) return True if operation == 'DeleteDomain': if (CheckWitness(owner)): Delete(GetContext(), domain_owner_key) Delete(GetContext(), domain_target_key) return True return False
def delete_game(game_id): context = GetContext() game_key_prefix = concat('game.', game_id) player1 = Get(context, concat(game_key_prefix, '.player1')) player2 = Get(context, concat(game_key_prefix, '.player2')) players_key = concat(concat(player1, '.'), player2) players_reverse_key = concat(concat(player2, '.'), player1) Delete(context, players_key) Delete(context, players_reverse_key)
def do_mint_token(ctx, args): """Mints a new NFT token; stores it's properties, URI info, and owner on the blockchain; updates the totalSupply :param StorageContext ctx: current store context :param list args: 0: byte[] t_owner: token owner 1: byte[] t_properties: token's read only data 2: bytes t_uri: token's uri 3: extra_arg (optional): extra arg to be passed to a smart contract :return: mint success :rtype: bool """ t_id = Get(ctx, TOKEN_CIRC_KEY) # the int 0 is represented as b'' in neo-boa, this caused bugs # throughout my code # This is the reason why token id's start at 1 instead t_id += 1 # this should never already exist if len(Get(ctx, t_id)) == 20: Notify('token already exists') return False t_owner = args[0] if len(t_owner) != 20: Notify(INVALID_ADDRESS_ERROR) return False t_properties = args[1] if len(t_properties) == b'\x00': Notify('missing properties data string') return False t_uri = args[2] if GetContract(t_owner): contract_args = [t_owner, t_id] if len(args) == 4: # append optional extra arg contract_args.append(args[3]) success = transfer_to_smart_contract(ctx, GetExecutingScriptHash(), contract_args, True) if success is False: return False Put(ctx, t_id, t_owner) # update token's owner Put(ctx, concat('properties/', t_id), t_properties) Put(ctx, concat('uri/', t_id), t_uri) add_token_to_owners_list(ctx, t_owner, t_id) Put(ctx, TOKEN_CIRC_KEY, t_id) # update total supply # Log this minting event OnMint(t_owner, 1) OnNFTMint(t_owner, t_id) return True
def do_transfer(ctx, t_from, t_to, amount): """ Method to transfer NEP5 tokens of a specified amount from one account to another :param t_from: the address to transfer from :type t_from: bytearray :param t_to: the address to transfer to :type t_to: bytearray :param amount: the amount of NEP5 tokens to transfer :type amount: int :return: whether the transfer was successful :rtype: bool """ if amount <= 0: return False if len(t_from) != 20: return False if len(t_to) != 20: return False if CheckWitness(t_from): if t_from == t_to: print("transfer to self!") return True from_val = Get(ctx, t_from) if from_val < amount: print("insufficient funds") return False if from_val == amount: Delete(ctx, t_from) else: difference = from_val - amount Put(ctx, t_from, difference) to_value = Get(ctx, t_to) to_total = to_value + amount Put(ctx, t_to, to_total) OnTransfer(t_from, t_to, amount) return True else: print("from address is not the tx sender") return False
def buy(player, numbers): context = GetContext() current_game_no = Get(context, CURRENT_GAME_NO) # Check if the lottery is launched. # A method called launch() needs to be triggered by this contract owner in order to begin the lottery. if not current_game_no: return notifyErrorAndReturnFalse("The game has not been launched yet") # Ticket price will be transferred to the POOL is_transferred = do_transfer(player, POOL, TICKET_PRICE) if is_transferred: last_ticket_no = Get(context, LAST_TICKET_NO) new_ticket_no = last_ticket_no + 1 new_ticket_key = concat(TICKET, new_ticket_no) new_ticket = [ current_game_no, player, serialize_array(numbers), GetTime() ] Put(context, new_ticket_key, serialize_array(new_ticket)) Put(context, LAST_TICKET_NO, new_ticket_no) player_key = concat(PLAYER, player) player_key = concat(player_key, current_game_no) # It needs flags to fetch all tickets by addresses and in order to check if a user is qualified for drawing. if not has_user_participated(player): player_key = concat(player_key, "first") else: player_key = concat(player_key, new_ticket_no) Put(context, player_key, new_ticket_no) DispatchBuyEvent(player, new_ticket_no, numbers[0], numbers[1], numbers[2], numbers[3], numbers[4]) return True return False
def DoTransfer(t_from, t_to, amount): """ Method to transfer NEP5 tokens of a specified amount from one account to another :param t_from: the address to transfer from :type t_from: bytearray :param t_to: the address to transfer to :type t_to: bytearray :param amount: the amount of NEP5 tokens to transfer :type amount: int :return: whether the transfer was successful :rtype: bool """ if amount <= 0: print("cannot transfer zero or less") return False from_is_sender = CheckWitness(t_from) if from_is_sender: if t_from == t_to: return True context = GetContext() from_val = Get(context, t_from) if from_val < amount: print("Insufficient funds") return False if from_val == amount: print("Removing all funds!") Delete(context, t_from) else: difference = from_val - amount Put(context, t_from, difference) to_value = Get(context, t_to) to_total = to_value + amount Put(context, t_to, to_total) OnTransfer(t_from, t_to, amount) return True else: print("from address is not the tx sender") return False
def calculate_exchange_amount(ctx, attachments, verify_only): """ Calculate the amount of tokens that can be exchanged :param ctx:GetContext() used to access contract storage :param attachments:list [receiver, sender, neo, gas] :param verify_only:bool if this is the actual exchange, or just a verification :return:int Amount of tokens to be exchanged """ address = attachments[1] neo_amount = attachments[2] if attachments[2] == 0: print("no neo attached") return 0 # the following looks up whether an address has been # registered with the contract for KYC regulations # this is not required for operation of the contract if not get_kyc_status(ctx, address): return 0 current_timestamp = get_now() saleStatus = Get(ctx, SALE_STATUS_KEY) # if the sale has not yet started no amount can be exchanged if saleStatus == b'': print('token sale has not started yet') return 0 # if the token sale is paused dont allow any exchanges if saleStatus == SALE_PAUSED: print('token sale has be paused') return 0 current_in_circulation = Get(ctx, TOKEN_CIRC_KEY) # if are still in the limit round of the crowdsale # ensure only amount abides but limit round rules if saleStatus == LIMITSALE_ROUND: return calculate_limitsale_amount(ctx, address, neo_amount, current_in_circulation, verify_only) if saleStatus == CROWDSALE_BONUS_ROUND: return calculate_crowdsale_bonus_round_amount(ctx, address, neo_amount, current_in_circulation, verify_only) # calculate amount if still in crowdsale timeline if saleStatus == CROWDSALE_ROUND: return calculate_crowdsale_amount(ctx, address, neo_amount, current_in_circulation, verify_only) return 0
def calculate_can_exchange(ctx, amount, address, verify_only, is_private): # don't allow exchange if sale is paused if Get(ctx, SALE_PAUSED_KEY): print("Sale is paused") return False # don't allow exchange if sale has been ended if Get(ctx, END_SALE_KEY): print("Sale has ended!") return False # Favor doing by unix time of latest block time_now = get_now() if time_now < ICO_DATE_START: print("Token sale has not yet begun!") return False if time_now > ICO_DATE_END: print("Token sale has ended! ") return False # Check overflow of public amount current_sold = Get(ctx, ICO_TOKEN_SOLD_KEY) new_total = current_sold + amount if new_total > TOKEN_TOTAL_PUBLIC: print("Amount would overflow amount for public sale") return False if amount < MIN_PUBLIC_AMOUNT: print("Must purchase at least 50 tokens") return False # Only need to check maximum contribution for non-private placement if is_private: return True if amount <= MAX_PUBLIC_AMOUNT: # Make sure amount is less than maximum amount # to reserve current_balance = Get(ctx, address) if not current_balance: return True new_total = amount + current_balance if new_total <= MAX_PUBLIC_AMOUNT: return True print("Transaction exceeds maximum contribution") return False
def do_transfer_from(ctx, t_from, t_to, t_id): if len(t_id) == 0: t_id = 0 if len(t_from) != 20: return False if len(t_to) != 20: return False if t_from == t_to: print("transfer to self!") return True t_owner = Get(ctx, t_id) if len(t_owner) != 20: print("token does not exist") return False if (t_from != t_owner): print("from address is not the owner of this token") return False approval_key = concat("approved/", t_id) authorized_spend = Get(ctx, approval_key) if len(authorized_spend) == 0: print("no approval exists for this token") return False if authorized_spend == concat(t_from, t_to): res = removeTokenFromOwnersList(ctx, t_from, t_id) if res == False: print("unable to transfer token") return False addTokenToOwnersList(ctx, t_to, t_id) Put(ctx, t_id, t_to) # remove the approval for this token Delete(ctx, approval_key) print("transfer complete") OnTransfer(t_from, t_to, 1) OnNFTTransfer(t_from, t_to, t_id) return True print("spend not approved") return False
def DoTransfer(sender, receiver, amount): """ Method to transfer tokens from one account to another :param sender: the address to transfer from :type sender: bytearray :param receiver: the address to transfer to :type receiver: bytearray :param amount: the amount of tokens to transfer :type amount: int :return: whether the transfer was successful :rtype: bool """ if amount <= 0: Log("Cannot transfer negative amount") return False from_is_sender = CheckWitness(sender) if not from_is_sender: Log("Not owner of funds to be transferred") return False if sender == receiver: Log("Sending funds to self") return True context = GetContext() from_val = Get(context, sender) if from_val < amount: Log("Insufficient funds to transfer") return False if from_val == amount: Delete(context, sender) else: difference = from_val - amount Put(context, sender, difference) to_value = Get(context, receiver) to_total = to_value + amount Put(context, receiver, to_total) DispatchTransferEvent(sender, receiver, amount) return True