def transfer(from_acct, to_acct, amount): """ Transfer amount of tokens from from_acct to to_acct :param from_acct: the account from which the amount of tokens will be transferred :param to_acct: the account to which the amount of tokens will be transferred :param amount: the amount of the tokens to be transferred, >= 0 :return: True means success, False or raising exception means failure. """ if len(to_acct) != 20 or len(from_acct) != 20: raise Exception("address length error") if CheckWitness(from_acct) == False or amount < 0: return False fromKey = concat(BALANCE_PREFIX, from_acct) fromBalance = Get(ctx, fromKey) if amount > fromBalance: return False if amount == fromBalance: Delete(ctx, fromKey) else: Put(ctx, fromKey, fromBalance - amount) toKey = concat(BALANCE_PREFIX, to_acct) toBalance = Get(ctx, toKey) Put(ctx, toKey, toBalance + amount) # Notify(["transfer", AddressToBase58(from_acct), AddressToBase58(to_acct), amount]) # TransferEvent(AddressToBase58(from_acct), AddressToBase58(to_acct), amount) TransferEvent(from_acct, to_acct, amount) return True
def transfer(from_acct, to_acct, amount): """ Transfer amount of tokens from from_acct to to_acct :param from_acct: the account from which the amount of tokens will be transferred :param to_acct: the account to which the amount of tokens will be transferred :param amount: the amount of the tokens to be transferred, >= 0 :return: True means success, False or raising exception means failure. """ assert (len(to_acct) == 20) assert (len(from_acct) == 20) assert (CheckWitness(from_acct)) assert (amount > 0) fromKey = concat(BALANCE_PREFIX, from_acct) fromBalance = Get(ctx, fromKey) assert (fromBalance >= amount) if amount == fromBalance: Delete(ctx, fromKey) else: Put(ctx, fromKey, fromBalance - amount) toKey = concat(BALANCE_PREFIX, to_acct) toBalance = Get(ctx, toKey) Put(ctx, toKey, toBalance + amount) TransferEvent(from_acct, to_acct, amount) return True
def transferFrom(spender, from_acct, to_acct, amount): if not CheckWitness(spender): return False Require(amount > 0) fromKey = concat(BALANCE_PREFIX,from_acct) fromBalance = Get(ctx, fromKey) if amount > fromBalance: return False approveKey = concat(concat(from_acct,APPROVE_PREFIX), spender) approvedAmount = Get(ctx, approveKey) if amount > approvedAmount: return False toKey = concat(to_acct,BALANCE_PREFIX) toBalance = Get(ctx, toKey) if amount == approvedAmount: Delete(ctx, approveKey) Put(ctx, fromKey, fromBalance - amount) else: Put(ctx, approveKey, approvedAmount - amount) Put(ctx, fromKey, fromBalance - amount) Put(ctx, toKey, toBalance + amount) TransferEvent(from_acct, to_acct, amount) return True
def WriteBool(v, buff): if v == True: buff = concat(buff, b'\x01') elif v == False: buff = concat(buff, b'\x00') else: assert (False) return buff
def approve(owner, spender, amount): if not CheckWitness(owner): return False key = concat(concat(APPROVE_PREFIX, owner), spender) Put(ctx, key, amount) ApprovalEvent(owner, spender, amount) return True
def concatKey(str1, str2): """ connect str1 and str2 together as a key :param str1: string1 :param str2: string2 :return: string1_string2 """ return concat(concat(str1, '_'), str2)
def bindAssetHash(fromAssetHash, toChainId, toAssetHash): assert (CheckWitness(Get(GetContext(), OPERATOR_PREFIX))) assert (_addFromAssetHash(fromAssetHash)) Put(GetContext(), concat(ASSET_HASH, concat(fromAssetHash, toChainId)), toAssetHash) curBalance = getBalanceFor(fromAssetHash) Notify( ["bindAssetHash", fromAssetHash, toChainId, toAssetHash, curBalance]) return True
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 """ key = concat(concat(APPROVE_PREFIX, owner), spender) return Get(ctx, key) + 0
def unlock(account, idx): KEY_lockCount = concat(USER_LOCK_CNT_PREFIX, account) lockCount = Get(ctx, KEY_lockCount) # idx is smaller than count of lock # require(idx<lockCount,"idx out of range") if idx >= lockCount: return False # Get lock info and releaseAmount KEY_lockInfo = concat(concat(USER_LOCK_PREFIX, account), idx) serializedLockinfo = Get(ctx, KEY_lockInfo) lockInfo = Deserialize(serializedLockinfo) releaseAmount = lockInfo['releaseAmount'] releaseTime = lockInfo['releaseTime'] # releaseAmount is Added to balance balance = Get(ctx, concat(BALANCE_PREFIX, account)) Put(ctx, concat(BALANCE_PREFIX, account), balance + releaseAmount) # last lockinfo copy to this idx lastLockInfo = Get( ctx, concat(concat(USER_LOCK_PREFIX, account), lockCount - 1)) Put(ctx, KEY_lockInfo, lastLockInfo) # delete last lockinfo (duplicated) Delete(ctx, concat(concat(USER_LOCK_PREFIX, account), lockCount - 1)) # decrease lockup count Put(ctx, KEY_lockCount, lockCount - 1) Notify([releaseTime, releaseAmount]) return True
def _transfer(_from, _to, _amount): fromKey = concat(BALANCE_PREFIX, _from) fromBalance = Get(GetContext(), fromKey) assert (_amount <= fromBalance) if _amount == fromBalance: Delete(GetContext(), concat(BALANCE_PREFIX, _from)) else: Put(GetContext(), fromKey, fromBalance - _amount) Put(GetContext(), concat(BALANCE_PREFIX, _to), balanceOf(_to) + _amount) TransferEvent(_from, _to, _amount) return True
def WriteVarUint(v, buff): if v < 0xFD: return WriteUint8(v, buff) elif v <= 0xFFFF: buff = concat(buff, 0xFD) return WriteUint16(v, buff) elif v <= 0xFFFFFFFF: buff = concat(buff, 0xFE) return WriteUint32(v, buff) else: buff = concat(buff, 0xFF) return WriteUint64(v, buff)
def startGame(pokerHashList, playerList, gameId): """ admin send param to start game algorithm: pokeHash = abs(sha256(pokerNum) ^ sha256(salt)) :param pokerHashList: [pokerHash1, pokerHash2, pokerHash3, ..., pokerHash52] send a list include 52 pokerHash :param playerList: [address1, address2, address3...] send all player address in this game :param gameId: game's id :return: bool """ assert (CheckWitness(Admin)) playerNum = len(playerList) pokerNum = len(pokerHashList) helperRandom = abs(GetCurrentBlockHash()) % pokerNum # deal poker to player playerPokerList = [] tmp = 0 while tmp < playerNum: # deal first poker playerHandPokerList = [] poker = pokerHashList[helperRandom] pokerHashList.remove(helperRandom) playerHandPokerList.append(poker) pokerNum = Sub(pokerNum, 1) # deal second poker helperRandom = abs(sha256(concat(helperRandom, poker))) % pokerNum poker = pokerHashList[helperRandom] pokerHashList.remove(helperRandom) playerHandPokerList.append(poker) pokerNum = Sub(pokerNum, 1) helperRandom = abs(sha256(concat(helperRandom, poker))) % pokerNum tmp += 1 playerPokerList.append(playerHandPokerList) # deal common poker commonPokerList = [] commonPokerNum = 0 while commonPokerNum < 5: poker = pokerHashList[helperRandom] pokerHashList.remove(helperRandom) commonPokerList.append(poker) pokerNum = Sub(pokerNum, 1) helperRandom = abs(sha256(concat(helperRandom, poker))) % pokerNum commonPokerNum += 1 Notify( ["startGame", pokerHashList, commonPokerList, playerPokerList, gameId]) return True
def approve(owner, spender, amount): """ owner allow spender to spend amount of token from owner account Note here, the amount should be less than the balance of owner right now. :param owner: :param spender: :param amount: amount>=0 :return: True means success, False or raising exception means failure. """ assert (len(spender) == 20 and len(owner) == 20) assert (amount >= 0 and amount <= balanceOf((owner))) assert (CheckWitness(owner)) approveKey = concat(concat(APPROVE_PREFIX, owner), spender) Put(GetContext(), approveKey, amount) ApprovalEvent(owner, spender, amount) return True
def unlock(params, fromContractAddr, fromChainId): """ the method should only be accessable for the ontology cross chain manager native contract. the 'params' will be deserialized just as it was serialized at the other side indicated by 'fromChainId'. make sure the fromContractAddr is we previously bound address through 'bindContractAddrWithChainId()' method. then update the balance and total supply :param params: :param fromContractAddr: :param fromChainId: :return: """ # make sure this method is being invoked by the ontology native cross chain manager contract assert (CheckWitness(CROSS_CHAIN_CONTRACT_ADDRESS)) # deserialize the params, obtain the toAddress and value and check its legality res = _deserialzieArgs(params) toAddress = res[0] value = res[1] assert (value >= 0) assert (isAddress(toAddress)) assert(len(fromContractAddr) != 0) assert(fromContractAddr == getContractAddrWithChainId(fromChainId)) # update the balance of toAddress and total supply Put(ctx, concat(BALANCE_KEY, toAddress), Add(balanceOf(toAddress), value)) Put(ctx, TOTAL_SUPPLY_KEY, Add(totalSupply(), value)) # emit the event UnlockEvent(CONTRACT_ADDRESS, toAddress, value) return True
def getContractAddrWithChainId(toChainId): """ return the asset contract hash of btc in 'toChainId' blockchain :param toChainId: this parameter is in integer format :return: the asset contract hash of btc in 'toChainId' blockchain, returned value is in hex format """ return Get(GetContext(), concat(CONTRACT_HASH, toChainId))
def balanceOf(account): """ :param account: :return: the token balance of account """ assert (len(account) == 20) return Get(ctx, concat(BALANCE_PREFIX, account)) + 0
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 unfreezeAccount(account): onlyOwner() requireFreeze(account) require(len(account) == 20, "address length error") Put(ctx, concat(USER_FREEZE_PREFIX, account), False) UserFreezeEvent(account, False) 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: """ require( len(spender) == 20 and len(from_acct) == 20 and len(to_acct) == 20, "address length error") require(CheckWitness(spender) == True, "Invalid invoker") whenNotPaused() requireNotFreeze(spender) requireNotFreeze(from_acct) requireNotFreeze(to_acct) autoUnlock(from_acct) fromKey = concat(BALANCE_PREFIX, from_acct) fromBalance = Get(ctx, fromKey) require(amount <= fromBalance and amount > 0, "Invalid amount") approveKey = concat(concat(APPROVE_PREFIX, from_acct), spender) approvedAmount = Get(ctx, approveKey) toKey = concat(BALANCE_PREFIX, to_acct) require(amount <= approvedAmount, "Invalid amount") if amount == approvedAmount: Delete(ctx, approveKey) Put(ctx, fromKey, fromBalance - amount) else: Put(ctx, approveKey, approvedAmount - amount) Put(ctx, fromKey, fromBalance - amount) toBalance = Get(ctx, toKey) Put(ctx, toKey, toBalance + amount) # Notify(["transfer", AddressToBase58(from_acct), AddressToBase58(to_acct), amount]) # TransferEvent(AddressToBase58(from_acct), AddressToBase58(to_acct), amount) TransferEvent(from_acct, to_acct, amount) return True
def getXZeroes(n): if n == 0: return b'' else: tmp = b'\x00' for i in range(0, n - 1): tmp = concat(tmp, b'\x00') return tmp
def approve(owner, spender, amount): """ owner allow spender to spend amount of token from owner account Note here, the amount should be less than the balance of owner right now. """ if len(spender) != 20 or len(owner) != 20: raise Exception("address length error") if CheckWitness(owner) == False: return False if amount > balanceOf(owner) or amount < 0: return False key = concat(concat(APPROVE_PREFIX, owner), spender) Put(ctx, key, amount) ApprovalEvent(owner, spender, amount) return True
def _convertNumToBytes(_val, bytesLen): l = len(_val) if l < bytesLen: for i in range(bytesLen - l): _val = concat(_val, b'\x00') if l > bytesLen: _val = _val[:bytesLen] return _val
def balanceOf(account): """ :param account: :return: the token balance of account """ require(len(account) == 20, "address length error") return Get(ctx,concat(BALANCE_PREFIX,account))
def _convertBytesToNum(_bs): firstNonZeroPostFromR2L = _getFirstNonZeroPosFromR2L(_bs) assert (firstNonZeroPostFromR2L >= 0) Notify(["111", _bs, firstNonZeroPostFromR2L]) if firstNonZeroPostFromR2L > len(_bs): return concat(_bs, b'\x00') else: return _bs[:firstNonZeroPostFromR2L]
def get_bucket(ont_id): """ get owner address with ont id :param ont_id: :return: """ return Get(ctx, concat(KEY_ONT, ont_id))
def checkIn(address, userId): assert (CheckWitness(address)) checkInDays = canCheckIn(address) assert (checkInDays > 0) Put(GetContext(), concat(PLAYER_LAST_CHECK_IN_DAY, address), checkInDays) Notify(["checkIn", address, userId, GetTime()]) return True
def balanceOf(account): """ :param account: :return: the token balance of account """ if len(account) != 20: raise Exception("Address length error") return Get(ctx,concat(BALANCE_PREFIX,account))
def init(): supply = Get(GetContext(), TOTAL_SUPPLY_KEY) assert (supply == 0) total = TotalSupply * FACTOR Put(GetContext(), TOTAL_SUPPLY_KEY, total) Put(GetContext(), concat(BALANCE_PREFIX, Admin), total) TransferEvent(ZERO_ADDRESS, Admin, total) return True
def bind(ont_id, bucket): """ bind ontID with address :param ont_id: :param bucket: storage server bucket id or url :return: """ assert CheckWitness(ADMIN) bound_bucket = Get(ctx, concat(KEY_ONT, ont_id)) if bound_bucket == bucket: raise Exception("ont id bind to the same bucket") if not bound_bucket: bind_map = get_bind_map(bucket) bind_map[ont_id] = True Put(ctx, concat(KEY_ONT, ont_id), bucket) Put(ctx, concat(KEY_BUCKET, bucket), Serialize(bind_map)) else: bound_data = Get(ctx, concat(KEY_BUCKET, bound_bucket)) bound_map = Deserialize(bound_data) bound_map.remove(ont_id) Put(ctx, concat(KEY_BUCKET, bound_bucket), Serialize(bound_map)) bind_map = get_bind_map(bucket) bind_map[ont_id] = True Put(ctx, concat(KEY_ONT, ont_id), bucket) Put(ctx, concat(KEY_BUCKET, bucket), Serialize(bind_map)) Notify(["bind", ont_id, bucket]) return True
def _transfer(_from, _to, _amount): fromKey = concat(BALANCE_PREFIX, _from) fromBalance = Get(ctx, fromKey) if _amount > fromBalance: return False if _amount == fromBalance: Delete(ctx, fromKey) else: Put(ctx, fromKey, fromBalance - _amount) toKey = concat(BALANCE_PREFIX, _to) toBalance = Get(ctx, toKey) Put(ctx, toKey, toBalance + _amount) # Notify(["transfer", AddressToBase58(from_acct), AddressToBase58(to_acct), amount]) # TransferEvent(AddressToBase58(from_acct), AddressToBase58(to_acct), amount) TransferEvent(_from, _to, _amount) return True