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
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
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
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
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
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
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
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 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
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
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 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
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
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
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
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)
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)
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
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
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)
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
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
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
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
def do_allowance(self, storage: StorageAPI, t_owner, t_spender): allowance_key = concat(t_owner, t_spender) amount = storage.get(allowance_key) return amount
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
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
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 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 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
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)
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)
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 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)
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
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
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)
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