Exemple #1
0
def Main(operation, args):
    trigger = GetTrigger()
    token = Token()

    if trigger == Verification:

        is_owner = CheckWitness(token.owner)
        if is_owner:
            return True

        attachments = get_asset_attachments()
        storage = StorageAPI()
        crowdsale = Crowdsale()

        return crowdsale.can_exchange(token, attachments, storage, True)

    elif trigger == Application:

        if operation != None:
            nep = NEP5Handler()

            for op in nep.get_methods():
                if operation == op:
                    return nep.handle_nep51(operation, args, token)

            if operation == 'deploy':
                return deploy(token)

            if operation == 'circulation':
                storage = StorageAPI()
                return token.get_circulation(storage)

            sale = Crowdsale()

            if operation == 'mintTokens':
                return sale.exchange(token)

            if operation == 'crowdsale_register':
                return sale.kyc_register(args, token)

            if operation == 'crowdsale_status':
                return sale.kyc_status(args)

            if operation == 'crowdsale_available':
                return token.crowdsale_available_amount()

            return 'unknown operation'

    return False
Exemple #2
0
    def exchange(self, token: Token):

        attachments = get_asset_attachments()

        storage = StorageAPI()

        can_exchange = self.can_exchange(token, attachments, storage, False)

        if not can_exchange:
            print("Cannot exchange value")

            if attachments.neo_attached > 0:
                OnRefund(attachments.sender_addr, attachments.neo_attached)

        return False

        current_balance = storage.get(attachments.sender_addr)

        exchanged_tokens = attachments.neo_attached * token.tokens_per_neo / 100000000

        new_total = exchanged_tokens + current_balance
        storage.put(attachments.sender_addr, new_total)

        token.add_to_circulation(exchanged_tokens, storage)

        OnTransfer(attachments.receiver_addr, attachments.sender_addr,
                   exchanged_tokens)

        return True
Exemple #3
0
    def kyc_register(self, args, token:Token):
        """

        :param args:List Eine Liste der Adressen die zu registrieren sind
        :param token:Token Ein Token Objekt mit Ihren ICO Einstellungen
        :return:
            int: Die Nummer der Adressen die mit KYC registriert werden
        """
        ok_count = 0

        if CheckWitness(token.owner):

            for address in args:

                if len(address) == 20:

                    storage = StorageAPI()

                    kyc_storage_key = concat(self.kyc_key, address)
                    storage.put(kyc_storage_key, True)

                    OnKYCRegister(address)
                    ok_count += 1

        return ok_count
Exemple #4
0
def crowdfunding_get_members(crowdfunding_address):
    storage = StorageAPI()

    crowdfunding_meta_key = storage.get_crowdfunding_members_key(
        crowdfunding_address)
    print(crowdfunding_meta_key)

    # Check if this address or crowdfunding_meta already exists
    addresses = storage.get(crowdfunding_meta_key)
    if len(addresses) == 0:
        print("Error: address does not belong to a crowdfunding")
        return False

    n = len(addresses)
    num_addresses = n / 20

    msg = ["Crowdfunding found. Members:", num_addresses]
    Notify(msg)

    address_list = []
    i = 0
    while i < num_addresses:
        addr = addresses[0:20]
        addresses = addresses[20:]
        address_list.append(addr)
        i += 1

    return address_list
    def kyc_register(self, args, token: Token):
        """

        :param args:list a list of addresses to register
        :param token:Token A token object with your ICO settings
        :return:
            int: The number of addresses to register for KYC
        """
        ok_count = 0

        if CheckWitness(token.owner):

            for address in args:

                if len(address) == 20:

                    storage = StorageAPI()

                    kyc_storage_key = concat(self.kyc_key, address)
                    storage.put(kyc_storage_key, True)

                    OnKYCRegister(address)
                    ok_count += 1

        return ok_count
Exemple #6
0
    def AddOracle(self, args):
        storage = StorageAPI()

        isValidOwner = self.ValidateOwner()
        if isValidOwner == False:
            return False

        isValidLength = ValidateArgsLength(args, 1)
        if isValidLength == False:
            return False

        oracleID = args[0]
        oracleKey = concat(self.oracle_prefix, oracleID)

        isOracle = storage.get(oracleKey)
        if isOracle == True:
            Log("Address is already an oracle")
            return False

        oracleCount = storage.get(self.oracle_count_key)
        newCount = oracleCount + 1

        storage.put(oracleKey, True)
        storage.put(self.oracle_count_key, newCount)

        OnOracleAdded(oracleID, newCount)

        return True
