Пример #1
0
    def test_itoa(self):
        engine = test_engine(has_snapshot=True)
        original_item = 100
        base = 10
        sb = vm.ScriptBuilder()
        sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "itoa",
                                       [original_item, base])
        engine.load_script(vm.Script(sb.to_array()))
        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        item = engine.result_stack.pop()
        self.assertEqual('100', item.to_array().decode('utf-8'))

        engine = test_engine(has_snapshot=True)
        base = 16
        sb = vm.ScriptBuilder()
        sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "itoa",
                                       [original_item, base])
        engine.load_script(vm.Script(sb.to_array()))
        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        item = engine.result_stack.pop()
        self.assertEqual('64', item.to_array().decode('utf-8'))

        engine = test_engine(has_snapshot=True)
        invalid_base = 2
        sb = vm.ScriptBuilder()
        sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash, "itoa",
                                       [original_item, invalid_base])
        engine.load_script(vm.Script(sb.to_array()))
        engine.execute()

        self.assertEqual(vm.VMState.FAULT, engine.state)
        self.assertIn("Invalid base specified", engine.exception_message)
Пример #2
0
def multisig_contract_costs(threshold: int, public_key_count: int) -> int:
    fee = contracts.ApplicationEngine.opcode_price(vm.OpCode.PUSHDATA1) * (threshold + public_key_count)
    opcode = vm.OpCode(vm.ScriptBuilder().emit_push(threshold).to_array()[0])
    fee += contracts.ApplicationEngine.opcode_price(opcode)
    opcode = vm.OpCode(vm.ScriptBuilder().emit_push(public_key_count).to_array()[0])
    fee += contracts.ApplicationEngine.opcode_price(opcode)
    fee += contracts.ApplicationEngine.opcode_price(vm.OpCode.SYSCALL)
    fee += CHECKSIG_PRICE * public_key_count
    return fee
Пример #3
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)
Пример #4
0
    def test_verify_secp256k1(self):
        """
        byte[] message = System.Text.Encoding.Default.GetBytes("hello");
        byte[] signature = "5331be791532d157df5b5620620d938bcb622ad02c81cfc184c460efdad18e695480d77440c511e9ad02ea30d773cb54e88f8cbb069644aefa283957085f38b5".HexToBytes();
        byte[] pubKey = "03ea01cb94bdaf0cd1c01b159d474f9604f4af35a3e2196f6bdfdb33b2aa4961fa".HexToBytes();

        Crypto.VerifySignature(message, signature, pubKey, Neo.Cryptography.ECC.ECCurve.Secp256k1).Should().BeTrue();
        """
        message = b'hello'
        signature = binascii.unhexlify(
            b'5331be791532d157df5b5620620d938bcb622ad02c81cfc184c460efdad18e695480d77440c511e9ad02ea30d773cb54e88f8cbb069644aefa283957085f38b5'
        )
        public_key = binascii.unhexlify(
            b'03ea01cb94bdaf0cd1c01b159d474f9604f4af35a3e2196f6bdfdb33b2aa4961fa'
        )
        self.assertTrue(
            cryptography.verify_signature(message, signature, public_key,
                                          cryptography.ECCCurve.SECP256K1))

        sb = vm.ScriptBuilder()
        sb.emit_push(signature)
        sb.emit_push(public_key)
        sb.emit_push(message)
        sb.emit_syscall(
            syscall_name_to_int("Neo.Crypto.VerifyWithECDsaSecp256k1"))

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

        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())

        # again with bad signature
        bad_signature = b'\xFF' + signature[1:]
        sb = vm.ScriptBuilder()
        sb.emit_push(bad_signature)
        sb.emit_push(public_key)
        sb.emit_push(message)
        sb.emit_syscall(
            syscall_name_to_int("Neo.Crypto.VerifyWithECDsaSecp256k1"))

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

        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        self.assertEqual(vm.BooleanStackItem(False), engine.result_stack.pop())
