def handle_sts(self, operation, args):

        # project_id always first arg
        project_id = args[0]

        sts = sts_get(project_id)

        storage = StorageManager()
        arg_error = 'Incorrect Arg Length'

        if operation == 'decimals':
            return sts.decimals

        elif operation == 'symbol':
            return sts.symbol

        elif operation == 'totalSupply':
            return sts.total_supply

        elif operation == 'balanceOf':
            if len(args) == 2:
                account = args[1]
                return storage.get_double(project_id, account)
            return arg_error

        elif operation == 'transfer':
            if len(args) == 4:
                t_from = args[1]
                t_to = args[2]
                t_amount = args[3]
                return self.do_transfer(project_id, t_from, t_to, t_amount)
            return arg_error

        elif operation == 'transferFrom':
            if len(args) == 4:
                t_from = args[1]
                t_to = args[2]
                t_amount = args[3]
                return self.do_transfer_from(project_id, t_from, t_to,
                                             t_amount)
            return arg_error

        elif operation == 'approve':
            if len(args) == 4:
                t_owner = args[1]
                t_spender = args[2]
                t_amount = args[3]
                return self.do_approve(project_id, t_owner, t_spender,
                                       t_amount)
            return arg_error

        elif operation == 'allowance':
            if len(args) == 3:
                t_owner = args[1]
                t_spender = args[2]
                return self.do_allowance(project_id, t_owner, t_spender)

            return arg_error

        return False
예제 #2
0
def ms_update_progress(ms: Milestone, updated_progress):
    """
    Args:
        ms (Milestone):
            Milestone object containing specific attributes
        
        updated_progress (int):
            New progress of the milestone

    Return:
        (int): The avaliable tokens for the Milestone
    """
    storage = StorageManager()

    # If the updated progress is higher
    if updated_progress > ms.progress:

        # Clamp at 100%
        if updated_progress > 100:
            updated_progress = 100

        # Updates object variable
        ms.progress = updated_progress

        # Output milestone info
        updated_milestone_info = [
            ms.title, ms.subtitle, ms.extra_info_hash, updated_progress
        ]

        # Saving info to storage
        updated_milestone_info_serialized = storage.serialize_array(
            updated_milestone_info)
        storage.put_triple('MS', ms.project_id, ms.milestone_id,
                           updated_milestone_info_serialized)
예제 #3
0
def sts_get(project_id) -> SmartTokenShare:
    """
    Get the info list

    Args:
        project_id (str):
            ID for referencing the project
    Return:
        (SmartTokenShare): 
            Returns a Smart Token Share object containing attributes
    """
    storage = StorageManager()
    sts = SmartTokenShare()

    # Pull STS info
    sts_info_serialized = storage.get_double('STS', project_id)

    if sts_info_serialized:
        sts_info = storage.deserialize_bytearray(sts_info_serialized)

        # Saves vars to object
        sts.project_id = project_id
        sts.symbol = sts_info[0]
        sts.decimals = sts_info[1]
        sts.owner = sts_info[2]
        sts.total_supply = sts_info[3]
        sts.total_in_circulation = sts_info[4]

        print('sts_get')
        print(sts.owner)

    return sts
예제 #4
0
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)
예제 #5
0
    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
예제 #6
0
    def test_add_to_circulation(self):
        fs = FundingStage()

        # Setting default info
        storage = StorageManager()
        storage.put_triple('FS', self.test_project_id,
                           self.test_funding_stage_id, self.test_fs_info)

        # # Running add_to_crowdfund_circulation()
        # fs.add_to_circulation(self.test_project_id, self.test_funding_stage_id, self.test_add_amount)
        # fs.add_to_circulation(self.test_project_id, self.test_funding_stage_id, self.test_add_amount)
        # fs.add_to_circulation(self.test_project_id, self.test_funding_stage_id, self.test_add_amount)

        in_circ = fs.get_circulation(self.test_project_id,
                                     self.test_funding_stage_id)

        test_in_circ = self.test_add_amount * 3

        # Check Test
        if in_circ == test_in_circ:
            print('test_add_to_circulation PASSED')
            return True

        print('test_add_to_circulation FAILED')
        return False