Exemple #7
0
    def PlaceBet(self, args, sender):
        storage = StorageAPI()

        user = GetUser(storage, sender, True)
        if user.isUser == False:
            return False
        
        isValidLength = ValidateArgsLength(args, 5)
        if isValidLength == False:
            return False

        isValidBet = self.ValidateNewBet(user, args)
        if isValidBet == False:
            return False
        
        bet = InitialiseNewBet(storage, args)

        user.RemoveFromBalance(storage, bet.betAmount)

        storage.put(bet.betAmountKey, bet.betAmount)
        storage.put(bet.unmatchedAmountKey, bet.returnAmount)
        storage.put(bet.betMakerKey, sender)
        storage.put(bet.statusKey, "valid")

        OnBetAdded(bet.betID, sender, args, bet.betIndex)

        return True
Exemple #8
0
    def handle_nep51(self, operation, args, token: Token):

        # these first 3 don't require get ctx

        if operation == 'name':
            return token.name

        elif operation == 'decimals':
            return token.decimals

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

        storage = StorageAPI()

        arg_error = 'Incorrect Arg Length'

        if operation == 'totalSupply':
            return storage.get(token.in_circulation_key)

        elif operation == 'balanceOf':
            if len(args) == 1:
                account = args[0]
                return storage.get(account)
            return arg_error

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

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

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

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

            return arg_error

        return False
def level_of(address):
    """
    Return the level of the user who owns the address.
    """
    storage = StorageAPI()
    level_key = storage.get_level_key(address)
    stored_level = storage.get(level_key)
    return stored_level
Exemple #10
0
def is_crowdfunding_address(crowdfunding_address):
    storage = StorageAPI()
    crowdfunding_meta_key = storage.get_crowdfunding_members_key(
        crowdfunding_address)
    addresses = storage.get(crowdfunding_meta_key)
    if len(addresses) == 0:
        return False
    return True
    def calculate_can_exchange(self, token: Token, amount: int, address,
                               verify_only: bool):
        """
        Perform custom token exchange calculations here.

        :param token:Token The token settings for the sale
        :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
        """
        height = GetHeight()

        storage = StorageAPI()

        current_in_circulation = storage.get(token.in_circulation_key)

        new_amount = current_in_circulation + amount

        if new_amount > token.total_supply:
            print("amount greater than total supply")
            return False

        print("trying to calculate height????")
        if height < token.block_sale_start:
            print("sale not begun yet")
            return False

        # if we are in free round, any amount
        if height > token.limited_round_end:
            print("Free for all, accept as much as possible")
            return True

        # check amount in limited round

        if amount <= token.max_exchange_limited_round:

            # check if they have already exchanged in the limited round
            r1key = concat(address, self.limited_round_key)

            has_exchanged = storage.get(r1key)

            # if not, then save the exchange for limited round
            if not has_exchanged:
                # note that this method can be invoked during the Verification trigger, so we have the
                # verify_only param to avoid the Storage.Put during the read-only Verification trigger.
                # this works around a "method Neo.Storage.Put not found in ->" error in InteropService.py
                # since Verification is read-only and thus uses a StateReader, not a StateMachine
                if not verify_only:
                    storage.put(r1key, True)
                return True

            print("already exchanged in limited round")
            return False

        print("too much for limited round")

        return False
def level_up(address):
    """
    Loop up the level of the owner of address. Then raise it
    by 1, put it back into storage and return the new value.
    """
    storage = StorageAPI()
    level_key = storage.get_level_key(address)
    level = level_of(level_key)
    new_level = level + 1
    storage.put(level_key, new_level)
    return new_level
Exemple #13
0
    def crowdsale_available_amount(self):
        """

        :return: int Der Betrag der Tokens der für den Crowdsale Verkauf übrig ist
        """
        storage = StorageAPI()

        in_circ = storage.get(self.in_circulation_key)

        available = self.total_supply - in_circ

        return available
Exemple #14
0
    def kyc_status(self, args):

        storage = StorageAPI()

        if len(args) > 0:
            addr = args[0]

            kyc_storage_key = concat(self.kyc_key, addr)

            return storage.get(kyc_storage_key)

        return False
Exemple #15
0
    def crowdsale_available_amount(self):
        """

        :return: int The amount of tokens left for sale in the crowdsale
        """
        storage = StorageAPI()

        in_circ = storage.get(self.in_circulation_key)

        available = self.total_supply - in_circ

        return available