Пример #5
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())
Пример #6
0
    def test_storage_get_key_not_found(self):
        engine = test_engine(has_snapshot=True, has_container=True)
        script = vm.ScriptBuilder()
        # key parameter for the `Storage.Get` syscall
        script.emit(vm.OpCode.PUSH2)
        script.emit_syscall(syscall_name_to_int("System.Storage.GetContext"))
        # at this point our stack looks like follows
        # * storage context
        # * key
        script.emit_syscall(syscall_name_to_int("System.Storage.Get"))
        engine.load_script(vm.Script(script.to_array()))

        # we have to store our contract or some sanity checks will fail (like getting a StorageContext
        nef = contracts.NEF(script=script.to_array())
        contract = contracts.ContractState(1, nef, self.manifest, 0,
                                           to_script_hash(nef.script))
        engine.snapshot.contracts.put(contract)

        storage_key = storage.StorageKey(contract.id, b'\x01')
        storage_item = storage.StorageItem(b'\x11')
        engine.snapshot.storages.put(storage_key, storage_item)

        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        item = engine.result_stack.pop()
        self.assertIsInstance(item, vm.NullStackItem)
Пример #7
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)
Пример #8
0
    def test_storage_get_ok2(self):
        # this is basically the same as `test_storage_get_ok`
        # but performed by executing a script
        # it exists to validate that the `Optional[bytes]` return value is converted properly
        engine = test_engine(has_snapshot=True)
        script = vm.ScriptBuilder()
        script.emit(vm.OpCode.PUSH1)
        script.emit_syscall(syscall_name_to_int("System.Storage.GetContext"))
        script.emit_syscall(syscall_name_to_int("System.Storage.Get"))
        engine.load_script(vm.Script(script.to_array()))

        nef = contracts.NEF(script=script.to_array())
        contract_hash = to_script_hash(nef.script)
        contract = contracts.ContractState(1, nef, self.manifest, 0,
                                           contract_hash)
        engine.snapshot.contracts.put(contract)

        storage_key = storage.StorageKey(contract.id, b'\x01')
        storage_item = storage.StorageItem(b'\x11')
        engine.snapshot.storages.put(storage_key, storage_item)

        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        item = engine.result_stack.pop()
        self.assertEqual(storage_item.value, item.to_array())
Пример #9
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
Пример #10
0
    def test_storage_get_key_not_found(self):
        engine = test_engine(has_snapshot=True)
        script = vm.ScriptBuilder()
        # key parameter for the `Get` syscall
        script.emit(vm.OpCode.PUSH2)
        script.emit_syscall(syscall_name_to_int("System.Storage.GetContext"))
        # at this point our stack looks like follows
        # * storage context
        # * key
        script.emit_syscall(syscall_name_to_int("System.Storage.Get"))
        engine.load_script(vm.Script(script.to_array()))

        # we set the script parameter of the ContractState to our script
        # which ensures that `engine.current_scripthash` matches the script we manually build above
        # this basically means the engine thinks it is running a smart contract that we can find in our storage
        # which in turns enables us to call the `System.Storage.GetContext` syscall
        contract = storage.ContractState(script=script.to_array(),
                                         _manifest=self.manifest)
        engine.snapshot.contracts.put(contract)

        storage_key = storage.StorageKey(contract.script_hash(), b'\x01')
        storage_item = storage.StorageItem(b'\x11')
        engine.snapshot.storages.put(storage_key, storage_item)

        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        item = engine.result_stack.pop()
        self.assertIsInstance(item, vm.NullStackItem)
Пример #11
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

        for i in range(2):
            # setup
            engine = test_engine(has_snapshot=True)
            script = vm.ScriptBuilder()
            if i == 0:
                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"))
            else:
                script.emit(vm.OpCode.PUSH0)  # storage put call flags
                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.PutEx"))
            engine.load_script(vm.Script(script.to_array()))

            contract = storage.ContractState(script=script.to_array(),
                                             _manifest=self.manifest)
            engine.snapshot.contracts.put(contract)

            engine.execute()

            self.assertEqual(vm.VMState.HALT, engine.state)
            storage_key = storage.StorageKey(contract.script_hash(), b'\x01')
            item = engine.snapshot.storages.try_get(storage_key)
            self.assertIsNotNone(item)
            self.assertEqual(b'\x02', item.value)
