Beispiel #1
0
    def test_call_contract_without_args(self):
        call_flag = Integer(CallFlags.ALL).to_byte_array(signed=True,
                                                         min_length=1)
        expected_output = (
            Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.NEWARRAY0 +
            Opcode.LDARG1 + Opcode.LDARG0 + Opcode.PUSHDATA1 +
            Integer(len(call_flag)).to_byte_array(min_length=1) + call_flag +
            Opcode.ROT + Opcode.ROT + Opcode.SYSCALL +
            Interop.CallContract.interop_method_hash + Opcode.RET)

        path = self.get_contract_path('CallScriptHashWithoutArgs.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)

        call_contract_path = self.get_contract_path('test_sc/list_test',
                                                    'IntList.py')
        Boa3.compile_and_save(call_contract_path)

        contract, manifest = self.get_output(call_contract_path)
        call_hash = hash160(contract)
        call_contract_path = call_contract_path.replace('.py', '.nef')

        engine = TestEngine()
        with self.assertRaises(TestExecutionException,
                               msg=self.CALLED_CONTRACT_DOES_NOT_EXIST_MSG):
            self.run_smart_contract(engine, path, 'Main', call_hash, 'Main')
        engine.add_contract(call_contract_path)

        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'Main')
        self.assertEqual([1, 2, 3], result)
Beispiel #2
0
    def test_call_contract(self):
        path = self.get_contract_path('CallScriptHash.py')
        call_contract_path = self.get_contract_path('test_sc/arithmetic_test',
                                                    'Addition.py')
        Boa3.compile_and_save(call_contract_path)

        contract, manifest = self.get_output(call_contract_path)
        call_hash = hash160(contract)
        call_contract_path = call_contract_path.replace('.py', '.nef')

        engine = TestEngine()
        with self.assertRaises(TestExecutionException,
                               msg=self.CALLED_CONTRACT_DOES_NOT_EXIST_MSG):
            self.run_smart_contract(engine, path, 'Main', call_hash, 'add',
                                    [1, 2])
        engine.add_contract(call_contract_path)

        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'add', [1, 2])
        self.assertEqual(3, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'add', [-42, -24])
        self.assertEqual(-66, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'add', [-42, 24])
        self.assertEqual(-18, result)
Beispiel #3
0
    def test_create_contract_data_deploy(self):
        path = self.get_contract_path('CreateContract.py')
        call_contract_path = self.get_contract_path('NewContract.py')
        Boa3.compile_and_save(call_contract_path)

        nef_file, manifest = self.get_bytes_output(call_contract_path)
        arg_manifest = String(json.dumps(manifest,
                                         separators=(',', ':'))).to_bytes()

        engine = TestEngine()
        data = 'some sort of data'
        result = self.run_smart_contract(engine, path, 'Main', nef_file,
                                         arg_manifest, data)

        self.assertEqual(5, len(result))
        self.assertEqual(nef_file, result[3])
        manifest_struct = NeoManifestStruct.from_json(manifest)
        self.assertEqual(manifest_struct, result[4])

        notifies = engine.get_events('notify')
        self.assertEqual(2, len(notifies))
        self.assertEqual(False, notifies[0].arguments[0])  # not updated
        self.assertEqual(data, notifies[1].arguments[0])  # data
        result = self.run_smart_contract(engine, call_contract_path, 'main')
        self.assertEqual(data, result)
    def test_generate_nef_file(self):
        path = self.get_contract_path('GenerationWithDecorator.py')
        expected_nef_output = path.replace('.py', '.nef')
        Boa3.compile_and_save(path)

        self.assertTrue(os.path.exists(expected_nef_output))
        with open(expected_nef_output, 'rb') as nef_output:
            magic = nef_output.read(constants.SIZE_OF_INT32)
            compiler_with_version = nef_output.read(64)
            compiler, version = compiler_with_version.rsplit(b'-', maxsplit=1)
            version = version[:32]

            nef_output.read(2)  # reserved
            nef_output.read(1)  # TODO: method tokens
            nef_output.read(2)  # reserved

            script_size = nef_output.read(1)
            script = nef_output.read(int.from_bytes(script_size, BYTEORDER))
            check_sum = nef_output.read(constants.SIZE_OF_INT32)

        self.assertEqual(int.from_bytes(script_size, BYTEORDER), len(script))

        nef = NefFile(script)._nef
        self.assertEqual(compiler.decode(ENCODING), nef.compiler)
        self.assertEqual(check_sum, nef.checksum)
        self.assertEqual(version, nef.version.to_array())
