예제 #1
0
    def test_can_call(self):
        # create a default contract, which is allowed to call any other contract and any other method
        cm = contracts.ContractManifest()
        target_manifest = contracts.ContractManifest()
        target_manifest.abi.contract_hash = types.UInt160.from_string("11" *
                                                                      20)
        self.assertTrue(cm.can_call(target_manifest, "some_method"))

        # now add a permission that allows all methods, but for a different contract hash
        contract_hash = types.UInt160.from_string("22" * 20)
        cpd = contracts.ContractPermissionDescriptor(
            contract_hash=contract_hash)
        cp = contracts.ContractPermission(
            contract=cpd,
            methods=contracts.WildcardContainer.create_wildcard())
        cm.permissions = [cp]
        self.assertFalse(cm.can_call(target_manifest, "some_method"))

        # now change the permissions (specifically the contract_hash) to allow calling
        new_contract_hash = types.UInt160.zero()
        cpd = contracts.ContractPermissionDescriptor(
            contract_hash=new_contract_hash)
        cp = contracts.ContractPermission(
            contract=cpd,
            methods=contracts.WildcardContainer.create_wildcard())
        cm.permissions = [cp]
        self.assertTrue(cm.can_call(target_manifest, "some_method"))
예제 #2
0
    def test_getcallingscripthash(self):
        """
        Testing this requires 2 contracts

        1) caller_contract: uses a System.Contract.Call to call callee_contract. This will set the calling script hash on the ExecutionContext of the callee_contract
        2) callee_contract: uses a System.Runtime.GetCallingScriptHash to return the calling script
        """
        sb = vm.ScriptBuilder()
        sb.emit_syscall(
            syscall_name_to_int("System.Runtime.GetCallingScriptHash"))
        callee_contract_script = sb.to_array()
        callee_nef = contracts.NEF(script=callee_contract_script)
        callee_contract_name = "callee_contract"
        callee_manifest = contracts.ContractManifest(callee_contract_name)
        callee_manifest.abi.methods = [
            contracts.ContractMethodDescriptor(
                "test_func", 0, [], contracts.ContractParameterType.ANY, True)
        ]
        callee_contract_hash = contract_hash(types.UInt160.zero(),
                                             callee_nef.checksum,
                                             callee_contract_name)
        callee_contract = contracts.ContractState(1, callee_nef,
                                                  callee_manifest, 0,
                                                  callee_contract_hash)

        # create caller_contract script
        sb = vm.ScriptBuilder()
        sb.emit_dynamic_call(callee_contract.hash, "test_func")
        caller_script = sb.to_array()
        caller_nef = contracts.NEF(script=caller_script)
        caller_contract_name = "caller_contract"
        caller_manifest = contracts.ContractManifest(caller_contract_name)
        caller_contract_hash = contract_hash(types.UInt160.zero(),
                                             caller_nef.checksum,
                                             caller_contract_name)
        caller_contract = contracts.ContractState(2, caller_nef,
                                                  caller_manifest, 0,
                                                  caller_contract_hash)

        engine = test_engine(has_snapshot=True, default_script=False)
        engine.snapshot.contracts.put(callee_contract)
        engine.snapshot.contracts.put(caller_contract)
        engine.load_script(vm.Script(caller_script))
        engine.execute()

        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        item = engine.result_stack.pop()
        self.assertEqual(
            to_script_hash(caller_nef.script).to_array(), item.to_array())
예제 #3
0
    def transfer_helper(self, contract: contracts.NativeContract,
                        from_account: types.UInt160, to_account: types.UInt160,
                        amount: vm.BigInteger):
        engine = test_engine(has_snapshot=True)
        block = test_block(0)
        # set or we won't pass the native deploy call
        engine.snapshot.persisting_block = block
        engine.invoke_syscall_by_name("Neo.Native.Deploy")
        engine.invocation_stack.pop()  # we no longer need the default script
        engine.script_container = TestIVerifiable()
        engine.script_container.script_hashes = [from_account]

        sb = vm.ScriptBuilder()
        sb.emit_push(amount)
        sb.emit_push(to_account.to_array())
        sb.emit_push(from_account.to_array())
        sb.emit_push(3)
        sb.emit(vm.OpCode.PACK)
        sb.emit_push(b'transfer')
        sb.emit_push(contract.script_hash.to_array())
        sb.emit_syscall(syscall_name_to_int("System.Contract.Call"))
        engine.load_script(vm.Script(sb.to_array()))

        engine.snapshot.contracts.put(
            storage.ContractState(sb.to_array(), contracts.ContractManifest()))
        return engine
