def CreateOracleRequest(request, address): #check witness RequireWitness(address) fee = Get(GetContext(), Fee) #transfer ong to oracle Admin address res = TransferONG(address, Admin, fee) Require(res) #get transaction hash txHash = GetTransactionHash(GetScriptContainer()) #update undoRequestMap undoRequestMap = GetUndoRequestMap() undoRequestMap[txHash] = request b = Serialize(undoRequestMap) Put(GetContext(), UndoRequestKey, b) Notify(["createOracleRequest", request, address]) return True
def init(operator, stateRoot, confirmHeight): inited = Get(GetContext(), INITED) if inited: Notify(["idiot admin, you have initialized the contract"]) return False else: assert (len(operator) == 20) assert (CheckWitness(operator)) assert (len(stateRoot) == 3) Put(GetContext(), INITED, 1) assert (confirmHeight > 0) Put(GetContext(), CONFRIM_HEIGHT, confirmHeight) Put(GetContext(), OPERATOR_ADDRESS, operator) Put(GetContext(), CURRENT_HEIGHT, stateRoot[1]) stateRootInfo = Serialize(stateRoot) Put(GetContext(), concatKey(Current_STATE_PREFIX, stateRoot[1]), stateRootInfo) Notify(["Initialized contract successfully"]) return True
def reset(ont_id, account): """ bind account with ont id, only be invoked by the admin :param ont_id: :param account: :return: """ assert is_address(account) assert CheckWitness(get_owner()) bound_ont_id = Get(ctx, concat(KEY_ACCOUNT, account)) assert bound_ont_id != ont_id Put(ctx, concat(KEY_ACCOUNT, account), ont_id) Put(ctx, concat(KEY_ONT_ID, ont_id), account) Notify(["reset", ont_id, account]) return True
def _createWithdrawState(height, withdrawAmounts, toAddresses, assetAddresses): assert (len(withdrawAmounts) == len(toAddresses)) length = len(withdrawAmounts) id = Get(GetContext(), CURRENT_WITHDRAW_ID) if not id: id = 1 for i in range(length): assert (withdrawAmounts[i] > 0) assert (len(toAddresses[i]) == 20) withdrawStatus = [ id, withdrawAmounts[i], toAddresses[i], height, 0, assetAddresses[i] ] withdrawStatusInfo = Serialize(withdrawStatus) Put(GetContext(), concatKey(WITHDRAW_PREFIX, id), withdrawStatusInfo) WithdrawEvent(id, withdrawAmounts[i], toAddresses[i], height, 0, assetAddresses[i]) id = id + 1 Put(GetContext(), CURRENT_WITHDRAW_ID, id) return True
def init(): ''' based on your requirements, initialize the tokens :return: ''' # Notify(["111_init"]) if not Get(ctx, INITED) and CheckWitness(admin) == True: Put(ctx, INITED, 'TRUE') Put(ctx, TOTAL_SUPPLY, 0) tt = createMultiTokens() if tt == True: # adminBalance = Get(ctx, concatkey(OWNER_BALANCE_PREFIX, admin)) # Put(ctx, TOTAL_SUPPLY, adminBalance) # Notify(["222_init", adminBalance]) return True return False else: Notify(["222_init"]) return False
def sendReqToOracle(jsonIndex): """ call oracle to get format or info of Games, including the, diskId :param jsonIndex: Int :return: """ RequireWitness(Operater) req = getOracleReq(jsonIndex) txhash = GetTransactionHash(GetScriptContainer()) if Get(GetContext(), concatKey(SENTREQHASH_FORMGAME_PREFIX, jsonIndex)): Put(GetContext(), concatKey(SENTREQHASH_SAVERES_PREFIX, jsonIndex), txhash) else: Put(GetContext(), concatKey(SENTREQHASH_FORMGAME_PREFIX, jsonIndex), txhash) res = OracleContract('CreateOracleRequest', [req, Operater]) Notify(["sendReqToOracle", txhash]) return True
def bind(ont_id, account): """ bind ontID with address :param ont_id: :param account: ontid owner wallet address :return: """ assert CheckWitness(account) bound_ont_id = Get(ctx, concat(KEY_ACCOUNT, account)) if bound_ont_id == ont_id: raise Exception("account bind to the same ont id") Put(ctx, concat(KEY_ACCOUNT, account), ont_id) Put(ctx, concat(KEY_ONT_ID, ont_id), account) stat(1) Notify(["bind", ont_id, account]) return True
def init(): if Get(ctx, BETKEY): Notify(['Already initialized']) return False else: BETID = 1 Put(ctx, BETKEY, BETID) Notify(['BETID inited']) aes_amount = 10000 * AES_FACTOR subtract_bank(token_owner, aes_amount) Put(ctx, AESKEY, aes_amount) Notify(['AES transferred to contract']) ong_amount = 1000 * ONG_FACTOR subtract_ong(token_owner, ong_amount) Put(ctx, ONGKEY, ong_amount) Notify(['ONG transferred to contract']) Notify(['Successfully inited']) return True
def remove_list(element): ab_info = Get(ctx, ABKEY) if ab_info: ab = Deserialize(ab_info) else: Notify(['Active bet list is empty before remove']) return False # find the index of the element to remove index = binary_search(ab, element) ab.remove(index) ab_info = Serialize(ab) if ab_info: Put(ctx, ABKEY, ab_info) Notify(["remove_list", element]) return True else: Delete(ctx, ABKEY) Notify(['Active bet list is empty after remove']) return False
def init(): """ initialize the contract, put some important info into the storage in the blockchain :return: """ if len(OWNER) != 20: Notify(["Owner illegal!"]) return False if Get(ctx,SUPPLY_KEY): Notify("Already initialized!") return False else: total = TOTAL_AMOUNT * FACTOR Put(ctx,SUPPLY_KEY,total) Put(ctx,concat(BALANCE_PREFIX,OWNER),total) # Notify(["transfer", "", Base58ToAddress(OWNER), total]) # ownerBase58 = AddressToBase58(OWNER) TransferEvent("", OWNER, total) return True
def autoUnlock(account): now = GetTime() KEY_lockCount = concat(USER_LOCK_CNT_PREFIX, account) lockCount = Get(ctx, KEY_lockCount) if lockCount > 0: i = 0 while i < lockCount: lockInfo = getLockState(account, i) deserializeUserLock = Deserialize(lockInfo) releaseTime = deserializeUserLock['releaseTime'] Notify([releaseTime]) if releaseTime <= now: if unlock(account, i): i -= 1 lockCount -= 1 i += 1 return True
def vote(bet, address, amount_staked, for_against): assert (CheckWitness(address)) # check if active bet list is populated/exists assert (check_bet_status(bet) == 1) assert (user_exist(address)) assert (for_against == False or for_against == True) if not get_voter_staked_amount(bet, address, for_against): Put( ctx, concatkey(bet, concatkey(address, concatkey(for_against, VOTE_PREFIX))), amount_staked) bet_voters = get_bet_voters(bet, for_against) Put(ctx, concatkey(bet, concatkey(for_against, BET_VOTERS_LIST)), Serialize(bet_voters.append(address))) versa_bet_voters = get_bet_voters(bet, 1 - for_against) assert (len(bet_voters) + len(versa_bet_voters) <= VOTES_PER_BET) else: Put( ctx, concatkey(bet, concatkey(address, concatkey(for_against, VOTE_PREFIX))), get_voter_staked_amount(bet, address, for_against) + amount_staked) bet_content_info = Get( ctx, concatkey(bet, concatkey(for_against, BET_CONTENT_PREFIX))) bet_content = Deserialize(bet_content_info) bet_content["reputation"] += get_user_repution(address) bet_content["count"] += 1 bet_content["staked"] += amount_staked Put(ctx, concatkey(bet, concatkey(for_against, BET_CONTENT_PREFIX)), Serialize(bet_content)) assert (deposit(address, amount_staked)) Notify(["vote", bet, address, amount_staked, for_against]) return True
def SetOracleOutcome(txHash, data, status, errMessage): #check witness syncAddress = Get(GetContext(), SyncAddress) Require(len(syncAddress) == 20) RequireWitness(syncAddress) #get undoRequest map undoRequestMap = GetUndoRequestMap() #TODO : check if key exist #put result into storage result = state(data, status, errMessage) r = Serialize(result) Put(GetContext(), txHash, r) #remove txHash from undoRequest map undoRequestMap.remove(txHash) b = Serialize(undoRequestMap) Put(GetContext(), UndoRequestKey, b) Notify(["setOracleOutcome", txHash, status, errMessage]) return True
def subtract_bank(address, amount): byte_address = Base58ToAddress(address) if len(byte_address) != 20: Notify(['Invalid address']) return False params = [byte_address] if RepContract('balanceOf', params) < amount: Notify(['Wallet balance too low']) return False else: from_acct = byte_address to_acct = contract_address supply = Get(ctx, SUPPKEY) supply += amount Put(ctx, SUPPKEY, supply) Notify(['Supply increased by', amount]) params = [from_acct, to_acct, amount] return RepContract('transfer', params)
def endGame(gameIdList): RequireWitness(Operater) totalDiskProfitForDev = 0 for gameId in gameIdList: # make sure placing bets stage is over Require(canPlaceBet(gameId) == False) # maker sure the game results have been saved diskResMapInfo = Get(GetContext(), concatKey(GAME_RES_PREFIX, gameId)) Require(diskResMapInfo) diskResMap = Deserialize(diskResMapInfo) diskIdList = getDiskIdList(gameId) for diskId in diskIdList: # if the gameId-diskId game hasn't been settled yet. if getDiskStatus(diskId) == 0: diskRes = diskResMap[diskId] diskProfitForDev = _endDisk(diskId, diskRes) totalDiskProfitForDev = Add(totalDiskProfitForDev, diskProfitForDev) # update the profit for dev _updateProfitForDev(totalDiskProfitForDev) return True
def GetAllowance(t_owner, t_spender): """ Gets the amount of tokens that a spender is allowed to spend from the owners' account. :param t_owner: Owner of tokens :type t_owner: bytearray :param t_spender: Requestor of tokens :type t_spender: bytearray :return: Amount allowed to be spent by Requestor on behalf of owner :rtype: int """ context = GetContext() allowance_key = concat(t_owner, t_spender) amount = Get(context, allowance_key) return amount
def init(): """ initialize the contract, put some important info into the storage in the blockchain :return: """ if len(OWNER) != 20: Notify(["Owner illegal!"]) return False if len(CONTRACT_ADDRESS) != 20: Notify(["Owner illegal!"]) return False if Get(ctx, SUPPLY_KEY): Notify("Already initialized!") return False else: total = TOTAL_AMOUNT * FACTOR Put(ctx, SUPPLY_KEY, total) Put(ctx, concat(BALANCE_PREFIX, CONTRACT_ADDRESS), total) TransferEvent("", CONTRACT_ADDRESS, total) return True
def testSink(bl, u8, u16, u32, u64, b, bs, vbs, addr, hash1, str1): sinkHash = Get(GetContext(), "SINK") Notify(["sinkHash", sinkHash]) buff = None buff = DynamicAppCall(sinkHash, "WriteBool", [bl, buff]) Notify([1, buff]) buff = DynamicAppCall(sinkHash, "WriteUint8", [u8, buff]) Notify([2, buff]) buff = DynamicAppCall(sinkHash, "WriteUint16", [u16, buff]) Notify([3, buff, 0xFFFF, 0xFFFF > 0]) buff = DynamicAppCall(sinkHash, "WriteUint32", [u32, buff]) Notify([4, buff]) buff = DynamicAppCall(sinkHash, "WriteUint64", [u64, buff]) Notify([5, buff, u64, 18446744073709551615]) buff = DynamicAppCall(sinkHash, "WriteByte", [b, buff]) Notify([6, buff]) buff = DynamicAppCall(sinkHash, "WriteBytes", [bs, buff]) Notify([7, buff]) buff = DynamicAppCall(sinkHash, "WriteVarBytes", [vbs, buff]) Notify([8, buff]) buff = DynamicAppCall(sinkHash, "WriteBytes20", [addr, buff]) Notify([9, buff]) buff = DynamicAppCall(sinkHash, "WriteBytes32", [hash1, buff]) Notify([10, buff]) buff = DynamicAppCall(sinkHash, "WriteString", [str1, buff]) Notify([11, buff]) return buff
def testSource(buff): sourceHash = Get(GetContext(), "SOURCE") Notify(["sourceHash", sourceHash]) offset = 0 res = DynamicAppCall(sourceHash, "NextBool", [buff, offset]) Notify([1, res, False]) res = DynamicAppCall(sourceHash, "NextUint8", [buff, res[1]]) Notify([2, res, 255]) res = DynamicAppCall(sourceHash, "NextUint16", [buff, res[1]]) Notify([3, res, 65535]) res = DynamicAppCall(sourceHash, "NextUint32", [buff, res[1]]) Notify([4, res, 4294967295]) res = DynamicAppCall(sourceHash, "NextUint64", [buff, res[1]]) Notify([5, res, 10100]) res = DynamicAppCall(sourceHash, "NextByte", [buff, res[1]]) Notify([6, res, 200]) res = DynamicAppCall(sourceHash, "NextBytes", [buff, res[1], 6]) Notify([7, res, "hahaha"]) res = DynamicAppCall(sourceHash, "NextVarBytes", [buff, res[1]]) Notify([8, res, "heiheihei"]) res = DynamicAppCall(sourceHash, "NextBytes20", [buff, res[1]]) Notify([9, res]) res = DynamicAppCall(sourceHash, "NextBytes32", [buff, res[1]]) Notify([10, res]) res = DynamicAppCall(sourceHash, "NextString", [buff, res[1]]) Notify([11, res]) return buff
def view_wallet(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: params = [byte_address] return RepContract("balanceOf", params)
def unbind(ont_id, account): """ unbind ont id with address :param ont_id: :param account: ont id owner wallet address :return: """ assert CheckWitness(account) bound_ont_id = Get(ctx, concat(KEY_ACCOUNT, account)) if not bound_ont_id: raise Exception("account not bind with any ont id") assert bound_ont_id == ont_id Delete(ctx, concat(KEY_ACCOUNT, account)) Delete(ctx, concat(KEY_ONT_ID, ont_id)) stat(-1) Notify(["unbind", ont_id, account]) return True
def transferFrom(spender, from_acct, to_acct, amount): """ spender spends amount of tokens on the behalf of from_acct, spender makes a transaction of amount of tokens from from_acct to to_acct :param spender: :param from_acct: :param to_acct: :param amount: :return: """ assert (amount > 0) assert (not isPaused()) assert (isAddress(from_acct) and isAddress(to_acct)) assert (CheckWitness(spender)) fromKey = concat(BALANCE_KEY, from_acct) fromBalance = balanceOf(from_acct) assert (fromBalance >= amount) approveKey = concat(concat(APPROVE_KEY, from_acct), spender) approvedAmount = Get(ctx, approveKey) if amount > approvedAmount: return False elif amount == approvedAmount: Delete(ctx, approveKey) Put(ctx, fromKey, Sub(fromBalance, amount)) else: Put(ctx, approveKey, Sub(approvedAmount, amount)) Put(ctx, fromKey, Sub(fromBalance, amount)) toBalance = balanceOf(to_acct) Put(ctx, concat(BALANCE_KEY, to_acct), Add(toBalance, amount)) TransferEvent(from_acct, to_acct, amount) return True
def RemoveToken(symbol, hash): """ :param symbol:token symbol, like "ONT", "ONG" :param hash: this token will be removed from the exchange. :return:True or False """ require(CheckWitness(Admin), "not admin") supportToken = Get(ctx, SUPPORTED_TOKEN) if not supportToken: return False tokenMap = Deserialize(supportToken) if tokenMap[symbol] != hash: return False tokenMap.remove(symbol) Put(ctx, SUPPORTED_TOKEN, Serialize(tokenMap)) Delete(ctx, concatKey(TOKEN_SYMBOL_PREFIX, symbol)) Delete(ctx, concatKey(TOKEN_HASH_PREFIX, hash)) return True
def RemoveExchange(exchangeName, exchangeId): """ :param exchangeName:exchange name, like "Huobi" :param exchangeId:exchange Id :return:True or False, if success, the exchange can't invoke token proxy smart contract. """ require(CheckWitness(Admin), "not admin") registerExchange = Get(ctx, REGISTERED_EXCHANGE) if not registerExchange: return False exchangeMap = Deserialize(registerExchange) if exchangeMap[exchangeName] != exchangeId: return False exchangeMap.remove(exchangeName) Put(ctx, REGISTERED_EXCHANGE, Serialize(exchangeMap)) Delete(ctx, concatKey(EXCHANGE_NAME_PREFIX, exchangeName)) Delete(ctx, concatKey(EXCHANGE_ID_PREFIX, exchangeId)) return True
def saveGameResultByHand(gameId, diskIdList, diskResList): RequireWitness(Operater) Require(canPlaceBet(gameId) == False) diskResMapInfo = Get(GetContext(), concatKey(GAME_RES_PREFIX, gameId)) if not diskResMapInfo: # 401: "Operator Should Request Game Result First!" Notify(["Error", 401]) return False diskResMap = Deserialize(diskResMapInfo) gameDiskIdList = getDiskIdList(gameId) diskIdLen = len(diskIdList) diskIdIndex = 0 while diskIdIndex < diskIdLen: diskId = diskIdList[diskIdIndex] Require(_checkInList(diskId, gameDiskIdList)) Require(getDiskStatus(diskId) == 0) # Require(diskResMap[diskId] == DefaultSide) diskResMap[diskId] = diskResList[diskIdIndex] diskIdIndex = diskIdIndex + 1 Put(GetContext(), concatKey(GAME_RES_PREFIX, gameId), Serialize(diskResMap)) Notify(["saveGameResultByHand", gameId, diskIdList, diskResList]) return True
def getPlayerDNAFromRange(Account, fromNum, toNum): """ get player's DNA list from fromNum to toNum toNum - fromNum must < 1000 can only get 1000 at most once paramExample: [Account, fromNum, toNum] :param Account: player's account :param fromNum: int :param toNum: int :return: [DNA1, DNA2, DNA3] """ Require(Sub(toNum, fromNum) < 1000) DNAlist = Get(context, concatKey(PLAYER_ADDRESS_PRE_KEY, Account)) if DNAlist: DNAlist = Deserialize(DNAlist) else: raise Exception("NO DNA") Require(Sub(toNum, fromNum) < len(DNAlist)) tmpList = [] while fromNum <= toNum: tmpList.append(DNAlist[Sub(fromNum, 1)]) fromNum += 1 return tmpList
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 transferFrom(spender, from_acct, to_acct, amount): """ spender spends amount of tokens on the behalf of from_acct, spender makes a transaction of amount of tokens from from_acct to to_acct :param spender: :param from_acct: :param to_acct: :param amount: :return: """ if len(spender) != 20 or len(from_acct) != 20 or len(to_acct) != 20: raise Exception("Address length error") if CheckWitness(spender) == False: return False fromKey = concat(BALANCE_PREFIX, from_acct) fromBalance = Get(ctx, fromKey) if amount > fromBalance: return False approveKey = concat(concat(APPROVE_PREFIX, from_acct), spender) approvedAmount = Get(ctx, approveKey) toKey = concat(BALANCE_PREFIX, to_acct) toBalance = Get(ctx, toKey) if amount > approvedAmount: return False elif amount == approvedAmount: Delete(ctx, approveKey) Put(ctx, fromKey, fromBalance - amount) else: Put(ctx, approveKey, approvedAmount - amount) Put(ctx, fromKey, fromBalance - amount) VaasAssert(approvedAmount > Get(ctx, approveKey)) Put(ctx, toKey, toBalance + amount) VaasAssert(toBalance < Get(ctx, toKey)) VaasAssert(fromBalance > Get(ctx, fromKey)) #TransferEvent(from_acct, to_acct, amount) return True
def getRecord(key): return Get(GetContext(), key)
def getFeeCollector(): return Get(GetContext(), FEE_COLLECTOR_KEY)