def test_itoa(self): engine = test_engine(has_snapshot=True) original_item = 100 base = 10 sb = vm.ScriptBuilder() sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "itoa", [original_item, base]) engine.load_script(vm.Script(sb.to_array())) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) item = engine.result_stack.pop() self.assertEqual('100', item.to_array().decode('utf-8')) engine = test_engine(has_snapshot=True) base = 16 sb = vm.ScriptBuilder() sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "itoa", [original_item, base]) engine.load_script(vm.Script(sb.to_array())) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) item = engine.result_stack.pop() self.assertEqual('64', item.to_array().decode('utf-8')) engine = test_engine(has_snapshot=True) invalid_base = 2 sb = vm.ScriptBuilder() sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "itoa", [original_item, invalid_base]) engine.load_script(vm.Script(sb.to_array())) engine.execute() self.assertEqual(vm.VMState.FAULT, engine.state) self.assertIn("Invalid base specified", engine.exception_message)
def test_json_deserialization(self): script = vm.ScriptBuilder() script.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "jsonDeserialize", [123]) script.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "jsonDeserialize", ["null"]) engine = test_engine(has_snapshot=True) data = script.to_array() engine.load_script(vm.Script(data)) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) self.assertEqual(2, len(engine.result_stack._items)) self.assertIsInstance(engine.result_stack.pop(), vm.NullStackItem) self.assertEqual(vm.BigInteger(123), engine.result_stack.pop().to_biginteger())
def test_base58_decode(self): engine = test_engine(has_snapshot=True) original_item = 100 sb = vm.ScriptBuilder() sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "base58Encode", [original_item]) # now take the results of the "base58Encode" call and call "base64Decode" on the StdLib contract sb.emit_push(1) sb.emit( vm.OpCode.PACK ) # pack the results of "base58Encode" as the arguments for the next call sb.emit_push(0xF) # CallFlags.ALL sb.emit_push("base58Decode") sb.emit_push(contracts.StdLibContract().hash.to_array()) sb.emit_syscall(syscall_name_to_int("System.Contract.Call")) engine.load_script(vm.Script(sb.to_array())) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) item = engine.result_stack.pop() self.assertEqual(original_item, int(item.to_biginteger()))
def test_base58_encode(self): engine = test_engine(has_snapshot=True) original_item = 100 sb = vm.ScriptBuilder() sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "base58Encode", [original_item]) engine.load_script(vm.Script(sb.to_array())) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) item = engine.result_stack.peek() self.assertEqual('2j', item.to_array().decode())
def test_json_deserialization(self): script = vm.ScriptBuilder() script.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "jsonDeserialize", ["{\"key\":\"value\"}"]) script.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "jsonDeserialize", ["null"]) engine = test_engine(has_snapshot=True) data = script.to_array() engine.load_script(vm.Script(data)) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) self.assertEqual(2, len(engine.result_stack._items)) self.assertIsInstance(engine.result_stack.pop(), vm.NullStackItem) r = engine.result_stack.pop() self.assertIsInstance(r, vm.MapStackItem) self.assertEqual(1, len(r)) self.assertEqual(vm.ByteStringStackItem("key"), r.keys()[0]) self.assertEqual(vm.ByteStringStackItem("value"), r.values()[0])
def init(self): self._methods: Dict[int, _NativeMethodMeta] = {} # offset, meta self._management = contracts.ManagementContract() self._neo = contracts.NeoToken() self._gas = contracts.GasToken() self._policy = contracts.PolicyContract() self._oracle = contracts.OracleContract() self._ledger = contracts.LedgerContract() self._role = contracts.DesignationContract() self._crypto = contracts.CryptoContract() self._stdlib = contracts.StdLibContract() # Find all methods that have been augmented by the @register decorator # and turn them into methods that can be called by VM scripts methods_meta = [] for pair in inspect.getmembers(self, lambda m: hasattr(m, "native_call")): methods_meta.append(_NativeMethodMeta(pair[1])) methods_meta.sort( key=lambda x: (x.descriptor.name, len(x.descriptor.parameters))) sb = vm.ScriptBuilder() for meta in methods_meta: meta.descriptor.offset = len(sb) sb.emit_push(0) self._methods.update({len(sb): meta}) sb.emit_syscall(1736177434) # "System.Contract.CallNative" sb.emit(vm.OpCode.RET) self._script: bytes = sb.to_array() self.nef = contracts.NEF("neo-core-v3.0", self._script) sender = types.UInt160.zero() # OpCode.PUSH1 sb = vm.ScriptBuilder() sb.emit(vm.OpCode.ABORT) sb.emit_push(sender.to_array()) sb.emit_push(0) sb.emit_push(self.service_name()) self._hash: types.UInt160 = to_script_hash(sb.to_array()) self._manifest: contracts.ContractManifest = contracts.ContractManifest( ) self._manifest.name = self.service_name() self._manifest.abi.methods = list( map(lambda m: m.descriptor, methods_meta)) if self._id != NativeContract._id: self._contracts.update({self.service_name(): self}) self._contract_hashes.update({self._hash: self}) self.active_block_index = settings.native_contract_activation.get( self.service_name, 0)
def test_binary_serialization(self): engine = test_engine(has_snapshot=True) original_item = 100 sb = vm.ScriptBuilder() sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "serialize", [original_item]) engine.load_script(vm.Script(sb.to_array())) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) item = engine.result_stack.pop() self.assertIsInstance(item, vm.ByteStringStackItem) self.assertEqual(b'\x21\x01\x64', item.to_array())
def test_json_serialization(self): sb = vm.ScriptBuilder() sb.emit_push(5) sb.emit_push(1) # arg len sb.emit(vm.OpCode.PACK) sb.emit_push(0xF) # CallFlags.ALL sb.emit_push("jsonSerialize") sb.emit_push(contracts.StdLibContract().hash.to_array()) sb.emit_syscall(syscall_name_to_int("System.Contract.Call")) sb.emit(vm.OpCode.PUSH0) sb.emit(vm.OpCode.NOT) sb.emit_push(1) # arg len sb.emit(vm.OpCode.PACK) sb.emit_push(0xF) # CallFlags.ALL sb.emit_push("jsonSerialize") sb.emit_push(contracts.StdLibContract().hash.to_array()) sb.emit_syscall(syscall_name_to_int("System.Contract.Call")) sb.emit_push("test") sb.emit_push(1) # arg len sb.emit(vm.OpCode.PACK) sb.emit_push(0xF) # CallFlags.ALL sb.emit_push("jsonSerialize") sb.emit_push(contracts.StdLibContract().hash.to_array()) sb.emit_syscall(syscall_name_to_int("System.Contract.Call")) sb.emit(vm.OpCode.PUSHNULL) sb.emit_push(1) # arg len sb.emit(vm.OpCode.PACK) sb.emit_push(0xF) # CallFlags.ALL sb.emit_push("jsonSerialize") sb.emit_push(contracts.StdLibContract().hash.to_array()) sb.emit_syscall(syscall_name_to_int("System.Contract.Call")) sb.emit(vm.OpCode.NEWMAP) sb.emit(vm.OpCode.DUP) sb.emit_push("key") sb.emit_push("value") sb.emit(vm.OpCode.SETITEM) sb.emit_push(1) # arg len sb.emit(vm.OpCode.PACK) sb.emit_push(0xF) # CallFlags.ALL sb.emit_push("jsonSerialize") sb.emit_push(contracts.StdLibContract().hash.to_array()) sb.emit_syscall(syscall_name_to_int("System.Contract.Call")) data = sb.to_array() engine = test_engine(has_snapshot=True) engine.load_script(vm.Script(data)) engine.execute() self.assertEqual(vm.VMState.HALT, engine.state) def pop_to_human_readable(): return binascii.unhexlify(str( engine.result_stack.pop()).encode()).decode() self.assertEqual('{"key":"value"}', pop_to_human_readable()) self.assertEqual('null', pop_to_human_readable()) self.assertEqual('"test"', pop_to_human_readable()) self.assertEqual('true', pop_to_human_readable()) self.assertEqual('5', pop_to_human_readable())