예제 #4
0
    def test_storage_put_new(self):
        # see `test_storage_get_key_not_found()` for a description on why the storage is setup with a script as is

        # setup
        engine = test_engine(has_snapshot=True)
        script = vm.ScriptBuilder()
        script.emit(vm.OpCode.PUSH2)  # storage put value
        script.emit(vm.OpCode.PUSH1)  # storage put key
        script.emit_syscall(syscall_name_to_int("System.Storage.GetContext"))
        script.emit_syscall(syscall_name_to_int("System.Storage.Put"))
        engine.load_script(vm.Script(script.to_array()))

        nef = contracts.NEF(script=script.to_array())
        manifest = contracts.ContractManifest(f"contractname1")
        manifest.abi.methods = [
            contracts.ContractMethodDescriptor(
                "test_func", 0, [], contracts.ContractParameterType.ANY, True)
        ]
        hash_ = to_script_hash(nef.script)

        contract = contracts.ContractState(1, nef, manifest, 0, hash_)
        engine.snapshot.contracts.put(contract)

        engine.execute()

        self.assertEqual(vm.VMState.HALT, engine.state)
        storage_key = storage.StorageKey(1, b'\x01')
        item = engine.snapshot.storages.try_get(storage_key)
        self.assertIsNotNone(item)
        self.assertEqual(b'\x02', item.value)
예제 #5
0
    def test_is_valid(self):
        # create a contract
        cm = contracts.ContractManifest("test_contract")
        method1 = contracts.ContractMethodDescriptor(
            name="main_entry",
            offset=0,
            parameters=[],
            return_type=contracts.ContractParameterType.INTEGER,
            safe=True)
        cm.abi.methods = [method1]

        # A contract hash is normally created from a combination of transaction sender (UInt160), NEF checksum and manifest.name
        # For this test we'll keep it simple and pretend that hash is all zeros
        dummy_contract_hash = types.UInt160.zero()

        # a "default" contract has no groups data, which is the same as always allow
        self.assertTrue(cm.is_valid(dummy_contract_hash))

        # now try to add a malicious group member (meaning; the member did not actually sign the ABI)
        private_key = b'\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
        keypair = cryptography.KeyPair(private_key)
        bad_signature = bytes(64)
        cm.groups = [
            contracts.ContractGroup(keypair.public_key, bad_signature)
        ]
        # this time validation should fail
        self.assertFalse(cm.is_valid(dummy_contract_hash))

        # Finally test with a group member that did sign the ABI
        good_signature = cryptography.sign(dummy_contract_hash.to_array(),
                                           keypair.private_key)
        cm.groups = [
            contracts.ContractGroup(keypair.public_key, good_signature)
        ]
        self.assertTrue(cm.is_valid(dummy_contract_hash))
예제 #6
0
    def test_is_allowed_based_on_group(self):
        # We test the group permissions where all methods are allowed to be called
        # if the 'groups' member is valid.

        private_key = b'\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
        keypair = cryptography.KeyPair(private_key)

        dummy_contract_hash = types.UInt160.from_string("01" * 20)
        contract_state = contracts.ContractState(1, contracts.NEF(),
                                                 contracts.ContractManifest(),
                                                 0, dummy_contract_hash)

        signature = cryptography.sign(contract_state.hash.to_array(),
                                      keypair.private_key)
        contract_state.manifest.groups = [
            contracts.ContractGroup(keypair.public_key, signature)
        ]

        cpd = contracts.ContractPermissionDescriptor(group=keypair.public_key)
        cp = contracts.ContractPermission(
            contract=cpd,
            methods=contracts.WildcardContainer.create_wildcard())
        self.assertTrue(cp.is_allowed(contract_state, "dummy_method"))

        # now modify the manifest to have a different `groups` attribute such that validation fails
        public_key = cryptography.ECPoint.deserialize_from_bytes(
            b'\x00')  # ECPoint.Infinity
        contract_state.manifest.groups = [
            contracts.ContractGroup(public_key, signature)
        ]
        self.assertFalse(cp.is_allowed(contract_state, "dummy_method"))
