Esempio n. 1
0
 def test_dunders(self):
     wc = contracts.WildcardContainer(data=['method1', 'method2'])
     wc2 = contracts.WildcardContainer(data=['method1', 'method2'])
     self.assertIn('method1', wc)
     self.assertIn('method2', wc)
     self.assertNotIn('method3', wc)
     self.assertEqual('method2', wc[1])
     self.assertEqual(2, len(wc))
     self.assertNotEqual(wc, object())
     self.assertEqual(wc, wc2)
Esempio n. 2
0
    def test_to_json_with_trusts_safemethods_extra(self):
        # create a default manifest
        m = contracts.ContractManifest(types.UInt160.zero())
        t1 = types.UInt160.from_string("01" * 20)
        t2 = types.UInt160.from_string("02" * 20)
        m.trusts = contracts.WildcardContainer(data=[t1, t2])
        m.safe_methods = contracts.WildcardContainer(data=["safe1"])
        m.extra = False
        json_out = m.to_json()

        self.assertIn("0x" + str(t1), json_out['trusts'])
        self.assertIn("0x" + str(t2), json_out['trusts'])
        self.assertIn("safe1", json_out['safemethods'])
        self.assertFalse(json_out['extra'])
Esempio n. 3
0
    def test_to_json(self):
        wc = contracts.WildcardContainer.create_wildcard()
        self.assertDictEqual({'wildcard': '*'}, wc.to_json())

        wc = contracts.WildcardContainer(data=['method1', 'method2'])
        self.assertDictEqual({'wildcard': ['method1', 'method2']},
                             wc.to_json())
Esempio n. 4
0
    def test_is_allowed_invalid_method(self):
        # in the above tests we validated the 'group' and 'contract_hash' matching logic
        # now we validate 'method' matching
        mock_manifest = mock.MagicMock()
        mock_manifest.contract_hash = types.UInt160.zero()

        # setup an allowed permission for a contract with UInt160.zero hash for 2 methods
        cpd = contracts.ContractPermissionDescriptor(
            contract_hash=types.UInt160.zero())
        cp = contracts.ContractPermission(
            contract=cpd,
            methods=contracts.WildcardContainer(data=['method1', 'method2']))
        self.assertTrue(cp.is_allowed(mock_manifest, "method1"))
        self.assertTrue(cp.is_allowed(mock_manifest, "method2"))
        self.assertFalse(cp.is_allowed(mock_manifest, "method3"))
Esempio n. 5
0
    def test_is_allowed_invalid_method(self):
        # in the above tests we validated the 'group' and 'contract_hash' matching logic
        # now we validate 'method' matching
        dummy_contract_hash = types.UInt160.from_string("01" * 20)
        contract_state = contracts.ContractState(1, contracts.NEF(),
                                                 contracts.ContractManifest(),
                                                 0, dummy_contract_hash)

        # setup an allowed permission for a contract with UInt160.zero hash for 2 methods
        cpd = contracts.ContractPermissionDescriptor(
            contract_hash=dummy_contract_hash)
        cp = contracts.ContractPermission(
            contract=cpd,
            methods=contracts.WildcardContainer(data=['method1', 'method2']))
        self.assertTrue(cp.is_allowed(contract_state, "method1"))
        self.assertTrue(cp.is_allowed(contract_state, "method2"))
        self.assertFalse(cp.is_allowed(contract_state, "method3"))
Esempio n. 6
0
    def test_to_json_with_trusts_extra(self):
        # create a default manifest
        m = contracts.ContractManifest("test_contract")
        method1 = contracts.ContractMethodDescriptor(
            name="main_entry",
            offset=0,
            parameters=[],
            return_type=contracts.ContractParameterType.INTEGER,
            safe=True)
        m.abi.methods = [method1]

        t1 = types.UInt160.from_string("01" * 20)
        t2 = types.UInt160.from_string("02" * 20)
        m.trusts = contracts.WildcardContainer(data=[t1, t2])
        m.extra = False
        json_out = m.to_json()

        self.assertIn("0x" + str(t1), json_out['trusts'])
        self.assertIn("0x" + str(t2), json_out['trusts'])
        self.assertFalse(json_out['extra'])
