Exemple #1
0
    def fn2spec(fn):
        spec = dict()

        if fn['type'] == 'function':
            for attr in ("name", "constant", "payable"):
                spec[attr] = fn[attr]

            spec['title'] = fn['name']  # to be extended by contract author
            spec['inputs'] = abi_arguments2schema(fn['inputs'])
            spec['outputs'] = abi_arguments2schema(fn['outputs'])

        elif fn['type'] == 'fallback':
            spec = {
                'name': '',
                'title': '',
                'constant': False,
                'payable': fn['payable'],
                'inputs': abi_arguments2schema([]),
                'outputs': abi_arguments2schema([])
            }

        else:
            assert False

        assert_conforms2definition(spec,
                                   load_schema('internal/front-back.json'),
                                   'ETHFunctionSpec')

        return spec
Exemple #2
0
    def fn2spec(fn):
        if obj_type(fn['name']) == 'actions':
            spec = {
                'name': fn['name'],
                'title': fn['name'],
                'constant': False,
                'payable': False,
                'inputs': abi_arguments2schema(fn['fields']),
                'outputs': abi_arguments2schema([])
            }
        elif obj_type(fn['name']) == 'tables':
            spec = {
                'name': fn['name'],
                'title': fn['name'],
                'constant': True,
                'payable': False,
                'inputs': abi_arguments2schema(table_indexes(fn['name'])),
                'outputs': abi_arguments2schema(fn['fields'])
            }
        else:
            assert False

        assert_conforms2definition(spec,
                                   load_schema('internal/front-back.json'),
                                   'ETHFunctionSpec')

        return spec
Exemple #3
0
def merge_function_titles2specs(spec_array, titles_info):
    """
    Attach human-friendly titles and descriptions to passed ETHFunctionSpec list.

    Processed elements: function titles and descriptions, function input arguments titles and descriptions,
    titles and descriptions of function outputs.

    :param spec_array: list of ETHFunctionSpec
    :param titles_info: data according to function_titles_info.json schema
    :return: modified ETHFunctionSpec
    """
    assert_conforms2schema_part(
        titles_info, load_schema('public/constructor.json'),
        'definitions/ETHFunctionAdditionalDescriptions')

    def set_title(to_spec, from_info):
        # todo how to deduplicate with json schema?
        # deduplicate with eth
        fields = ('title', 'description', 'sorting_order', 'ui:widget',
                  'ui:widget_options', 'payable_details', 'ui:options', 'icon')
        for field in fields:
            if field in from_info:
                to_spec[field] = from_info[field]

    for spec in spec_array:
        fn_titles = titles_info.get(spec['name'])
        if not fn_titles:
            continue

        set_title(spec, fn_titles)

        for io in ('inputs', 'outputs'):
            if not (io in fn_titles and 'items' in spec[io]):
                continue

            for (idx, arg_titles) in enumerate(fn_titles[io]):
                if idx >= len(spec[io]["items"]):
                    break

                set_title(spec[io]["items"][idx], arg_titles)

    # assume that it is ask function, since ask is getting record from special table
    spec_functions = [x['name'] for x in spec_array]
    for name, info in titles_info.items():
        if name not in spec_functions and not titles_info.get('inputs'):
            spec_fn = {  #todo remove copy paste
                'name': name,
                'title': '',
                'constant': True,
                'payable': False,
                'inputs': abi_arguments2schema([]),
                'outputs': abi_arguments2schema([])
            }

            set_title(spec_fn, info)
            spec_array.append(spec_fn)

    return spec_array
Exemple #4
0
def abi_arguments2schema(abi_args_array):
    """
    Конвертация массива аргументов функции контракта в json schema, пригодную для отрисовки и валидации в браузере.
    :param abi_args_array: массив аргументов функции контракта в формате Ethereum ABI
    :return: json schema в виде структуры
    """
    def abi_type2schema(abi_type, abi_name=None):
        if 'bool' == abi_type:
            result = {"type": "boolean", "default": False}

        elif abi_type in (
                'account_name', 'name', 'asset', 'uint32', 'uint64',
                'checksum256'):  # todo why name instead of account_name ?
            result = {"$ref": "#/definitions/" + abi_type}

        elif 'string' == abi_type:
            result = {"type": "string"}

        elif abi_type.endswith('[]'):
            result = {"type": "array", "items": abi_type2schema(abi_type[:-2])}

        else:
            raise NotImplementedError(
                'ABI type is not supported: {}'.format(abi_type))

        if abi_name is not None:
            result['title'] = abi_name

        return result

    schema = {
        "type": "array",
        "minItems": len(abi_args_array),
        "maxItems": len(abi_args_array),
    }
    if len(abi_args_array) > 0:
        schema["items"] = [
            abi_type2schema(arg['type'], arg.get("name"))
            for arg in abi_args_array
        ]
        return add_definitions(schema, load_schema('public/eos-sc.json'))
    else:
        return schema