예제 #7
0
    def test_transfer_partial_balance_to_account_with_balance(self):
        gas = contracts.GasToken()

        manifest = contracts.ContractManifest("contract_name")
        nef = contracts.NEF(script=b'\x40')
        state_to = contracts.ContractState(
            1, nef, manifest, 0,
            contract_hash(types.UInt160.zero(), nef.checksum, manifest.name))
        account_to = state_to.hash
        storage_key_to = gas.key_account + account_to
        account_to_state = gas._state()
        account_to_state.balance = vm.BigInteger(100)
        storage_item_to = storage.StorageItem(account_to_state.to_array())

        account_from = types.UInt160(b'\x01' * 20)
        storage_key_from = gas.key_account + account_from
        account_from_state = gas._state()
        account_from_state.balance = vm.BigInteger(123)
        storage_item_from = storage.StorageItem(account_from_state.to_array())

        amount = vm.BigInteger(50)

        engine = self.transfer_helper(gas, account_from, account_to, amount)
        # ensure the source and destination account have balances
        engine.snapshot.storages.put(storage_key_from, storage_item_from)
        engine.snapshot.storages.put(storage_key_to, storage_item_to)

        transfer_event = ()

        def notify_listener(contract_script_hash, event, state):
            nonlocal transfer_event
            transfer_event = (contract_script_hash, event, state)

        msgrouter.interop_notify += notify_listener
        engine.execute()
        self.assertEqual(1, len(engine.result_stack))
        result = engine.result_stack.pop()
        self.assertTrue(result)
        self.assertEqual(gas.hash, transfer_event[0])
        self.assertEqual("Transfer", transfer_event[1])
        state_items = list(transfer_event[2])
        self.assertEqual(account_from,
                         types.UInt160(state_items[0].to_array()))
        self.assertEqual(account_to, types.UInt160(state_items[1].to_array()))
        self.assertEqual(amount, state_items[2].to_biginteger())

        # validate from account is deducted by `amount`
        new_storage_account_from = engine.snapshot.storages.get(
            storage_key_from)
        new_account_state_from = gas._state.deserialize_from_bytes(
            new_storage_account_from.value)
        self.assertEqual(account_from_state.balance - amount,
                         new_account_state_from.balance)

        # validate to account is credited with `amount`
        new_storage_account_to = engine.snapshot.storages.get(storage_key_to)
        new_account_state_to = gas._state.deserialize_from_bytes(
            new_storage_account_to.value)
        self.assertEqual(account_to_state.balance + amount,
                         new_account_state_to.balance)
예제 #8
0
    def transfer_helper(self, contract: contracts.NativeContract,
                        from_account: types.UInt160, to_account: types.UInt160,
                        amount: vm.BigInteger):
        engine = test_engine(has_snapshot=True)
        block = test_block(0)
        # set or we won't pass the native deploy call
        engine.snapshot.persisting_block = block
        engine.invocation_stack.pop()  # we no longer need the default script
        engine.script_container = TestIVerifiable()
        engine.script_container.script_hashes = [from_account]

        sb = vm.ScriptBuilder()
        sb.emit(vm.OpCode.PUSHNULL)
        sb.emit_push(amount)
        sb.emit_push(to_account.to_array())
        sb.emit_push(from_account.to_array())
        sb.emit_push(4)
        sb.emit(vm.OpCode.PACK)
        sb.emit_push(15)  # callflags
        sb.emit_push(b'transfer')
        sb.emit_push(contract.hash.to_array())
        sb.emit_syscall(syscall_name_to_int("System.Contract.Call"))
        engine.load_script(vm.Script(sb.to_array()))

        nef = contracts.NEF(script=sb.to_array())
        manifest = contracts.ContractManifest("test_contract")
        contract_state = contracts.ContractState(
            1, nef, manifest, 0,
            contract_hash(from_account, nef.checksum, manifest.name))
        engine.snapshot.contracts.put(contract_state)
        return engine
