def na_alias_data(alias, args): """ :param alias: \n:param args [type]: \n:returns alias data as array if success or None if failed: \nif sub_nas defined passes call to sub_nas otherwise we try to get alias data """ if len(args) > 0: alias_type = args[0] else: alias_type = 0 stored_alias = init_alias(alias,alias_type) if alias_exists(stored_alias) : stored_alias = alias_load(stored_alias) if not alias_expired(stored_alias): data = alias_get_data(stored_alias) Notify(data) return data msg = concat("Alias ", alias) msg = concat(msg, " not found or expired.") Notify(msg) return return_value(False,msg)
def SetSubdomain(domain_name, subdomain): msg = concat("SetSubdomain: ", domain_name, subdomain) Notify(msg) context = GetContext() owner = Get(context, domain_name) if stringCompare(subdomain): Notify("Domain has incorrect char inside") return False if not owner: Notify("Domain is not yet registered") return False if not CheckWitness(owner): Notify("Sender is not the owner, cannot set subdomain") return False domain = concat(subdomain, ".") domain = concat(domain, domain_name) Put(context, domain, owner) msg2 = [domain, "is owned by ", owner] Notify(msg2) return True
def register_delegator(context, args): if not CheckWitness(OWNER): Notify(ILLEGAL_CALL) return False delegator = args[0] name = args[1] if len(delegator) != 20: Notify(INVALID_ADDRESS) return False if not name: Notify(MISSING_DELEGATOR_NAME) return False if Get(context, delegator): Notify(ALREADY_EXISTING_DELEGATOR) return False Notify(['[REGISTER-DELEGATOR] delegator:', delegator, 'name:', name]) Put(context, delegator, name) return True
def Main(): # pobieramy kontekst storage'u dla danego kontraktu # każdy kontrakt ma własny obszar storage context = GetContext() # klucz item_key = 'moj-klucz' # pobieramy wartość za pomocą klucza item_value = Get(context, item_key) msg = ['Wartosc odczytana ze storage:', item_value] Notify(msg) # w przypadku gdy para klucz-wartość nie są zapisane # próba pobrania wartości za pomocą nie istniejącego w storage klucza # zwróci wartość pustego ciągu bajtów b'' if len(item_value) == 0: Notify('Klucz nie istnieje w storage, ustawiam wartosc na 1') item_value = 1 else: Notify("Klucz juz jest w storage, zwiększam wartosc o 1.") item_value += 1 # zapisanie wartości pod kluczem Put(context, item_key, item_value) msg = ["Nowa wartosc zapisana do storage:", item_value] Notify(msg) return item_value
def RegisterFarmContract(FarmContract_name, OwnerNeoAddress, Farmer_id, Buyer_id, Project_id, Contract_id, Balance, Status, Other_data): msg = concat("RegisterFarmContract: ", FarmContract_name) msg2 = concat(msg, OwnerNeoAddress) Notify(msg2) storage_key = concat(FarmContract_name, OwnerNeoAddress) if not CheckWitness(OwnerNeoAddress): Notify("Owner argument is not the same as the person who registered") return False context = GetContext() exists = getRegistry(context, storage_key) if exists: Notify("Contract is already registered") return False raw_data = [ Farmer_id, Buyer_id, Project_id, Contract_id, Balance, Status, Other_data ] farm_contract_info_serialised = serialize_array(raw_data) putRegistry(context, storage_key, farm_contract_info_serialised) return True
def Main(): m = bytearray(b'\x01\x02\x03\x04\x05\x06\x07\x08') # this is a test to see if slice notation without specifying an end # is functional # s1 = m[2:] # it is not # without specifying beginning it is: s2 = m[:4] j = 2 k = 4 s3 = m[j:k] Notify(s3) s4 = m[get_slice_start():get_slice_end()] Notify(s4) ind = [1, 3, 4, 5] s6 = m[get_slice_start():ind[2]] Notify(s6) res = concat(s6, concat(s4, concat(s2, s3))) Notify(res) return res
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 Main(operation, args): trigger = GetTrigger() if trigger == Verification(): is_owner = CheckWitness(CONTRACT_OWNER) if is_owner: return True else: return False elif trigger == Application(): sender = args[0] authorized = CheckWitness(sender) """ Make sure that invoker is valid """ if not authorized: Notify("Not authorized") return False Log("test") Notify(len(args)) """ query operations """ if operation == "sendMessage" and len(args) == 4: Notify("In operation sendMessage") return sendMessage(args) else: return False return False
def InsertCharacter(attrList): ID_TIP_KEY = "id-tip-key" Notify("Calling InsertCharacterByAttrList") context = GetContext() # Make sure that it can be converted correctly character = ConvertFromList(attrList) nextId = Get(context, ID_TIP_KEY) if not nextId: Notify("id-tip-key is not set") nextId = 0 else: Notify("id-tip-key is set") nextId = nextId + 1 serialized = Serialize(attrList) Notify(serialized) Put(context, nextId, serialized) Put(context, ID_TIP_KEY, nextId) return nextId
def TransferFarmContract(FarmContract_name, OwnerNeoAddress, to_address): msg = concat("TransferFarmContract: ", FarmContract_name) msg2 = concat(msg, OwnerNeoAddress) Notify(msg2) storage_key = concat(FarmContract_name, OwnerNeoAddress) context = GetContext() Owner = Get(context, storage_key) if not Owner: Notify("This farm contract is not yet registered") return False if not CheckWitness(Owner): Notify( "This person is not the Owner, Farm Contract ownership cannot be Transfered" ) return False if not len(to_address) != 34: Notify("Invalid new owner neo address. Must be exactly 34 characters") return False putRegistry(context, storage_key, to_address) return True
def set_webpage(adr, webpage): msg = concat("Change webpage for: ", adr) Notify(msg) termsba = Get(ctx, adr) if not termsba: Notify("Partnership for address is not yet created") return False serterms = deserialize_bytearray(termsba) currency = serterms[0] flatfees_struc = serterms[1] partnership_struc = serterms[2] terms = [currency, flatfees_struc, partnership_struc, webpage] serterms = serialize_array(terms) Put(ctx, adr, serterms) msg = concat("Webpage updated:", " ") a = concat("Address : ", adr) msg = concat(msg, a) c = concat(", Currency : ", currency) msg = concat(msg, c) d = concat(", Flatfee Structure : ", flatfees_struc) msg = concat(msg, d) e = concat(", Partnership Structure: ", partnership_struc) msg = concat(msg, e) f = concat(", Webpage: ", webpage) msg = concat(msg, f) Notify(msg) return True
def Main(op, args): context = GetContext() if op == 'registerDelegator': if len(args) == 2: return register_delegator(context, args) else: Notify(ARG_ERROR) return False elif op == 'registerWallet': if len(args) == 1: return register_wallet(context, args) else: Notify(ARG_ERROR) return False elif op == 'verifyClaim': if len(args) == 1: delegator = GetEntryScriptHash() return verify_claim(context, delegator, args) else: Notify(ARG_ERROR) return False else: Notify(INVALID_OPERATION) return False
def Main(): context = GetContext() # This is the storage key we use in this example item_key = 'test-storage-key' # Try to get a value for this key from storage item_value = Get(context, item_key) msg = ["Value read from storage:", item_value] Notify(msg) if len(item_value) == 0: Notify("Storage key not yet set. Setting to 1") item_value = 1 else: Notify("Storage key already set. Incrementing by 1") item_value += 1 # Store the new value Put(context, item_key, item_value) msg = ["New value written into storage:", item_value] Notify(msg) return item_value
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 addMessage(party, direction, message, partySecond, time): context = GetContext() partyHelper = concat(direction, 'latest') partyLast = concat(party, partyHelper) lastIndex = Get(context, partyLast) if lastIndex == '': # No last Index, set first (1) newLastIndex = 1 else: # Increment last index newLastIndex = lastIndex + 1 Notify(concat('lastindex +1: ', newLastIndex)) # Set new last index Put(context, partyLast, newLastIndex) Notify(concat('put partyLast: ', partyLast)) # Set message for index partyHelper2 = concat(direction, newLastIndex) partyMessageId = concat(party, partyHelper2) # Create message with header and body # header contains partySecond (sender / receiver) and time # body contains message # messageData = [partySecond,time,message] messageData = [message, time, partySecond] messageTemp = Serialize(messageData) Put(context, partyMessageId, messageTemp) Notify(concat('pt msg: ', messageTemp)) return True
def RegisterDomain(domain_name, owner): msg = concat("RegisterDomain: ", domain_name) Notify(msg) ''' Check if the domain contain . if ture then return false ''' if stringCompare(domain_name): Notify("Domain has incorrect char inside") return False if not CheckWitness(owner): Notify("Owner argument is not the same as the sender") return False context = GetContext() exists = Get(context, domain_name) if exists: Notify("Domain is already registered") return False Put(context, domain_name, owner) msg2 = [domain_name, "is owned by ", owner] Notify(msg2) return True
def na_query(alias, args): """ :param alias: \n:param args [type]: \n:returns alias target if success or False if failed: \nif sub_nas defined passes call to sub_nas otherwise we try to query alias target """ if len(args) > 0: alias_type = args[0] else: alias_type = 0 stored_alias = init_alias(alias,alias_type) if alias_exists(stored_alias): stored_alias = alias_load(stored_alias) if not alias_expired(stored_alias): target = alias_get_target(stored_alias) msg = concat("Query resolved: ", target) Notify(msg) QueryAliasEvent(alias, alias_type, target) return target msg = concat("Alias ", alias) msg = concat(msg, " not found or expired.") Notify(msg) return return_value(False,msg)
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 register_provider(context, args): if not CheckWitness(OWNER): Notify(ILLEGAL_CALL) return False name = args[0] provider = args[1] if not name: Notify(MISSING_PROVIDER_NAME) return False if len(provider) != 20: Notify(INVALID_ADDRESS) return False if Get(context, name): Notify(ALREADY_EXISTING_PROVIDER) return False Notify(['[REGISTER-PROVIDER] name:', name, 'provider:', provider]) Put(context, name, provider) return True
def create_verification_request(source_address, target_address): """ The target user is doing this! :param target_address: :param source_address: :return: """ msg = concat("Target users requests verification from ", source_address) Notify(msg) # if not CheckWitness(target_address): # Notify("target_address argument is not the same as the tx sender") # return False context = GetContext() key = _build_verification_request_key(source_address, target_address) result = Get(context, key) if not result: msg = concat("Verification request has been created for source ", source_address) Notify(msg) Put(context, key, PENDING_STATUS) return True Notify( "Verification has already been started or completed for this source target combination" ) return False
def remove_token_from_owners_list(ctx, t_owner, t_id): """Removes a token from owner's list of tokens :param StorageContext ctx: current store context :param byte[] t_owner: token owner :param bytes t_id: token id :return: token removal success :rtype: bool """ length = Get(ctx, t_owner) # get how many tokens this owner owns # this should be impossible, but just in case, leaving it here if len(length) == b'\x00': Notify('owner has no tokens') return False # if Delete returns True, that means the token was # successfully deleted and we should decrement the owner's balance. # otherwise, the token didn't exist/didn't belong to the owner, # so Delete returns False in that case. if Delete(ctx, concat(t_owner, t_id)): new_balance = length - 1 if new_balance > 0: Put(ctx, t_owner, new_balance) else: Delete(ctx, t_owner) Log("removed token from owner's list and decremented owner's balance") return True Notify("token not found in owner's list") return False
def removeQuestionId(questionId): Notify("[!] Remove QuestionID to all_question_ids object") serial = Get(GetContext(), get_all_ids) all_question_ids = Deserialize(serial) all_question_ids.remove(questionId) new_serial = Serialize(all_question_ids) Put(GetContext(), get_all_ids, new_serial) Notify("[!] Removed QuestionID from all_question_ids object")
def removePostId(postId): Notify("[!] Remove PostID to all_posts object") serial = Get(GetContext(), get_all_ids) all_posts = Deserialize(serial) all_posts.remove(postId) new_serial = Serialize(all_posts) Put(GetContext(), get_all_ids, new_serial) Notify("[!] Removed PostID from all_posts object")
def addQuestionId(questionId, question): Notify("[!] Add QuestionID to all_question_ids object") serial = Get(GetContext(), get_all_ids) all_question_ids = Deserialize(serial) all_question_ids[questionId] = question new_serial = Serialize(all_question_ids) Put(GetContext(), get_all_ids, new_serial) Notify("[!] Added QuestionID to all_question_ids object")
def addPostId(postId, title): Notify("[!] Add PostID to all_posts object") serial = Get(GetContext(), get_all_ids) all_posts = Deserialize(serial) all_posts[postId] = title new_serial = Serialize(all_posts) Put(GetContext(), get_all_ids, new_serial) Notify("[!] Added PostID to all_posts object")
def unFollow(ctx, uid, uFAddr, index_a, index_b): """ Unfollow another user Args: uid -> unique user id uFAddr -> to-follow script hash index_a -> Index of iterated storage of uid, for the following of fUid index_b -> Index of iterated storage of FUid, for the follow of uid """ uFUid = isRegistered(ctx, uFAddr) if not uFUid == False: if uFUid == uid: Notify("User cannot unfollow himself") return False if isFollowing(ctx, uid, uFUid): #User has to be follower, respecitve follower has to be followed by user a_temp = GetThree(ctx, uid, ".following.", index_a) a_temp_d = Deserialize(a_temp) b_temp = GetThree(ctx, uFUid, ".followers.", index_b) b_temp_d = Deserialize(b_temp) if a_temp_d[0] == uFUid and b_temp_d[0] == uid: # Count unfollowing += 1 for uid ##a_save = Get(ctx, uid) ##a_save_d = Deserialize(a_save) ##a_count = a_save_d[8] ##aa_count = a_count + 1 ##a_save_d[8] = aa_count ##a_save_s = Serialize(a_save_d) ##Put(ctx, uid, a_save_s) updateAccCount(ctx, uid, 8, False) # Count unfollowed += 1 for uFUid ##b_save = Get(ctx, uFUid) ##b_save_d = Deserialize(b_save) ##b_count = b_save_d[7] ##bb_count = b_count + 1 ##b_save_d[7] = bb_count ##b_save_s = Serialize(b_save_d) ##Put(ctx, uFUid, b_save_s) updateAccCount(ctx, uFUid, 7, False) # Mark index as unfollowed for uid PutThree(ctx, uid, ".following.", index_a, "unfollowing") # Mark index as unfollowed for uFUid PutThree(ctx, uFUid, ".followers.", index_b, "unfollowed") #Set follow indicator = false PutThree(ctx, uid, ".followcheck.", uFUid, False) OnUnfollow(uid, uFUid) return True Notify("Following and Follower indexes do not match") return False Notify("User is not following.") return False Notify("User to unfollow not registered") return False
def addPostId(postId): check_allPostIds() Notify("[!] Add PostID to all_posts object") serial = Get(GetContext(), get_all_ids) all_posts = Deserialize(serial) all_posts.append(postId) new_serial = Serialize(all_posts) Put(GetContext(), get_all_ids, new_serial) Notify("[!] Added PostID to all_posts object")
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_tokens_of_owner(ctx, t_owner, start_index): """This method returns ten of the owner's tokens starting at the given index. The index is used for paginating through the results. Pagination is needed for the situation where the owner's dict of tokens could be quite large. For example, the specified owner could have 100,000 tokens out of 1,000,000 minted tokens. In such a scenario, returning the full list of token id's would be quite expensive and could possibly be too large to return anyway. Hence, @hal0x2328 recognized the need to paginate the data in such a scenario. So, if we know that this user has a balanceOf() 100,000 tokens and we want to get their 10 most recent tokens, then our call would be like so: `testinvoke {my_hash} tokensOfOwner [{owner address string}, 999990]` The results would look something like: [{'type': 'ByteArray', 'value': '82060007746f6b656e2f010001010007746f6b656e2f020001020007746f6b656e2f030001030007746f6b656e2f040001040007746f6b656e2f050001050007746f6b656e2f06000106''}] :param StorageContext ctx: current store context :param byte[] t_owner: token owner :param bytes start_index: the index to start searching through the owner's tokens :return: dict of tokens :rtype: bool or dict """ if len(t_owner) != 20: Notify(INVALID_ADDRESS_ERROR) return False if len(start_index) == b'\x00': start_index = b'\x01' # token id's cannot go below 1 start_key = concat(t_owner, start_index) count = 0 token_dict = {} token_iter = Find(ctx, t_owner) # while loop explained: keep looping through the owner's list # of tokens until 10 have been found beginning at the starting # index. # if statement explained: once a key has been found matching # my search key (or of greater value), # update the dictionary, increment the counter, # and disregard trying to find a matching key thereafter. # (once a key has been found matching my search key # (or greater), just get everything afterward while count < 10) while token_iter.next() and (count < 10): if (token_iter.Key >= start_key) or (count > 0): token_dict[concat('token/', token_iter.Value)] = token_iter.Value count += 1 if len(token_dict) >= 1: return token_dict Notify(TOKEN_DNE_ERROR) return False
def do_approve(ctx, caller, t_receiver, t_id, revoke): """Approve a token to eventually be transferred to the t_receiver :param StorageContext ctx: current store context :param byte[] caller: calling script hash :param byte[] t_receiver: address of the future token owner :param bytes t_id: int: token id :param bytes revoke: set to 1 to revoke previous approval :return: approval success :rtype: bool """ if len(t_receiver) != 20: Notify(INVALID_ADDRESS_ERROR) return False if len(revoke) == b'\x00': revoke = b'\x00' t_owner = Get(ctx, t_id) if len(t_owner) != 20: Notify(TOKEN_DNE_ERROR) return False if t_owner == t_receiver: Notify('approved spend to self') return True is_token_owner = CheckWitness(t_owner) if is_token_owner and GetEntryScriptHash() != caller: Notify('third party script is bouncing the signature to us') return False # if token owner is a smart contract and is the calling # script hash, continue elif GetContract(t_owner) and t_owner == caller: is_token_owner = True if is_token_owner: approval_key = concat('approved/', t_id) # revoke previous approval if revoke != 0 if revoke != b'\x00': Delete(ctx, approval_key) # log the revoking of previous approvals OnApprove(t_owner, t_receiver, b'\x00') OnNFTApprove(t_owner, '', t_id) return True # approve this transfer Put(ctx, approval_key, concat(t_owner, t_receiver)) # Log this approval event OnApprove(t_owner, t_receiver, 1) OnNFTApprove(t_owner, t_receiver, t_id) return True Notify(PERMISSION_ERROR) return False