def __init__(self, event_type, event_payload, contract_hash, block_number, tx_hash, execution_success=False, test_mode=False): super(NotifyEvent, self).__init__(event_type, event_payload, contract_hash, block_number, tx_hash, execution_success, test_mode) self.is_standard_notify = False plen = len(self.event_payload) if plen > 0: self.notify_type = self.event_payload[0] empty = UInt160(data=bytearray(20)) try: if plen == 4 and self.notify_type in [ NotifyType.TRANSFER, NotifyType.APPROVE ]: if self.event_payload[1] is None: self.addr_from = empty else: self.addr_from = UInt160( data=self.event_payload[1]) if len( self.event_payload[1]) == 20 else empty self.addr_to = UInt160(data=self.event_payload[2]) if len( self.event_payload[2]) == 20 else empty self.amount = int(BigInteger.FromBytes( event_payload[3])) if isinstance( event_payload[3], bytes) else int(event_payload[3]) self.is_standard_notify = True elif plen == 3 and self.notify_type == NotifyType.REFUND: self.addr_to = UInt160(data=self.event_payload[1]) if len( self.event_payload[1]) == 20 else empty self.amount = int(BigInteger.FromBytes( event_payload[2])) if isinstance( event_payload[2], bytes) else int(event_payload[2]) self.addr_from = self.contract_hash self.is_standard_notify = True except Exception as e: logger.info("Could not determine notify event: %s %s" % (e, self.event_payload))
def Storage_GetContext(self, engine): hash = UInt160(data=engine.CurrentContext.ScriptHash()) context = StorageContext(script_hash=hash) engine.EvaluationStack.PushT(StackItem.FromInterface(context)) return True
def Storage_GetReadOnlyContext(self, engine: ExecutionEngine): hash = UInt160(data=engine.CurrentContext.ScriptHash()) context = StorageContext(script_hash=hash, read_only=True) engine.CurrentContext.EvaluationStack.PushT( StackItem.FromInterface(context)) return True
def test_get_contract_state_0x(self): contract_hash = '0x%s' % UInt160(data=bytearray( b'\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[') ).ToString() req = self._gen_rpc_req("getcontractstate", params=[contract_hash]) mock_req = mock_request(json.dumps(req).encode("utf-8")) res = json.loads(self.app.home(mock_req)) self.assertEqual(res['result']['code_version'], '3')
def Blockchain_GetAccount(self, engine): hash = UInt160(data=engine.EvaluationStack.Pop().GetByteArray()) address = Crypto.ToAddress(hash).encode('utf-8') account = self.Accounts.GetOrAdd( address, new_instance=AccountState(script_hash=hash)) engine.EvaluationStack.PushT(StackItem.FromInterface(account)) return True
def ReadUInt160(self): """ Read a UInt160 value from the stream. Returns: UInt160: """ return UInt160(data=bytearray(self.ReadBytes(20)))
def Blockchain_GetContract(self, engine): hash = UInt160(data=engine.EvaluationStack.Pop().GetByteArray()) contract = self.Contracts.TryGet(hash.ToBytes()) if contract is None: engine.EvaluationStack.PushT(bytearray(0)) else: engine.EvaluationStack.PushT(StackItem.FromInterface(contract)) return True
def test_accountstate_ToJson(self): hash = UInt160(data=self.ac2_h) account = AccountState(script_hash=hash) res = account.ToJson() self.assertEqual(res['address'], account.Address) self.assertEqual(res['script_hash'], str(hash))
def Blockchain_GetContract(self, engine): hash = UInt160(data=engine.EvaluationStack.Pop().GetByteArray()) contract = None if Blockchain.Default() is not None: contract = Blockchain.Default().GetContract(hash) engine.EvaluationStack.PushT(StackItem.FromInterface(contract)) return True
def __init__(self, event_type, event_payload, contract_hash, block_number, tx_hash, execution_success=False, test_mode=False): super(NotifyEvent, self).__init__(event_type, event_payload, contract_hash, block_number, tx_hash, execution_success, test_mode) self.is_standard_notify = False if self.event_payload.Type == ContractParameterType.Array and len(self.event_payload.Value) > 0: payload = self.event_payload.Value plen = len(payload) self.notify_type = payload[0].Value empty = UInt160(data=bytearray(20)) try: if plen == 4 and self.notify_type in [NotifyType.TRANSFER, NotifyType.APPROVE]: if payload[1].Value is None: self.addr_from = empty logger.debug("Using contract addr from address %s " % self.event_payload) elif payload[1].Value is False: logger.debug("Using contract addr from address %s " % self.event_payload) self.addr_from = empty else: self.addr_from = UInt160(data=payload[1].Value) if len(payload[1].Value) == 20 else empty self.addr_to = UInt160(data=payload[2].Value) if len(payload[2].Value) == 20 else empty self.amount = int(BigInteger.FromBytes(payload[3].Value)) if isinstance(payload[3].Value, (bytes, bytearray)) else int(payload[3].Value) self.is_standard_notify = True elif self.notify_type == NotifyType.REFUND and plen >= 3: # Might have more arguments self.addr_to = UInt160(data=payload[1].Value) if len(payload[1].Value) == 20 else empty self.amount = int(BigInteger.FromBytes(payload[2].Value)) if isinstance(payload[2].Value, (bytes, bytearray)) else int(payload[2].Value) self.addr_from = self.contract_hash self.is_standard_notify = True elif self.notify_type == NotifyType.MINT and plen == 3: self.addr_to = UInt160(data=payload[1].Value) if len(payload[1].Value) == 20 else empty self.amount = int(BigInteger.FromBytes(payload[2].Value)) if isinstance(payload[2].Value, (bytes, bytearray)) else int(payload[2].Value) self.addr_from = self.contract_hash self.is_standard_notify = True except Exception as e: logger.debug("Could not determine notify event: %s %s" % (e, self.event_payload)) elif self.event_payload.Type == ContractParameterType.String: self.notify_type = self.event_payload.Value
def Contract_Create(self, engine): script = engine.EvaluationStack.Pop().GetByteArray() if len(script) > 1024 * 1024: return False param_list = engine.EvaluationStack.Pop().GetByteArray() if len(param_list) > 252: return False return_type = int(engine.EvaluationStack.Pop().GetBigInteger()) contract_properties = int(engine.EvaluationStack.Pop().GetBigInteger()) if len(engine.EvaluationStack.Peek().GetByteArray()) > 252: return False name = engine.EvaluationStack.Pop().GetByteArray() if len(engine.EvaluationStack.Peek().GetByteArray()) > 252: return False code_version = engine.EvaluationStack.Pop().GetByteArray() if len(engine.EvaluationStack.Peek().GetByteArray()) > 252: return False author = engine.EvaluationStack.Pop().GetByteArray() if len(engine.EvaluationStack.Peek().GetByteArray()) > 252: return False email = engine.EvaluationStack.Pop().GetByteArray() if len(engine.EvaluationStack.Peek().GetByteArray()) > 65536: return False description = engine.EvaluationStack.Pop().GetByteArray() hash = Crypto.ToScriptHash(script, unhex=False) contract = self._contracts.TryGet(hash.ToBytes()) if contract is None: code = FunctionCode(script=script, param_list=param_list, return_type=return_type, contract_properties=contract_properties) contract = ContractState(code, contract_properties, name, code_version, author, email, description) self._contracts.GetAndChange(code.ScriptHash().ToBytes(), contract) self._contracts_created[hash.ToBytes()] = UInt160(data=engine.CurrentContext.ScriptHash()) engine.EvaluationStack.PushT(StackItem.FromInterface(contract)) # logger.info("*****************************************************") # logger.info("CREATED CONTRACT %s " % hash.ToBytes()) # logger.info("*****************************************************") return True
def test_get_contract_state(self): contract_hash = UInt160(data=bytearray(b'\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[')).ToString() req = self._gen_rpc_req("getcontractstate", params=[contract_hash]) mock_req = mock_request(json.dumps(req).encode("utf-8")) res = json.loads(self.app.home(mock_req)) self.assertEqual(res['result']['code_version'], '3') self.assertEqual(res['result']['properties']['storage'], True) self.assertEqual(res['result']['code']['hash'], '0x5b7074e873973a6ed3708862f219a6fbf4d1c411') self.assertEqual(res['result']['code']['returntype'], 5) self.assertEqual(res['result']['code']['parameters'], '0710')
def address_to_scripthash(address): data = b58decode(address) if len(data) != 25: raise ValueError('Not correct Address, wrong length.') if data[0] != settings.ADDRESS_VERSION: raise ValueError('Not correct Coin Version') checksum = Crypto.Default().Hash256(data[:21])[:4] if checksum != data[21:]: raise Exception('Address format error') return UInt160(data=data[1:21]).ToBytes()
def process_hold_created_event(self, payload): if len(payload) == 4: vin = payload[0] from_addr = UInt160(data=payload[1]) to_addr = UInt160(data=payload[2]) amount = int.from_bytes(payload[3], 'little') v_index = int.from_bytes(vin[32:], 'little') v_txid = UInt256(data=vin[0:32]) if to_addr.ToBytes() in self._contracts.keys( ) and from_addr in self._watch_only: hold, created = VINHold.get_or_create( Index=v_index, Hash=v_txid.ToBytes(), FromAddress=from_addr.ToBytes(), ToAddress=to_addr.ToBytes(), Amount=amount, IsComplete=False) if created: self.LoadHolds()
def get_nep5token_id(contract_hash): hash_ar = bytearray(binascii.unhexlify(contract_hash)) hash_ar.reverse() hash = UInt160(data=hash_ar) token = NEP5Token() token.SetScriptHash(hash) # token.symbol = "TNC" token.decimals = 8 return token
def test_5_addr_conv(self): wallet = self.GetWallet1() addr = UInt160(data=b'\xec\xa8\xfc\xf9Nz*\x7f\xc3\xfdT\xae\x0e\xd3\xd3MR\xec%\x90') addr_str = 'AdMDZGto3xWozB1HSjjVv27RL3zUM8LzpV' to_uint = wallet.ToScriptHash(addr_str) self.assertEqual(to_uint, addr)
def Storage_Get(self, engine): context = None try: item = engine.EvaluationStack.Pop() context = item.GetInterface() shash = context.ScriptHash except Exception as e: logger.error("could not get storage context %s " % e) return False contract = Blockchain.Default().GetContract( context.ScriptHash.ToBytes()) if contract is not None: if not contract.HasStorage: return False else: return False key = engine.EvaluationStack.Pop().GetByteArray() storage_key = StorageKey(script_hash=context.ScriptHash, key=key) item = Blockchain.Default().GetStorageItem(storage_key) keystr = key valStr = bytearray(0) if item is not None: valStr = bytearray(item.Value) if len(key) == 20: keystr = Crypto.ToAddress(UInt160(data=key)) try: valStr = int.from_bytes(valStr, 'little') except Exception as e: logger.error("Could not convert %s to number: %s " % (valStr, e)) if item is not None: engine.EvaluationStack.PushT(bytearray(item.Value)) else: engine.EvaluationStack.PushT(bytearray(0)) self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.STORAGE_GET, ['%s -> %s' % (keystr, valStr)], context.ScriptHash, Blockchain.Default().Height + 1, engine.ScriptContainer.Hash, test_mode=engine.testMode)) return True
def Blockchain_GetAccount(self, engine): hash = UInt160(data=engine.EvaluationStack.Pop().GetByteArray()) address = Crypto.ToAddress(hash).encode('utf-8') account = Blockchain.Default().GetAccountState(address) if account: engine.EvaluationStack.PushT(StackItem.FromInterface(account)) else: engine.EvaluationStack.PushT(False) return True
def ToScriptHash(address): data = b58decode(address) if len(data) != 25: raise ValueError('Not correct Address, wrong length.') if data[0] != 23: raise ValueError('Not correct Coin Version') checksum = Crypto.Default().Hash256(data[:21])[:4] if checksum != data[21:]: raise Exception('Address format error') return UInt160(data=data[1:21])
def Storage_Get(self, engine): context = None try: item = engine.EvaluationStack.Pop() context = item.GetInterface() except Exception as e: logger.error("could not get storage context %s " % e) return False if not self.CheckStorageContext(context): return False key = engine.EvaluationStack.Pop().GetByteArray() storage_key = StorageKey(script_hash=context.ScriptHash, key=key) item = self.Storages.TryGet(storage_key.ToArray()) keystr = key valStr = bytearray(0) if item is not None: valStr = bytearray(item.Value) if len(key) == 20: keystr = Crypto.ToAddress(UInt160(data=key)) try: valStr = int.from_bytes(valStr, 'little') except Exception as e: logger.error("Could not convert %s to number: %s " % (valStr, e)) if item is not None: engine.EvaluationStack.PushT(bytearray(item.Value)) else: engine.EvaluationStack.PushT(bytearray(0)) tx_hash = None if engine.ScriptContainer: tx_hash = engine.ScriptContainer.Hash self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.STORAGE_GET, ContractParameter(ContractParameterType.String, value='%s -> %s' % (keystr, valStr)), context.ScriptHash, Blockchain.Default().Height + 1, tx_hash, test_mode=engine.testMode)) return True
def test_9_lookup_should_be_empty(self): ndb = NotificationDB.instance() sh = UInt160( data=b')\x96S\xb5\xe3e\xcb3\xb4\xea:\xd1\xd7\xe1\xb3\xf5\xe6\x82N/' ) events = ndb.get_by_addr(sh) self.assertEqual(len(events), 0)
def test_7_lookup_addr_by_script_hash(self): ndb = NotificationDB.instance() sh = UInt160( data=b')\x96S\xb5\xe3e\xcb3\xb4\xea:\xd1\xd7\xe1\xb3\xf5\xe6\x81N/' ) events = ndb.get_by_addr(sh) self.assertEqual(len(events), 1)
def test_4_delete_addr(self): wallet = self.GetWallet1() self.assertEqual(len(wallet.GetContracts()), 2) imported_addr = UInt160(data=b'\xec\xa8\xfc\xf9Nz*\x7f\xc3\xfdT\xae\x0e\xd3\xd3MR\xec%\x90') wallet.DeleteAddress(imported_addr) self.assertEqual(len(wallet.GetContracts()), 1)
def CheckDynamicInvoke(self): cx = self.CurrentContext if cx.InstructionPointer >= len(cx.Script): return True opcode = cx.NextInstruction if opcode in [OpCode.APPCALL, OpCode.TAILCALL]: opreader = cx.OpReader # read the current position of the stream start_pos = opreader.stream.tell() # normal app calls are stored in the op reader # we read ahead past the next instruction 1 the next 20 bytes script_hash = opreader.ReadBytes(21)[1:] # then reset the position opreader.stream.seek(start_pos) for b in script_hash: # if any of the bytes are greater than 0, this is a normal app call if b > 0: return True # if this is a dynamic app call, we will arrive here # get the current executing script hash current = UInt160(data=cx.ScriptHash()) current_contract_state = self._Table.GetContractState( current.ToBytes()) # if current contract state cant do dynamic calls, return False return current_contract_state.HasDynamicInvoke elif opcode in [OpCode.CALL_ED, OpCode.CALL_EDT]: current = UInt160(data=cx.ScriptHash()) current_contract_state = self._Table.GetContractState( current.ToBytes()) return current_contract_state.HasDynamicInvoke else: return True
def __init__(self, asset_id=None, asset_type=None, name=None, amount=Fixed8(0), available=Fixed8(0), precision=0, fee_mode=0, fee=Fixed8(0), fee_addr=UInt160(data=bytearray(20)), owner=None, admin=None, issuer=None, expiration=None, is_frozen=False): """ Create an instance. Args: asset_id (UInt256): asset_type (neo.Core.AssetType): name (str): the asset name. amount (Fixed8): available (Fixed8): precision (int): number of decimals the asset has. fee_mode (Fixed8): fee (int): fee_addr (UInt160): where the fee will be send to. owner (EllipticCurve.ECPoint): admin (UInt160): the administrator of the asset. issuer (UInt160): the issuer of the asset. expiration (UInt32): the block number on which the asset expires. is_frozen (bool): """ self.AssetId = asset_id self.AssetType = asset_type self.Name = name self.Amount = amount self.Available = available self.Precision = precision self.FeeMode = fee_mode self.Fee = fee self.FeeAddress = fee_addr if owner is not None and type(owner) is not EllipticCurve.ECPoint: raise Exception("Owner must be ECPoint Instance") self.Owner = owner self.Admin = admin self.Issuer = issuer self.Expiration = expiration self.IsFrozen = is_frozen
def RawBytesToScriptHash(raw): """ Get a hash of the provided raw bytes using the ripemd160 algorithm. Args: raw (bytes): byte array of raw bytes. e.g. b'\xAA\xBB\xCC' Returns: UInt160: """ rawh = binascii.unhexlify(raw) rawhashstr = binascii.unhexlify(bytes(Crypto.Hash160(rawh), encoding='utf-8')) return UInt160(data=rawhashstr)
def ToScriptHash(data, unhex=True): """ Get a script hash of the data. Args: data (bytes): data to hash. unhex (bool): (Default) True. Set to unhexlify the stream. Use when the bytes are not raw bytes; i.e. b'aabb' Returns: UInt160: script hash. """ if len(data) > 1 and unhex: data = binascii.unhexlify(data) return UInt160(data=binascii.unhexlify(bytes(Crypto.Hash160(data), encoding='utf-8')))
def Contract_GetStorageContext(self, engine): contract = engine.EvaluationStack.Pop().GetInterface() if contract.ScriptHash.ToBytes() in self._contracts_created: created = self._contracts_created[contract.ScriptHash.ToBytes()] if created == UInt160(data=engine.CurrentContext.ScriptHash()): context = StorageContext(script_hash=contract.ScriptHash) engine.EvaluationStack.PushT(StackItem.FromInterface(context)) return True
def test_compareto_valid(self): u1 = UInt160(b'12345678901234567890') # Same value should return 0 u2 = UIntBase(20, b'12345678901234567890') self.assertEqual(u1.CompareTo(u2), 0) # Higher digit in 'other' should return -1 u2 = UIntBase(20, b'12345678901234567891') self.assertEqual(u1.CompareTo(u2), -1) # Lower digit in 'other' should return 1 u2 = UIntBase(20, b'12345678901234567980') self.assertEqual(u1.CompareTo(u2), 1) # CompareTo across different UIntBase subclasses data = b'12345678901234567890' self.assertEqual(UInt160(data).CompareTo(UIntBase(len(data), data)), 0) self.assertEqual(UIntBase(len(data), data).CompareTo(UInt160(data)), 0) data = b'12345678901234567890123456789012' self.assertEqual(UInt256(data).CompareTo(UIntBase(len(data), data)), 0) self.assertEqual(UIntBase(len(data), data).CompareTo(UInt256(data)), 0)
def Runtime_Log(self, engine): message = engine.EvaluationStack.Pop().GetByteArray() hash = UInt160(data=engine.CurrentContext.ScriptHash()) # Build and emit smart contract event self.events_to_dispatch.append( SmartContractEvent(SmartContractEvent.RUNTIME_LOG, [message], hash, Blockchain.Default().Height, engine.ScriptContainer.Hash, test_mode=engine.testMode)) return True