Exemplo n.º 1
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
Exemplo n.º 2
0
    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
Exemplo n.º 3
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
Exemplo n.º 4
0
    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
Exemplo n.º 5
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
Exemplo n.º 6
0
    def do_approve(self, storage: StorageAPI, t_owner, t_spender, amount):

        if not CheckWitness(t_owner):
            print("Incorrect permission")
            return False

        from_balance = storage.get(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(approval_key)

            new_approved_balance = current_approved_balance + amount

            storage.put(approval_key, new_approved_balance)

            OnApprove(t_owner, t_spender, amount)

            return True

        return False
Exemplo n.º 7
0
    def do_approve(self, storage: StorageAPI, t_owner, t_spender, amount):

        if not CheckWitness(t_owner):
            print("Incorrect permission")
            return False

        from_balance = storage.get(t_owner)

        # Kann keinen Betrag bestätigen der momentan
        # größer ist als der von "from balance"
        if from_balance >= amount:

            approval_key = concat(t_owner, t_spender)

            current_approved_balance = storage.get(approval_key)

            new_approved_balance = current_approved_balance + amount

            storage.put(approval_key, new_approved_balance)

            OnApprove(t_owner, t_spender, amount)

            return True

        return False
Exemplo n.º 8
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
Exemplo n.º 9
0
    def do_approve(self, storage: StorageAPI, t_owner, t_spender, amount):

        if not CheckWitness(t_owner):
            print("Incorrect permission")
            return False

        if amount < 0:
            print("Negative amount")
            return False

        from_balance = storage.get(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)

            if amount == 0:
                storage.delete(approval_key)
            else:
                storage.put(approval_key, amount)

            OnApprove(t_owner, t_spender, amount)

            return True

        return False
Exemplo n.º 10
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
Exemplo n.º 11
0
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
Exemplo n.º 12
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
Exemplo n.º 13
0
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
Exemplo n.º 14
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
Exemplo n.º 15
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
Exemplo n.º 16
0
    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
Exemplo n.º 17
0
    def add_to_circulation(self, amount:int, storage:StorageAPI):
        """
        Adds an amount of token to circlulation

        :param amount: int the amount to add to circulation
        :param storage:StorageAPI A StorageAPI object for storage interaction
        """
        current_supply = storage.get(self.in_circulation_key)

        current_supply += amount

        storage.put(self.in_circulation_key, current_supply)
Exemplo n.º 18
0
    def add_to_circulation(self, amount:int, storage:StorageAPI):
        """
        Addiert einen Betrag an Tokens zu den Tokens im Umlauf

        :param amount: int Der Betrag der zu den Tokens im Umlauf addiert werden soll
        :param storage:StorageAPI Ein StorageAPI Objekt für storage Interaktionen
        """
        current_supply = storage.get(self.in_circulation_key)

        current_supply += amount

        storage.put(self.in_circulation_key, current_supply)
Exemplo n.º 19
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
Exemplo n.º 20
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
Exemplo n.º 21
0
    def add_to_circulation(self, amount: int, storage: StorageAPI):
        """
        Adds an amount of token to circlulation

        :param amount: int the amount to add to circulation
        :param storage:StorageAPI A StorageAPI object for storage interaction
        """
        current_supply = storage.get(self.in_circulation_key)

        current_supply += amount

        storage.put(self.in_circulation_key, current_supply)
Exemplo n.º 22
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
Exemplo n.º 23
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
Exemplo n.º 24
0
    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
Exemplo n.º 25
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
Exemplo n.º 26
0
    def do_allowance(self, storage: StorageAPI, t_owner, t_spender):

        allowance_key = concat(t_owner, t_spender)

        amount = storage.get(allowance_key)

        return amount
Exemplo n.º 27
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
Exemplo n.º 28
0
def InitialiseQueue(storage: StorageAPI, args) -> Queue:
    queue = Queue()

    queue = queue.CreateQueueIDs(args)

    queue.index = storage.get(queue.indexKey)
    if queue.index == 0:
        # Indexing starts at 1
        queue.index = 1

    rawBetID = concat(queue.rawQueueID, queue.index)
    queue.betID = sha1(rawBetID)

    betStatusKey = concat("bet/status/", queue.betID)
    queue.betStatus = storage.get(betStatusKey)

    return queue
Exemplo n.º 29
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
Exemplo n.º 30
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
Exemplo n.º 31
0
    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)

        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
            OnRefund(attachments.sender_addr, attachments.neo_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
Exemplo n.º 32
0
    def get_circulation(self, storage:StorageAPI):
        """
        Get the total amount of tokens in circulation

        :param storage:StorageAPI A StorageAPI object for storage interaction
        :return:
            int: Total amount in circulation
        """
        return storage.get(self.in_circulation_key)
Exemplo n.º 33
0
    def get_circulation(self, storage: StorageAPI):
        """
        Get the total amount of tokens in circulation

        :param storage:StorageAPI A StorageAPI object for storage interaction
        :return:
            int: Total amount in circulation
        """
        return storage.get(self.in_circulation_key)
Exemplo n.º 34
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
Exemplo n.º 35
0
    def get_circulation(self, storage:StorageAPI):
        """
        Gibt den Gesamtbetrag der Tokens im Umlauf zurück

        :param storage:StorageAPI Ein StorageAPI Objekt für storage Interaktionen
        :return:
            int: Gesamtbetrag im Umlauf
        """
        return storage.get(self.in_circulation_key)
Exemplo n.º 36
0
    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
Exemplo n.º 37
0
    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
Exemplo n.º 38
0
    def get_kyc_status(self, address, storage:StorageAPI):
        """
        Looks up the KYC status of an address

        :param address:bytearray The address to lookup
        :param storage:StorageAPI A StorageAPI object for storage interaction
        :return:
            bool: KYC Status of address
        """
        kyc_storage_key = concat(self.kyc_key, address)

        return storage.get(kyc_storage_key)
Exemplo n.º 39
0
def deploy(token: Token):
    """

    :param token: Token The token to deploy
    :return:
        bool: Whether the operation was successful
    """
    if not CheckWitness(token.owner):
        print("Must be owner to deploy")
        return False

    storage = StorageAPI()

    if not storage.get('initialized'):

        # do deploy logic
        storage.put('initialized', 1)
        storage.put(token.owner, token.initial_amount)
        token.add_to_circulation(token.initial_amount, storage)

        return True

    return False