Beispiel #5
0
    def test_dict_any_key_and_value(self):
        path = self.get_contract_path('DictAnyKeyAndValue.py')
        Boa3.compile_and_save(path)

        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'main')
        self.assertEqual(66, result)
    def test_create_contract(self):
        call_flag = Integer(CallFlags.ALL).to_byte_array(signed=True,
                                                         min_length=1)
        expected_output = (
            Opcode.INITSLOT + b'\x00' + b'\x02' + Opcode.LDARG1 +
            Opcode.LDARG0 + Opcode.PUSH2 + Opcode.PACK + Opcode.DUP +
            Opcode.PUSHNULL + Opcode.APPEND + Opcode.PUSHDATA1 +
            Integer(len(Interop.CreateContract.method_name)).to_byte_array(
                min_length=1) +
            String(Interop.CreateContract.method_name).to_bytes() +
            Opcode.PUSHDATA1 + Integer(len(
                constants.MANAGEMENT_SCRIPT)).to_byte_array(min_length=1) +
            constants.MANAGEMENT_SCRIPT + Opcode.PUSHDATA1 +
            Integer(len(call_flag)).to_byte_array(min_length=1) + call_flag +
            Opcode.ROT + Opcode.ROT + Opcode.SYSCALL +
            Interop.CallContract.interop_method_hash + Opcode.RET)

        path = self.get_contract_path('CreateContract.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)

        call_contract_path = self.get_contract_path('test_sc/arithmetic_test',
                                                    'Addition.py')
        Boa3.compile_and_save(call_contract_path)

        nef_file, manifest = self.get_bytes_output(call_contract_path)
        arg_manifest = String(json.dumps(manifest,
                                         separators=(',', ':'))).to_bytes()

        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'Main', nef_file,
                                         arg_manifest)

        self.assertEqual(5, len(result))
        self.assertEqual(nef_file, result[3])
Beispiel #7
0
    def test_generate_files(self):
        path = self.get_contract_path('GenerationWithDecorator.py')
        expected_nef_output = path.replace('.py', '.nef')
        expected_manifest_output = path.replace('.py', '.manifest.json')
        Boa3.compile_and_save(path)

        self.assertTrue(os.path.exists(expected_nef_output))
        self.assertTrue(os.path.exists(expected_manifest_output))
Beispiel #8
0
    def test_compare_same_value_argument(self):
        path = self.get_contract_path('CompareSameValueArgument.py')
        Boa3.compile_and_save(path)

        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'testing_something', bytes(20),
                                         expected_result_type=bool)
        self.assertEqual(True, result)
Beispiel #9
0
    def test_generate_files(self):
        path = '%s/boa3_test/test_sc/generation_test/GenerationWithDecorator.py' % self.dirname
        expected_nef_output = path.replace('.py', '.nef')
        expected_manifest_output = path.replace('.py', '.manifest.json')
        expected_debug_info_output = path.replace('.py', '.nefdbgnfo')
        Boa3.compile_and_save(path)

        self.assertTrue(os.path.exists(expected_nef_output))
        self.assertTrue(os.path.exists(expected_manifest_output))
        self.assertTrue(os.path.exists(expected_debug_info_output))
    def test_compiler_error(self):
        path = self.get_contract_path('test_sc/built_in_methods_test',
                                      'ClearTooManyParameters.py')

        with self.assertRaises(NotLoadedException):
            Boa3.compile(path)

        with self.assertRaises(NotLoadedException):
            Boa3.compile_and_save(path)

        with self.assertRaises(NotLoadedException):
            self.compile_and_save(path)
Beispiel #11
0
    def setUpClass(cls):
        folders = os.path.abspath(__file__).split(os.sep)
        cls.dirname = '/'.join(folders[:-2])

        test_engine_installation_folder = cls.dirname  # Change this to your test engine installation folder
        cls.engine = TestEngine(test_engine_installation_folder)

        path = f'{cls.dirname}/src/BetOnFlyby.py'
        cls.nef_path = path.replace('.py', '.nef')

        if not os.path.isfile(cls.nef_path):
            Boa3.compile_and_save(path, output_path=cls.nef_path)