Esempio n. 7
0
    def test_wildcard(self):
        wc = contracts.WildcardContainer.create_wildcard()
        self.assertTrue(wc.is_wildcard)

        wc = contracts.WildcardContainer(['method1'])
        self.assertFalse(wc.is_wildcard)
    def test_contract_call_exceptions(self):
        engine = test_engine(has_snapshot=True, default_script=False)
        engine.load_script(vm.Script(hello_world_nef.script))

        # can't find contract
        with self.assertRaises(ValueError) as context:
            engine._contract_call_internal(
                types.UInt160.zero(), "valid_method", contracts.CallFlags.ALL,
                False, vm.ArrayStackItem(engine.reference_counter))
        self.assertEqual("[System.Contract.Call] Can't find target contract",
                         str(context.exception))

        fake_contract_hash = types.UInt160(b'\x01' * 20)
        target_contract = contracts.ContractState(0, contract3_nef,
                                                  contract3_manifest, 0,
                                                  fake_contract_hash)
        engine.snapshot.contracts.put(target_contract)

        # modify the manifest of the current executing contract to only allow to call 1 specific method on other contracts
        new_current_manifest = deepcopy(hello_world_manifest)
        new_current_manifest.permissions = [
            contracts.ContractPermission(
                contracts.ContractPermissionDescriptor(
                ),  # allow to call any contract
                contracts.WildcardContainer(
                    ['method_aaaa'])  # allowing to call the listed method only
            )
        ]
        fake_contract_hash2 = types.UInt160(b'\x02' * 20)
        new_current_contract = contracts.ContractState(1, hello_world_nef,
                                                       new_current_manifest, 0,
                                                       fake_contract_hash2)
        engine.snapshot.contracts.put(new_current_contract)
        with self.assertRaises(ValueError) as context:
            engine._contract_call_internal(
                target_contract.hash, "invalid_method",
                contracts.CallFlags.ALL, False,
                vm.ArrayStackItem(engine.reference_counter))
        self.assertEqual(
            "[System.Contract.Call] Method 'invalid_method' with 0 arguments does not exist on target contract",
            str(context.exception))

        # restore current contract to its original form and try to call a non-existing contract
        current_contract = contracts.ContractState(1, hello_world_nef,
                                                   hello_world_manifest, 1,
                                                   fake_contract_hash2)
        engine.snapshot.contracts.delete(new_current_contract.hash)
        engine.snapshot.contracts.put(current_contract)

        with self.assertRaises(ValueError) as context:
            engine._contract_call_internal(
                target_contract.hash, "invalid_method",
                contracts.CallFlags.ALL, False,
                vm.ArrayStackItem(engine.reference_counter))
        self.assertEqual(
            "[System.Contract.Call] Method 'invalid_method' with 0 arguments does not exist on target contract",
            str(context.exception))

        # call the target method with invalid number of arguments
        array = vm.ArrayStackItem(engine.reference_counter)
        array.append([vm.NullStackItem(), vm.NullStackItem()])
        with self.assertRaises(ValueError) as context:
            engine._contract_call_internal(target_contract.hash, "test_func",
                                           contracts.CallFlags.ALL, False,
                                           array)
        self.assertEqual(
            "[System.Contract.Call] Method 'test_func' with 2 arguments does not exist on target contract",
            str(context.exception))
    def test_contract_call_exceptions(self):
        engine = test_engine(has_snapshot=True, default_script=False)
        engine.load_script(vm.Script(hello_world_nef.script))
        with self.assertRaises(ValueError) as context:
            contract_call_internal(engine, types.UInt160.zero(),
                                   "_invalid_method",
                                   vm.ArrayStackItem(engine.reference_counter),
                                   contracts.native.CallFlags)
        self.assertEqual(
            "[System.Contract.Call] Method not allowed to start with _",
            str(context.exception))

        # can't find contract
        with self.assertRaises(ValueError) as context:
            contract_call_internal(engine, types.UInt160.zero(),
                                   "valid_method",
                                   vm.ArrayStackItem(engine.reference_counter),
                                   contracts.native.CallFlags)
        self.assertEqual("[System.Contract.Call] Can't find target contract",
                         str(context.exception))

        target_contract = storage.ContractState(contract3_nef.script,
                                                contract3_manifest)
        engine.snapshot.contracts.put(target_contract)

        # modify the manifest of the current executing contract to only allow to call 1 specific method on other contracts
        new_current_manifest = deepcopy(hello_world_manifest)
        new_current_manifest.permissions = [
            contracts.ContractPermission(
                contracts.ContractPermissionDescriptor(
                ),  # allow to call any contract
                contracts.WildcardContainer(
                    ['method_aaaa'])  # allowing to call the listed method only
            )
        ]
        new_current_contract = storage.ContractState(hello_world_nef.script,
                                                     new_current_manifest)
        engine.snapshot.contracts.put(new_current_contract)
        with self.assertRaises(ValueError) as context:
            contract_call_internal(engine, target_contract.script_hash(),
                                   "invalid_method",
                                   vm.ArrayStackItem(engine.reference_counter),
                                   contracts.native.CallFlags)
        self.assertEqual(
            "[System.Contract.Call] Not allowed to call target method 'invalid_method' according to manifest",
            str(context.exception))

        # restore current contract to its original form and try to call a non-existing contract
        current_contract = storage.ContractState(hello_world_nef.script,
                                                 hello_world_manifest)
        engine.snapshot.contracts.delete(new_current_contract.script_hash())
        engine.snapshot.contracts.put(current_contract)

        with self.assertRaises(ValueError) as context:
            contract_call_internal(engine, target_contract.script_hash(),
                                   "invalid_method",
                                   vm.ArrayStackItem(engine.reference_counter),
                                   contracts.native.CallFlags)
        self.assertEqual(
            "[System.Contract.Call] requested target method 'invalid_method' does not exist on target contract",
            str(context.exception))

        # call the target method with invalid number of arguments
        array = vm.ArrayStackItem(engine.reference_counter)
        array.append([vm.NullStackItem(), vm.NullStackItem()])
        with self.assertRaises(ValueError) as context:
            contract_call_internal(engine, target_contract.script_hash(),
                                   "test_func", array,
                                   contracts.native.CallFlags)
        self.assertEqual(
            "[System.Contract.Call] Invalid number of contract arguments. Expected 0 actual 2",
            str(context.exception))