def upgrade(code): """ migrate data to new contract, transfer asset to admin address :param code: :return: """ assert CheckWitness(ADMIN) # transfer ont ont_balance = Invoke(VERSION, ONT_ADDRESS, "balanceOf", state(CONTRACT_ADDRESS)) ont_response = Invoke(VERSION, ONT_ADDRESS, "transfer", [state(CONTRACT_ADDRESS, ADMIN, ont_balance)]) if ont_response != INVOKE_SUCCESS: raise Exception("contract upgrade - transfer ont failed") # transfer ong ong_balance = Invoke(VERSION, ONG_ADDRESS, "balanceOf", state(CONTRACT_ADDRESS)) ong_response = Invoke(VERSION, ONG_ADDRESS, "transfer", [state(CONTRACT_ADDRESS, ADMIN, ong_balance)]) if ong_response != INVOKE_SUCCESS: raise Exception("contract upgrade - transfer ong failed") # migrate avm migrate_response = Migrate(code, "", "", "", "", "", "") if not migrate_response: raise Exception("contract upgrade - migrate avm failed") Notify(["upgrade", "success"]) return True
def subtract_ong(address, amount): byte_address = Base58ToAddress(address) assert (CheckWitness(byte_address)) if len(byte_address) != 20: Notify(['Invalid address']) return False if amount < 0: Notify(['Negative amount']) return False param = state(byte_address) if Invoke(0, contract_address_ONG, 'balanceOf', param) < amount: Notify(['Not enough ONG in wallet']) return False else: from_acct = byte_address to_acct = contract_address supply = Get(ctx, ONGKEY) supply += amount Put(ctx, ONGKEY, supply) Notify(['ONG supply increased by', amount]) params = state(from_acct, to_acct, amount) return Invoke(1, contract_address_ONG, 'transfer', [params])
def upgrade(code): """ upgrade current smart contract to new smart contract. :param code:new smart contract avm code. :return: True or raise exception. """ owner = getOwner() assert (CheckWitness(owner)) ongBalance = Invoke(0, ONG_ADDRESS, 'balanceOf', state(CONTRACT_ADDRESS)) res = Invoke(0, ONG_ADDRESS, "transfer", [state(CONTRACT_ADDRESS, owner, ongBalance)]) if res != b'\x01': assert (False) ontBalance = Invoke(0, ONT_ADDRESS, 'balanceOf', state(CONTRACT_ADDRESS)) res = Invoke(0, ONT_ADDRESS, "transfer", [state(CONTRACT_ADDRESS, owner, ontBalance)]) if res != b'\x01': assert (False) # upgrade smart contract res = Migrate(code, "", "", "", "", "", "") if not res: assert (False) Notify(["upgrade smart contract"]) return True
def upgrade(code, needStorage, name, version, author, email, description): """ upgrade current smart contract to new smart contract. :param code:new smart contract avm code. :return: True or raise exception. """ owner = getOwner() assert (CheckWitness(owner)) ontBalance = _getSelfONTBalance() if ontBalance > 0: res = Invoke(0, ONT_ADDRESS, "transfer", [state(CONTRACT_ADDRESS, owner, ontBalance)]) assert (res) assert (_tryUnboundOng()) ongBalance = _getSelfOngBalance() if ongBalance > 0: res = Invoke(0, ONG_ADDRESS, "transfer", [state(CONTRACT_ADDRESS, owner, ongBalance)]) assert (res) # upgrade smart contract res = Migrate(code, needStorage, name, version, author, email, description) if not res: assert (False) Notify(["upgrade", AddressFromVmCode(code)]) return True
def checkBalanceOf(ongFlag, account): param = state(ContractAddress) # do not use [param] res = Invoke(0, ONGAddress, 'balanceOf', param) Notify(["ContractAddress", ContractAddress, res]) param = state(account) if ongFlag == 1: Notify(["ongFlag", ongFlag]) res = Invoke(0, ONGAddress, 'balanceOf', param) else: Notify(["ongFlag", ongFlag]) res = Invoke(0, ONTAddress, 'balanceOf', param) Notify(["checkBalanceOf", account, res]) return res
def _transferONT(fromAcct, toAcct, amount): param = state(fromAcct, toAcct, amount) res = Invoke(0, ONTAddress, 'transfer', [param]) if res and res == b'\x01': return True else: return False
def _tranferNativeAsset(_nativeAssetAddress, _from, _to, _amount): param = state(_from, _to, _amount) res = Invoke(0, _nativeAssetAddress, 'transfer', [param]) if res and res == b'\x01': return True else: return False
def transferONT(fromacct, toacct, amount): """ transfer ONT :param fromacct: :param toacct: :param amount: :return: """ if CheckWitness(fromacct): param = makeState(fromacct, toacct, amount) res = Invoke(0, contractAddress, 'transfer', [fromacct, toacct, amount]) Notify(["11111", res]) if res and res == b'\x01': Notify('transfer succeed') return True else: Notify('transfer failed') return False else: Notify('checkWitness failed') return False
def lock(fee, to_chain_id, address, amount): """ lock some amount of tokens of this contract, call cross chain method to release to_amount of tokens of another chain's contract :param fee: miner fee of this cross chain tx :param to_chain_id: chain id of destination chain :param address: address of caller :param to_amount: amount to lock :return: """ if len(address) != 20: raise Exception("address length error") if CheckWitness(address) == False: raise Exception("address checkwitness failed.") # transfer asset res = transfer(address, CONTRACT_ADDRESS, amount) if not res: raise Exception("transfer failed.") # call cross chain contract input_map = {"address": address, "amount": amount} input_bytes = Serialize(input_map) destination_contract = Get(ctx, DESTINATION_CONTRACT) if destination_contract: param = state(fee, address, to_chain_id, destination_contract, "unlock", input_bytes) res = Invoke(0, CROSS_CHAIN_CONTRACT_ADDRESS, "createCrossChainTx", param) if not res: raise Exception("call cross chain contract failed.") else: raise Exception("destination contract can not be empty") LockEvent(fee, to_chain_id, destination_contract, address, amount) return True
def view_ong(address): byte_address = Base58ToAddress(address) if len(byte_address) != 20: Notify(['Invalid address']) return False # check if user list exists user_info = Get(ctx, USERKEY) if user_info: all_users = Deserialize(user_info) else: Notify(['User list is empty']) return False # check if user has been created if address not in all_users: Notify(['User not yet created']) return False # if the above checks hold, we can check the user's wallet. else: param = state(byte_address) ong_balance = Invoke(0, contract_address_ONG, 'balanceOf', param) if ong_balance == '': ong_balance = 0 Notify([ong_balance]) return ong_balance
def transferOntOng(from_acct, to_acct, ont, ong): param = state(from_acct, to_acct, ont) res = Invoke(0, OntContract, "transfer", [param]) if res != b'\x01': raise Exception("transfer ont error.") param = state(from_acct, to_acct, ong) Notify("transferONT succeed") res = Invoke(0, OngContract, "transfer", [param]) if res and res == b'\x01': Notify('transfer succeed') return True else: Notify('transfer failed') return False
def lock(fromAssetHash, fromAddress, toChainId, toAddress, amount): """ Decrease token supply from deducter address. :param amount: decreased token amount. :return: """ assert (amount >= 0) assert (CheckWitness(fromAddress)) assert (len(toAddress) != 0) # transfer asset from fromAddress to lock proxy contract assert (_transferToContract(fromAssetHash, fromAddress, amount)) # construct args for proxy contract in target chain toAssetHash = getAssetHash(fromAssetHash, toChainId) # make sure the toAssetHash is not empty assert (len(toAssetHash) != 0) argsList = [toAssetHash, toAddress, amount] # invoke the native cross chain manager contract to make transaction to target chain inputArgs = _serialzieArgs(argsList) toProxyHash = getProxyHash(toChainId) # make sure the toProxyHash is not empty assert (len(toProxyHash) != 0) param = state(toChainId, toProxyHash, "unlock", inputArgs) assert (Invoke(0, CROSS_CHAIN_CONTRACT_ADDRESS, "createCrossChainTx", param)) LockEvent(fromAssetHash, fromAddress, toChainId, toAssetHash, toAddress, amount) return True
def transferONGToContact(fromAcct, amount): param = state(fromAcct, ContractAddress, amount) res = Invoke(0, ONGAddress, 'transfer', [param]) if res and res == b'\x01': return True else: return False
def _tryUnboundOng(): unboundOng = _getUnboundOngBalance() if unboundOng > 0: params = state(CONTRACT_ADDRESS, ONT_ADDRESS, CONTRACT_ADDRESS, _getUnboundOngBalance()) return Invoke(0, ONG_ADDRESS, 'transferFrom', params) return True
def VerifyCaller(operation, caller, keyNo): authContractAddr = bytearray( b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06' ) param = state(GetExecutingScriptHash(), caller, operation, keyNo) res = Invoke(0, authContractAddr, "verifyToken", param) Require(res)
def lock(toChainId, fromAddress, toAddress, amount): """ Decrease token supply from deducter address. :param amount: decreased token amount. :return: """ fee = 0 assert (amount >= 0) assert (CheckWitness(fromAddress)) assert (not isPaused()) # eth address format:0x673dfa9caf9145fdbef98e9d9874f36e63d8a5b4,length is 42 assert (len(toAddress) != 0) Put(ctx, concat(BALANCE_KEY, fromAddress), Sub(balanceOf(fromAddress), amount)) Put(ctx, TOTAL_SUPPLY_KEY, Sub(totalSupply(), amount)) # construct args for proxy contract in target chain toAssetHash = getAssetHash(toChainId) argsList = [toAddress, amount] input_bytes = _serialzieArgs(argsList) param = state(toChainId, toAssetHash, "unlock", input_bytes) assert (Invoke(0, CROSS_CHAIN_CONTRACT_ADDRESS, "createCrossChainTx", param)) LockEvent(toChainId, fromAddress, toAddress, amount) return True
def add_ong(address, amount): byte_address = Base58ToAddress(address) assert (CheckWitness(byte_address)) if len(byte_address) != 20: Notify(['Invalid address']) return False if amount < 0: Notify(['Negative amount']) return False supply = Get(ctx, ONGKEY) if supply < amount: Notify(['Not enough ONG in supply']) return False else: from_acct = contract_address to_acct = byte_address supply -= amount Put(ctx, ONGKEY, supply) Notify(['ONG supply decreased by', amount]) params = state(from_acct, to_acct, amount) return Invoke(1, contract_address_ONG, 'transfer', [params])
def _transferONGFromContact(toAcct, amount): param = state(ContractAddress, toAcct, amount) res = Invoke(0, ONGAddress, 'transfer', [param]) if res and res == b'\x01': return True else: return False
def deposit_ong(address, ong_amount): assert (CheckWitness(address)) assert (ong_amount >= 0) params = state(address, contract_address, ong_amount) res = Invoke(0, contract_address_ONG, 'transfer', [params]) assert (res) Notify(["depositONG", address, ong_amount]) return True
def withdraw(): """ In case someone transfers ong or ont into this contract by accident, Admin can withdraw all the money left in the contract. :return: """ assert (CheckWitness(Admin)) param = state(SelfContractAddress) totalOngAmount = Invoke(0, ONGAddress, 'balanceOf', param) if totalOngAmount > 0: assert (_tranferNativeAsset(ONGAddress, SelfContractAddress, PreSaleReceiver, totalOngAmount)) totalOntAmount = Invoke(0, ONTAddress, 'balanceOf', param) if totalOntAmount > 0: assert (_tranferNativeAsset(ONTAddress, SelfContractAddress, PreSaleReceiver, totalOntAmount)) Notify(["withdraw", PreSaleReceiver, totalOngAmount, totalOntAmount]) return True
def withdrawOng(toAcct): param = state(ONTAddress, ContractAddress) unboundOngAmount = Invoke(0, ONGAddress, 'allowance', param) Notify(["unboundOngAmount", unboundOngAmount]) if unboundOngAmount > 0: unboundOngAmount = 147 params = state(ContractAddress, ONTAddress, toAcct, unboundOngAmount) res = Invoke(0, ONGAddress, "transferFrom", params) if res and res == b'\x01': Notify(["withdraw ong successful!"]) return True else: Notify(["withdraw ong failed!"]) return False else: Notify(["Not enough unboundOngAmount", unboundOngAmount]) return False
def balanceOf(account): """ can be invoked at every shard. If invoked at non-root shard, the shard must receive a xshard transfer before. Otherwise the function will throw an exception. :param account: user address :return: the token balance of account """ if len(account) != 20: raise Exception("address length error") return Invoke(SHARD_VERSION, XSHARD_ASSET_ADDR, 'oep4BalanceOf', account)
def getOngXShardTransferDetail(user, transferId): """ query user ong xshard transfer detail :param user: :param transferId: :return: xshard transfer info """ param = state(user, ONG_ASSET_ID, transferId) return Invoke(SHARD_VERSION, XSHARD_ASSET_ADDR, 'getOep4Transfer', param)
def getOngPendingXShardTransfer(user): """ get all pending ong transfer from user :param user: :return: user all pending ong xshard transfer detail """ param = state(user, ONG_ASSET_ID) return Invoke(SHARD_VERSION, XSHARD_ASSET_ADDR, 'getOep4PendingTransfer', param)
def burn(user, amount): """ burn asset from user account :param user: :param amount: :return: True means success, False or raising exception means failure. """ param = state(user, amount) return Invoke(SHARD_VERSION, XSHARD_ASSET_ADDR, 'oep4Burn', param)
def xshardTransferOngRetry(from_acc, transferId): """ if cross shard transfer failed, invoke this method to retry :param from_acc: :param transferId: xshard transfer id :return: True means success, False or raising exception means failure. """ param = state(from_acc, transferId) return Invoke(SHARD_VERSION, XSHARD_ASSET_ADDR, 'ongXShardTransferRetry', param)
def migrateContract(code, needStorage, name, version, author, email, description): RequireWitness(Admin) Require(_whenNotPaused() == False) param = state(SelfContractAddress) totalOngAmount = Invoke(0, ONGAddress, 'balanceOf', param) totalOntAmount = Invoke(0, ONTAddress, 'balanceOf', param) # Option1: TODO # newContractHash = AddressFromVmCode(code) # res = _tranferNativeAsset(ONGAddress, SelfContractAddress, newContractHash, totalOngAmount) # assert (res) # Option2: make sure there is no ong left Require(totalOngAmount == 0 and totalOntAmount == 0) res = Migrate(code, needStorage, name, version, author, email, description) Require(res) Notify(["migreate"]) return True
def xshardTransferOng(from_acc, to_acc, to_shard, amount): """ cross shard transfe ong :param from_acc: :param to_acc: :param to_shard: :param amount: :return: xshard transfer id """ param = state(from_acc, to_acc, to_shard, amount) return Invoke(SHARD_VERSION, XSHARD_ASSET_ADDR, 'ongXShardTransfer', param)
def checkWithdraw(account): allowanceOng = checkAllowance(account) withdrawOngAmount = allowanceOng / 2 params = state(account, ONTAddress, account, withdrawOngAmount) res = Invoke(0, ONGAddress, 'transferFrom', params) if res and res == b'\x01': Notify(["withdraw ong successful!"]) return True else: Notify(["withdraw ong failed!"]) return False
def allowance(owner, spender): """ check how many token the spender is allowed to spend from owner account :param owner: token owner :param spender: token spender :return: the allowed amount of tokens """ if len(owner) != 20 or len(spender) != 20: raise Exception("address length error") param = state(owner, spender) return Invoke(SHARD_VERSION, XSHARD_ASSET_ADDR, 'oep4Allowance', param)