Exemple #16
0
    def calculate_can_exchange(self, token: Token, amount: int, address):
        """
        Führt benutzerdefinierte Token exchange Kalkulationen aus.

        :param token:Token Die Token Einstellungen für den Verkauf
        :param amount:int Nummer der Tokens die von Asset zu Tokens konvertiert werden
        :param address:bytearray Die Adresse wo die Tokens erzeugt werden sollen
        :return:
            bool: Ob eine Adresse einen bestimmten Betrag tauschen kann oder nicht
        """
        height = GetHeight()

        storage = StorageAPI()

        current_in_circulation = storage.get(token.in_circulation_key)

        new_amount = current_in_circulation + amount

        if new_amount > token.total_supply:
            # print("amount greater than total supply")
            return False

        if height < token.block_sale_start:
            # print("sale not begun yet")
            return False

        # Ob wir in einer freien Runde sind, jeder Betrag
        if height > token.limited_round_end:
            # print("Free for all, accept as much as possible")
            return True


        # Überprüfe Betrag in einer limitierten Runde

        if amount <= token.max_exchange_limited_round:

            # Überprüfe ob die Adresse bereits in einer limitierten Runde teilgenommen haben
            r1key = concat(address, self.limited_round_key)

            has_exchanged = storage.get(r1key)

            # falls nicht, dann sichere den exchange für die limitierte Runde
            if not has_exchanged:
                storage.put(r1key, True)
                return True

            print("already exchanged in limited round")
            return False

        print("too much for limited round")

        return False 
    def calculate_can_exchange(self, token: Token, amount: int, address):
        """
        Perform custom token exchange calculations here.

        :param token:Token The token settings for the sale
        :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
        """
        height = GetHeight()

        storage = StorageAPI()

        current_in_circulation = storage.get(token.in_circulation_key)

        new_amount = current_in_circulation + amount

        if new_amount > token.total_supply:
            print("amount greater than total supply")
            return False

        print("trying to calculate height????")
        if height < token.block_sale_start:
            print("sale not begun yet")
            return False

        # if we are in free round, any amount
        if height > token.limited_round_end:
            print("Free for all, accept as much as possible")
            return True

        # check amount in limited round

        if amount <= token.max_exchange_limited_round:

            # check if they have already exchanged in the limited round
            r1key = concat(address, self.limited_round_key)

            has_exchanged = storage.get(r1key)

            # if not, then save the exchange for limited round
            if not has_exchanged:
                storage.put(r1key, True)
                return True

            print("already exchanged in limited round")
            return False

        print("too much for limited round")

        return False
Exemple #18
0
    def UpdateEventOutcome(self, args, oracleID):
        storage = StorageAPI()

        isValidSender = self.ValidateOracle(storage, oracleID)
        if isValidSender == False:
            return False

        isValidLength = ValidateArgsLength(args, 2)
        if isValidLength == False:
            return False

        eventID = args[0]
        outcome = args[1]

        eventKey = concat(self.event_prefix, eventID)
        event = storage.get(eventKey)

        if event != "active":
            msg1 = concat("Cannot update event: ", eventID)
            msg2 = concat(", Event state is currently: ", event)
            msg = concat(msg1, msg2)

            Log(msg)

            return False

        oracleSuffix = concat(self.outcome_oracle_prefix, oracleID)
        countSuffix = concat(self.outcome_count_prefix, outcome)

        oracleKey = concat(eventKey, oracleSuffix)
        countKey = concat(eventKey, countSuffix)

        reachedConsensus = self.CheckEventConsensus(storage, oracleKey,
                                                    countKey)

        if reachedConsensus == False:
            OnEventOutcomeConsensus(eventID, oracleID)

        else:
            if outcome == "void":
                storage.put(eventKey, "void")

            else:
                outcomeKey = concat(eventKey, "/outcome")

                storage.put(outcomeKey, outcome)
                storage.put(eventKey, "finished")

            OnEventOutcomeConfirmed(eventID, outcome, oracleID)

        return True
    def exchange(self, token: Token):
        """

        :param token:Token The token object with NEP5/sale settings
        :return:
            bool: Whether the exchange was successful
        """

        attachments = get_asset_attachments()  # type:  Attachments

        storage = StorageAPI()

        # this looks up whether the exchange can proceed
        can_exchange = self.can_exchange(token, attachments, storage, False)

        if not can_exchange:
            print("Cannot exchange value")
            # 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.neo_attached > 0:
                OnRefund(attachments.sender_addr, attachments.neo_attached)
            # if you want to exchange gas instead of neo, use this
            #if attachments.gas_attached > 0:
            #    OnRefund(attachments.sender_addr, attachments.gas_attached)
            return False

        # lookup the current balance of the address
        current_balance = storage.get(attachments.sender_addr)

        # calculate the amount of tokens the attached neo will earn
        exchanged_tokens = attachments.neo_attached * token.tokens_per_neo / 100000000

        # if you want to exchange gas instead of neo, use this
        # exchanged_tokens += attachments.gas_attached * token.tokens_per_gas / 100000000

        # add it to the the exchanged tokens and persist in storage
        new_total = exchanged_tokens + current_balance
        storage.put(attachments.sender_addr, new_total)

        # update the in circulation amount
        token.add_to_circulation(exchanged_tokens, storage)

        # dispatch transfer event
        OnTransfer(attachments.receiver_addr, attachments.sender_addr,
                   exchanged_tokens)

        return True
