def addTokenToOwnersList(ctx, t_owner, t_id): length = Get(ctx, t_owner) if len(length) == 0: length = 0 addkey = concat(t_owner, length) Put(ctx, addkey, t_id) print("added token to owners list") newbalance = length + 1 Put(ctx, t_owner, newbalance)
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 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 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 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 deploy(): if not CheckWitness(OWNER): print("Must be owner to deploy") return False if not Get(context, 'initialized'): # do deploy logic Put(context, 'initialized', 1) Put(context, OWNER, TOTAL_SUPPLY) return add_to_circulation(context, TOTAL_SUPPLY) return False
def initialize(): context = GetContext() ini_flag = Get(context, 'ini_flag') if not ini_flag: Put(context, 'counter', 0) Put(context, 'ini_flag', 1) Notify('Initialized') return 1 else: return 1
def do_approve(ctx, Caller, args): """Approve a token to be transferred to a third party by an approved spender :param StorageContext ctx: current store context :param bytearray t_owner: current owner of the token :param bytearray t_spender: spender to approve :param int t_id: int: token id :param bool revoke: set to True to revoke previous approval :return: approval success :rtype: bool """ t_owner = args[0] t_spender = args[1] t_id = args[2] revoke = False if len(args) > 3: revoke = args[3] if Caller != GetEntryScriptHash() and not is_whitelisted_dex(ctx, Caller): # non-whitelisted contracts can only approve their own funds for transfer, # even if they have the signature of the owner on the invocation t_owner = Caller assert len(t_owner) == 20, INVALID_ADDRESS_ERROR assert len(t_spender) == 20, INVALID_ADDRESS_ERROR assert t_id, TOKEN_DNE_ERROR ownership_key = concat('ownership/', t_id) ownership = safe_deserialize(Get(ctx, ownership_key)) assert ownership, TOKEN_DNE_ERROR assert has_key(ownership, 'owner'), TOKEN_DNE_ERROR assert t_owner == ownership['owner'], PERMISSION_ERROR assert t_owner != t_spender, 'same owner and spender' assert authenticate(t_owner, Caller), PERMISSION_ERROR # revoke previous approval if revoke is True if revoke: if has_key(ownership, 'approved'): ownership.remove('approved') Put(ctx, ownership_key, Serialize(ownership)) # log the revoking of previous approvals OnApprove(t_owner, t_spender, 0) OnNFTApprove(t_owner, '', t_id) return True ownership['approved'] = concat(t_owner, t_spender) # approve this transfer Put(ctx, ownership_key, Serialize(ownership)) # Log this approval event OnApprove(t_owner, t_spender, 1) OnNFTApprove(t_owner, t_spender, t_id) return True
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: bytearray t_owner: token owner 1: int t_id: token id (must not already exist) 2: str t_properties: token's read only data 3: str t_uri: token's uri 4: str t_rw_properties: token's read/write data (optional) :return: mint success :rtype: bool """ t_circ = Get(ctx, TOKEN_CIRC_KEY) t_circ += 1 assert len(args[0]) == 20, INVALID_ADDRESS_ERROR assert args[1], 'missing token id' assert args[2], 'missing properties' assert args[3], 'missing uri' t_id = args[1] token = safe_deserialize(Get(ctx, concat('token/', t_id))) assert not token, 'token already exists' # basically a token 'object' containing the token's # id, uri, and properties token = {} ownership = {} # information about the token's owner token['id'] = t_id token['uri'] = args[3] token['properties'] = args[2] # this can never change if len(args) > 4: token['rwproperties'] = args[4] else: token['rwproperties'] = '' ownership['owner'] = args[0] Put(ctx, concat('token/', t_id), Serialize(token)) # update token's owner Put(ctx, concat('ownership/', t_id), Serialize(ownership)) res = add_token_to_owners_list(ctx, ownership['owner'], t_id) Put(ctx, TOKEN_CIRC_KEY, t_circ) # update total supply # Log this minting event OnTransfer('', ownership['owner'], 1) OnNFTTransfer('', ownership['owner'], t_id) OnMint(ownership['owner'], 1) OnNFTMint(ownership['owner'], t_id) return True
def owner_mint(ctx, args): """ This method allows owners to mint their share at 500k increments over 2 years It does not require 'full' owner approval ( 3 of 5 sigs) but only approval by the owner wishing to mint. :param args: list :return: bool """ if len(args) != 1: return False which_owner = args[0] if not is_owner_str(which_owner): return False current_owner_addr = Get(ctx, which_owner) if not CheckWitness(current_owner_addr): return False amount_to_mint = PER_OWNER_TOTAL # get the key used to track mint amount per owner owner_minted_key = concat(which_owner, 'Minted') # lookup whether owner has minted already_minted = Get(ctx, owner_minted_key) if already_minted: print("Owner already minted") return False # update that owner has minted Put(ctx, owner_minted_key, True) # Add this amount to circulation added_to_circ = add_to_circulation(ctx, amount_to_mint) # dispatch mint OnTransfer(False, current_owner_addr, amount_to_mint) # now get current owners balance owner_balance_key = get_balance_key(current_owner_addr) current_balance = Get(ctx, owner_balance_key) # update it with the amount to mint new_balance = current_balance + amount_to_mint # now persist the new balance Put(ctx, owner_balance_key, new_balance) return True
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
def DoDeploy(ctx, accept_coin): """ Method to init totalSupply tokens to OWNER """ result = Get(ctx, "DEPLOY") if result == 1: return False me = GetExecutingScriptHash() Put(ctx, "DEPLOY", 1) Put(ctx, me, TOTAL_SUPPLY) Put(ctx, "ACCEPTCOIN", accept_coin) return True
def add_contribution(ctx, to_address, neo_contribution, gas_contribution): neo_contributed_key = concat(NEO_CONTRIBUTION_KEY, to_address) gas_contributed_key = concat(GAS_CONTRIBUTION_KEY, to_address) current_neo_contributed = Get(ctx, neo_contributed_key) current_gas_contributed = Get(ctx, gas_contributed_key) current_neo_contributed += neo_contribution current_gas_contributed += gas_contribution Put(ctx, neo_contributed_key, current_neo_contributed) Put(ctx, gas_contributed_key, current_gas_contributed)
def Main(operation, addr, value): print("Running Sample v4") trigger = GetTrigger() print(trigger) # This determines that the SC is runnning in Verification mode # This determines whether the TX will be relayed to the rest of the network # The `Verification` portion of SC is *read-only*, so calls to `Storage.Put` will fail. # You can, however, use `Storage.Get` if trigger == Verification(): print("Running Verification!") # This routine is: if the invoker ( or the Address that signed the contract ) is not OWNER, # Then we return False, and the TX will not be relayed to the network # Otherwise, we know the owner address signed the TX and return True is_owner = CheckWitness(OWNER) if is_owner: print("Is Owner!") return True print("Not Owner") return False elif trigger == Application(): print("Running Application!") if not is_valid_addr(addr): print("Not Valid Address") return False ctx = GetContext() if operation == 'add': balance = Get(ctx, addr) new_balance = balance + value Put(ctx, addr, new_balance) return new_balance elif operation == 'remove': balance = Get(ctx, addr) Put(ctx, addr, balance - value) return balance - value elif operation == 'balance': return Get(ctx, addr) return False
def DoTransferFrom(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 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 vote_for_selection(ctx, voter, poll, selection): poll_voter_key = concat(poll, voter) voter_status = Get(ctx, poll_voter_key) if voter_status == "voted": return False else: poll_selection_key = concat(poll, selection) votes = Get(ctx, poll_selection_key) + 1 Put(ctx, poll_voter_key, "voted") Put(ctx, poll_selection_key, votes) print(concat("Selected: ", selection)) return votes
def perform_exchange(ctx): """ :param token:Token The token object with NEP5/sale settings :return: bool: Whether the exchange was successful """ last_tx = Get(ctx, LAST_TX_KEY) current_tx = GetScriptContainer().Hash if last_tx == current_tx: return False Put(ctx, LAST_TX_KEY, current_tx) attachments = get_asset_attachments() # [receiver, sender, neo, gas] # this looks up whether the exchange can proceed exchange_ok = can_exchange(ctx, attachments, False) sender = attachments['sender'] if not exchange_ok: # This should only happen in the case that there are a lot of TX on the final # block before the total amount is reached. An amount of TX will get through # the verification phase because the total amount cannot be updated during that phase # because of this, there should be a process in place to manually refund tokens if attachments['sent_neo'] > 0: OnRefund(sender, attachments['sent_neo'], neo_asset_id) if attachments['sent_gas'] > 0: OnRefund(sender, attachments['sent_gas'], gas_asset_id) return False balance_key = get_balance_key(sender) # lookup the current balance of the address current_balance = Get(ctx, balance_key) new_nex_tokens = calculate_exchange_amount(attachments) # add it to the the exchanged tokens and persist in storage new_total = new_nex_tokens + current_balance Put(ctx, balance_key, new_total) # update the in circulation amount result = add_to_circulation(ctx, new_nex_tokens) # dispatch transfer event OnTransfer(False, sender, new_nex_tokens) return True
def transfer(context, arguments): address = arguments[0] to = arguments[1] amount = arguments[2] # Allow only authenticated requests if not CheckWitness(address): print('Permission denied') return False # To address has to be 20 bytes if len(to) != 20: print('Address is incorrect') return False # Allow only a positive amount if not amount >= 0: print('Amount must be positive') return False balance = Get(context, address) if balance < amount: print('Insufficient funds') return False if address == to: return True # Calculate the balance for the sender if balance == amount: Delete(context, address) else: balance = balance - amount Put(context, address, balance) # Check if the tokens have been burned if to == burn: # Reduce supply when tokens are burned print('Tokens have been burned') supply = Get(context, 'circulating') - amount Put(context, 'circulating', supply) else: # Calculate the balance for the recipient balance = Get(context, to) + amount Put(context, to, balance) # Send the notification OnTransfer(address, to, amount) return True
def do_transfer(t_from, t_to, amount): context = GetContext() if amount < 0: # raise Exception('Amount MUST be greater than or equal to 0') notifyErrorAndReturnFalse("Amount MUST be greater than or equal to 0") if len(t_from) != 20: return notifyErrorAndReturnFalse("From should be 20-byte addresses") if len(t_to) != 20: return notifyErrorAndReturnFalse("From should be 20-byte addresses") if CheckWitness(t_from): if t_from == POOL: return notifyErrorAndReturnFalse( "Nobody can withdraw from the pool") if t_from == t_to: Log("Transfer to self") return True from_val = Get(context, t_from) if from_val < amount: return notifyErrorAndReturnFalse("insufficient funds") if from_val == amount: Put(context, t_from, 0) 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 else: Log("from address is not the tx sender") return False
def init(): if not CheckWitness(TOKEN_OWNER): print("Must be token owner to init") return False if Get(ctx, INIT_KEY): print("Token already init") return False Put(ctx, INIT_KEY, 1) Put(ctx, TOTAL_SUPPLY_KEY, TOTAL_SUPPLY) Put(ctx, TOKEN_OWNER, TOTAL_SUPPLY) OnTransfer(None, TOKEN_OWNER, TOTAL_SUPPLY) return True
def Deploy(dapp_name, oracle, time_margin, min_time, max_time): """ Method for the dApp owner initiate settings in storage :param dapp_name: name of the dapp :type dapp_name: str :param oracle: oracle that is used :type oracle: bytearray :param time_margin: time margin in seconds :type time_margin: int :param min_time: minimum time until the datetime of the event in seconds :type min_time: int :param max_time: max_time until the datetime of the event in seconds :type max_time: int :return: whether the update succeeded :rtype: bool """ # if not CheckWitness(OWNER): # Log("Must be owner to deploy dApp") # return False context = GetContext() Put(context, 'dapp_name', dapp_name) Put(context, 'oracle', oracle) if time_margin < 0: Log("time_margin must be positive") return False Put(context, 'time_margin', time_margin) if min_time < 3600 + time_margin: Log("min_time must be greater than 3600 + time_margin") return False Put(context, 'min_time', min_time) if max_time <= (min_time + time_margin): Log("max_time must be greather than min_time + time_margin") return False Put(context, 'max_time', max_time) return True
def calculate_can_exchange(ctx, amount, address, verify_only): """ Perform custom token exchange calculations here. :param amount:int Number of tokens to convert from asset to tokens :param address:bytearray The address to mint the tokens to :return: bool: Whether or not an address can exchange a specified amount """ timestap = GetTime() current_in_circulation = Get(ctx, TOKEN_CIRC_KEY) new_amount = current_in_circulation + amount if new_amount > TOKEN_TOTAL_SUPPLY: return False if timestap >= ROUND1_START and timestap <= ROUND1_END: print("Minting Round 1") r1key = concat(address, MINTED_ROUND1_KEY) # the following looks up whether an address has been # registered with the contract for KYC regulations # check if they have already exchanged in round 1 # if not, then save the exchange for limited round if amount <= MAX_EXCHANGE_ROUND1 and kyc_status( ctx, 'round1', address) and not Get(ctx, r1key): if not verify_only: Put(ctx, r1key, True) return True if timestap >= ROUND2_START and timestap <= ROUND2_END: print("Minting round 2") r2key = concat(address, MINTED_ROUND2_KEY) if amount <= MAX_EXCHANGE_ROUND2 and kyc_status( ctx, 'round2', address) and not Get(ctx, r2key): if not verify_only: Put(ctx, r2key, True) return True print("Not eligible") return False
def add_users(users): ok_count = 0 for user in users: msg = concat("Adding user: "******"blank_vote") current_user_number = Get(ctx, "all_users") Put(ctx, "all_users", current_user_number + 1) res = kyc_register(ctx, user) if res: ok_count += 1 Notify(concat("Added users ", ok_count)) return ok_count
def addSubaccountAsMaster(executionerPublicKey, domainName, subDomainName, walletHash): if not CheckWitness(executionerPublicKey): return False #check if owner and domain exists if not existDomainAndOwnerWithHash(executionerPublicKey, domainName): return False ctx = GetContext() # "simpli/sub/ SubaccountKey = createSubMainKey(domainName, walletHash) subKey = createSubNameKey(SubaccountKey, subDomainName) #if exist subdomain name, return false if existSubDomain(subKey): return False if existSubaccount(SubaccountKey): masterApproved = Get(ctx, createMasterApprovedKey(SubaccountKey)) masterApproved = masterApproved + 0x30 if masterApproved is None: return False if not masterApproved: return False subsKeyValue = concat(subDomainName, ":") subsKeyValue = concat(subsKeyValue, walletHash) #save to all subs keyHashes = createSubsKey(domainName) addHashToHashes(keyHashes, subsKeyValue, ";") #save to all scripthash domains tr = concat("s:", subDomainName) addDomainToStorage(walletHash, tr) else: #save sub scripthash Put(ctx, SubaccountKey, walletHash) #save sub approved false Put(ctx, createSubApprovedKey(SubaccountKey), 0x30) #save master approved Put(ctx, createMasterApprovedKey(SubaccountKey), 0x01) Put(ctx, subKey, subDomainName) Put(ctx, createSubRootNameKey(SubaccountKey), subDomainName) return True
def MintTokens(ctx): """ MintTokens """ infos = GetMintInfo(ctx) if infos[2] > 0: current_balance = Get(ctx, infos[1]) amount = infos[2] * 100000000 new_total = current_balance + amount Put(ctx, infos[1], new_total) my_balance = Get(ctx, infos[0]) my_new_total = my_balance - amount Put(ctx, infos[0], my_new_total) return True return False
def do_transfer_from(ctx, t_from, t_to, amount): if amount <= 0: return False if len(t_from) != 20: return False if len(t_to) != 20: return False available_key = concat(t_from, t_to) available_to_to_addr = Get(ctx, available_key) if available_to_to_addr < amount: print("Insufficient funds approved") return False from_balance = Get(ctx, t_from) if from_balance < amount: print("Insufficient tokens in from balance") return False to_balance = Get(ctx, t_to) new_from_balance = from_balance - amount new_to_balance = to_balance + amount Put(ctx, t_to, new_to_balance) Put(ctx, t_from, new_from_balance) print("transfer complete") new_allowance = available_to_to_addr - amount if new_allowance == 0: print("removing all balance") Delete(ctx, available_key) else: print("updating allowance to new allowance") Put(ctx, available_key, new_allowance) OnTransfer(t_from, t_to, amount) 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 make_vote(vote): kyc_status = sender_is_in_DAO(ctx) address = get_asset_attachments()[1] print("user", address) is_sender = CheckWitness(address) if kyc_status and is_sender: poll_key = Get(ctx, "poll") kyc_poll_key = concat(poll_key, address) Put(ctx, kyc_poll_key, vote) poll_res = concat(poll_key, "res") cur_res = Get(ctx, poll_res) Put(ctx, poll_res, cur_res + vote) return True return False
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 create_partnership(adr, currency, flatfees_struc, partnership_struc, webpage): """ address, currency, flatfees_struc, partnership_struc, webpage Creates the partnership structure for the given address format for flatfee_struc = addr:fees,addr:fees... format for partnership_struc = addr:fees,addr:fees... :return: indication success execution of the command :rtype: bool """ terms = [currency, flatfees_struc, partnership_struc, webpage] serterms = serialize_array(terms) Put(ctx, adr, serterms) msg = concat("New Partnership Created:", " ") 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