예제 #9
0
 def test_contractstate_clone(self):
     manifest = contracts.ContractManifest()
     nef = contracts.NEF()
     state = contracts.ContractState(1, nef, manifest, 0,
                                     types.UInt160.zero())
     clone = state.clone()
     self.assertNotEqual(id(state), id(clone))
     self.assertNotEqual(id(state.manifest), id(clone.manifest))
예제 #10
0
 def test_from_json(self):
     expected_json = deepcopy(self.expected_json)
     cm = contracts.ContractManifest.from_json(expected_json)
     default = contracts.ContractManifest()
     self.assertEqual(default.groups, cm.groups)
     self.assertEqual(default.permissions, cm.permissions)
     self.assertEqual(default.trusts, cm.trusts)
     self.assertEqual(default.extra, cm.extra)
예제 #11
0
    def test_checkwitness_called_by_entry(self):
        """
        We need to setup 2 contracts
        1) caller_contract: uses a System.Contract.Call to call callee_contract. This will set the calling script hash on the ExecutionContext of the callee_contract
        2) callee_contract: uses a System.Runtime.CheckWitness
        """
        engine = test_engine(has_snapshot=True,
                             has_container=False,
                             default_script=False)
        tx = test_tx()
        tx.signers[0].scope = payloads.WitnessScope.CALLED_BY_ENTRY
        engine.script_container = tx

        sb = vm.ScriptBuilder()
        sb.emit_push(tx.sender.to_array())
        sb.emit_syscall(syscall_name_to_int("System.Runtime.CheckWitness"))
        callee_contract_script = sb.to_array()
        callee_manifest = contracts.ContractManifest(
            contract_hash=to_script_hash(callee_contract_script))
        callee_manifest.abi.methods = [
            contracts.ContractMethodDescriptor(
                "test_func", 0, [], contracts.ContractParameterType.ANY)
        ]
        callee_contract = storage.ContractState(callee_contract_script,
                                                callee_manifest)

        sb = vm.ScriptBuilder()
        sb.emit(vm.OpCode.NEWARRAY0)  # args (empty array)
        sb.emit_push('test_func')  # target method name
        sb.emit_push(callee_contract.script_hash().to_array())  # contract hash
        sb.emit_syscall(syscall_name_to_int("System.Contract.Call"))
        caller_script = sb.to_array()
        caller_manifest = contracts.ContractManifest(
            contract_hash=to_script_hash(caller_script))
        caller_contract = storage.ContractState(caller_script, caller_manifest)

        engine.snapshot.contracts.put(callee_contract)
        engine.snapshot.contracts.put(caller_contract)
        engine.load_script(vm.Script(caller_script))
        engine.execute()

        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        item = engine.result_stack.pop()
        self.assertTrue(item.to_boolean())
