Exemple #1
0
    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])
Exemple #2
0
    def _native_to_stackitem(self, value, native_type) -> vm.StackItem:
        """
        Convert native type to VM type

        Note: order of checking matters.
        e.g. a Transaction should be treated as IInteropable, while its also ISerializable
        """
        if isinstance(value, vm.StackItem):
            return value
        elif value is None:
            return vm.NullStackItem()
        elif native_type in [int, vm.BigInteger]:
            return vm.IntegerStackItem(value)
        elif issubclass(native_type, IInteroperable):
            value_ = cast(IInteroperable, value)
            return value_.to_stack_item(self.reference_counter)
        elif issubclass(native_type, serialization.ISerializable):
            serializable_value = cast(serialization.ISerializable, value)
            return vm.ByteStringStackItem(serializable_value.to_array())
        # mypy bug? https://github.com/python/mypy/issues/9756
        elif native_type in [bytes, bytearray]:  # type: ignore
            return vm.ByteStringStackItem(value)
        elif native_type == str:
            return vm.ByteStringStackItem(bytes(value, 'utf-8'))
        elif native_type == bool:
            return vm.BooleanStackItem(value)
        elif issubclass(native_type, (enum.IntFlag, enum.IntEnum)):
            return self._native_to_stackitem(value.value, int)
        else:
            return vm.StackItem.from_interface(value)
Exemple #3
0
    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)
Exemple #4
0
    def test_deserialization_array_of_items(self):
        ref_ctr = vm.ReferenceCounter()
        array = contracts.JSONSerializer.deserialize(
            contracts.NEOJson.loads(
                r'[[true,"test1", 123, null],[false,"test2",321]]'), ref_ctr)
        self.assertIsInstance(array, vm.ArrayStackItem)
        self.assertEqual(2, len(array))

        sub_array1 = array[0]
        self.assertIsInstance(sub_array1, vm.ArrayStackItem)
        self.assertEqual(4, len(sub_array1))

        self.assertIsInstance(sub_array1[0], vm.BooleanStackItem)
        self.assertTrue(sub_array1[0])

        self.assertIsInstance(sub_array1[1], vm.ByteStringStackItem)
        self.assertEqual(vm.ByteStringStackItem("test1"), sub_array1[1])

        self.assertIsInstance(sub_array1[2], vm.IntegerStackItem)
        self.assertEqual(vm.BigInteger(123), sub_array1[2].to_biginteger())

        self.assertIsInstance(sub_array1[3], vm.NullStackItem)

        sub_array2 = array[1]
        self.assertIsInstance(sub_array2, vm.ArrayStackItem)
        self.assertEqual(3, len(sub_array2))

        self.assertIsInstance(sub_array2[0], vm.BooleanStackItem)
        self.assertFalse(sub_array2[0])

        self.assertIsInstance(sub_array2[1], vm.ByteStringStackItem)
        self.assertEqual(vm.ByteStringStackItem("test2"), sub_array2[1])

        self.assertIsInstance(sub_array2[2], vm.IntegerStackItem)
        self.assertEqual(vm.BigInteger(321), sub_array2[2].to_biginteger())
Exemple #5
0
 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_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))
Exemple #7
0
    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())