Beispiel #12
0
    def test_deploy_contract(self):
        path = self.get_contract_path('DeployContract.py')
        call_contract_path = self.get_contract_path('test_sc/arithmetic_test', 'Addition.py')
        Boa3.compile_and_save(call_contract_path)

        nef_file, manifest = self.get_bytes_output(call_contract_path)
        arg_manifest = String(json.dumps(manifest, separators=(',', ':'))).to_bytes()

        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'Main', nef_file, arg_manifest, None)

        self.assertEqual(5, len(result))
        self.assertEqual(nef_file, result[3])
        manifest_struct = NeoManifestStruct.from_json(manifest)
        self.assertEqual(manifest_struct, result[4])
Beispiel #13
0
    def test_get_contract(self):
        from boa3.neo3.contracts import CallFlags
        call_flag = Integer(CallFlags.ALL).to_byte_array(signed=True, min_length=1)
        expected_output = (
            Opcode.INITSLOT
            + b'\x00\x01'
            + Opcode.LDARG0
            + Opcode.PUSH1
            + Opcode.PACK
            + Opcode.PUSHDATA1
            + Integer(len(Interop.GetContract.method_name)).to_byte_array(min_length=1)
            + String(Interop.GetContract.method_name).to_bytes()
            + Opcode.PUSHDATA1
            + Integer(len(constants.MANAGEMENT_SCRIPT)).to_byte_array(min_length=1)
            + constants.MANAGEMENT_SCRIPT
            + Opcode.PUSHDATA1
            + Integer(len(call_flag)).to_byte_array(min_length=1)
            + call_flag
            + Opcode.ROT
            + Opcode.ROT
            + Opcode.SYSCALL
            + Interop.CallContract.interop_method_hash
            + Opcode.RET
        )
        path = self.get_contract_path('GetContract.py')
        output = Boa3.compile(path)
        self.assertEqual(expected_output, output)

        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'main', bytes(20))
        self.assertIsNone(result)

        call_contract_path = self.get_contract_path('test_sc/arithmetic_test', 'Addition.py')
        Boa3.compile_and_save(call_contract_path)

        script, manifest = self.get_output(call_contract_path)
        nef, manifest = self.get_bytes_output(call_contract_path)
        call_hash = hash160(script)
        call_contract_path = call_contract_path.replace('.py', '.nef')

        engine.add_contract(call_contract_path)
        arg_manifest = json.dumps(manifest, separators=(',', ':'))

        result = self.run_smart_contract(engine, path, 'main', call_hash)
        self.assertEqual(5, len(result))
        self.assertEqual(call_hash, result[2])
        self.assertEqual(nef, result[3])
Beispiel #14
0
    def compile_and_save(self, path: str, log: bool = True) -> Tuple[bytes, Dict[str, Any]]:
        nef_output = path.replace('.py', '.nef')
        manifest_output = path.replace('.py', '.manifest.json')

        from boa3.boa3 import Boa3
        from boa3.neo.contracts.neffile import NefFile
        Boa3.compile_and_save(path, show_errors=log)

        with open(nef_output, mode='rb') as nef:
            file = nef.read()
            output = NefFile.deserialize(file).script

        with open(manifest_output) as manifest_output:
            import json
            manifest = json.loads(manifest_output.read())

        return output, manifest
Beispiel #15
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("input", help=".py smart contract to compile")
    args = parser.parse_args()

    if not args.input.endswith(".py") or not os.path.isfile(args.input):
        logging.error("Input file is not .py")
        sys.exit(1)

    fullpath = os.path.realpath(args.input)
    path, filename = os.path.split(fullpath)

    try:
        Boa3.compile_and_save(args.input)
        logging.info(f"Wrote {filename.replace('.py', '.nef')} to {path}")
    except NotLoadedException as e:
        logging.error("Could not compile")
    except Exception as e:
        logging.exception(e)