예제 #12
0
    def test_get_invocation_counter_ok(self):
        """
        We need to setup 2 contracts
        1) caller_contract: uses a System.Contract.Call to call callee_contract. This will increase the invocation counter of the callee contract
        2) callee_contract: uses a System.Runtime.GetInvocationCounter
        """
        engine = test_engine(has_snapshot=True,
                             has_container=False,
                             default_script=False)

        sb = vm.ScriptBuilder()
        sb.emit_syscall(
            syscall_name_to_int("System.Runtime.GetInvocationCounter"))
        callee_contract_script = sb.to_array()
        callee_nef = contracts.NEF(script=callee_contract_script)
        callee_manifest = contracts.ContractManifest("contract1")
        callee_manifest.abi.methods = [
            contracts.ContractMethodDescriptor(
                "test_func", 0, [], contracts.ContractParameterType.ANY, True)
        ]
        callee_contract = contracts.ContractState(
            1, callee_nef, callee_manifest, 0,
            contract_hash(types.UInt160.zero(), callee_nef.checksum,
                          callee_manifest.name))

        sb = vm.ScriptBuilder()
        sb.emit_dynamic_call(callee_contract.hash, "test_func")
        caller_script = sb.to_array()
        caller_nef = contracts.NEF(script=caller_script)
        caller_manifest = contracts.ContractManifest("contract2")
        caller_contract = contracts.ContractState(
            2, caller_nef, caller_manifest, 0,
            contract_hash(types.UInt160.zero(), caller_nef.checksum,
                          caller_manifest.name))

        engine.snapshot.contracts.put(callee_contract)
        engine.snapshot.contracts.put(caller_contract)
        engine.load_script(vm.Script(caller_script))
        engine.execute()

        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        item = engine.result_stack.pop()
        self.assertEqual(1, int(item))
예제 #13
0
    def test_equals(self):
        manifest = contracts.ContractManifest()
        state = storage.ContractState(b'\x01', manifest)
        clone = state.clone()
        self.assertEqual(state, clone)

        state2 = storage.ContractState(b'\x02', manifest)
        self.assertNotEqual(state, state2)
        self.assertNotEqual(state, None)
        self.assertNotEqual(state, object())
예제 #14
0
 def test_create(self):
     cm = contracts.ContractManifest("test_contract")
     method1 = contracts.ContractMethodDescriptor(
         name="main_entry",
         offset=0,
         parameters=[],
         return_type=contracts.ContractParameterType.INTEGER,
         safe=True)
     cm.abi.methods = [method1]
     self.assertEqual(self.expected_json, cm.to_json())
예제 #15
0
    def test_getcallingscripthash(self):
        """
        Testing this requires 2 contracts

        1) caller_contract: uses a System.Contract.Call to call callee_contract. This will set the calling script hash on the ExecutionContext of the callee_contract
        2) callee_contract: uses a System.Runtime.GetCallingScriptHash to return the calling script
        """
        sb = vm.ScriptBuilder()
        sb.emit_syscall(
            syscall_name_to_int("System.Runtime.GetCallingScriptHash"))
        callee_contract_script = sb.to_array()
        callee_manifest = contracts.ContractManifest(
            contract_hash=to_script_hash(callee_contract_script))
        callee_manifest.abi.methods = [
            contracts.ContractMethodDescriptor(
                "test_func", 0, [], contracts.ContractParameterType.ANY)
        ]
        callee_contract = storage.ContractState(callee_contract_script,
                                                callee_manifest)

        # create caller_contract script
        sb = vm.ScriptBuilder()
        sb.emit(vm.OpCode.NEWARRAY0)  # args (empty array)
        sb.emit_push('test_func')  # target method name
        sb.emit_push(callee_contract.script_hash().to_array())  # contract hash
        sb.emit_syscall(syscall_name_to_int("System.Contract.Call"))
        caller_script = sb.to_array()
        caller_manifest = contracts.ContractManifest(
            contract_hash=to_script_hash(caller_script))
        caller_contract = storage.ContractState(caller_script, caller_manifest)

        engine = test_engine(has_snapshot=True, default_script=False)
        engine.snapshot.contracts.put(callee_contract)
        engine.snapshot.contracts.put(caller_contract)
        engine.load_script(vm.Script(caller_script))
        engine.execute()

        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        item = engine.result_stack.pop()
        self.assertEqual(caller_contract.script_hash().to_array(),
                         item.to_array())