Exemple #8
0
    def value(self) -> vm.StackItem:
        if self._pair is None:
            raise ValueError(
                "Cannot call 'value' without having advanced the iterator at least once"
            )
        key = self._pair[0].key
        value = self._pair[1].value
        if contracts.FindOptions.REMOVE_PREFIX in self.options:
            key = key[self.prefix_len:]

        if contracts.FindOptions.DESERIALIZE_VALUES in self.options:
            item: vm.StackItem = contracts.BinarySerializer.deserialize(
                value, 1024, self.reference_counter)
        else:
            item = vm.ByteStringStackItem(value)

        if contracts.FindOptions.PICK_FIELD0 in self.options:
            item = cast(vm.ArrayStackItem, item)
            item = item[0]
        elif contracts.FindOptions.PICK_FIELD1 in self.options:
            item = cast(vm.ArrayStackItem, item)
            item = item[1]

        if contracts.FindOptions.KEYS_ONLY in self.options:
            return vm.ByteStringStackItem(key)

        if contracts.FindOptions.VALUES_ONLY in self.options:
            return vm.ByteStringStackItem(value)

        return vm.StructStackItem(self.reference_counter, [
            vm.ByteStringStackItem(self._pair[0].key),
            vm.ByteStringStackItem(self._pair[1].value)
        ])
    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_update_exceptions6(self):
        # asking to update with a new script but with an invalid manifest (new manifest does not support storage,
        # while the old contract has existing storage)
        engine = test_engine(has_snapshot=True, default_script=False)

        contract_old = storage.ContractState(hello_world_nef.script,
                                             deepcopy(hello_world_manifest))
        contract_old.manifest.features |= contracts.ContractFeatures.HAS_STORAGE
        engine.snapshot.contracts.put(contract_old)

        storage_key = storage.StorageKey(contract_old.script_hash(),
                                         b'firstkey')
        storage_item = storage.StorageItem(b'firstitem')
        engine.snapshot.storages.put(storage_key, storage_item)

        # we load the stored as script to properly setup "engine.current_scripthash"
        engine.load_script(vm.Script(contract_old.script))
        # next we push the necessary items on the stack before calling the update funcztion
        # we take the matching manifest and change it to have no storage
        bad_manifest = deepcopy(bye_world_manifest)
        bad_manifest.features &= ~contracts.ContractFeatures.HAS_STORAGE
        engine.push(vm.ByteStringStackItem(str(bad_manifest).encode()))
        engine.push(vm.ByteStringStackItem(bye_world_nef.script))

        with self.assertRaises(ValueError) as context:
            engine.invoke_syscall_by_name("System.Contract.Update")
        self.assertEqual(
            "Error: New contract does not support storage while old contract has existing storage",
            str(context.exception))
    def test_contract_update_ok(self):
        engine = test_engine(has_snapshot=True, default_script=False)
        # the real world setup should be
        # 1) deploy a smart contract with an update function that internally calls "System.Contract.Update"
        # 2) perform a contract call to the old contract and supply a new script + manifest as arguments
        #
        # here we will bypass deploying a contract with an update function and directly call "System.Contract.Update" on
        # the engine. We start by persisting the contract we want to update
        contract = storage.ContractState(hello_world_nef.script,
                                         hello_world_manifest)
        engine.snapshot.contracts.put(contract)

        # we load the old contract as script to properly setup "engine.current_scripthash"
        engine.load_script(vm.Script(contract.script))
        # next we push the necessary items on the stack before calling the update function
        engine.push(vm.ByteStringStackItem(str(bye_world_manifest).encode()))
        engine.push(vm.ByteStringStackItem(bye_world_nef.script))
        engine.invoke_syscall_by_name("System.Contract.Update")

        # test that we cannot find the old contract anymore
        self.assertIsNone(
            engine.snapshot.contracts.try_get(contract.script_hash()))
        new_contract = storage.ContractState(bye_world_nef.script,
                                             bye_world_manifest)
        # make sure the new contract is still there (and that we not just cleared the whole storage)
        self.assertIsNotNone(
            engine.snapshot.contracts.try_get(new_contract.script_hash()))
    def test_get_contract(self):
        engine = test_engine(has_container=True, has_snapshot=True)
        bad_contract_hash_bytes = b'\x01' * 20
        engine.push(vm.ByteStringStackItem(bad_contract_hash_bytes))
        engine.invoke_syscall_by_name("System.Blockchain.GetContract")
        item = engine.pop()
        self.assertIsInstance(item, vm.NullStackItem)

        # now get a valid contract
        # first put one in storage
        contract = storage.ContractState(b'\x01\x02',
                                         manifest.ContractManifest())
        engine.snapshot.contracts.put(contract)
        engine.push(vm.ByteStringStackItem(contract.script_hash().to_array()))
        engine.invoke_syscall_by_name("System.Blockchain.GetContract")
        item = engine.pop()
        self.assertIsInstance(item, vm.ArrayStackItem)
        self.assertEqual(len(item), 4)
        self.assertEqual(contract.script, item[0].to_array())
        self.assertEqual(
            contract.manifest,
            manifest.ContractManifest.from_json(json.loads(
                item[1].to_array())))
        self.assertEqual(contract.has_storage, item[2].to_boolean())
        self.assertEqual(contract.is_payable, item[3].to_boolean())