예제 #7
0
def ms_get(project_id, milestone_id) -> Milestone:
    """
    Pulls an existing Milestone from storage using the input attributes, and returns
    a Milestone object
    Args:
        project_id (str):
            ID for referencing the project

        milestone_id (str):
            ID for referencing the Milestone
            
    Return:
        (Milestone):
            Returns a Milestone object containing attributes
    """
    storage = StorageManager()
    ms = Milestone()

    # Pull Milestone info
    milestone_info_serialized = storage.get_triple('MS', project_id,
                                                   milestone_id)
    milestone_info = storage.deserialize_bytearray(milestone_info_serialized)

    if len(milestone_info) == 4:
        # Saves vars to object
        ms.project_id = project_id
        ms.milestone_id = milestone_id
        ms.title = milestone_info[0]
        ms.subtitle = milestone_info[1]
        ms.extra_info_hash = milestone_info[2]
        ms.progress = milestone_info[3]

    return ms
예제 #8
0
def fs_add_to_circulation(fs: FundingStage, amount: int) -> bool:
    """
    Args:
        fs (FundingStage):
            Funding Stage object containing specific attributes

        amount (int):
            Amount of tokens added  
    """
    storage = StorageManager()

    # Calculation
    fs.in_circulation = fs.in_circulation + amount

    # Output STS info
    updated_fs_info = [
        fs.start_block, fs.end_block, fs.supply, fs.tokens_per_gas,
        fs.in_circulation
    ]

    # Serialize array and save to storage
    updated_fs_info_serialized = storage.serialize_array(updated_fs_info)
    storage.put_triple('FS', fs.project_id, fs.funding_stage_id,
                       updated_fs_info_serialized)

    # Update sts **
    sts = sts_get(fs.project_id)
    sts_add_to_total_circulation(sts, amount)

    return True
    def do_allowance(self, project_id, t_owner, t_spender):
        storage = StorageManager()

        allowance_key = concat(t_owner, t_spender)

        amount = storage.get_double(project_id, allowance_key)

        return amount
예제 #10
0
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)
예제 #11
0
def claim():
    storage = StorageManager()
    attachments = get_asset_attachments()
    
    claim_amount = storage.get_double('CLAIM', attachments.receiver_addr)

    if claim_amount == attachments.gas_attached:
        return True
    
    return False
예제 #12
0
def fr_get_active_index(project_id):
    """    
    Gets the active index
    Args:
        project_id (list): ID for referencing the project
    
    Return:
        (int): Index
    """
    storage = StorageManager()
    idx = storage.get_double(project_id, 'FR_active_idx')
    return idx
예제 #13
0
def fs_create(project_id, funding_stage_id, start_block, end_block, supply,
              tokens_per_gas) -> FundingStage:
    """
    Creates a new Funding Stage using the input attributes, saves it to storage and returns
    a FundingStage object
    Args:
        project_id (str):
            ID for referencing the project

        funding_stage_id (str):
            ID for referencing the funding stage
            
        start_block (int):
            Block to start fund

        end_block (int):
            Block to end fund

        supply (int):
            Supply of the token in this fs

        tokens_per_gas (int):
            Token to gas ratio
    Return:
        (FundingStage):
            Returns a funding stage object containing these attributes
    """
    # init objects
    storage = StorageManager()
    fs = FundingStage()

    # Saves vars to object
    fs.project_id = project_id
    fs.funding_stage_id = funding_stage_id
    fs.start_block = start_block
    fs.end_block = end_block
    fs.supply = supply
    fs.tokens_per_gas = tokens_per_gas
    fs.in_circulation = 0

    # Info structure
    fs_info = [start_block, end_block, supply, tokens_per_gas, 0]

    # Saving info to storage
    fs_info_serialized = storage.serialize_array(fs_info)
    storage.put_triple('FS', project_id, funding_stage_id, fs_info_serialized)

    return fs