Пример #12
0
    def test_gasleft(self):
        engine = test_engine()
        engine.is_test_mode = True

        sb = vm.ScriptBuilder()
        sb.emit_syscall(syscall_name_to_int("System.Runtime.GasLeft"))
        data = sb.to_array()

        # test with test mode
        engine.load_script(vm.Script(data))
        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack._items))
        item = engine.result_stack.pop()
        self.assertEqual(vm.IntegerStackItem(-1), item)

        # test with actual consumption
        engine = test_engine()
        engine.is_test_mode = False
        engine.gas_amount = 500
        # we can re-use the script
        engine.load_script(vm.Script(data))
        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack._items))
        item = engine.result_stack.pop()
        # the syscall itself costs 400
        self.assertEqual(vm.IntegerStackItem(100), item)
Пример #13
0
    def test_ripemd160_other_types(self):
        """
        using var script = new ScriptBuilder();
        script.EmitPush(new byte[] {0x1, 0x2, 0x3, 0x4});
        script.EmitSysCall(ApplicationEngine.Neo_Crypto_RIPEMD160); // Syscall
        var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 100_000_000, false);
        engine.LoadScript(script.ToArray());
        Assert.AreEqual(engine.Execute(), VMState.HALT);
        Assert.AreEqual(1, engine.ResultStack.Count);
        var item = engine.ResultStack.Pop<ByteString>();
        Console.WriteLine($"{item.GetSpan().ToHexString()}");
        """
        sb = vm.ScriptBuilder()
        sb.emit_push(b'\x01\x02\x03\x04')
        sb.emit_syscall(syscall_name_to_int("Neo.Crypto.RIPEMD160"))

        engine = test_engine()
        script = vm.Script(sb.to_array())
        engine.load_script(script)
        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        # captured from C#
        expected = '179bb366e5e224b8bf4ce302cefc5744961839c5'
        self.assertEqual(expected, str(engine.result_stack.pop()))
Пример #14
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
Пример #15
0
    def test_serialization(self):
        script = vm.ScriptBuilder()
        script.emit_push(5)
        script.emit_syscall(syscall_name_to_int("System.Json.Serialize"))
        script.emit(vm.OpCode.PUSH0)
        script.emit(vm.OpCode.NOT)
        script.emit_syscall(syscall_name_to_int("System.Json.Serialize"))
        script.emit_push("test")
        script.emit_syscall(syscall_name_to_int("System.Json.Serialize"))
        script.emit(vm.OpCode.PUSHNULL)
        script.emit_syscall(syscall_name_to_int("System.Json.Serialize"))
        script.emit(vm.OpCode.NEWMAP)
        script.emit(vm.OpCode.DUP)
        script.emit_push("key")
        script.emit_push("value")
        script.emit(vm.OpCode.SETITEM)
        script.emit_syscall(syscall_name_to_int("System.Json.Serialize"))

        data = script.to_array()

        engine = contracts.ApplicationEngine(contracts.TriggerType.APPLICATION,
                                             None, None, 0, True)
        engine.load_script(vm.Script(data))
        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)

        def pop_to_human_readable():
            return binascii.unhexlify(str(
                engine.result_stack.pop()).encode()).decode()

        self.assertEqual('{"key":"value"}', pop_to_human_readable())
        self.assertEqual('null', pop_to_human_readable())
        self.assertEqual('"test"', pop_to_human_readable())
        self.assertEqual('true', pop_to_human_readable())
        self.assertEqual('5', pop_to_human_readable())
Пример #16
0
    def sign_tx(self,
                tx: payloads.Transaction,
                password: str,
                magic: Optional[int] = None) -> None:
        """
        Helper function that signs the TX, adds the Witness and Sender

        Args:
            tx: transaction to sign
            password: the password to decrypt the private key for signing
            magic: the network magic

        Raises:
            ValueError: if transaction validation fails
        """
        if magic is None:
            magic = settings.network.magic

        self._validate_tx(tx)

        message = magic.to_bytes(4, byteorder="little",
                                 signed=False) + tx.hash().to_array()
        signature = self.sign(message, password)

        invocation_script = vm.ScriptBuilder().emit_push(signature).to_array()
        # mypy can't infer that the is_watchonly check ensures public_key has a value
        verification_script = contracts.Contract.create_signature_redeemscript(
            self.public_key)  # type: ignore
        tx.witnesses.insert(
            0, payloads.Witness(invocation_script, verification_script))
