def to_stack_item(self, reference_counter: vm.ReferenceCounter) -> vm.StackItem: struct = vm.StructStackItem(reference_counter) struct.append(vm.ByteStringStackItem(self.name)) struct.append(vm.ArrayStackItem(reference_counter, list(map(lambda g: g.to_stack_item(reference_counter), self.groups))) ) struct.append(vm.ArrayStackItem(reference_counter, list(map(lambda s: vm.ByteStringStackItem(s), self.supported_standards))) ) struct.append(self.abi.to_stack_item(reference_counter)) struct.append(vm.ArrayStackItem(reference_counter, list(map(lambda p: p.to_stack_item(reference_counter), self.permissions))) ) if self.trusts.is_wildcard: struct.append(vm.NullStackItem()) else: struct.append( vm.ArrayStackItem(reference_counter, list(map(lambda t: vm.ByteStringStackItem(t.to_array()), self.trusts))) # type: ignore ) if self.extra is None: struct.append(vm.ByteStringStackItem("null")) else: struct.append(vm.ByteStringStackItem(json.dumps(self.extra))) return struct
def test_check_multisig_with_ECDSA_Secp256k1(self): # values taken from test_verify_secp256k1() engine = test_engine() message = vm.ByteStringStackItem(b'hello') signature = vm.ByteStringStackItem( binascii.unhexlify( b'5331be791532d157df5b5620620d938bcb622ad02c81cfc184c460efdad18e695480d77440c511e9ad02ea30d773cb54e88f8cbb069644aefa283957085f38b5' )) signatures = vm.ArrayStackItem(engine.reference_counter) signatures.append(signature) public_keys = vm.ArrayStackItem(engine.reference_counter) public_key = vm.ByteStringStackItem( binascii.unhexlify( b'03ea01cb94bdaf0cd1c01b159d474f9604f4af35a3e2196f6bdfdb33b2aa4961fa' )) public_keys.append(public_key) sb = vm.ScriptBuilder() sb.emit_syscall( syscall_name_to_int("Neo.Crypto.CheckMultisigWithECDsaSecp256k1")) script = vm.Script(sb.to_array()) engine.load_script(script) engine.push(signatures) engine.push(public_keys) engine.push(message) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) self.assertEqual(1, len(engine.result_stack)) self.assertEqual(vm.BooleanStackItem(True), engine.result_stack.pop())
def test_iterator_concat(self): engine = test_engine() array1 = vm.ArrayStackItem(engine.reference_counter) item1 = vm.IntegerStackItem(123) array1.append(item1) array2 = vm.ArrayStackItem(engine.reference_counter) item2 = vm.IntegerStackItem(456) array2.append(item2) script = vm.ScriptBuilder() # initialize 1 slot to store the iterator in script.emit(vm.OpCode.INITSLOT) script.emit_raw(b'\x01\x00') # stack state at this point is # * array2 # * array1 script.emit_syscall(syscall_name_to_int("System.Iterator.Create")) # Iterator.create removed array2 and places an iterator on the stack, we store this in a variables slot script.emit(vm.OpCode.STLOC0) # so we can call iterator.create again, with array1 as argument script.emit_syscall(syscall_name_to_int("System.Iterator.Create")) # we restore the iterator of array2 script.emit(vm.OpCode.LDLOC0) # we concat and get [array2, array1] script.emit_syscall(syscall_name_to_int("System.Iterator.Concat")) script.emit(vm.OpCode.STLOC0) # have just 1 value per iterator, so we call next and value just 2 times for _ in range(2): script.emit(vm.OpCode.LDLOC0) script.emit_syscall(syscall_name_to_int("System.Enumerator.Next")) script.emit(vm.OpCode.DROP) script.emit(vm.OpCode.LDLOC0) script.emit_syscall(syscall_name_to_int("System.Enumerator.Value")) # we add a call to key for coverage script.emit(vm.OpCode.LDLOC0) script.emit_syscall(syscall_name_to_int("System.Iterator.Key")) engine.load_script(vm.Script(script.to_array())) engine.push(array1) engine.push(array2) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) # we expect 3 values on there, 1 key/array index and 2 array values self.assertEqual(len(engine.result_stack), 3) key_from_engine = engine.result_stack.pop() self.assertEqual(vm.IntegerStackItem(0), key_from_engine) item1_from_engine = engine.result_stack.pop() self.assertEqual(item1, item1_from_engine) # item2 was put on last, comes of first item2_from_engine = engine.result_stack.pop() self.assertEqual(item2, item2_from_engine)
def tokens_of(self, snapshot: storage.Snapshot, owner: types.UInt160) -> interop.IIterator: storage_item_account = snapshot.storages.try_get(self.key_account + owner.to_array(), read_only=True) reference_counter = vm.ReferenceCounter() if storage_item_account is None: return interop.ArrayWrapper(vm.ArrayStackItem(reference_counter)) account = storage_item_account.get(NFTAccountState) tokens: List[vm.StackItem] = list(map(lambda t: vm.ByteStringStackItem(t), account.tokens)) return interop.ArrayWrapper(vm.ArrayStackItem(reference_counter, tokens))
def get_notifications(engine: contracts.ApplicationEngine, for_hash: types.UInt160) -> vm.ArrayStackItem: array = vm.ArrayStackItem(engine.reference_counter) for notification in engine.notifications: if notification[1] == for_hash: notification_stackitem = vm.ArrayStackItem(engine.reference_counter) notification_stackitem.append([ vm.ByteStringStackItem(notification[1].to_array()), # script_hash vm.ByteStringStackItem(notification[2]), # message notification[3].deep_copy() # state ]) array.append(notification_stackitem) if len(array) > engine.MAX_STACK_SIZE: raise ValueError("Notification count exceeds limits") return array
def finish(self, engine: contracts.ApplicationEngine) -> None: tx = engine.script_container tx = cast(payloads.Transaction, tx) response = tx.try_get_attribute(payloads.OracleResponse) if response is None: raise ValueError("Oracle response not found") request = self.get_request(engine.snapshot, response.id) if request is None: raise ValueError("Oracle request not found") state = vm.ArrayStackItem( engine.reference_counter, [vm.IntegerStackItem(response.id), vm.ByteStringStackItem(request.original_tx_id.to_array()) ] ) msgrouter.interop_notify(self.hash, "OracleResponse", state) user_data = contracts.BinarySerializer.deserialize(request.user_data, engine.MAX_STACK_SIZE, engine.reference_counter) args: List[vm.StackItem] = [vm.ByteStringStackItem(request.url.encode()), user_data, vm.IntegerStackItem(int(response.code)), vm.ByteStringStackItem(response.result)] engine.call_from_native(self.hash, request.callback_contract, request.callback_method, args)
def to_stack_item(self, reference_counter: vm.ReferenceCounter) -> vm.StackItem: struct = vm.StructStackItem(reference_counter) struct.append( vm.ArrayStackItem( reference_counter, list( map(lambda m: m.to_stack_item(reference_counter), self.methods)))) struct.append( vm.ArrayStackItem( reference_counter, list( map(lambda e: e.to_stack_item(reference_counter), self.events)))) return struct
def test_contract_call_ex(self): # code is the same as "test_contract_call" except for the interop engine = test_engine(has_snapshot=True, default_script=False) # current executing contract contract = storage.ContractState(hello_world_nef.script, hello_world_manifest) engine.snapshot.contracts.put(contract) # target contract target_contract = storage.ContractState(contract3_nef.script, contract3_manifest) engine.snapshot.contracts.put(target_contract) engine.load_script(vm.Script(contract.script)) engine.push(vm.IntegerStackItem(15)) # call flags array = vm.ArrayStackItem(engine.reference_counter) array.append(vm.IntegerStackItem(3)) engine.push(array) # args engine.push(vm.ByteStringStackItem("test_func2")) # method engine.push( vm.ByteStringStackItem(target_contract.script_hash().to_array())) engine.invoke_syscall_by_name("System.Contract.CallEx") engine.execute() self.assertEqual(2, len(engine.result_stack)) main_contract_return_value = engine.result_stack.pop() syscall_called_contract_return_value = engine.result_stack.pop() self.assertEqual("hello world", main_contract_return_value.to_array().decode()) self.assertEqual(4, int(syscall_called_contract_return_value))
def test_contract_call(self): engine = test_engine(has_snapshot=True, default_script=False) # current executing contract fake_hash = types.UInt160.deserialize_from_bytes(b'\x01' * 20) contract = contracts.ContractState(0, hello_world_nef, hello_world_manifest, 0, fake_hash) engine.snapshot.contracts.put(contract) # target contract fake_hash2 = types.UInt160.deserialize_from_bytes(b'\x02' * 20) target_contract = contracts.ContractState(1, contract3_nef, contract3_manifest, 0, fake_hash2) engine.snapshot.contracts.put(target_contract) engine.load_script(vm.Script(contract.script)) array = vm.ArrayStackItem(engine.reference_counter) array.append(vm.IntegerStackItem(3)) engine.push(array) # args engine.push(vm.IntegerStackItem(15)) # callflags engine.push(vm.ByteStringStackItem("test_func2")) # method engine.push(vm.ByteStringStackItem(target_contract.hash.to_array())) engine.invoke_syscall_by_name("System.Contract.Call") engine.execute() self.assertEqual(2, len(engine.result_stack)) main_contract_return_value = engine.result_stack.pop() syscall_called_contract_return_value = engine.result_stack.pop() self.assertEqual("hello world", main_contract_return_value.to_array().decode()) self.assertEqual(4, int(syscall_called_contract_return_value))
def test_with_array(self): """ var a = new Neo.VM.Types.Array(); var i = new Integer(new BigInteger(1)); var i2 = new Integer(new BigInteger(2)); a.Add(i); a.Add(i2); """ # Console.WriteLine($"b'\\x{BitConverter.ToString(BinarySerializer.Serialize(a, 999)).Replace("-", @"\x")}'"); # moved outside of multiline comment because pycharm is broken: https://youtrack.jetbrains.com/issue/PY-43117 i = vm.IntegerStackItem(vm.BigInteger(1)) i2 = vm.IntegerStackItem(vm.BigInteger(2)) a = vm.ArrayStackItem(self.reference_counter) a.append(i) a.append(i2) expected = b'\x40\x02\x21\x01\x01\x21\x01\x02' out = contracts.BinarySerializer.serialize(a, 999) self.assertEqual(expected, out) # now we add a reference to ourselves. with self.assertRaises(ValueError) as context: a.append(a) contracts.BinarySerializer.serialize(a, 999) self.assertEqual("Item already exists", str(context.exception)) # now test deserialization # first remove the reference to self a.remove(len(a) - 1) new_a = contracts.BinarySerializer.deserialize(out, 2048, self.reference_counter) self.assertIsInstance(a, vm.ArrayStackItem) self.assertEqual(a._items, new_a._items)
def _post_transfer(self, engine: contracts.ApplicationEngine, account_from: types.UInt160, account_to: types.UInt160, amount: vm.BigInteger, data: vm.StackItem, call_on_payment: bool) -> None: state = vm.ArrayStackItem(vm.ReferenceCounter()) if account_from == types.UInt160.zero(): state.append(vm.NullStackItem()) else: state.append(vm.ByteStringStackItem(account_from.to_array())) if account_to == types.UInt160.zero(): state.append(vm.NullStackItem()) else: state.append(vm.ByteStringStackItem(account_to.to_array())) state.append(vm.IntegerStackItem(amount)) msgrouter.interop_notify(self.hash, "Transfer", state) # wallet or smart contract if not call_on_payment \ or account_to == types.UInt160.zero() \ or contracts.ManagementContract().get_contract(engine.snapshot, account_to) is None: return if account_from == types.UInt160.zero(): from_: vm.StackItem = vm.NullStackItem() else: from_ = vm.ByteStringStackItem(account_from.to_array()) engine.call_from_native( self.hash, account_to, "onNEP17Payment", [from_, vm.IntegerStackItem(amount), data])
def designate_as_role(self, engine: contracts.ApplicationEngine, role: DesignateRole, nodes: List[cryptography.ECPoint]) -> None: if len(nodes) == 0: raise ValueError( "[DesignateContract] Cannot designate empty nodes list") if len(nodes) > 32: raise ValueError( "[DesignateContract] Cannot designate a nodes list larger than 32" ) if not self._check_committee(engine): raise ValueError("[DesignateContract] check committee failed") if engine.snapshot.persisting_block is None: raise ValueError nodes.sort() index = engine.snapshot.persisting_block.index + 1 storage_key = self.create_key( role.to_bytes(1, 'little') + self._to_uint32(index)) with serialization.BinaryWriter() as writer: writer.write_serializable_list(nodes) storage_item = storage.StorageItem(writer.to_array()) engine.snapshot.storages.update(storage_key, storage_item) state = vm.ArrayStackItem(engine.reference_counter) state.append(vm.IntegerStackItem(role.value)) state.append( vm.IntegerStackItem(engine.snapshot.persisting_block.index)) msgrouter.interop_notify(self.hash, "Designation", state)
def get_candidates(self, engine: contracts.ApplicationEngine) -> None: array = vm.ArrayStackItem(engine.reference_counter) for k, v in self._get_candidates(engine.snapshot): struct = vm.StructStackItem(engine.reference_counter) struct.append(vm.ByteStringStackItem(k.to_array())) struct.append(vm.IntegerStackItem(v)) array.append(struct) engine.push(array)
def to_stack_item(self, reference_counter: vm.ReferenceCounter) -> vm.StackItem: array = vm.ArrayStackItem(reference_counter) script = vm.ByteStringStackItem(self.script) manifest = vm.ByteStringStackItem(str(self.manifest)) has_storage = vm.BooleanStackItem(self.has_storage) is_payable = vm.BooleanStackItem(self.is_payable) array.append([script, manifest, has_storage, is_payable]) return array
def test_enumerator_create_from_array(self): engine = test_engine() array = vm.ArrayStackItem(engine.reference_counter) item1 = vm.ByteStringStackItem(b'\x01') array.append(item1) engine.push(array) r = engine.invoke_syscall_by_name("System.Enumerator.Create") self.assertIsInstance(r, ArrayWrapper) self.assertTrue(r.next()) self.assertEqual(item1, r.value())
def test_serialization_array(self): b = vm.BooleanStackItem(True) bs = vm.ByteStringStackItem("test") i = vm.IntegerStackItem(123) n = vm.NullStackItem() ref_ctr = vm.ReferenceCounter() a = vm.ArrayStackItem(ref_ctr) a.append([b, bs, i, n]) expected = r'[true,"test",123,null]' self.assertEqual(expected, contracts.JSONSerializer.serialize(a, 999))
def get_candidates(self, engine: contracts.ApplicationEngine) -> None: """ Fetch all registered candidates, convert them to a StackItem and push them onto the evaluation stack. """ array = vm.ArrayStackItem(engine.reference_counter) for k, v in self._get_candidates(engine.snapshot): struct = vm.StructStackItem(engine.reference_counter) struct.append(vm.ByteStringStackItem(k.to_array())) struct.append(vm.IntegerStackItem(v)) array.append(struct) engine.push(array)
def contract_create_with_data( self, engine: contracts.ApplicationEngine, nef_file: bytes, manifest: bytes, data: vm.StackItem) -> contracts.ContractState: if not isinstance(engine.script_container, payloads.Transaction): raise ValueError( "Cannot create contract without a Transaction script container" ) nef_len = len(nef_file) manifest_len = len(manifest) if (nef_len == 0 or nef_len > engine.MAX_CONTRACT_LENGTH or manifest_len == 0 or manifest_len > contracts.ContractManifest.MAX_LENGTH): raise ValueError("Invalid NEF or manifest length") engine.add_gas( max(engine.STORAGE_PRICE * (nef_len + manifest_len), self.get_minimum_deployment_fee(engine.snapshot))) nef = contracts.NEF.deserialize_from_bytes(nef_file) parsed_manifest = contracts.ContractManifest.from_json( json.loads(manifest.decode())) self.validate(nef.script, parsed_manifest.abi) sb = vm.ScriptBuilder() sb.emit(vm.OpCode.ABORT) sb.emit_push(engine.script_container.sender.to_array()) sb.emit_push(nef.checksum) sb.emit_push(parsed_manifest.name) hash_ = to_script_hash(sb.to_array()) existing_contract = engine.snapshot.contracts.try_get(hash_) if existing_contract is not None: raise ValueError("Contract already exists") contract = contracts.ContractState( self.get_next_available_id(engine.snapshot), nef, parsed_manifest, 0, hash_) if not contract.manifest.is_valid(hash_): raise ValueError("Error: invalid manifest") engine.snapshot.contracts.put(contract) method_descriptor = contract.manifest.abi.get_method("_deploy", 2) if method_descriptor is not None: engine.call_from_native(self.hash, hash_, method_descriptor.name, [data, vm.BooleanStackItem(False)]) msgrouter.interop_notify( self.hash, "Deploy", vm.ArrayStackItem(engine.reference_counter, vm.ByteStringStackItem( contract.hash.to_array()))) return contract
def test_runtime_notify_exceed_size(self): engine = test_engine() engine.push(vm.ArrayStackItem(engine.reference_counter)) # state engine.push( vm.ByteStringStackItem( b'\x01' * (engine.MAX_EVENT_SIZE + 1))) # event messasge with self.assertRaises(ValueError) as context: engine.invoke_syscall_by_name("System.Runtime.Notify") self.assertEqual( "Notify event name length (33) exceeds maximum allowed (32)", str(context.exception))
def to_stack_item(self, reference_counter: vm.ReferenceCounter) -> vm.StackItem: struct = vm.StructStackItem(reference_counter) struct.append(vm.ByteStringStackItem(self.name)) array = vm.ArrayStackItem( reference_counter, list( map(lambda p: p.to_stack_item(reference_counter), self.parameters))) struct.append(array) return struct
def test_notify_state_helper_basics(self): bssi = vm.ByteStringStackItem(b'\x01\x02') # 2 null = vm.NullStackItem() # 0 primitive = vm.IntegerStackItem(2) # 1 engine = test_engine() array1 = vm.ArrayStackItem(engine.reference_counter) array2 = vm.ArrayStackItem(engine.reference_counter) array2.append(primitive) # we expect a size of 3, given that our self reference should be ignored. # 5 would mean a failure of detecting a circular reference for ArrayStackItem types array1.append([bssi, null, array2, array1]) self.assertEqual(3, _validate_state_item_limits(engine, array1)) with self.assertRaises(ValueError) as context: _validate_state_item_limits(engine, vm.InteropStackItem(object())) self.assertEqual( "An item in the notification state exceeds the allowed notification size limit", str(context.exception))
def to_stack_item(self, reference_counter: vm.ReferenceCounter) -> vm.StackItem: array = vm.ArrayStackItem(reference_counter) id_ = vm.IntegerStackItem(self.id) nef = vm.ByteStringStackItem(self.nef.to_array()) update_counter = vm.IntegerStackItem(self.update_counter) hash_ = vm.ByteStringStackItem(self.hash.to_array()) array.append([ id_, update_counter, hash_, nef, self.manifest.to_stack_item(reference_counter) ]) return array
def test_serialization_array_nested(self): bool_t = vm.BooleanStackItem(True) bool_f = vm.BooleanStackItem(False) bs1 = vm.ByteStringStackItem("test1") bs2 = vm.ByteStringStackItem("test2") i1 = vm.IntegerStackItem(123) i2 = vm.IntegerStackItem(321) ref_ctr = vm.ReferenceCounter() a1 = vm.ArrayStackItem(ref_ctr) a1.append([bool_t, bs1, i1]) a2 = vm.ArrayStackItem(ref_ctr) a2.append([bool_f, bs2, i2]) parent = vm.ArrayStackItem(ref_ctr) parent.append([a1, a2]) expected = r'[[true,"test1",123],[false,"test2",321]]' self.assertEqual(expected, contracts.JSONSerializer.serialize(parent, 999))
def test_contract_call_ex_fail(self): engine = test_engine() array = vm.ArrayStackItem(engine.reference_counter) engine.push(vm.IntegerStackItem(123)) # invalid value for CallFlags engine.push(array) # args engine.push(vm.ByteStringStackItem("test_func2")) # method engine.push(vm.ByteStringStackItem(b'\x00')) # call flags with self.assertRaises(ValueError) as context: engine.invoke_syscall_by_name("System.Contract.CallEx") self.assertIn("Failed to convert parameter stack item", str(context.exception))
def test_check_multisig_with_ECDSA_Secp256r1(self): engine = test_engine() message = vm.ByteStringStackItem(b'hello') kp1 = cryptography.KeyPair(private_key=b'\x01' * 32) sig1 = cryptography.sign(message.to_array(), kp1.private_key) sb = vm.ScriptBuilder() sb.emit_syscall( syscall_name_to_int("Neo.Crypto.CheckMultisigWithECDsaSecp256r1")) script = vm.Script(sb.to_array()) engine.load_script(script) # setup the stack for the syscall signatures = vm.ArrayStackItem(engine.reference_counter) signatures.append(vm.ByteStringStackItem(sig1)) public_keys = vm.ArrayStackItem(engine.reference_counter) public_keys.append( vm.ByteStringStackItem(kp1.public_key.encode_point(False))) engine.push(signatures) engine.push(public_keys) engine.push(message) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) self.assertEqual(1, len(engine.result_stack)) self.assertEqual(vm.BooleanStackItem(True), engine.result_stack.pop()) # do the same but change the message such that the signature and key are wrong engine = test_engine() engine.load_script(script) engine.push(signatures) engine.push(public_keys) engine.push(vm.ByteStringStackItem(b'badmessage')) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) self.assertEqual(1, len(engine.result_stack)) self.assertEqual(vm.BooleanStackItem(False), engine.result_stack.pop())
def test_runtime_getnotifications_limit_exceeded(self): engine = test_engine() target_hash = types.UInt160.zero() state = vm.ArrayStackItem(engine.reference_counter) # we can't adjust the limit, so we need to exceed it for i in range(0, engine.MAX_STACK_SIZE + 1): engine.notifications.append( (object(), target_hash, b'notif' + str(i).encode(), state)) engine.push(vm.ByteStringStackItem(target_hash.to_array())) with self.assertRaises(ValueError) as context: engine.invoke_syscall_by_name("System.Runtime.GetNotifications") self.assertEqual("Notification count exceeds limits", str(context.exception))
def test_array_key_exception(self): """ calling `key` on an array iterator without having called `next` should fail """ engine = test_engine() array = vm.ArrayStackItem(engine.reference_counter) item = vm.IntegerStackItem(123) array.append(item) engine.push(array) engine.invoke_syscall_by_name("System.Iterator.Create") with self.assertRaises(ValueError) as context: engine.invoke_syscall_by_name("System.Iterator.Key") self.assertEqual( "Cannot call 'key' without having advanced the iterator at least once", str(context.exception))
def test_serialization_basics(self): ref = vm.ReferenceCounter() m = vm.MapStackItem(ref) s = contracts.JSONSerializer.serialize(m, 999) self.assertEqual("{}", s) a = vm.ArrayStackItem(ref) s = contracts.JSONSerializer.serialize(a, 999) self.assertEqual(r'[]', s) i1 = vm.IntegerStackItem(1) i2 = vm.IntegerStackItem(9007199254740992) a.append([i1, i2]) s = contracts.JSONSerializer.serialize(a, 999) self.assertEqual(r'[1,"9007199254740992"]', s)
def contract_update_with_data(self, engine: contracts.ApplicationEngine, nef_file: bytes, manifest: bytes, data: vm.StackItem) -> None: nef_len = len(nef_file) manifest_len = len(manifest) engine.add_gas(engine.STORAGE_PRICE * (nef_len + manifest_len)) contract = engine.snapshot.contracts.try_get(engine.calling_scripthash, read_only=False) if contract is None: raise ValueError("Can't find contract to update") if nef_len == 0: raise ValueError(f"Invalid NEF length: {nef_len}") # update contract contract.nef = contracts.NEF.deserialize_from_bytes(nef_file) if manifest_len == 0 or manifest_len > contracts.ContractManifest.MAX_LENGTH: raise ValueError(f"Invalid manifest length: {manifest_len}") manifest_new = contracts.ContractManifest.from_json( json.loads(manifest.decode())) if manifest_new.name != contract.manifest.name: raise ValueError("Error: cannot change contract name") if not contract.manifest.is_valid(contract.hash): raise ValueError("Error: manifest does not match with script") contract.manifest = manifest_new self.validate(contract.nef.script, contract.manifest.abi) contract.update_counter += 1 if len(nef_file) != 0: method_descriptor = contract.manifest.abi.get_method("_deploy", 2) if method_descriptor is not None: engine.call_from_native(self.hash, contract.hash, method_descriptor.name, [data, vm.BooleanStackItem(True)]) msgrouter.interop_notify( self.hash, "Update", vm.ArrayStackItem(engine.reference_counter, vm.ByteStringStackItem( contract.hash.to_array())))
def test_native_call(self): engine = test_engine(has_snapshot=True, default_script=True) block = test_block(0) engine.snapshot.persisting_block = block # need to create and store a contract matching the current_context.script # otherwise system.contract.call checks will fail engine.snapshot.contracts.put( storage.ContractState(b'\x40', contracts.ContractManifest())) engine.invoke_syscall_by_name("Neo.Native.Deploy") engine.push(vm.ArrayStackItem( engine.reference_counter)) # empty array for no arguments engine.push(vm.ByteStringStackItem(b'getMaxTransactionsPerBlock')) policy_contract_hash = vm.ByteStringStackItem( contracts.PolicyContract().script_hash.to_array()) engine.push(policy_contract_hash) engine.invoke_syscall_by_name("System.Contract.Call")