예제 #14
0
def ms_create(project_id, milestone_id, title, subtitle,
              extra_info_hash) -> Milestone:
    """
    Creates a new Milestone using the input attributes, saves it to storage and returns
    a Milestone object
    Args:
        project_id (str):
            ID for referencing the project

        milestone_id (str):
            ID for referencing the Milestone
            
        title (str):
            Block to start fund

        subtitle (str):
            Block to end fund

        extra_info_hash (str):
            Supply of the token in this fs

    Return:
        (Milestone):
            Returns a Milestone object containing these attributes
    """
    # init objects
    storage = StorageManager()
    ms = Milestone()

    # Saves vars to object
    ms.project_id = project_id
    ms.milestone_id = milestone_id
    ms.title = title
    ms.subtitle = subtitle
    ms.extra_info_hash = extra_info_hash

    # Sets progress to 0
    ms.progress = 0

    # Info structure
    milestone_info = [title, subtitle, extra_info_hash, 0]

    # Saving info to storage
    milestone_info_serialized = storage.serialize_array(milestone_info)
    storage.put_triple('MS', project_id, milestone_id,
                       milestone_info_serialized)

    return ms
예제 #15
0
    def kyc_status(self, project_id, address):
        """
        Gets the KYC Status of an address

        Args:
            args (list):
                list a list of arguments
            
            sts (SmartTokenShare):
                Smart Token Share reference object
        Return:
            (bool): Returns the kyc status of an address
        """
        storage = StorageManager()

        return storage.get_triple(project_id, 'KYC_address', address)
예제 #16
0
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
예제 #17
0
    def kyc_submit(self, project_id, address, phys_address, first_name, last_name, id_type, id_number, id_expiry, file_location, file_hash):
        """    
        Submits a KYC information to the smart contract 
        Args:
            sts (SmartTokenShare):
                Smart Token Share reference object
            
            address (str):
                Wallet address to whitelist

            phys_address (str):
                Physical Address

            first_name (str):
                First Name

            last_name (str):
                Last Name

            id_type (str):
                Id type, eg passport, drivers licence

            id_number (str):
                ID Number

            id_expiry (str):
                Expiry data

            file_location (str):
                web location where file is stored

            file_hash (str):
                hash of file
        """
        storage = StorageManager()

        # Checking its the correct address
        if CheckWitness(address):
            if len(address) == 20:

                # Combines all args into a single list
                output_kyc_array = list(address, phys_address, first_name, last_name, id_type, id_number, id_expiry, file_location, file_hash)
                
                # Serialises list into a single bytearray, and stores that into storeage
                serialized_kyc = storage.serialize_array(output_kyc_array)
                storage.put_triple('KYC', project_id, address, serialized_kyc)
예제 #18
0
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)
예제 #19
0
    def test_create(self):
        sts = SmartTokenShare()

        # Running create()
        sts.create(self.test_project_id, self.test_symbol, self.test_decimals,
                   self.test_owner, self.test_total_supply)

        # Pull output from storage
        storage = StorageManager()
        output = storage.get_double('STS', self.test_project_id)

        # Check Test
        if output == self.test_sts_info:
            print('test_create PASSED')
            return True

        print('test_create FAILED')
        return False
예제 #20
0
def fr_get_list(project_id, key):
    """    
    Registers all input addresses
    Args:
        project_id (list): ID for referencing the project

    Return:
        (list): Output list for key
    """
    storage = StorageManager()

    # Gets current stored list
    serialized_list = storage.get_double(project_id, key)

    # Converts serialized list to normal list
    output_list = storage.deserialize_bytearray(serialized_list)
    # output_list = ['sdad','sdads']

    return output_list
예제 #21
0
    def test_create(self):
        fs = FundingStage()

        # Running start_new_crowdfund()
        fs.create(self.test_project_id, self.test_funding_stage_id,
                  self.test_start_block, self.test_end_block, self.test_supply,
                  self.test_tokens_per_gas)

        # Pull output from storage
        storage = StorageManager()
        output = storage.get_triple('FS', self.test_project_id,
                                    self.test_funding_stage_id)

        # Check Test
        if output == self.test_fs_info:
            print('test_create PASSED')
            return True

        print('test_create FAILED')
        return False
예제 #22
0
    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