Пример #17
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])
Пример #18
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())
Пример #19
0
    def test_sha256(self):
        """
        using var script = new ScriptBuilder();
        script.EmitPush(new byte[] {0x1, 0x2, 0x3, 0x4});
        script.EmitSysCall(ApplicationEngine.Neo_Crypto_SHA256); // Syscall
        var engine = ApplicationEngine.Create(TriggerType.Application, null, null, 100_000_000, false);
        engine.LoadScript(script.ToArray());
        Assert.AreEqual(engine.Execute(), VMState.HALT);
        Assert.AreEqual(1, engine.ResultStack.Count);
        var item = engine.ResultStack.Pop<ByteString>();
        Console.WriteLine($"{item.GetSpan().ToHexString()}");
        """
        sb = vm.ScriptBuilder()
        sb.emit_push(b'\x01\x02\x03\x04')
        sb.emit_syscall(syscall_name_to_int("Neo.Crypto.SHA256"))

        engine = test_engine()
        script = vm.Script(sb.to_array())
        engine.load_script(script)
        engine.execute()
        self.assertEqual(vm.VMState.HALT, engine.state)
        self.assertEqual(1, len(engine.result_stack))
        # captured from C#
        expected = '9f64a747e1b97f131fabb6b447296c9b6f0201e79fb3c5356e6c77e89b6a806a'
        self.assertEqual(expected, str(engine.result_stack.pop()))
    def test_iterator_concat(self):
        engine = test_engine()
        array1 = vm.ArrayStackItem(engine.reference_counter)
        item1 = vm.IntegerStackItem(123)
        array1.append(item1)

        array2 = vm.ArrayStackItem(engine.reference_counter)
        item2 = vm.IntegerStackItem(456)
        array2.append(item2)

        script = vm.ScriptBuilder()
        # initialize 1 slot to store the iterator in
        script.emit(vm.OpCode.INITSLOT)
        script.emit_raw(b'\x01\x00')

        # stack state at this point is
        # * array2
        # * array1
        script.emit_syscall(syscall_name_to_int("System.Iterator.Create"))
        # Iterator.create removed array2 and places an iterator on the stack, we store this in a variables slot
        script.emit(vm.OpCode.STLOC0)
        # so we can call iterator.create again, with array1 as argument
        script.emit_syscall(syscall_name_to_int("System.Iterator.Create"))
        # we restore the iterator of array2
        script.emit(vm.OpCode.LDLOC0)
        # we concat and get [array2, array1]
        script.emit_syscall(syscall_name_to_int("System.Iterator.Concat"))
        script.emit(vm.OpCode.STLOC0)

        # have just 1 value per iterator, so we call next and value just 2 times
        for _ in range(2):
            script.emit(vm.OpCode.LDLOC0)
            script.emit_syscall(syscall_name_to_int("System.Enumerator.Next"))
            script.emit(vm.OpCode.DROP)
            script.emit(vm.OpCode.LDLOC0)
            script.emit_syscall(syscall_name_to_int("System.Enumerator.Value"))

        # we add a call to key for coverage
        script.emit(vm.OpCode.LDLOC0)
        script.emit_syscall(syscall_name_to_int("System.Iterator.Key"))

        engine.load_script(vm.Script(script.to_array()))
        engine.push(array1)
        engine.push(array2)
        engine.execute()

        self.assertEqual(vm.VMState.HALT, engine.state)
        # we expect 3 values on there, 1 key/array index and 2 array values
        self.assertEqual(len(engine.result_stack), 3)

        key_from_engine = engine.result_stack.pop()
        self.assertEqual(vm.IntegerStackItem(0), key_from_engine)

        item1_from_engine = engine.result_stack.pop()
        self.assertEqual(item1, item1_from_engine)

        # item2 was put on last, comes of first
        item2_from_engine = engine.result_stack.pop()
        self.assertEqual(item2, item2_from_engine)