Exemple #20
0
def deploy(token: Token):

    if not CheckWitness(token.owner):
        print("Must be owner to deploy")
        return False

    storage = StorageAPI()

    if not storage.get('initialized'):
        storage.put('initialized', 1)
        storage.put(token.owner, token.initial_amount)
        token.add_to_circulation(token.initial_amount, storage)
        return True

    return False
Exemple #21
0
    def InitialiseContract(self):
        storage = StorageAPI()

        isValidOwner = self.ValidateOwner()
        if isValidOwner == False:
            return False
        
        isInitialised = storage.get(self.admin_init_key)
        if isInitialised:
            Log("Contract has already been initialised")
            return False

        storage.put(self.admin_init_key, True)

        return True
Exemple #22
0
def crowdfunding_create(args):
    """ args:
     0: crowdfunding address
     1..n: member addresses
    """

    print("Create a crowdfunding")
    storage = StorageAPI()

    crowdfunding_address = args[0]
    crowdfunding_meta_key = storage.get_crowdfunding_members_key(
        crowdfunding_address)
    print(crowdfunding_meta_key)

    # Check for minimum number of arguments
    nargs = len(args)
    if nargs < 3:
        print(
            "Error: need at least 3 arguments: (1) crowdfunding address, (2+3) member addresses"
        )
        return False

    # Check if this address or crowdfunding_meta already exists
    balance = storage.get(crowdfunding_address)
    if len(balance) > 0:
        print("Error: address is already in use")
        return False

    meta = storage.get(crowdfunding_meta_key)
    if len(meta) > 0:
        print("Error: crowdfunding is already setup")
        return False

    # Build list of addresses to store in meta key
    print("Build list of addresses")
    nargs = len(args)
    member_addresses = args[1]
    print(member_addresses)
    i = 2
    while i < nargs:
        member_address = args[i]
        print(member_address)
        i += 1
        member_addresses = concat(member_addresses, member_address)

    storage.put(crowdfunding_meta_key, member_addresses)
    print("Created the crowdfunding with those member addresses")
    print(member_addresses)
Exemple #23
0
    def AddEvent(self, args, oracleID):
        storage = StorageAPI()

        isValidSender = self.ValidateOracle(storage, oracleID)
        if isValidSender == False:
            return False

        isValidLength = ValidateArgsLength(args, 7)
        if isValidLength == False:
            return False

        eventID = CreateEventID(args)

        eventKey = concat(self.event_prefix, eventID)
        event = storage.get(eventKey)

        if event == False:
            _ = StoreEventDetails(storage, eventKey, args)

            event = "pending"

            OnNewEventAdded(eventID, oracleID, args)

        if event == "pending":
            oracleKey = concat(eventKey, oracleID)
            countKey = concat(eventKey, "/count")

            reachedConsensus = self.CheckEventConsensus(
                storage, oracleKey, countKey)

            if reachedConsensus == False:
                OnNewEventConsensus(eventID, oracleID)

            else:
                storage.put(eventKey, "active")

                OnNewEventConfirmed(eventID, oracleID)

            return True
        else:
            msg1 = concat("Consensus has finished for: ", eventID)
            msg2 = concat(", Event state is currently: ", event)
            msg = concat(msg1, msg2)

            Log(msg)

        return False