예제 #23
0
    def kyc_register(self, project_id, addresses):
        """    
        Registers all input addresses 
        Args:
            args (list):
                list a list of arguments
            
            sts (SmartTokenShare):
                Smart Token Share reference object

        Return:
            (int): The number of addresses to registered for KYC
        """
        # Gets sts object
        sts = sts_get(project_id)
        print('kyc_register')
        print(sts.owner)
        ok_count = 0
        
        check_addr = sts.owner
        
        check = CheckWitness(check_addr)
        print('check')
        print(check)

        if CheckWitness(check_addr):
            for address in addresses:

                if len(address) == 20:

                    storage = StorageManager()
                    storage.put_triple(project_id, 'KYC_address', address, True)

                    OnKYCRegister(project_id, address)
                    ok_count += 1
        else:
            print(sts.owner)
            print('Only the project owner can register kyc addresses')            
            return 0

        return ok_count
예제 #24
0
    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
예제 #25
0
    def test_can_exchange(self):
        fs = FundingStage()

        attachments = get_asset_attachments()

        # Registers KYC address
        storage = StorageManager()
        storage.put_triple(self.test_project_id, 'KYC_address',
                           self.test_address2, True)

        fs.create(self.test_project_id, 'test_can_exchange', 1, 999999, 10000,
                  100)
        test_result = fs.can_exchange(self.test_project_id,
                                      'test_can_exchange', attachments)

        # Check Test
        if test_result:
            print('test_can_exchange PASSED')
            return True

        print('test_can_exchange FAILED')
        return False
예제 #26
0
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
예제 #27
0
    def test_available_amount(self):
        fs = FundingStage()

        # Running crowdfund_available_amount()
        # fs.create(self.test_project_id, 'test_available_amount', self.test_start_block, self.test_end_block, self.test_supply, self.test_tokens_per_gas)
        storage = StorageManager()
        storage.put_triple('FS', self.test_project_id, 'test_available_amount',
                           self.test_fs_info)

        available = fs.available_amount(self.test_project_id,
                                        'test_available_amount')
        print('available')
        print(available)

        test_available = self.test_supply - 0

        # Check Test
        if available == test_available:
            print('test_available_amount PASSED')
            return True

        print('test_available_amount FAILED')
        return False
예제 #28
0
def fs_get(project_id, funding_stage_id) -> FundingStage:
    """
    Pulls an existing Funding Stage from storage using the input attributes, and returns
    a FundingStage object
    Args:
        project_id (str):
            ID for referencing the project

        funding_stage_id (str):
            ID for referencing the funding stage
            
    Return:
        (FundingStage):
            Returns a funding stage object containing attributes
    """
    storage = StorageManager()
    fs = FundingStage()

    # Pull FundingStage info
    fs_info_serialized = storage.get_triple('FS', project_id, funding_stage_id)

    if not fs_info_serialized:
        print('fs_info_serialized is null')
        return None

    fs_info = storage.deserialize_bytearray(fs_info_serialized)

    # Saves vars to object
    fs.project_id = project_id
    fs.funding_stage_id = funding_stage_id
    fs.start_block = fs_info[0]
    fs.end_block = fs_info[1]
    fs.supply = fs_info[2]
    fs.tokens_per_gas = fs_info[3]
    fs.in_circulation = fs_info[4]

    return fs
예제 #29
0
    def get_kyc_submission(self, project_id, address):
        """    
        Submits a KYC information to the smart contract 
        Args:
            sts (SmartTokenShare):
                Smart Token Share reference object
            
            address (str):
                Wallet address to whitelist
        Returns:
            (list): Of KYC submission list (address, phys_address, first_name, last_name, id_type, id_number, id_expiry, file_location, file_hash)
        """
        storage = StorageManager()

        # Gets sts object
        sts = sts_get(project_id)

        # Checking the invoker is the owner/admin
        if CheckWitness(sts.owner):
            if len(address) == 20:

                # Deserialises bytearray back into a list
                serialized_kyc_sub = storage.get_triple('KYC', project_id, address)
                return storage.deserialize_bytearray(serialized_kyc_sub)                
예제 #30
0
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