Exemple #13
0
 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_contract_update_exceptions1(self):
     # asking to update a contract that is not already deployed
     engine = test_engine(has_snapshot=True, default_script=True)
     fake_manifest = b'\x01' * 10
     fake_nef = b'\x01' * 10
     engine.push(vm.ByteStringStackItem(fake_manifest))
     engine.push(vm.ByteStringStackItem(fake_nef))
     with self.assertRaises(ValueError) as context:
         engine.invoke_syscall_by_name("System.Contract.Update")
     self.assertEqual("Can't find contract to update",
                      str(context.exception))
Exemple #15
0
    def test_deserialization_map(self):
        ref_ctr = vm.ReferenceCounter()
        item = contracts.JSONSerializer.deserialize(
            contracts.NEOJson.loads(r'{"test1":123, "test2": 321}'), ref_ctr)
        self.assertIsInstance(item, vm.MapStackItem)
        self.assertEqual(2, len(item))

        key1 = vm.ByteStringStackItem("test1")
        self.assertEqual(vm.BigInteger(123), item[key1].to_biginteger())
        key2 = vm.ByteStringStackItem("test2")
        self.assertEqual(vm.BigInteger(321), item[key2].to_biginteger())
 def test_contract_create_manifest_mismatch(self):
     engine = test_engine(has_snapshot=True)
     manifest_copy = deepcopy(hello_world_manifest)
     # invalidate the associated contract hash
     manifest_copy.abi.contract_hash = types.UInt160.zero()
     engine.push(vm.ByteStringStackItem(str(manifest_copy).encode()))
     engine.push(vm.ByteStringStackItem(hello_world_nef.script))
     with self.assertRaises(ValueError) as context:
         engine.invoke_syscall_by_name("System.Contract.Create")
     self.assertEqual("Error: manifest does not match with script",
                      str(context.exception))
    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))
Exemple #18
0
 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_contract_create_already_exits(self):
        engine = test_engine(has_snapshot=True)

        # store store the contract ourselves
        contract = storage.ContractState(hello_world_nef.script,
                                         hello_world_manifest)
        engine.snapshot.contracts.put(contract)
        # now try to create a contract
        engine.push(vm.ByteStringStackItem(str(hello_world_manifest).encode()))
        engine.push(vm.ByteStringStackItem(hello_world_nef.script))
        with self.assertRaises(ValueError) as context:
            engine.invoke_syscall_by_name("System.Contract.Create")
        self.assertEqual("Contract already exists", str(context.exception))
 def test_iterator_create_from_array(self):
     engine = test_engine()
     array = vm.ArrayStackItem(engine.reference_counter)
     item1 = vm.ByteStringStackItem(b'\x01')
     item2 = vm.ByteStringStackItem(b'\x02')
     array.append(item1)
     array.append(item2)
     engine.push(array)
     r = engine.invoke_syscall_by_name("System.Iterator.Create")
     self.assertIsInstance(r, ArrayWrapper)
     self.assertTrue(r.next())
     self.assertEqual(item1, r.value())
     self.assertTrue(r.next())
     self.assertEqual(item2, r.value())