Exemple #24
0
    def exchange(self, token: Token):
        """

        :param token:Token Das Token Objekt mit NEP5/sale Einstellungen
        :return:
            bool: Ob der exchange erfolgreich war
        """

        attachments = get_asset_attachments()  # type:  Attachments

        storage = StorageAPI()

        # Dies überprüft ob der exchange ausgeführt werden kann
        can_exchange = self.can_exchange(token, attachments, storage)

        if not can_exchange:
            print("Cannot exchange value")
            # Dies sollte nur passieren im Fall das viele TX auf dem Final Block sind bevor 
            # der total amount erreicht ist. Nur eine Teilmenge der TX wird durch die Verification
            # Phase kommen und da die Gesamtmenge während dieser Phase nicht erhöht werden kann,
            # sollte es einen Prozess zur manuellen Erstattung der Tokens geben.
            OnRefund(attachments.sender_addr, attachments.neo_attached)
            return False


        # Suche den aktuellen Kontostand einer Adresse
        current_balance = storage.get(attachments.sender_addr)

        # Kalkuliere den Wert an Tokens die die angehängten NEO Wert sind
        exchanged_tokens = attachments.neo_attached * token.tokens_per_neo / 100000000

        # Wenn Sie anstatt Neo, Gas verwenden wollen benutzen Sie dies hier
        # exchanged_tokens += attachments.gas_attached * token.tokens_per_gas / 100000000


        # Fügen Sie die erhaltenen Tokens zu dem Persisten Storage hinzu
        new_total = exchanged_tokens + current_balance
        storage.put(attachments.sender_addr, new_total)

        # Updaten Sie den im Umlauf befindenden Wert 
        token.add_to_circulation(exchanged_tokens, storage)

        # Dispatch Transfer Event
        OnTransfer(attachments.receiver_addr, attachments.sender_addr, exchanged_tokens)

        return True
def reward_user(address):
    """
    Raise the user level corresponding to address and reward him/her.
    """
    token = Token()
    if not CheckWitness(token.owner):
        print("Must be owner to reward")
        return False

    nep = NEP5Handler()
    storage = StorageAPI()
    level = level_up(
        address
    )  ### you might wanna just set this constant for debugging purposes
    reward = calculate_reward(level)
    success = nep.do_transfer(storage, token.owner, address, reward)
    return success
    def kyc_status(self, args):
        """
        Gets the KYC Status of an address

        :param args:list a list of arguments
        :return:
            bool: Returns the kyc status of an address
        """
        storage = StorageAPI()

        if len(args) > 0:
            addr = args[0]

            kyc_storage_key = concat(self.kyc_key, addr)

            return storage.get(kyc_storage_key)

        return False
Exemple #27
0
    def kyc_status(self, args):
        """
        Gibt den KYC Status einer Adresse aus

        :param args:list Eine Liste mit Argumenten
        :return:
            bool: Gibt den KYC Status einer Adresse aus
        """
        storage = StorageAPI()

        if len(args) > 0:
            addr = args[0]

            kyc_storage_key = concat(self.kyc_key, addr)

            return storage.get(kyc_storage_key)

        return False
def calculate_reward(address):
    """
    Apply the calculation function for the user reward.
    """
    storage = StorageAPI()
    level_key = storage.get_level_key(address)
    level = level_of(address)
    bonus_factor = 1

    if level > 1:
        bonus_factor = 2
    if level > 3:
        bonus_factor = 5
    if level > 9:
        bonus_factor = 20

    basic_reward = 100000000
    reward = basic_reward * bonus_factor
    return reward
Exemple #29
0
    def kyc_register(self, args, token: Token):

        ok_count = 0

        if CheckWitness(token.owner):

            for address in args:

                if len(address) == 20:

                    storage = StorageAPI()

                    kyc_storage_key = concat(self.kyc_key, address)
                    storage.put(kyc_storage_key, True)

                    OnKYCRegister(address)
                    ok_count += 1

        return ok_count
Exemple #30
0
    def InitialiseContract(self):
        storage = StorageAPI()

        isValidOwner = self.ValidateOwner()
        if isValidOwner == False:
            return False

        isInitialised = storage.get(self.admin_init_key)
        if isInitialised:
            Log("Contract has already been initialised")
            return False

        oracleKey = concat(self.oracle_prefix, self.OWNER)

        storage.put(oracleKey, True)
        storage.put(self.oracle_count_key, 1)
        storage.put(self.oracle_consensus_key, 70)
        storage.put(self.admin_init_key, True)

        return True