Beispiel #16
0
    def test_call_contract_without_args(self):
        path = self.get_contract_path('CallScriptHashWithoutArgs.py')
        call_contract_path = self.get_contract_path('test_sc/list_test',
                                                    'IntList.py')
        Boa3.compile_and_save(call_contract_path)

        contract, manifest = self.get_output(call_contract_path)
        call_hash = hash160(contract)
        call_contract_path = call_contract_path.replace('.py', '.nef')

        engine = TestEngine()
        with self.assertRaises(TestExecutionException,
                               msg=self.CALLED_CONTRACT_DOES_NOT_EXIST_MSG):
            self.run_smart_contract(engine, path, 'Main', call_hash, 'Main')
        engine.add_contract(call_contract_path)

        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'Main')
        self.assertEqual([1, 2, 3], result)
Beispiel #17
0
    def test_get_call_flags(self):
        path = self.get_contract_path('CallScriptHashWithFlags.py')
        call_contract_path = self.get_contract_path('GetCallFlags.py')
        Boa3.compile_and_save(call_contract_path)

        engine = TestEngine()
        self.run_smart_contract(engine, call_contract_path, 'main')
        call_hash = engine.executed_script_hash.to_array()

        engine = TestEngine()
        call_contract_path = call_contract_path.replace('.py', '.nef')
        with self.assertRaises(TestExecutionException,
                               msg=self.CALLED_CONTRACT_DOES_NOT_EXIST_MSG):
            self.run_smart_contract(engine, path, 'Main', call_hash, 'main')
        engine.add_contract(call_contract_path)

        from boa3.neo3.contracts import CallFlags

        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'main', [], CallFlags.ALL)
        self.assertEqual(CallFlags.ALL, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'main', [], CallFlags.READ_ONLY)
        self.assertEqual(CallFlags.READ_ONLY, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'main', [], CallFlags.STATES)
        self.assertEqual(CallFlags.STATES, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'main', [], CallFlags.NONE)
        self.assertEqual(CallFlags.NONE, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'main', [], CallFlags.READ_STATES)
        self.assertEqual(CallFlags.READ_STATES, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'main', [], CallFlags.WRITE_STATES)
        self.assertEqual(CallFlags.WRITE_STATES, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'main', [], CallFlags.ALLOW_CALL)
        self.assertEqual(CallFlags.ALLOW_CALL, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'main', [], CallFlags.ALLOW_NOTIFY)
        self.assertEqual(CallFlags.ALLOW_NOTIFY, result)
Beispiel #18
0
    def test_generate_nef_file(self):
        path = '%s/boa3_test/test_sc/generation_test/GenerationWithDecorator.py' % self.dirname
        expected_nef_output = path.replace('.py', '.nef')
        Boa3.compile_and_save(path)

        self.assertTrue(os.path.exists(expected_nef_output))
        with open(expected_nef_output, 'rb') as nef_output:
            magic = nef_output.read(constants.SIZE_OF_INT32)
            compiler = nef_output.read(32)
            version = nef_output.read(16)
            hash = nef_output.read(constants.SIZE_OF_INT160)
            check_sum = nef_output.read(constants.SIZE_OF_INT32)
            script_size = nef_output.read(1)
            script = nef_output.read()

        self.assertEqual(int.from_bytes(script_size, BYTEORDER), len(script))

        nef = NefFile(script)._nef
        self.assertEqual(compiler.decode(ENCODING), nef.compiler)
        self.assertEqual(hash, nef.script_hash.to_array())
        self.assertEqual(check_sum, nef.checksum)
        self.assertEqual(version, nef.version.to_array())
Beispiel #19
0
    def test_get_contract(self):
        path = self.get_contract_path('GetContract.py')
        engine = TestEngine()
        result = self.run_smart_contract(engine, path, 'main', bytes(20))
        self.assertIsNone(result)

        call_contract_path = self.get_contract_path('test_sc/arithmetic_test',
                                                    'Addition.py')
        Boa3.compile_and_save(call_contract_path)

        script, manifest = self.get_output(call_contract_path)
        nef, manifest = self.get_bytes_output(call_contract_path)
        call_hash = hash160(script)
        call_contract_path = call_contract_path.replace('.py', '.nef')

        engine.add_contract(call_contract_path)

        result = self.run_smart_contract(engine, path, 'main', call_hash)
        self.assertEqual(5, len(result))
        self.assertEqual(call_hash, result[2])
        self.assertEqual(nef, result[3])
        manifest_struct = NeoManifestStruct.from_json(manifest)
        self.assertEqual(manifest_struct, result[4])