Exemple #21
0
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 test_get_block(self):
        engine = test_engine(has_container=True, has_snapshot=True)
        # test with height
        engine.push(vm.ByteStringStackItem(b'\x01'))
        engine.invoke_syscall_by_name("System.Blockchain.GetBlock")
        self.assertIsInstance(engine.pop(), vm.NullStackItem)

        # test with invalid height (-1)
        engine.push(vm.ByteStringStackItem(b'\xFF'))
        with self.assertRaises(ValueError) as context:
            engine.invoke_syscall_by_name("System.Blockchain.GetBlock")
        self.assertEqual("Invalid height", str(context.exception))

        # test with invalid data > 32 bytes
        engine.push(vm.ByteStringStackItem(b'\xFF' * 33))
        with self.assertRaises(ValueError) as context:
            engine.invoke_syscall_by_name("System.Blockchain.GetBlock")
        self.assertEqual("Invalid data", str(context.exception))

        # test with serialized block hash (UInt256). This fake hash won't return a block
        engine.push(vm.ByteStringStackItem(b'\x01' * 32))
        engine.invoke_syscall_by_name("System.Blockchain.GetBlock")
        self.assertIsInstance(engine.pop(), vm.NullStackItem)

        # now find an existing block
        # first add a block and update the snapshot
        # normally this would be done while persisting in Blockchain
        testblock = test_block()
        engine.snapshot.block_height = testblock.index
        engine.snapshot.blocks.put(testblock)
        engine.push(vm.ByteStringStackItem(testblock.hash().to_array()))
        engine.invoke_syscall_by_name("System.Blockchain.GetBlock")
        # # validate the right content was pushed onto the stack
        item = engine.pop()
        self.assertIsInstance(item, vm.ArrayStackItem)
        self.assertEqual(len(item), 8)
        self.assertEqual(item[0].to_array(), testblock.hash().to_array())
        self.assertEqual(item[1].to_biginteger(),
                         vm.BigInteger(testblock.version))
        self.assertEqual(item[2].to_array(), testblock.prev_hash.to_array())
        self.assertEqual(item[3].to_array(), testblock.merkle_root.to_array())
        self.assertEqual(item[4].to_biginteger(),
                         vm.BigInteger(testblock.timestamp))
        self.assertEqual(item[5].to_biginteger(),
                         vm.BigInteger(testblock.index))
        self.assertEqual(item[6].to_array(),
                         testblock.next_consensus.to_array())
        self.assertEqual(item[7].to_biginteger(),
                         vm.BigInteger(len(testblock.transactions)))
Exemple #23
0
    def test_storage_find(self):
        engine = test_engine(has_snapshot=True)
        engine.snapshot.contracts.put(self.contract)

        storage_key1 = storage.StorageKey(self.contract.script_hash(), b'\x01')
        storage_item1 = storage.StorageItem(b'\x11', is_constant=False)
        engine.snapshot.storages.put(storage_key1, storage_item1)
        storage_key2 = storage.StorageKey(self.contract.script_hash(), b'\x02')
        storage_item2 = storage.StorageItem(b'\x22', is_constant=False)
        engine.snapshot.storages.put(storage_key2, storage_item2)

        ctx = engine.invoke_syscall_by_name("System.Storage.GetContext")
        engine.push(vm.ByteStringStackItem(storage_key1.key))
        engine.push(vm.StackItem.from_interface(ctx))

        it = engine.invoke_syscall_by_name("System.Storage.Find")
        self.assertIsInstance(it, interop.StorageIterator)
        it.next()
        self.assertEqual(storage_key1.key, it.key().to_array())
        self.assertEqual(storage_item1.value, it.value().to_array())

        it.next()
        with self.assertRaises(ValueError) as context:
            it.key()
        self.assertEqual(
            "Cannot call 'key' without having advanced the iterator at least once",
            str(context.exception))
        with self.assertRaises(ValueError) as context:
            it.value()
        self.assertEqual(
            "Cannot call 'value' without having advanced the iterator at least once",
            str(context.exception))
 def test_contract_is_standard_fail(self):
     # can't find contract
     engine = test_engine(has_snapshot=True)
     engine.push(vm.ByteStringStackItem(types.UInt160.zero().to_array()))
     engine.invoke_syscall_by_name("System.Contract.IsStandard")
     engine.execute()
     self.assertEqual(False, engine.result_stack.pop().to_boolean())
