def test_call_function_written_before_caller(self): call_address = Integer(-9).to_byte_array(min_length=1, signed=True) expected_output = ( Opcode.INITSLOT # TestFunction + b'\x00' + b'\x02' + Opcode.LDARG0 # return a + b + Opcode.LDARG1 + Opcode.ADD + Opcode.RET + Opcode.PUSH2 # return TestAdd(a, b) + Opcode.PUSH1 + Opcode.CALL + call_address + Opcode.RET ) path = self.get_contract_path('CallFunctionWrittenBefore.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertEqual(3, result)
def test_call_function_on_return(self): called_function_address = Integer(3).to_byte_array(min_length=1, signed=True) expected_output = ( Opcode.INITSLOT # Main + b'\x02' + b'\x00' + Opcode.PUSH1 # a = 1 + Opcode.STLOC0 + Opcode.PUSH2 # b = 2 + Opcode.STLOC1 + Opcode.PUSH2 # return TestAdd(a, b) + Opcode.PUSH1 + Opcode.CALL + called_function_address + Opcode.RET + Opcode.INITSLOT # TestFunction + b'\x00' + b'\x02' + Opcode.LDARG0 # return a + b + Opcode.LDARG1 + Opcode.ADD + Opcode.RET # return ) path = self.get_contract_path('CallReturnFunctionOnReturn.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertEqual(3, result)
def test_event_with_name(self): event_id = 'example' event_name = String(event_id).to_bytes(min_length=1) expected_output = ( Opcode.PUSH10 # Main() + Opcode.PUSH1 + Opcode.PACK + Opcode.PUSHDATA1 # event(10) + Integer(len(event_name)).to_byte_array(min_length=1) + event_name + Opcode.SYSCALL + Interop.Notify.interop_method_hash + Opcode.PUSHNULL # return + Opcode.RET ) path = '%s/boa3_test/test_sc/event_test/EventWithName.py' % self.dirname output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine(self.dirname) self.run_smart_contract(engine, path, 'Main') self.assertGreater(len(engine.notifications), 0) event_notifications = engine.get_events(event_name=event_id) self.assertEqual(1, len(event_notifications)) self.assertEqual((10,), event_notifications[0].arguments)
def test_call_function_with_variable_args(self): called_function_address = Integer(5).to_byte_array(min_length=1, signed=True) expected_output = ( Opcode.INITSLOT # Main + b'\x03' + b'\x02' + Opcode.PUSH1 # a = 1 + Opcode.STLOC0 + Opcode.PUSH2 # b = 2 + Opcode.STLOC1 + Opcode.PUSH2 # c = TestAdd(a, b) + Opcode.PUSH1 + Opcode.CALL + called_function_address + Opcode.STLOC2 + Opcode.LDLOC2 # return c + Opcode.RET + Opcode.INITSLOT # TestFunction + b'\x00' + b'\x02' + Opcode.LDARG0 # return a + b + Opcode.LDARG1 + Opcode.ADD + Opcode.RET # return ) path = self.get_contract_path('CallReturnFunctionWithVariableArgs.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() self.run_smart_contract(engine, path, 'TestAdd', 1, 2) self.assertEqual(1, len(engine.result_stack)) self.assertEqual(3, engine.result_stack[-1])
def test_event_nep5_transfer(self): event_id = 'transfer' event_name = String(event_id).to_bytes(min_length=1) expected_output = ( Opcode.INITSLOT # Main() + b'\x00\x03' + Opcode.LDARG2 # event(from_addr, to_addr, amount) + Opcode.LDARG1 + Opcode.LDARG0 + Opcode.PUSH3 + Opcode.PACK + Opcode.PUSHDATA1 + Integer(len(event_name)).to_byte_array(min_length=1) + event_name + Opcode.SYSCALL + Interop.Notify.interop_method_hash + Opcode.RET # return ) path = self.get_contract_path('EventNep5Transfer.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', b'1', b'2', 10) self.assertIsVoid(result) self.assertGreater(len(engine.notifications), 0) event_notifications = engine.get_events(event_name=event_id) self.assertEqual(1, len(event_notifications)) self.assertEqual(('1', '2', 10), event_notifications[0].arguments)
def test_hash256_int(self): path = self.get_contract_path('Hash256Int.py') engine = TestEngine() expected_result = hashlib.sha256( hashlib.sha256(Integer(10).to_byte_array()).digest()).digest() result = self.run_smart_contract(engine, path, 'Main') self.assertEqual(expected_result, result)
def test_event_with_annotation(self): event_id = 'example' event_name = String(event_id).to_bytes(min_length=1) expected_output = ( Opcode.PUSH10 # Main() + Opcode.PUSH1 + Opcode.PACK + Opcode.PUSHDATA1 # on_example(10) + Integer(len(event_name)).to_byte_array(min_length=1) + event_name + Opcode.SYSCALL + Interop.Notify.interop_method_hash + Opcode.RET # return ) path = self.get_contract_path('EventWithAnnotation.py') output, manifest = self.compile_and_save(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertIsVoid(result) self.assertGreater(len(engine.notifications), 0) event_notifications = engine.get_events(event_name=event_id) self.assertEqual(1, len(event_notifications)) self.assertEqual((10,), event_notifications[0].arguments)
def opcode(self) -> List[Tuple[Opcode, bytes]]: from boa3.compiler.codegenerator import get_bytes_count from boa3.neo.vm.type.Integer import Integer number_zero_to_bytes = b'\x00' jmp_place_holder = (Opcode.JMP, b'\x01') verify_number_is_zero = [ (Opcode.DUP, b''), (Opcode.NZ, b''), jmp_place_holder ] number_is_not_zero = super().opcode.copy() number_is_not_zero.append(jmp_place_holder) number_is_zero = [ (Opcode.DROP, b''), (Opcode.PUSHDATA1, Integer(len(number_zero_to_bytes)).to_byte_array() + number_zero_to_bytes), ] number_is_not_zero[-1] = Opcode.get_jump_and_data(Opcode.JMP, get_bytes_count(number_is_zero)) verify_number_is_zero[-1] = Opcode.get_jump_and_data(Opcode.JMPIFNOT, get_bytes_count(number_is_not_zero)) return ( verify_number_is_zero + number_is_not_zero + number_is_zero + [(Opcode.NOP, b'')] # TODO: change this when refactoring calling methods with methods as args )
def is_instance_opcodes(self) -> List[Tuple[Opcode, bytes]]: from boa3.neo.vm.type.Integer import Integer push_int_opcode, size_data = Opcode.get_push_and_data(20) return [ (Opcode.DUP, b''), # if isinstance(value, bytes): (Opcode.ISTYPE, self.stack_item), (Opcode.JMPIFNOT, Integer(7 + len(size_data)).to_byte_array(min_length=1)), (Opcode.SIZE, b''), # return len(value) == 20 (push_int_opcode, size_data), (Opcode.NUMEQUAL, b''), (Opcode.JMP, Integer(4).to_byte_array(min_length=1)), (Opcode.DROP, b''), (Opcode.PUSH0, b''), # return False ]
def test_event_without_arguments(self): event_id = 'Event' event_name = String(event_id).to_bytes(min_length=1) expected_output = ( Opcode.NEWARRAY0 # Main() + Opcode.PUSHDATA1 # event() + Integer(len(event_name)).to_byte_array(min_length=1) + event_name + Opcode.SYSCALL + Interop.Notify.interop_method_hash + Opcode.RET # return ) path = self.get_contract_path('EventWithoutArguments.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertIsVoid(result) self.assertGreater(len(engine.notifications), 0) event_notifications = engine.get_events(event_name=event_id) self.assertEqual(1, len(event_notifications)) self.assertEqual((), event_notifications[0].arguments)
def test_ripemd160_bool(self): import hashlib path = self.get_contract_path('Ripemd160Bool.py') engine = TestEngine() expected_result = hashlib.new('ripemd160', Integer(1).to_byte_array()) result = self.run_smart_contract(engine, path, 'Main') self.assertEqual(expected_result.digest(), result)
def test_sha256_bool(self): import hashlib path = self.get_contract_path('Sha256Bool.py') engine = TestEngine() expected_result = hashlib.sha256(Integer(1).to_byte_array()) result = self.run_smart_contract(engine, path, 'Main') self.assertEqual(expected_result.digest(), result)
def test_if_else_is_instance_condition_with_union_variable(self): path = self.get_contract_path( 'IfElseIsInstanceConditionWithUnionVariable.py') engine = TestEngine() result = self.run_smart_contract(engine, path, 'example', 4, expected_result_type=bytes) self.assertEqual(b'\x04', result) result = self.run_smart_contract(engine, path, 'example', '123', expected_result_type=bytes) self.assertEqual(b'123', result) result = self.run_smart_contract(engine, path, 'example', -70, expected_result_type=bytes) self.assertEqual(Integer(-70).to_byte_array(), result) result = self.run_smart_contract(engine, path, 'example', True, expected_result_type=bytes) self.assertEqual(b'\x01', result)
def test_call_void_function_with_variable_args(self): called_function_address = Integer(6).to_byte_array(min_length=1, signed=True) expected_output = ( Opcode.INITSLOT # Main + b'\x02' + b'\x00' + Opcode.PUSH1 # a = 1 + Opcode.STLOC0 + Opcode.PUSH2 # b = 2 + Opcode.STLOC1 + Opcode.PUSH2 # TestAdd(a, b) + Opcode.PUSH1 + Opcode.CALL + called_function_address + Opcode.PUSH1 # return True + Opcode.CONVERT + StackItemType.Boolean + Opcode.RET + Opcode.INITSLOT # TestFunction + b'\x01' + b'\x02' + Opcode.LDARG0 # c = a + b + Opcode.LDARG1 + Opcode.ADD + Opcode.STLOC0 + Opcode.RET # return ) path = self.get_contract_path('CallVoidFunctionWithVariableArgs.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertEqual(1, result)
def opcode(self) -> List[Tuple[Opcode, bytes]]: from boa3.neo.vm.type.Integer import Integer value = ORACLE_SCRIPT return [ (Opcode.PUSHDATA1, Integer(len(value)).to_byte_array() + value) ]
def test_nep5_main(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x00' + b'\x02' + Opcode.LDARG1 # args[0] + Opcode.PUSH0 + Opcode.DUP + Opcode.SIGN + Opcode.PUSHM1 + Opcode.JMPNE + Integer(5).to_byte_array(min_length=1, signed=True) + Opcode.OVER + Opcode.SIZE + Opcode.ADD + Opcode.PICKITEM + Opcode.RET # return ) path = self.get_contract_path('Nep5Main.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', 'op', (1, 2, 3, 4)) self.assertEqual(1, result) result = self.run_smart_contract(engine, path, 'Main', 'op', ('a', False)) self.assertEqual('a', result) with self.assertRaises(TestExecutionException, msg=self.VALUE_IS_OUT_OF_RANGE_MSG): self.run_smart_contract(engine, path, 'Main', 'op', ())
def get_store(index: int, local: bool, is_arg: bool = False) -> Opcode: """ Gets the opcode to store the variable :param index: index of the variable :param local: identifies if the variable is local or global :param is_arg: identifies if the variable is an argument of a function. False if local is False. :return: the respective opcode :rtype: Opcode """ if not local: is_arg = False if 0 <= index <= 6: if is_arg: opcode_value: int = Integer.from_bytes(Opcode.STARG0) + index elif local: opcode_value: int = Integer.from_bytes(Opcode.STLOC0) + index else: opcode_value: int = Integer.from_bytes(Opcode.STSFLD0) + index return Opcode(Integer(opcode_value).to_byte_array()) else: if is_arg: return Opcode.STARG elif local: return Opcode.STLOC else: return Opcode.STSFLD
def is_instance_opcodes(self) -> List[Tuple[Opcode, bytes]]: is_type_opcodes = [ (Opcode.DUP, b''), # if is the same internal type (Opcode.ISTYPE, self.stack_item) ] return_false = [ (Opcode.DROP, b''), (Opcode.PUSH0, b''), # return False ] return_false_bytes_size = get_bytes_count(return_false) final_instructions = [] final_jmp = [(Opcode.JMP, Integer(2 + return_false_bytes_size).to_byte_array(min_length=1))] validate_type = self._is_instance_inner_opcodes(get_bytes_count(final_jmp)) if len(validate_type) > 0: final_instructions += (validate_type + final_jmp) bytes_size = get_bytes_count(final_instructions) jmp_opcode, jmp_arg = Opcode.get_jump_and_data(Opcode.JMPIFNOT, bytes_size + 1) final_instructions = (is_type_opcodes + [(jmp_opcode, jmp_arg)] + final_instructions + return_false) else: is_type_opcodes.remove((Opcode.DUP, b'')) final_instructions = is_type_opcodes return final_instructions
def test_notify_int(self): event_name = String('notify').to_bytes() expected_output = ( Opcode.PUSHDATA1 + Integer(len(event_name)).to_byte_array(min_length=1) + event_name + Opcode.PUSH15 + Opcode.PUSH1 + Opcode.PACK + Opcode.SWAP + Opcode.SYSCALL + Interop.Notify.interop_method_hash + Opcode.RET ) path = self.get_contract_path('NotifyInt.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main') self.assertIsVoid(result) self.assertGreater(len(engine.notifications), 0) event_notifications = engine.get_events(event_name=Interop.Notify.name) self.assertEqual(1, len(event_notifications)) self.assertEqual((15,), event_notifications[0].arguments)
def test_tuple_get_value(self): expected_output = ( Opcode.INITSLOT # function signature + b'\x00' + b'\x01' + Opcode.LDARG0 # arg[0] + Opcode.PUSH0 + Opcode.DUP + Opcode.SIGN + Opcode.PUSHM1 + Opcode.JMPNE + Integer(5).to_byte_array(min_length=1, signed=True) + Opcode.OVER + Opcode.SIZE + Opcode.ADD + Opcode.PICKITEM + Opcode.RET # return ) path = self.get_contract_path('GetValue.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'Main', [1, 2, 3, 4]) self.assertEqual(1, result) result = self.run_smart_contract(engine, path, 'Main', [5, 3, 2]) self.assertEqual(5, result) with self.assertRaises(TestExecutionException, msg=self.VALUE_IS_OUT_OF_RANGE_MSG): self.run_smart_contract(engine, path, 'Main', [])
def test_contract_manual_interface_code_optimization(self): from boa3.model.builtin.interop.interop import Interop from boa3.neo.vm.opcode.Opcode import Opcode from boa3.neo.vm.type.Integer import Integer from boa3.neo.vm.type.String import String from boa3.neo3.core.types import UInt160 external_contract_name = 'symbol' function_name_bytes = String(external_contract_name).to_bytes() contract_script_bytes = UInt160.from_string( '21f19f84e144f91abe755efb21a6798ac95c2e70').to_array() expected_output = ( # start public method Opcode.LDSFLD0 # generated cls arg + Opcode.CALL + Integer(35).to_byte_array() + Opcode.RET # end public method # start initialize method + Opcode.INITSSLOT + b'\x01' + Opcode.PUSH1 + Opcode.NEWARRAY + Opcode.STSFLD0 + Opcode.PUSHDATA1 + Integer(len(contract_script_bytes)).to_byte_array() + contract_script_bytes + Opcode.PUSH0 + Opcode.LDSFLD0 + Opcode.REVERSE3 + Opcode.SETITEM + Opcode.RET # end initialize method # start 'symbol' class method + Opcode.INITSLOT + b'\x00\x01' + Opcode.NEWARRAY0 # arguments list + Opcode.PUSH15 # CallFlag + Opcode.PUSHDATA1 # function name + Integer(len(function_name_bytes)).to_byte_array() + function_name_bytes + Opcode.LDARG0 # contract script + Opcode.PUSH0 + Opcode.PICKITEM + Opcode.SYSCALL + Interop.CallContract.interop_method_hash + Opcode.RET # start class method ) path = self.get_contract_path( 'ContractManualInterfaceCodeOptimization.py') output, manifest = self.compile_and_save(path) self.assertEqual(expected_output, output) nep17_path = self.get_contract_path('examples', 'nep17.py') engine = TestEngine() nep17_result = self.run_smart_contract(engine, nep17_path, 'symbol') result = self.run_smart_contract(engine, path, 'nep17_symbol') self.assertEqual(nep17_result, result)
def test_get_contract(self): from boa3.neo3.contracts import CallFlags call_flag = Integer(CallFlags.ALL).to_byte_array(signed=True, min_length=1) expected_output = ( Opcode.INITSLOT + b'\x00\x01' + Opcode.LDARG0 + Opcode.PUSH1 + Opcode.PACK + Opcode.PUSHDATA1 + Integer(len(Interop.GetContract.method_name)).to_byte_array(min_length=1) + String(Interop.GetContract.method_name).to_bytes() + Opcode.PUSHDATA1 + Integer(len(constants.MANAGEMENT_SCRIPT)).to_byte_array(min_length=1) + constants.MANAGEMENT_SCRIPT + Opcode.PUSHDATA1 + Integer(len(call_flag)).to_byte_array(min_length=1) + call_flag + Opcode.ROT + Opcode.ROT + Opcode.SYSCALL + Interop.CallContract.interop_method_hash + Opcode.RET ) path = self.get_contract_path('GetContract.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() result = self.run_smart_contract(engine, path, 'main', bytes(20)) self.assertIsNone(result) call_contract_path = self.get_contract_path('test_sc/arithmetic_test', 'Addition.py') Boa3.compile_and_save(call_contract_path) script, manifest = self.get_output(call_contract_path) nef, manifest = self.get_bytes_output(call_contract_path) call_hash = hash160(script) call_contract_path = call_contract_path.replace('.py', '.nef') engine.add_contract(call_contract_path) arg_manifest = json.dumps(manifest, separators=(',', ':')) result = self.run_smart_contract(engine, path, 'main', call_hash) self.assertEqual(5, len(result)) self.assertEqual(call_hash, result[2]) self.assertEqual(nef, result[3])
def test_integer_script_hash(self): from boa3.neo import cryptography, to_script_hash input = Integer(123).to_byte_array() expected_output = cryptography.hash160(input) output = to_script_hash(input) self.assertEqual(expected_output, output)
def test_script_hash_variable(self): path = self.get_contract_path('ScriptHashVariable.py') engine = TestEngine() with self.assertRaises(TestExecutionException): self.run_smart_contract(engine, path, 'Main', 123) from boa3.neo import to_script_hash from base58 import b58encode value = b58encode(Integer(123).to_byte_array()) if isinstance(value, int): value = Integer(value).to_byte_array() script_hash = to_script_hash(value) result = self.run_smart_contract(engine, path, 'Main', value, expected_result_type=bytes) self.assertEqual(script_hash, result)
def test_hash160_bool(self): import hashlib path = self.get_contract_path('Hash160Bool.py') self.compile_and_save(path) engine = TestEngine() expected_result = hashlib.new('ripemd160', (hashlib.sha256(Integer(1).to_byte_array()).digest())).digest() result = self.run_smart_contract(engine, path, 'Main') self.assertEqual(expected_result, result)
def test_verify_with_ecdsa_secp256k1_int(self): byte_input1 = b'publickey' byte_input2 = b'signature' function_id = String(Interop.VerifyWithECDsaSecp256k1._sys_call).to_bytes() call_flag = Integer(CallFlags.ALL).to_byte_array(signed=True, min_length=1) expected_output = ( Opcode.PUSHDATA1 + Integer(len(byte_input2)).to_byte_array(min_length=1) + byte_input2 + Opcode.PUSHDATA1 + Integer(len(byte_input1)).to_byte_array(min_length=1) + byte_input1 + Opcode.PUSH10 + Opcode.PUSH3 + Opcode.PACK + Opcode.DUP + Opcode.PUSHINT8 + Integer(NamedCurve.SECP256K1).to_byte_array(min_length=1) + Opcode.APPEND + Opcode.PUSHDATA1 + Integer(len(call_flag)).to_byte_array() + call_flag + Opcode.PUSHDATA1 + Integer(len(function_id)).to_byte_array() + function_id + Opcode.PUSHDATA1 + Integer(len(CRYPTO_SCRIPT)).to_byte_array() + CRYPTO_SCRIPT + Opcode.SYSCALL + Interop.CallContract.interop_method_hash + Opcode.DROP + Opcode.RET ) path = self.get_contract_path('VerifyWithECDsaSecp256k1Int.py') output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_verify_with_ecdsa_secp256k1_int(self): byte_input1 = b'0123456789ABCDEFGHIJKLMNOPQRSTUVW' byte_input2 = b'signature' named_curve = Integer(NamedCurve.SECP256K1).to_byte_array(signed=True, min_length=1) function_id = String(Interop.VerifyWithECDsa._sys_call).to_bytes() call_flag = Integer(CallFlags.ALL).to_byte_array(signed=True, min_length=1) expected_output = ( Opcode.PUSHINT8 + named_curve + Opcode.PUSHDATA1 + Integer(len(byte_input2)).to_byte_array(min_length=1) + byte_input2 + Opcode.PUSHDATA1 + Integer(len(byte_input1)).to_byte_array(min_length=1) + byte_input1 + self.ecpoint_init + Opcode.PUSH10 + Opcode.PUSH4 + Opcode.PACK + Opcode.PUSHDATA1 + Integer(len(call_flag)).to_byte_array() + call_flag + Opcode.PUSHDATA1 + Integer(len(function_id)).to_byte_array() + function_id + Opcode.PUSHDATA1 + Integer(len(constants.CRYPTO_SCRIPT)).to_byte_array() + constants.CRYPTO_SCRIPT + Opcode.SYSCALL + Interop.CallContract.interop_method_hash + Opcode.DROP + Opcode.RET ) path = self.get_contract_path('VerifyWithECDsaSecp256k1Int.py') output = Boa3.compile(path) self.assertEqual(expected_output, output)
def test_storage_put_str_key_int_value(self): value = Integer(123).to_byte_array() expected_output = ( Opcode.INITSLOT + b'\x01' + b'\x01' + Opcode.PUSHDATA1 + Integer(len(value)).to_byte_array(min_length=1, signed=True) + value + Opcode.CONVERT + Type.int.stack_item + Opcode.STLOC0 + Opcode.PUSHDATA1 + Integer(len(value)).to_byte_array(min_length=1, signed=True) + value + Opcode.CONVERT + Type.int.stack_item + Opcode.LDARG0 + Opcode.SYSCALL + Interop.StorageGetContext.interop_method_hash + Opcode.SYSCALL + Interop.StoragePut.interop_method_hash + Opcode.RET) path = self.get_contract_path('StoragePutStrKeyIntValue.py') output = Boa3.compile(path) self.assertEqual(expected_output, output) engine = TestEngine() stored_value = Integer(123).to_byte_array() result = self.run_smart_contract(engine, path, 'Main', 'test1') self.assertIsVoid(result) storage_value = engine.storage_get(b'test1', path) self.assertIsNotNone(storage_value) self.assertEqual(stored_value, storage_value) result = self.run_smart_contract(engine, path, 'Main', 'test2') self.assertIsVoid(result) storage_value = engine.storage_get(b'test1', path) self.assertIsNotNone(storage_value) self.assertEqual(stored_value, storage_value) storage_value = engine.storage_get(b'test2', path) self.assertIsNotNone(storage_value) self.assertEqual(stored_value, storage_value) result = self.run_smart_contract(engine, path, 'Main', 'test2', fake_storage={}) self.assertIsVoid(result) storage_value = engine.storage_get(b'test1', path) self.assertIsNone(storage_value) storage_value = engine.storage_get(b'test2', path) self.assertIsNotNone(storage_value) self.assertEqual(stored_value, storage_value)
def __setitem__(self, key: StorageKey, value: Any): from boa3.neo.vm.type import StackItem if isinstance(value, int): storage_value = Integer(value).to_byte_array() elif isinstance(value, str): storage_value = String(value).to_bytes() else: storage_value = StackItem.serialize(value) self._dict[key] = StorageItem(storage_value)
def test_storage_get_bytes_key(self): expected_output = ( Opcode.INITSLOT + b'\x00' + b'\x01' + Opcode.LDARG0 + Opcode.SYSCALL + Interop.StorageGet.storage_context_hash + Opcode.SYSCALL + Interop.StorageGet.interop_method_hash + Opcode.DUP + Opcode.ISNULL + Opcode.JMPIFNOT + Integer(7).to_byte_array(signed=True, min_length=1) + Opcode.DROP + Opcode.PUSHDATA1 + Integer(0).to_byte_array(signed=False, min_length=1) + Opcode.CONVERT + Type.bytes.stack_item + Opcode.RET) path = '%s/boa3_test/test_sc/storage_test/StorageGetBytesKey.py' % self.dirname output, manifest = self.compile_and_save(path) self.assertEqual(expected_output, output) self.assertIn('features', manifest) self.assertIn('storage', manifest['features']) self.assertEqual(True, manifest['features']['storage'])