예제 #16
0
    def test_get_invocation_counter_ok(self):
        """
        We need to setup 2 contracts
        1) caller_contract: uses a System.Contract.Call to call callee_contract. This will increase the invocation counter of the callee contract
        2) callee_contract: uses a System.Runtime.GetInvocationCounter
        """
        engine = test_engine(has_snapshot=True,
                             has_container=False,
                             default_script=False)

        sb = vm.ScriptBuilder()
        sb.emit_syscall(
            syscall_name_to_int("System.Runtime.GetInvocationCounter"))
        callee_contract_script = sb.to_array()
        callee_manifest = contracts.ContractManifest(
            contract_hash=to_script_hash(callee_contract_script))
        callee_manifest.abi.methods = [
            contracts.ContractMethodDescriptor(
                "test_func", 0, [], contracts.ContractParameterType.ANY)
        ]
        callee_contract = storage.ContractState(callee_contract_script,
                                                callee_manifest)

        sb = vm.ScriptBuilder()
        sb.emit(vm.OpCode.NEWARRAY0)  # args (empty array)
        sb.emit_push('test_func')  # target method name
        sb.emit_push(callee_contract.script_hash().to_array())  # contract hash
        sb.emit_syscall(syscall_name_to_int("System.Contract.Call"))
        caller_script = sb.to_array()
        caller_manifest = contracts.ContractManifest(
            contract_hash=to_script_hash(caller_script))
        caller_contract = storage.ContractState(caller_script, caller_manifest)

        engine.snapshot.contracts.put(callee_contract)
        engine.snapshot.contracts.put(caller_contract)
        engine.load_script(vm.Script(caller_script))
        engine.execute()

        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        item = engine.result_stack.pop()
        self.assertEqual(1, int(item))
예제 #17
0
 def setUp(self) -> None:
     self.RET = b'\x40'
     self.manifest = contracts.ContractManifest("contract_name")
     self.nef = contracts.NEF(script=self.RET)
     self.contract_hash = to_script_hash(self.nef.script)
     self.contract = contracts.ContractState(1, self.nef, self.manifest, 0,
                                             self.contract_hash)
     self.contract.manifest.abi.methods = [
         contracts.ContractMethodDescriptor(
             "test_func", 0, [], contracts.ContractParameterType.ANY, True)
     ]
예제 #18
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)
예제 #19
0
    def test_to_account_not_payable(self):
        gas = contracts.GasToken()
        state = storage.ContractState(b'\x00', contracts.ContractManifest())

        engine = self.transfer_helper(gas, types.UInt160.zero(),
                                      state.script_hash(), vm.BigInteger(1))
        # default manifest is not payable
        engine.snapshot.contracts.put(state)
        engine.execute()
        self.assertEqual(1, len(engine.result_stack))
        result = engine.result_stack.pop()
        self.assertFalse(result)
예제 #20
0
    def test_policy_block_account_and_is_blocked(self):
        engine = test_engine(has_snapshot=True)
        block = test_block(0)
        # set or we won't pass the native deploy call
        engine.snapshot.persisting_block = block

        sb = vm.ScriptBuilder()

        # set or we won't pass the check_comittee() in the policy contract function implementations
        engine.script_container = TestIVerifiable()
        validator = settings.standby_committee[0]
        script_hash = to_script_hash(
            contracts.Contract.create_multisig_redeemscript(1, [validator]))
        engine.script_container.script_hashes = [script_hash]

        # first we setup the stack for calling `blockAccount`
        # push data to create a vm.Array holding 20 bytes for the UInt160 Account parameter of the _block_account function.
        sb.emit_push(b'\x11' * 20)
        sb.emit(vm.OpCode.PUSH1)
        sb.emit(vm.OpCode.PACK)
        sb.emit_push(15)  # call flags
        sb.emit_push("blockAccount")
        sb.emit_push(contracts.PolicyContract().hash.to_array())
        sb.emit_syscall(syscall_name_to_int("System.Contract.Call"))

        # next we call `isBlocked`
        sb.emit_push(b'\x11' * 20)
        sb.emit(vm.OpCode.PUSH1)
        sb.emit(vm.OpCode.PACK)
        sb.emit_push(15)  # call flags
        sb.emit_push("isBlocked")
        sb.emit_push(contracts.PolicyContract().hash.to_array())
        sb.emit_syscall(syscall_name_to_int("System.Contract.Call"))

        script = vm.Script(sb.to_array())
        engine.load_script(script)

        # storing the current script in a contract otherwise "System.Contract.Call" will fail its checks
        nef = contracts.NEF(script=sb.to_array())
        manifest = contracts.ContractManifest("test_contract")
        sender = engine.script_container.script_hashes[0]
        contract = contracts.ContractState(
            1, nef, manifest, 0,
            contract_hash(sender, nef.checksum, manifest.name))
        engine.snapshot.contracts.put(contract)

        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(2, len(engine.result_stack))
        get_is_blocked_result = engine.result_stack.pop()
        set_blocked_account_result = engine.result_stack.pop()
        self.assertTrue(set_blocked_account_result.to_boolean())
        self.assertTrue(get_is_blocked_result.to_boolean())
