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 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 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 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 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 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 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 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
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 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 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 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 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 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
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 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)
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 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 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 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
def CheckEventConsensus(self, storage: StorageAPI, oracleKey, countKey): oracleStatus = storage.get(oracleKey) if oracleStatus == "participated": Log("Oracle has already participated") return False count = storage.get(countKey) newCount = count + 1 storage.put(countKey, newCount) storage.put(oracleKey, "participated") oracleCount = storage.get(self.oracle_count_key) consensusRequired = storage.get(self.oracle_consensus_key) factoredCount = newCount * 100 required = oracleCount * consensusRequired return factoredCount >= required
def calculate_can_exchange(self, token: Token, amount: int, address, verify_only: bool): 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 height > token.limited_round_end: print("Free for all, accept as much as possible") return True if amount <= token.max_exchange_limited_round: r1key = concat(address, self.limited_round_key) has_exchanged = storage.get(r1key) if not has_exchanged: 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 CreateNewBetID(self, storage: StorageAPI): rawQueueID = concat(self.eventID, self.outcome) rawQueueID = concat(rawQueueID, self.odds) rawQueueID = concat(rawQueueID, self.betType) queueID = sha1(rawQueueID) betQueuePrefix = concat("bet_queue/", queueID) betQueueLengthKey = concat(betQueuePrefix, "/length") queueLength = storage.get(betQueueLengthKey) newQueueLength = queueLength + 1 storage.put(betQueueLengthKey, newQueueLength) rawBetID = concat(rawQueueID, newQueueLength) self.betID = sha1(rawBetID) self.betIndex = newQueueLength return self
def do_transfer(self, storage: StorageAPI, t_from, t_to, amount): if amount <= 0: return False if len(t_to) != 20: return False if CheckWitness(t_from): if t_from == t_to: print("transfer to self!") return True from_val = storage.get(t_from) if from_val < amount: print("insufficient funds") return False if from_val == amount: storage.delete(t_from) else: difference = from_val - amount storage.put(t_from, difference) to_value = storage.get(t_to) to_total = to_value + amount storage.put(t_to, to_total) OnTransfer(t_from, t_to, amount) return True else: print("from address is not the tx sender") return False
def CancelBet(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 bet = InitialiseBet(storage, args) isValidCancel = self.ValidateCancelBet(bet, sender) if isValidCancel == False: return False storage.put(bet.statusKey, "cancelled") _ = user.AddToBalance(storage, bet.betAmount) OnBetCancelled(bet.betID, sender, args) return True
def ProcessBetQueue(self, args): storage = StorageAPI() isValidLength = ValidateArgsLength(args, 4) if isValidLength == False: return False queue = InitialiseQueue(storage, args) if queue.betStatus == "cancelled": Log("Bet has been cancelled, move to next bet") newQueueIndex = queue.index + 1 storage.put(queue.indexKey, newQueueIndex) return True # could evaluate more, but leave here for v0.1 elif queue.betStatus != "valid": Log("Bet queue contains no bets to be matched") return False return queue.ProcessLoop(storage)
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
def deploy(token: Token): """ :param token: Token Der Token der implementiert wird :return: bool: Ob die Ausführung erfolgreich war """ 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
def DistributeBetWinnings(self, args): storage = StorageAPI() isValidLength = ValidateArgsLength(args, 5) if isValidLength == False: return False bet = InitialiseBet(storage, args) outcome = self.ValidateDistributeWinnings(bet) if outcome == False: return False userID = bet.betMaker # breaks if you pass this in directly user = GetUser(storage, userID, False) storage.put(bet.statusKey, "claimed") if outcome == "void": """ Reimburse original bet if the event was voided """ _ = user.AddToBalance(storage, bet.betAmount) _ = OnVoidBetClaimed(bet.betID, bet.betMaker, args) else: bet = bet.CalculateWinnings() feePoolKey = self.feePoolID # breaks if you pass this in directly feePool = GetUser(storage, feePoolKey, False) _ = user.AddToBalance(storage, bet.returnAmount) _ = feePool.AddToBalance(storage, bet.feeAmount) _ = OnBetClaimed(bet.betID, bet.betMaker, args) return True