Exemple #25
0
    def test_getscriptcontainer(self):
        # first test against an invalid script container (IVerifiable, but not IOperable)
        engine = test_engine()
        container = payloads.Header._serializable_init()
        engine.script_container = container

        with self.assertRaises(ValueError) as context:
            engine.invoke_syscall_by_name("System.Runtime.GetScriptContainer")
        self.assertEqual("script container is not a valid IInteroperable type",
                         str(context.exception))

        tx = test_tx(1)
        engine = test_engine()
        engine.script_container = tx

        sb = vm.ScriptBuilder()
        sb.emit_syscall(
            syscall_name_to_int("System.Runtime.GetScriptContainer"))
        engine.load_script(vm.Script(sb.to_array()))
        engine.execute()

        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack._items))
        item = engine.result_stack.pop()
        self.assertIsInstance(item, vm.ArrayStackItem)
        # we now have a Block that has been serialized, let's check the hash
        self.assertEqual(vm.ByteStringStackItem(tx.hash().to_array()), item[0])
Exemple #26
0
 def test_checkwitness_invalid_data(self):
     engine = test_engine()
     engine.push(vm.ByteStringStackItem(b''))
     with self.assertRaises(ValueError) as context:
         engine.invoke_syscall_by_name("System.Runtime.CheckWitness")
     self.assertEqual("Supplied CheckWitness data is not a valid hash",
                      str(context.exception))
Exemple #27
0
    def test_multisig_verify_helper_bounds(self):
        engine = None
        message = vm.ByteStringStackItem(b'')
        public_keys = [object()]
        signatures = []

        with self.assertRaises(ValueError) as context:
            _check_multisig(engine, message, public_keys, signatures,
                            cryptography.ECCCurve.SECP256R1)
        self.assertEqual("No signatures supplied", str(context.exception))

        public_keys = []
        signatures = [object()]
        with self.assertRaises(ValueError) as context:
            _check_multisig(engine, message, public_keys, signatures,
                            cryptography.ECCCurve.SECP256R1)
        self.assertEqual("No public keys supplied", str(context.exception))

        public_keys = [object()]
        signatures = [object(), object()]
        with self.assertRaises(ValueError) as context:
            _check_multisig(engine, message, public_keys, signatures,
                            cryptography.ECCCurve.SECP256R1)
        self.assertEqual("Verification requires 2 public keys, got only 1",
                         str(context.exception))
Exemple #28
0
    def test_storage_find(self):
        # settings.storage.default_provider = 'leveldb'
        engine = test_engine(has_snapshot=True)
        engine.snapshot.contracts.put(self.contract)

        storage_key1 = storage.StorageKey(self.contract.id, b'\x01')
        storage_item1 = storage.StorageItem(b'\x11')
        engine.snapshot.storages.put(storage_key1, storage_item1)
        storage_key2 = storage.StorageKey(self.contract.id, b'\x02')
        storage_item2 = storage.StorageItem(b'\x22')
        engine.snapshot.storages.put(storage_key2, storage_item2)

        ctx = engine.invoke_syscall_by_name("System.Storage.GetContext")
        engine.push(vm.IntegerStackItem(contracts.FindOptions.NONE))
        engine.push(vm.ByteStringStackItem(storage_key1.key))
        engine.push(vm.StackItem.from_interface(ctx))

        it = engine.invoke_syscall_by_name("System.Storage.Find")
        self.assertIsInstance(it, interop.StorageIterator)

        with self.assertRaises(ValueError) as context:
            it.value()
        self.assertEqual(
            "Cannot call 'value' without having advanced the iterator at least once",
            str(context.exception))

        self.assertTrue(it.next())

        struct = it.value()  # 0 key, 1 value
        self.assertEqual(storage_item1.value, struct[1].to_array())
Exemple #29
0
 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)
Exemple #30
0
 def test_serialization_map(self):
     ref = vm.ReferenceCounter()
     key1 = vm.ByteStringStackItem("test1")
     key2 = vm.ByteStringStackItem("test2")
     key3 = vm.ByteStringStackItem("test3")
     v1 = vm.IntegerStackItem(1)
     v2 = vm.IntegerStackItem(2)
     v3 = vm.IntegerStackItem(3)
     m = vm.MapStackItem(ref)
     m[key1] = v1
     m[key3] = v3
     m[key2] = v2
     s = contracts.JSONSerializer.serialize(m, 999)
     # this is a known deviation. NEO preserved key order, we don't
     # but shouldn't matter as it gets deserialized to a map stackitem
     expected = r'{"test1":1,"test2":2,"test3":3}'
     self.assertEqual(expected, s)