Exemple #5
0
def merge_function_titles2specs(spec_array, titles_info):
    """
    Attach human-friendly titles and descriptions to passed ETHFunctionSpec list.

    Processed elements: function titles and descriptions, function input arguments titles and descriptions,
    titles and descriptions of function outputs.

    :param spec_array: list of ETHFunctionSpec
    :param titles_info: data according to function_titles_info.json schema
    :return: modified ETHFunctionSpec
    """
    assert_conforms2schema_part(
        titles_info, load_schema('public/constructor.json'),
        'definitions/ETHFunctionAdditionalDescriptions')

    def set_title(to_spec, from_info):
        # todo how to deduplicate with json schema?
        fields = ('title', 'description', 'sorting_order', 'ui:widget',
                  'ui:widget_options', 'payable_details', 'ui:options', 'icon')
        for field in fields:
            if field in from_info:
                to_spec[field] = from_info[field]

    for spec in spec_array:
        fn_titles = titles_info.get(spec['name'])
        if not fn_titles:
            continue

        set_title(spec, fn_titles)

        for io in ('inputs', 'outputs'):
            if not (io in fn_titles and 'items' in spec[io]):
                continue

            for (idx, arg_titles) in enumerate(fn_titles[io]):
                if idx >= len(spec[io]["items"]):
                    break

                set_title(spec[io]["items"][idx], arg_titles)

    return spec_array
Exemple #6
0
    def _call_constructor_method(self, source, method, args=None):
        assert (method in self.CONSTRUCTOR_METHODS)
        data = {
            "constructor_file": source,
            "method": method,
            "args": args if args is not None else []
        }
        try:
            res = requests.post(settings.SMARTZ_CONSTRUCTOR_CALL_SERVICE_URL,
                                json=data)
            if res.status_code != requests.codes.ok:
                return {
                    "result": "error",
                    "error_descr": "Something got wrong/0"
                }

            is_call_valid = is_conforms2schema_part(
                res.json(),
                load_schema('internal/call_ctor_service/call-service.json'),
                'rpc_calls/call_service/output_{}'.format(method))

            if not is_call_valid:
                return {
                    "result":
                    "error",
                    "error_descr":
                    "Something got wrong/1 (Invalid response from method {} of constructor)"
                    .format(method)
                }

            return res.json()
        except Exception as e:
            self.logger.warning(
                "Failed to call constructor method {}: {}".format(
                    method, str(e)))
            return {"result": "error", "error_descr": "Something got wrong/1"}
Exemple #7
0
def _process_ctor_schema(blockchain: str, schema):
    assert blockchain in dict(
        BLOCKCHAINS), "Blockchain {} is not supported".format(blockchain)
    return add_definitions(schema,
                           load_schema('public/{}-sc.json'.format(blockchain)))
Exemple #8
0
def abi_arguments2schema(abi_args_array):
    """
    Конвертация массива аргументов функции контракта в json schema, пригодную для отрисовки и валидации в браузере.
    :param abi_args_array: массив аргументов функции контракта в формате Ethereum ABI
    :return: json schema в виде структуры
    """
    def abi_type2schema(abi_type, abi_name=None):
        if 'bool' == abi_type:
            result = {"type": "boolean", "default": False}

        elif abi_type in (
                'address',
                'uint',
                'uint256',
                'uint8',
                'uint16',
                'uint32',
                'uint64',
                'uint128',
                'bytes1',
                'bytes2',
                'bytes3',
                'bytes4',
                'bytes5',
                'bytes6',
                'bytes7',
                'bytes8',
                'bytes9',
                'bytes10',
                'bytes11',
                'bytes12',
                'bytes13',
                'bytes14',
                'bytes15',
                'bytes16',
                'bytes17',
                'bytes18',
                'bytes19',
                'bytes20',
                'bytes21',
                'bytes22',
                'bytes23',
                'bytes24',
                'bytes25',
                'bytes26',
                'bytes27',
                'bytes28',
                'bytes29',
                'bytes30',
                'bytes31',
                'bytes32',
                'bytes',
        ):
            result = {"$ref": "#/definitions/" + abi_type}

        elif 'string' == abi_type:
            result = {"type": "string"}

        elif abi_type.endswith('[]'):
            result = {"type": "array", "items": abi_type2schema(abi_type[:-2])}

        else:
            raise NotImplementedError(
                'ABI type is not supported: {}'.format(abi_type))

        if abi_name is not None:
            result['title'] = abi_name

        return result

    schema = {
        "type": "array",
        "minItems": len(abi_args_array),
        "maxItems": len(abi_args_array),
    }
    if len(abi_args_array) > 0:
        schema["items"] = [
            abi_type2schema(arg['type'], arg.get("name"))
            for arg in abi_args_array
        ]
        return add_definitions(schema, load_schema('public/ethereum-sc.json'))
    else:
        return schema
Exemple #9
0
def _prepare_instance_details(dapp: Dapp) -> Dict:
    output = dapp_pub_info(dapp)
    assert_conforms2schema_part(output, load_schema('internal/front-back.json'),
                                'rpc_calls/get_instance_details/output')

    return output