def sts_add_to_total_circulation(sts: SmartTokenShare, amount: int): """ Adds an amount of token to circlulation Args: sts (SmartTokenShare): Smart Token Share object containing specific attributes amount (int): amount of tokens added """ storage = StorageManager() # Calculation sts.total_in_circulation = sts.total_in_circulation + amount # output STS info updated_sts_info = [ sts.symbol, sts.decimals, sts.owner, sts.total_supply, sts.total_in_circulation ] # Save STS info updated_sts_info_serialized = storage.serialize_array(updated_sts_info) storage.put_double('STS', sts.project_id, updated_sts_info_serialized)
def test_add_to_total_circulation(self): sts = SmartTokenShare() # Setting default info storage = StorageManager() storage.put_double('STS', self.test_project_id, self.test_sts_info) # Running add_to_total_circulation() sts.add_to_total_circulation(self.test_project_id, self.test_add_amount) sts.add_to_total_circulation(self.test_project_id, self.test_add_amount) sts.add_to_total_circulation(self.test_project_id, self.test_add_amount) in_circ = sts.get_total_circulation(self.test_project_id) test_in_circ = self.test_add_amount * 3 # Check Test if in_circ == test_in_circ: print('test_add_to_total_circulation PASSED') return True print('test_add_to_total_circulation FAILED') return False
def fr_list_append(project_id, key, new_item): """Adds the input list of funding stages to storage (as serialized array) Args: project_id (list): ID for referencing the project new_list (list): list of funding stages to save to storage """ storage = StorageManager() print('new_item') print(new_item) # Gets current stored list current_serialized_list = storage.get_double(project_id, key) # Converts serialized list to normal list current_list = storage.deserialize_bytearray(current_serialized_list) current_list_len = len(current_list) print('current_list_len') print(current_list_len) if current_list_len == 0: output_list = [new_item] else: output_list = current_list output_list.append(new_item) # Serializes list serialized_output_list = storage.serialize_array(output_list) print('serialized_output_list') print(serialized_output_list) # Saves updated serialized list to storage storage.put_double(project_id, key, serialized_output_list)
def do_approve(self, project_id, t_owner, t_spender, amount): storage = StorageManager() if not CheckWitness(t_owner): print("Incorrect permission") return False from_balance = storage.get_double(project_id, t_owner) # cannot approve an amount that is # currently greater than the from balance if from_balance >= amount: approval_key = concat(t_owner, t_spender) current_approved_balance = storage.get_double( project_id, approval_key) new_approved_balance = current_approved_balance + amount storage.put_double(project_id, approval_key, new_approved_balance) OnApprove(project_id, t_owner, t_spender, amount) return True return False
def fr_set_active_index(project_id, idx): """ Sets the active index Args: project_id (list): ID for referencing the project idx (int): new active index """ storage = StorageManager() storage.put_double(project_id, 'FR_active_idx', idx)
def fs_claim_system_fee(fs: FundingStage, system_owner_addr): storage = StorageManager() if CheckWitness(system_owner_addr): # If the funding stage complted sucessfully if fs_status(fs) == 1: # Calculating fee fee_calculated = fs_calculate_system_fee(fs) # Sets the claim amount for the address, as 10^8 storage.put_double('CLAIM', system_owner_addr, fee_calculated) return True return False
def sts_create(project_id, symbol, decimals, owner, total_supply) -> SmartTokenShare: """ Args: project_id (str): ID for referencing the project symbol (str): Representation symbol decimals (int): Amount of decimal places, default 8 owner (bytes): Owner of the token total_supply (int): total supply of the token Return: (SmartTokenShare): Returns a Smart Token Share object containing these attributes """ # init objects storage = StorageManager() sts = SmartTokenShare() # Saves vars to object sts.project_id = project_id sts.symbol = symbol sts.decimals = decimals sts.owner = owner sts.total_supply = total_supply # Default circulation sts.total_in_circulation = 0 # Info structure sts_info = [symbol, decimals, owner, total_supply, 0] # Will only save to storage if none exsits for this project_id if not storage.get_double('STS', project_id): sts_info_serialized = storage.serialize_array(sts_info) storage.put_double('STS', project_id, sts_info_serialized) return sts
def test_exchange(self): fs = FundingStage() attachments = get_asset_attachments() # Test vars tokens_per_gas = 100 test_exchanged_sts = attachments.gas_attached * tokens_per_gas / 100000000 # Sets balance to 0 storage = StorageManager() storage.put_double(self.test_project_id, attachments.sender_addr, 0) # Registers KYC address storage.put_triple(self.test_project_id, 'KYC_address', self.test_address1, True) # Setting default info storage = StorageManager() storage.delete_triple('FS', self.test_project_id, self.test_funding_stage_id) # Creates new test fund fs.create(self.test_project_id, self.test_funding_stage_id, 1, 999999, 10000, tokens_per_gas) # Testing exchange method and checking stored balance fs.exchange(self.test_project_id, self.test_funding_stage_id) result1 = storage.get_double(self.test_project_id, attachments.sender_addr) # Testing exchange method and checking stored balance again (should double) fs.exchange(self.test_project_id, self.test_funding_stage_id) result2 = storage.get_double(self.test_project_id, attachments.sender_addr) # Check Test print('CHECK') if result1 == test_exchanged_sts and result2 == test_exchanged_sts * 2: print('test_exchange PASSED') return True print('test_exchange FAILED') return False
def do_transfer(self, project_id, t_from, t_to, amount): storage = StorageManager() # Pointless if amount <= 0: return False # Validate address if CheckWitness(t_from): # Pointless if t_from == t_to: print("transfer to self!") return True from_val = storage.get_double(project_id, t_from) if from_val < amount: print("insufficient funds") return False if from_val == amount: storage.delete_double(project_id, t_from) else: difference = from_val - amount storage.put_double(project_id, t_from, difference) to_value = storage.get_double(project_id, t_to) to_total = to_value + amount storage.put_double(project_id, t_to, to_total) OnTransfer(project_id, t_from, t_to, amount) return True else: print("from address is not the tx sender") return False
def fs_claim_contributions(fs: FundingStage, owner_addr): """ This is required to prep a claim for a verification transaction Args: fs (FundingStage): Funding Stage object containing specific attributes owner_addr (bytearray): Address of the claim deposit address Return: (bool): Can Claim """ storage = StorageManager() if CheckWitness(owner_addr): # If the funding stage complted sucessfully if fs_status(fs) == 1: # Checks the owner_addr matches the sts project owner sts = sts_get(fs.project_id) if sts_get_attr(sts, 'owner') == owner_addr: # Calculates the gas amount contributed, decimal safe 10^8 gas_contributed = fs.in_circulation / fs.tokens_per_gas * 100000000 # Calculating fee fee_calculated = fs_calculate_system_fee(fs) # Deducting fees gas_to_claim = gas_contributed - fee_calculated # Sets the claim amount for the address, as 10^8 storage.put_double('CLAIM', owner_addr, gas_to_claim) return True return False
def fs_refund(fs: FundingStage, refund_addr): """ This is required to prep a refund for for a verification transaction Args: fs (FundingStage): Funding Stage object containing specific attributes refund_addr (bytearray): Address of the refund address in question Return: (bool): Can Refund """ storage = StorageManager() if CheckWitness(refund_addr): # If the funding stage failed if fs_status(fs) != 1: # lookup the current balance of the address current_sts_balance = fs_get_addr_balance(fs, refund_addr) # Calculate gas from current_sts_balance gas_contribution = current_sts_balance / fs.tokens_per_gas * 100000000 # unlocks current_sts_balance to refund_addr, as 10^8 storage.put_double('CLAIM', refund_addr, gas_contribution) # sets refund_addr balance to 0 fs_set_addr_balance(fs, refund_addr, 0) return True return False
def do_transfer_from(self, project_id, t_from, t_to, amount): storage = StorageManager() if amount <= 0: return False available_key = concat(t_from, t_to) available_to_to_addr = storage.get_double(project_id, available_key) if available_to_to_addr < amount: print("Insufficient funds approved") return False from_balance = storage.get_double(project_id, t_from) if from_balance < amount: print("Insufficient tokens in from balance") return False to_balance = storage.get_double(project_id, t_to) new_from_balance = from_balance - amount new_to_balance = to_balance + amount storage.put_double(project_id, t_to, new_to_balance) storage.put_double(project_id, t_from, new_from_balance) print("transfer complete") new_allowance = available_to_to_addr - amount if new_allowance == 0: print("removing all balance") storage.delete_double(project_id, available_key) else: print("updating allowance to new allowance") storage.put_double(project_id, available_key, new_allowance) OnTransfer(project_id, t_from, t_to, amount) return True
def claim_clean(addr): storage = StorageManager() attachments = get_asset_attachments() storage.put_double('CLAIM', attachments.sender_addr, 0)
def test(self, operation, args): storage = StorageManager() attachments = get_asset_attachments() if operation == 'create_all': print('create_all') sts_create(self.project_id, self.symbol, self.decimals, self.owner, self.total_supply) fs_create(self.project_id, 'first_stage', 1, 999999, 1000, 100) fs_create(self.project_id, 'second_stage', 1, 12750, 500, 100) fs_create(self.project_id, 'third_stage', 1, 12450, 100, 100) fs_create(self.project_id, 'fourth_stage', 1, 99999, 200, 100) fss = [ 'first_stage', 'second_stage', 'third_stage', 'fourth_stage' ] ms_create(self.project_id, 'first_mile', 'First', 'sub', 'hash') ms_create(self.project_id, 'second_mile', 'First', 'sub', 'hash') ms_create(self.project_id, 'third_mile', 'First', 'sub', 'hash') ms_create(self.project_id, 'fourth_mile', 'First', 'sub', 'hash') mss = ['first_mile', 'second_mile', 'third_mile', 'fourth_mile'] admins = [self.owner] fr_add_funding_stages(self.project_id, fss) fr_add_milestones(self.project_id, mss) fr_add_project_admins(self.project_id, admins) fr_set_active_index(self.project_id, 0) return True if operation == 'get_funding_stages': print('get_funding_stages') stages = fr_get_funding_stages(self.project_id) print(stages) return stages if operation == 'kyc': print('attachments.sender_addr') print(attachments.sender_addr) storage.put_triple(self.project_id, 'KYC_address', self.owner, True) if operation == 'calim_test': storage.put_double('CLAIM', attachments.sender_addr, attachments.gas_attached) if operation == 'contribute': print('#contribute') # Registers KYC address storage.put_triple(self.project_id, 'KYC_address', attachments.sender_addr, True) active_idx = fr_get_active_index(self.project_id) funding_stages = fr_get_funding_stages(self.project_id) active_funding_stage = funding_stages[active_idx] fs = fs_get(self.project_id, active_funding_stage) fs_contribute(fs) # storage.put_double('CLAIM', attachments.sender_addr, attachments.gas_attached) print('contribute#') if operation == 'get_idx': active_idx = fr_get_active_index(self.project_id) print(active_idx) return active_idx if operation == 'get_active_fs': active_idx = fr_get_active_index(self.project_id) funding_stages = fr_get_funding_stages(self.project_id) active_funding_stage = funding_stages[active_idx] print(active_funding_stage) return active_funding_stage # 4 Put == (1 GAS per KB) # 7 Get == 0.7 GAS if operation == 'contribute_fs': print('#contribute_fs') active_funding_stage = args[0] fs = fs_get(self.project_id, active_funding_stage) fs_contribute(fs) print('contribute_fs#') if operation == 'balance': print('balance') # bal = storage.get_double(self.project_id, attachments.sender_addr) fs_id = args[0] addr = args[1] fs = fs_get('projectID', fs_id) bal = fs_get_addr_balance(fs, addr) print(bal) if operation == 'funding_stage_status': print('#funding_stage_status') active_idx = fr_get_active_index(self.project_id) funding_stages = fr_get_funding_stages(self.project_id) active_funding_stage = funding_stages[active_idx] fs = fs_get(self.project_id, active_funding_stage) status = fs_status(fs) print('funding_stage_status#') print(status) return status if operation == 'current_index': active_idx = fr_get_active_index(self.project_id) print(active_idx) return active_idx if operation == 'milestone_progress': print('#milestone_progress') active_idx = fr_get_active_index(self.project_id) milestones = fr_get_milestones(self.project_id) active_milestone = milestones[active_idx] ms = ms_get(self.project_id, active_milestone) prog = ms_get_progress(ms) print('milestone_progress#') print(prog) return prog if operation == 'complete_milestone': print('complete_milestone') fr_update_milestone_progress(self.project_id, 100) if operation == 'sts_get': sts = sts_get('projectID') arg = args[0] if arg == 'project_id': return sts.project_id if arg == 'symbol': return sts.symbol if arg == 'decimals': return sts.decimals if arg == 'owner': return sts.owner if arg == 'total_supply': return sts.total_supply if arg == 'total_in_circulation': return get_total_in_circulation(sts) if operation == 'fs_get': active_idx = fr_get_active_index('projectID') funding_stages = fr_get_funding_stages('projectID') active_funding_stage = funding_stages[active_idx] fs = fs_get('projectID', active_funding_stage) arg = args[0] # attr = fs_get_attr(fs, arg) if arg == 'project_id': return fs.project_id if arg == 'funding_stage_id': return fs.funding_stage_id if arg == 'start_block': return fs.start_block if arg == 'end_block': return fs.end_block if arg == 'supply': return fs.supply if arg == 'tokens_per_gas': return fs.tokens_per_gas if arg == 'in_circulation': return get_in_circulation(fs) if operation == 'fs_claim_contributions': fs_id = args[0] deposit_addr = args[1] fs = fs_get('projectID', fs_id) fs_claim_contributions(fs, deposit_addr) if operation == 'fs_claim_fee': print('fs_claim_fee') fs_id = args[0] owner_addr = b'j\x1agL0\xff\x926\x02\xde.a\x1fR\xe3FT\x0f\xba|' fs = fs_get('projectID', fs_id) fs_claim_system_fee(fs, owner_addr) if operation == 'fs_refund': fs_id = args[0] refund_addr = args[1] fs = fs_get('projectID', fs_id) fs_refund(fs, refund_addr) return True
def Main(operation, args): """Entry point for the smart contract. Args: operation (str): UUID used as the first part of the key for Storage.Put(). args (str): UUID used as the second part of the key for Storage.Put(). Return: (bytearray): The result of the operation """ # Gets the transaction trigger trigger = GetTrigger() storage = StorageManager() invalid_args_msg = 'INVALID ARGS' invaild_op_msg = 'INVALID OPERATION' if trigger == Verification: print('Verification') attachments = get_asset_attachments() prev_attachments = get_asset_attachments_for_prev() gas_requested = prev_attachments.gas_attached - attachments.gas_attached print(gas_requested) # Get amount avaliable for address claim_amount = storage.get_double('CLAIM', attachments.receiver_addr) # If the request is the EXACT amount (not less), approve the tx if claim_amount == gas_requested: print('Successfully send claim tx') return True elif trigger == Application: print('Application') kyc = KYC() # F U N D I N G R O A D M A P # project_id = args[0] sts = sts_get(project_id) # ARGS: project_id, refund_addr if operation == 'check_claim_owed': OnOperationInvoke('check_claim_owed') print('execute:check_claim_owed') if len(args) == 2: refund_addr = args[1] return storage.get_double('CLAIM', refund_addr) # ARGS: project_id, refund_addr if operation == 'reset_claim_owed': OnOperationInvoke('reset_claim_owed') print('execute:reset_claim_owed') if len(args) == 2: refund_addr = args[1] return storage.put_double('CLAIM', refund_addr, 0) # ARGS: project_id, new_admin if operation == 'add_project_admins': OnOperationInvoke('add_project_admins') print('execute:add_project_admins') if len(args) == 2: if CheckWitness(sts.owner): new_admin = args[1] fr_add_project_admin(project_id, new_admin) return True return invalid_args_msg # ARGS: project_id if operation == 'get_active_index': OnOperationInvoke('get_active_index') print('execute:get_active_index') if len(args) == 1: return fr_get_active_index(project_id) return invalid_args_msg # ARGS: project_id if operation == 'get_funding_stages': OnOperationInvoke('get_funding_stages') print('execute:get_funding_stages') if len(args) == 1: funding_stages = fr_get_funding_stages(project_id) return funding_stages return invalid_args_msg # ARGS: project_id if operation == 'get_active_fs': OnOperationInvoke('get_active_fs') print('execute:get_active_fs') if len(args) == 1: active_idx = fr_get_active_index(project_id) funding_stages = fr_get_funding_stages(project_id) active_funding_stage = funding_stages[active_idx] return active_funding_stage return invalid_args_msg # ARGS: project_id if operation == 'get_milestones': OnOperationInvoke('get_milestones') print('execute:get_milestones') if len(args) == 1: milestones = fr_get_milestones(project_id) return milestones return invalid_args_msg # ARGS: project_id if operation == 'get_active_ms': OnOperationInvoke('get_active_ms') print('execute:get_active_ms') if len(args) == 1: active_idx = fr_get_active_index(project_id) milestones = fr_get_milestones(project_id) active_milestone = milestones[active_idx] return active_milestone return invalid_args_msg # ARGS: project_id, updated_progress if operation == 'update_active_ms_progress': OnOperationInvoke('update_active_ms_progress') print('execute:update_active_ms_progress') if len(args) == 2: if CheckWitness(sts.owner): updated_progress = args[1] progress = fr_update_milestone_progress( project_id, updated_progress) return progress return invalid_args_msg # S M A R T T O K E N S H A R E # # ARGS: project_id, symbol, decimals, owner, total_supply if operation == 'create_sts': OnOperationInvoke('create_sts') print('execute:create_sts') if len(args) == 5: symbol = args[1] decimals = 8 # hardcoded to 8 owner = args[3] total_supply = args[4] sts_create(project_id, symbol, decimals, owner, total_supply) fr_set_active_index(project_id, 0) return project_id return invalid_args_msg # ARGS: project_id, attribute: {'project_id', 'symbol', 'decimals', 'owner', 'total_supply', 'total_in_circulation'} if operation == 'sts_attribute': OnOperationInvoke('sts_attribute') print('execute:sts_attribute') if len(args) == 2: attr = args[1] sts = sts_get(project_id) return sts_get_attr(sts, attr) return invalid_args_msg # ARGS: project_id if operation == 'total_tokens_available': OnOperationInvoke('total_tokens_available') print('execute:total_tokens_available') if len(args) == 1: sts = sts_get(project_id) return sts_total_available_amount(sts) return invalid_args_msg # F U N D I N G S T A G E # funding_stage_id = args[1] # ARGS: project_id, funding_stage_id, start_block, end_block, supply, tokens_per_gas if operation == 'create_fs': OnOperationInvoke('create_fs') print('execute:create_fs') if len(args) == 6: if CheckWitness(sts.owner): start_block = args[2] end_block = args[3] supply = args[4] tokens_per_gas = args[5] fs_create(project_id, funding_stage_id, start_block, end_block, supply, tokens_per_gas) fr_add_funding_stage(project_id, funding_stage_id) return funding_stage_id return invalid_args_msg # ARGS: project_id, funding_stage_id, attribute: {'project_id', 'funding_stage_id', 'start_block', 'end_block', 'supply', 'tokens_per_gas', 'in_circulation'} if operation == 'fs_attribute': OnOperationInvoke('fs_attribute') print('execute:fs_attribute') if len(args) == 3: attr = args[2] fs = fs_get(project_id, funding_stage_id) return fs_get_attr(fs, attr) # ARGS: project_id, funding_stage_id if operation == 'fs_tokens_available': OnOperationInvoke('fs_tokens_available') print('execute:fs_tokens_available') if len(args) == 2: fs = fs_get(project_id, funding_stage_id) return fs_available_amount(fs) return invalid_args_msg # ARGS: project_id, funding_stage_id if operation == 'fs_status': OnOperationInvoke('fs_status') print('execute:fs_status') if len(args) == 2: fs = fs_get(project_id, funding_stage_id) return fs_status(fs) return invalid_args_msg # ARGS: project_id, funding_stage_id if operation == 'fs_contribute': OnOperationInvoke('fs_contribute') print('execute:fs_contribute') if len(args) == 2: fs = fs_get(project_id, funding_stage_id) return fs_contribute(fs) return invalid_args_msg # ARGS: project_id, funding_stage_id, addr if operation == 'fs_addr_balance': OnOperationInvoke('fs_addr_balance') print('execute:fs_addr_balance') if len(args) == 2: addr = args[2] fs = fs_get(project_id, funding_stage_id) return fs_get_addr_balance(fs, addr) return invalid_args_msg # M I L E S T O N E # milestone_id = args[1] # ARGS: project_id, milestone_id, title, subtitle, extra_info_hash if operation == 'create_ms': OnOperationInvoke('create_ms') print('execute:create_ms') if len(args) == 5: if CheckWitness(sts.owner): title = args[2] subtitle = args[3] extra_info_hash = args[4] ms_create(project_id, milestone_id, title, subtitle, extra_info_hash) fr_add_milestone(project_id, milestone_id) return milestone_id return invalid_args_msg # ARGS: project_id, milestone_id, attribute: {'project_id', 'milestone_id', 'title', 'subtitle', 'extra_info_hash', 'progress'} if operation == 'ms_attribute': OnOperationInvoke('ms_attribute') print('execute:ms_attribute') if len(args) == 3: attr = args[2] ms = ms_get(project_id, milestone_id) return ms_get_attr(ms, attr) # ARGS: project_id, milestone_id if operation == 'get_ms_progess': OnOperationInvoke('get_ms_progess') print('execute:get_ms_progess') if len(args) == 2: ms = ms_get(project_id, milestone_id) return ms_get_progress(ms) return invalid_args_msg # C L A I M S # funding_stage_id = args[1] # ARGS: project_id, funding_stage_id, refund_addr if operation == 'claim_fs_refund': OnOperationInvoke('claim_fs_refund') print('execute:claim_fs_refund') if len(args) == 3: refund_addr = args[2] fs = fs_get(project_id, funding_stage_id) return fs_refund(fs, refund_addr) return invalid_args_msg # ARGS: project_id, funding_stage_id, owner_addr if operation == 'claim_fs_contributions': OnOperationInvoke('claim_fs_contributions') print('execute:claim_fs_contributions') if len(args) == 3: owner_addr = args[2] fs = fs_get(project_id, funding_stage_id) return fs_claim_contributions(fs, owner_addr) return invalid_args_msg # ARGS: project_id, funding_stage_id, system_owner_addr if operation == 'claim_fs_system_fee': OnOperationInvoke('claim_fs_system_fee') print('execute:claim_fs_system_fee') if len(args) == 3: system_owner_addr = args[2] fs = fs_get(project_id, funding_stage_id) return fs_claim_system_fee(fs, system_owner_addr) return invalid_args_msg # K Y C # # ARGS: project_id, address, phys_address, first_name, last_name, id_type, id_number, id_expiry, file_location, file_hash if operation == 'kyc_submit': OnOperationInvoke('kyc_submit') print('execute:kyc_submit') if len(args) == 10: address = args[1] phys_address = args[2] first_name = args[3] last_name = args[4] id_type = args[5] id_number = args[6] id_expiry = args[7] file_location = args[8] file_hash = args[9] kyc.kyc_submit(project_id, address, phys_address, first_name, last_name, id_type, id_number, id_expiry, file_location, file_hash) return address return invalid_args_msg # ARGS: project_id, addresses -> if operation == 'kyc_register': if CheckWitness(sts.owner): OnOperationInvoke('kyc_register') print('execute:kyc_register') if len(args) > 1: # addresses = args[1:] return kyc.kyc_register(project_id, args) return invalid_args_msg # ARGS: project_id, address if operation == 'kyc_status': OnOperationInvoke('kyc_status') print('execute:kyc_status') if len(args) == 2: address = args[1] return kyc.kyc_status(project_id, address) return invalid_args_msg # ARGS: project_id, address if operation == 'get_kyc_submission': OnOperationInvoke('get_kyc_submission') print('execute:get_kyc_submission') if len(args) == 2: address = args[1] return kyc.get_kyc_submission(project_id, address) return invalid_args_msg return invaild_op_msg