예제 #21
0
 def test_deserialization(self):
     # this assumes test_serialization() passes
     cm = contracts.ContractManifest("test_contract")
     method1 = contracts.ContractMethodDescriptor(
         name="main_entry",
         offset=0,
         parameters=[],
         return_type=contracts.ContractParameterType.INTEGER,
         safe=True)
     cm.abi.methods = [method1]
     cm_deserialized = contracts.ContractManifest.deserialize_from_bytes(
         cm.to_array())
     self.assertEqual(cm, cm_deserialized)
예제 #22
0
 def test_serialize(self):
     # if test_create() passes, then we know `to_json()` is ok, which serialize internally uses
     cm = contracts.ContractManifest("test_contract")
     method1 = contracts.ContractMethodDescriptor(
         name="main_entry",
         offset=0,
         parameters=[],
         return_type=contracts.ContractParameterType.INTEGER,
         safe=True)
     cm.abi.methods = [method1]
     with serialization.BinaryReader(cm.to_array()) as br:
         data = br.read_var_string()
     self.assertDictEqual(self.expected_json, json.loads(data))
예제 #23
0
    def test_transfer_from_empty_account(self):
        gas = contracts.GasToken()
        manifest = contracts.ContractManifest()
        manifest.features = contracts.ContractFeatures.PAYABLE
        state = storage.ContractState(b'\x00', manifest)

        engine = self.transfer_helper(gas, types.UInt160.zero(),
                                      state.script_hash(), vm.BigInteger(1))
        engine.snapshot.contracts.put(state)
        engine.execute()
        self.assertEqual(1, len(engine.result_stack))
        result = engine.result_stack.pop()
        self.assertFalse(result)
예제 #24
0
    def test_contract_is_standard_ok(self):
        keypair = cryptography.KeyPair(b'\x01' * 32)
        sig_contract = contracts.Contract.create_signature_contract(
            keypair.public_key)

        engine = test_engine(has_snapshot=True)
        contract = storage.ContractState(
            sig_contract.script,
            contracts.ContractManifest(sig_contract.script_hash))
        engine.snapshot.contracts.put(contract)
        engine.push(vm.ByteStringStackItem(contract.script_hash().to_array()))
        engine.invoke_syscall_by_name("System.Contract.IsStandard")
        engine.execute()
        self.assertEqual(True, engine.result_stack.pop().to_boolean())
예제 #25
0
    def test_equals(self):
        manifest = contracts.ContractManifest()
        nef = contracts.NEF()
        state = contracts.ContractState(1, nef, manifest, 0,
                                        types.UInt160.zero())
        clone = state.clone()
        self.assertEqual(state, clone)

        nef2 = contracts.NEF()
        state2 = contracts.ContractState(2, nef2, manifest, 0,
                                         types.UInt160(b'\x01' * 20))
        self.assertNotEqual(state, state2)
        self.assertNotEqual(state, None)
        self.assertNotEqual(state, object())