Beispiel #20
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("input", help=".py smart contract to compile")
    parser.add_argument("-db",
                        "--debug",
                        action='store_true',
                        help="generates a .nefdbgnfo file")
    parser.add_argument(
        "--project-path",
        help="Project root path. Path of the contract by default.",
        type=str)
    args = parser.parse_args()

    if not args.input.endswith(".py") or not os.path.isfile(args.input):
        logging.error("Input file is not .py")
        sys.exit(1)

    fullpath = os.path.realpath(args.input)
    path, filename = os.path.split(fullpath)

    if not args.project_path:
        args.project_path = os.path.dirname(path)

    try:
        Boa3.compile_and_save(args.input,
                              debug=args.debug,
                              root_folder=args.project_path)
        logging.info(f"Wrote {filename.replace('.py', '.nef')} to {path}")
    except NotLoadedException as e:
        error_message = e.message
        log_error = 'Could not compile'
        if len(error_message) > 0:
            log_error += f': {error_message}'

        logging.error(log_error)
    except Exception as e:
        logging.exception(e)
def build_contract(path):
    Boa3.compile_and_save(path)
Beispiel #22
0
    def test_call_contract_with_flags(self):
        path = self.get_contract_path('CallScriptHashWithFlags.py')
        call_contract_path = self.get_contract_path('CallFlagsUsage.py')
        Boa3.compile_and_save(call_contract_path)

        contract, manifest = self.get_output(call_contract_path)
        call_hash = hash160(contract)
        call_contract_path = call_contract_path.replace('.py', '.nef')

        engine = TestEngine()
        with self.assertRaises(TestExecutionException,
                               msg=self.CALLED_CONTRACT_DOES_NOT_EXIST_MSG):
            self.run_smart_contract(engine, path, 'Main', call_hash, 'Main')
        engine.add_contract(call_contract_path)

        from boa3.neo3.contracts import CallFlags

        with self.assertRaises(TestExecutionException):
            self.run_smart_contract(engine, path, 'Main', call_hash,
                                    'get_value', ['num'], CallFlags.NONE)

        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'get_value', ['num'],
                                         CallFlags.READ_ONLY)
        self.assertEqual(0, result)

        with self.assertRaises(TestExecutionException):
            self.run_smart_contract(engine, path, 'Main', call_hash,
                                    'put_value', ['num', 10],
                                    CallFlags.READ_ONLY)
            self.run_smart_contract(engine, path, 'Main', call_hash,
                                    'put_value', ['num', 10], CallFlags.NONE)

        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'put_value', ['num', 10],
                                         CallFlags.STATES)
        self.assertEqual(None, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'get_value', ['num'],
                                         CallFlags.READ_ONLY)
        self.assertEqual(10, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'put_value', ['num', 99],
                                         CallFlags.ALL)
        self.assertEqual(None, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'get_value', ['num'],
                                         CallFlags.READ_ONLY)
        self.assertEqual(99, result)

        with self.assertRaises(TestExecutionException):
            self.run_smart_contract(engine, path, 'Main', call_hash,
                                    'notify_user', [], CallFlags.READ_ONLY)
            self.run_smart_contract(engine, path, 'Main', call_hash,
                                    'notify_user', [], CallFlags.STATES)
            self.run_smart_contract(engine, path, 'Main', call_hash,
                                    'notify_user', [], CallFlags.NONE)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'notify_user', [], CallFlags.ALL)
        self.assertEqual(None, result)
        notify = engine.notifications
        self.assertEqual(1, len(notify))
        self.assertEqual('Notify was called', notify[0].arguments[0])

        with self.assertRaises(TestExecutionException):
            self.run_smart_contract(engine, path, 'Main', call_hash,
                                    'call_another_contract', [],
                                    CallFlags.STATES)
            self.run_smart_contract(engine, path, 'Main', call_hash,
                                    'call_another_contract', [],
                                    CallFlags.NONE)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'call_another_contract', [],
                                         CallFlags.ALL)
        self.assertEqual(0, result)
        result = self.run_smart_contract(engine, path, 'Main', call_hash,
                                         'call_another_contract', [],
                                         CallFlags.READ_ONLY)
        self.assertEqual(0, result)