def parse_single_item(item: Union[Dict, List]): if 'iterator' in item: item = item['iterator'] if item: if type(item[0]['value']) is not list: return [parse_single_item(i) for i in item] else: return { parse_single_item(i['value'][0]): parse_single_item(i['value'][1]) for i in item } _type = item['type'] if _type == 'Any' and 'value' not in item: return None else: value = item['value'] if _type == 'Integer': return int(value) elif _type == 'Boolean': return value elif _type == 'ByteString' or _type == 'Buffer': byte_value = base64.b64decode(value) try: return byte_value.decode() except UnicodeDecodeError: try: len_bytes = len(byte_value) if len_bytes == 20: return Hash160Str.from_UInt160(UInt160(byte_value)) if len_bytes == 32: return Hash256Str.from_UInt256(UInt256(byte_value)) except Exception: pass # may be an N3 address starting with 'N' # TODO: decode to N3 address return byte_value elif _type == 'Array': return [parse_single_item(i) for i in value] elif _type == 'Struct': return tuple([parse_single_item(i) for i in value]) elif _type == 'Map': return { parse_single_item(i['key']): parse_single_item(i['value']) for i in value } elif _type == 'Pointer': return int(value) else: raise ValueError(f'Unknown type {_type}')
def sendfrom(self, asset_id: Hash160Str, from_address: str, to_address: str, value: int, signers: List[Signer] = None): """ :param asset_id: NEO: '0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5'; GAS: '0xd2a4cff31913016155e38e474a2c06d08be276cf' :param from_address: "NgaiKFjurmNmiRzDRQGs44yzByXuSkdGPF" :param to_address: "NikhQp1aAD1YFCiwknhM5LQQebj4464bCJ" :param value: 100000000, including decimals :param signers: :return: """ if not signers: signers = [self.signer] return self.meta_rpc_method( 'sendfrom', [asset_id.to_str(), from_address, to_address, value, signers])
from tests.utils import Hash160Str, Signer, WitnessScope, \ gen_expiry_timestamp_and_str_in_seconds,\ ClientResultInterpreter, sleep_until, sleep_for_next_block from neo_test_with_rpc import TestClient from neo3.contracts import NeoToken, GasToken neo, gas = NeoToken(), GasToken() target_url = 'http://127.0.0.1:23332' # make sure you deploy ruler.nef manually # contract_hash = Hash160Str('0xaf9abd7ba5bfb7dd17d70267ed09ec9d0876c814') from tests.config import contract_hash consensus_wallet_address = 'NhSRQSzNv8BwjKwQn2Spk7tY194uxXiESv' consensus_wallet_hash = Hash160Str('0x113f10ed24f2b70115d37c103130a236b7011dec') consensus_signer = Signer(consensus_wallet_hash, WitnessScope.CalledByEntry) dev_wallet_address = 'NTzUx1Jm4oe7QPU2ankRtDwBzEGuiMfJim' dev_wallet_hash = Hash160Str('0xa44dcf7f3a95ae60c6c2e97cf904979fd4839b58') dev_signer = Signer(dev_wallet_hash, WitnessScope.CalledByEntry) administrating_client = TestClient(target_url, contract_hash, consensus_wallet_hash, consensus_wallet_address, 'consensus.json', '1') administrating_client.openwallet() # expiry_timestamp, expiry_str = gen_expiry_timestamp_and_str(33) # this works for deposit and repay expiry_timestamp, expiry_str = gen_expiry_timestamp_and_str_in_seconds(60) # this does not work for deposit print(expiry_timestamp - time.time() * 1000) DECIMAL_BASE = 100_000_000 mint_ratio = 7 * DECIMAL_BASE fee_rate = 0 * DECIMAL_BASE
from tests.utils import Hash160Str contract_hash = Hash160Str('0xc99053e99aeb4de8477cd1da1e528071ec0a06d6')
def bytes_to_UInt160(bytestring: bytes): return Hash160Str.from_UInt160( UInt160.deserialize_from_bytes(bytestring))
def get_gas_balance(self) -> int: return self.getwalletbalance(Hash160Str.from_UInt160(GasToken().hash))
def get_neo_balance(self) -> int: return self.getwalletbalance(Hash160Str.from_UInt160(NeoToken().hash))
def getwalletbalance(self, asset_id: Hash160Str) -> int: return int( self.meta_rpc_method('getwalletbalance', [asset_id.to_str()])['balance'])
def send_gas_to_address(self, to_address: Hash160Str, value: int): return self.sendtoaddress(Hash160Str.from_UInt160(gas.hash), to_address, value)
def parse_params( param: Union[str, int, dict, Hash160Str, UInt160, UInt256, bytes] ) -> Dict[str, str]: type_param = type(param) if type_param is UInt160: return { 'type': 'Hash160', 'value': str(Hash160Str.from_UInt160(param)), } elif type_param is Hash160Str: return { 'type': 'Hash160', 'value': str(param), } elif type_param is UInt256: return { 'type': 'Hash256', 'value': str(Hash256Str.from_UInt256(param)), } elif type_param is Hash256Str: return { 'type': 'Hash256', 'value': str(param), } elif type_param is PublicKeyStr: return { 'type': 'PublicKey', 'value': str(param), } elif type_param is bool: return { 'type': 'Boolean', 'value': param, } elif type_param is int: return { 'type': 'Integer', 'value': str(param), } elif type_param is str: return { 'type': 'String', 'value': param, } elif type_param is bytes: # not the best way to judge, but maybe no better method try: return { 'type': 'String', 'value': param.decode(), } except UnicodeDecodeError: return { 'type': 'ByteArray', 'value': base64.b64encode(param).decode() } elif type_param is list: return { 'type': 'Array', 'value': [parse_params(param_) for param_ in param] } elif type_param is dict: return { 'type': 'Map', 'value': [{ 'key': parse_params(k), 'value': parse_params(v) } for k, v in param.items()] } elif param is None: return { 'type': 'Any', } raise ValueError( f'Unable to handle param {param} with type {type_param}')