예제 #26
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'])
예제 #27
0
 def test_from_json(self):
     expected_json = deepcopy(self.expected_json)
     # we update the defaults to also test the features
     new_features = {'storage': True, 'payable': True}
     expected_json['features'] = new_features
     cm = contracts.ContractManifest.from_json(expected_json)
     default = contracts.ContractManifest(types.UInt160.zero())
     self.assertEqual(default.groups, cm.groups)
     self.assertIn(contracts.ContractFeatures.HAS_STORAGE, cm.features)
     self.assertIn(contracts.ContractFeatures.PAYABLE, cm.features)
     self.assertEqual(default.permissions, cm.permissions)
     self.assertEqual(default.trusts, cm.trusts)
     self.assertEqual(default.safe_methods, cm.safe_methods)
     self.assertEqual(default.extra, cm.extra)
예제 #28
0
    def test_transfer_from_empty_account(self):
        gas = contracts.GasToken()
        manifest = contracts.ContractManifest("test_contract2")
        nef = contracts.NEF(script=b'\x40')
        state = contracts.ContractState(
            2, nef, manifest, 0,
            contract_hash(types.UInt160.zero(), nef.checksum, manifest.name))

        engine = self.transfer_helper(gas, types.UInt160.zero(), state.hash,
                                      vm.BigInteger(1))
        engine.snapshot.contracts.put(state)
        engine.execute()
        self.assertEqual(1, len(engine.result_stack))
        result = engine.result_stack.pop()
        self.assertFalse(result)
예제 #29
0
    def test_policy_set_and_get_blocked_accounts(self):
        engine = test_engine(has_snapshot=True)
        block = test_block(0)
        # set or we won't pass the native deploy call
        engine.snapshot.persisting_block = block

        sb = vm.ScriptBuilder()
        sb.emit_syscall(syscall_name_to_int("Neo.Native.Deploy"))

        # set or we won't pass the check_comittee() in the policy contract function implementations
        engine.script_container = TestIVerifiable()
        validator = settings.standby_committee[0]
        script_hash = to_script_hash(
            contracts.Contract.create_multisig_redeemscript(1, [validator]))
        engine.script_container.script_hashes = [script_hash]

        # first we setup the stack for calling `blockAccount`
        # push data to create a vm.Array holding 20 bytes for the UInt160 Account parameter of the _block_account function.
        sb.emit_push(b'\x11' * 20)
        sb.emit(vm.OpCode.PUSH1)
        sb.emit(vm.OpCode.PACK)
        sb.emit_push("blockAccount")
        sb.emit_push(contracts.PolicyContract().script_hash.to_array())
        sb.emit_syscall(syscall_name_to_int("System.Contract.Call"))

        # next we call `getBlockedAccounts`
        sb.emit_contract_call(contracts.PolicyContract().script_hash,
                              "getBlockedAccounts")

        script = vm.Script(sb.to_array())
        engine.load_script(script)

        # storing the current script in a contract otherwise "System.Contract.Call" will fail its checks
        engine.snapshot.contracts.put(
            storage.ContractState(sb.to_array(), contracts.ContractManifest()))

        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(2, len(engine.result_stack))
        get_blocked_accounts_result = engine.result_stack.pop()
        set_blocked_accounts_result = engine.result_stack.pop()
        self.assertTrue(set_blocked_accounts_result.to_boolean())
        self.assertIsInstance(get_blocked_accounts_result, vm.InteropStackItem)
        stored_accounts = get_blocked_accounts_result.get_object()
        self.assertEqual(1, len(stored_accounts))

        expected_account = types.UInt160(data=b'\x11' * 20)
        self.assertEqual(expected_account, stored_accounts[0])
예제 #30
0
    def test_contract_is_standard_fail2(self):
        # can find contract, but is not a signature contract
        engine = test_engine(has_snapshot=True)

        # create a non-standard contract
        script = b'\x01\x02\x03'
        script_hash = to_script_hash(script)
        manifest = contracts.ContractManifest(script_hash)
        contract = storage.ContractState(script, manifest)
        engine.snapshot.contracts.put(contract)

        # push function argument and call
        engine.push(vm.ByteStringStackItem(script_hash.to_array()))
        engine.invoke_syscall_by_name("System.Contract.IsStandard")
        engine.execute()
        self.assertEqual(False, engine.result_stack.pop().to_boolean())