Пример #21
0
    def init(self,
             backend: storage.IDBImplementation = None,
             store_genesis_block=True):  # type: ignore
        self.backend = backend if backend else settings.database
        self._current_snapshot = None
        self.genesis_block = self._create_genesis_block()
        self.genesis_block.rebuild_merkle_root()

        sb = vm.ScriptBuilder().emit_syscall(
            syscall_name_to_int("System.Contract.NativeOnPersist"))
        self.native_onpersist_script = sb.to_array()
        sb = vm.ScriptBuilder().emit_syscall(
            syscall_name_to_int("System.Contract.NativePostPersist"))
        self.native_postpersist_script = sb.to_array()

        if self.currentSnapshot.best_block_height < 0 and store_genesis_block:
            self.persist(self.genesis_block)
Пример #22
0
def contract_hash(sender: types.UInt160, checksum: int,
                  name: str) -> types.UInt160:
    sb = vm.ScriptBuilder()
    sb.emit(vm.OpCode.ABORT)
    sb.emit_push(sender.to_array())
    sb.emit_push(checksum)
    sb.emit_push(name)
    return to_script_hash(sb.to_array())
Пример #23
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())
Пример #24
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))
Пример #25
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())
Пример #26
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))
Пример #27
0
    def contract_create_with_data(
            self, engine: contracts.ApplicationEngine, nef_file: bytes,
            manifest: bytes, data: vm.StackItem) -> contracts.ContractState:
        if not isinstance(engine.script_container, payloads.Transaction):
            raise ValueError(
                "Cannot create contract without a Transaction script container"
            )

        nef_len = len(nef_file)
        manifest_len = len(manifest)
        if (nef_len == 0 or nef_len > engine.MAX_CONTRACT_LENGTH
                or manifest_len == 0
                or manifest_len > contracts.ContractManifest.MAX_LENGTH):
            raise ValueError("Invalid NEF or manifest length")

        engine.add_gas(
            max(engine.STORAGE_PRICE * (nef_len + manifest_len),
                self.get_minimum_deployment_fee(engine.snapshot)))

        nef = contracts.NEF.deserialize_from_bytes(nef_file)
        parsed_manifest = contracts.ContractManifest.from_json(
            json.loads(manifest.decode()))

        self.validate(nef.script, parsed_manifest.abi)

        sb = vm.ScriptBuilder()
        sb.emit(vm.OpCode.ABORT)
        sb.emit_push(engine.script_container.sender.to_array())
        sb.emit_push(nef.checksum)
        sb.emit_push(parsed_manifest.name)
        hash_ = to_script_hash(sb.to_array())

        existing_contract = engine.snapshot.contracts.try_get(hash_)
        if existing_contract is not None:
            raise ValueError("Contract already exists")

        contract = contracts.ContractState(
            self.get_next_available_id(engine.snapshot), nef, parsed_manifest,
            0, hash_)
        if not contract.manifest.is_valid(hash_):
            raise ValueError("Error: invalid manifest")
        engine.snapshot.contracts.put(contract)

        method_descriptor = contract.manifest.abi.get_method("_deploy", 2)
        if method_descriptor is not None:
            engine.call_from_native(self.hash, hash_, method_descriptor.name,
                                    [data, vm.BooleanStackItem(False)])

        msgrouter.interop_notify(
            self.hash, "Deploy",
            vm.ArrayStackItem(engine.reference_counter,
                              vm.ByteStringStackItem(
                                  contract.hash.to_array())))
        return contract
Пример #28
0
 def test_base58_encode(self):
     engine = test_engine(has_snapshot=True)
     original_item = 100
     sb = vm.ScriptBuilder()
     sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash,
                                    "base58Encode", [original_item])
     engine.load_script(vm.Script(sb.to_array()))
     engine.execute()
     self.assertEqual(vm.VMState.HALT, engine.state)
     item = engine.result_stack.peek()
     self.assertEqual('2j', item.to_array().decode())
Пример #29
0
 def test_binary_serialization(self):
     engine = test_engine(has_snapshot=True)
     original_item = 100
     sb = vm.ScriptBuilder()
     sb.emit_dynamic_call_with_args(contracts.StdLibContract().hash,
                                    "serialize", [original_item])
     engine.load_script(vm.Script(sb.to_array()))
     engine.execute()
     self.assertEqual(vm.VMState.HALT, engine.state)
     item = engine.result_stack.pop()
     self.assertIsInstance(item, vm.ByteStringStackItem)
     self.assertEqual(b'\x21\x01\x64', item.to_array())
Пример #30
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())