Beispiel #1
0
def withdraw(priv, pub, to_address, amount):
    substrate = SubstrateInterface(url='wss://rpc.polkadot.io', ss58_format=0, type_registry_preset='polkadot', use_remote_preset=True)
    call = substrate.compose_call(
        call_module='Balances',
        call_function='transfer',
        call_params={'dest': to_address, 'value': int(amount * 1e8)}
    )
    from_address = public_key_to_address(pub)
    nonce = substrate.get_account_nonce(from_address)
    payload = substrate.generate_signature_payload(call, nonce=nonce).data
    signature = '0x' + eddsa_sign.eddsa_sign(priv, payload).hex()

    keypair = Keypair(ss58_address=from_address, ss58_format=0, crypto_type=KeypairType.ED25519)
    extrinsic = substrate.create_signed_extrinsic(call=call, keypair=keypair, nonce=nonce, signature=signature)
    result=substrate.submit_extrinsic(extrinsic=extrinsic)
    print(result)
Beispiel #2
0
class JSONRPCResource(BaseResource):

    def __init__(self, cache_region):

        self.cache_region = cache_region

        # Check for custom types in Redis

        self.substrate = None

        custom_type_registry = self.cache_region.get('CUSTOM_TYPE_REGISTRY')
        self.init_type_registry(custom_type_registry)

        self.block_hash = None
        self.metadata_decoder = None
        self.runtime_version = None

        self.metadata_cache = {}

        self.methods = [
            'rpc_methods',
            'runtime_decodeScale',
            'runtime_encodeScale',
            'runtime_getMetadata',
            'runtime_getMetadataModules',
            'runtime_getMetadataCallFunctions',
            'runtime_getMetadataCallFunction',
            'runtime_getMetadataEvents',
            'runtime_getMetadataEvent',
            'runtime_getMetadataConstants',
            'runtime_getMetadataConstant',
            'runtime_getMetadataStorageFunctions',
            'runtime_getMetadataStorageFunction',
            'runtime_getMetadataErrors',
            'runtime_getMetadataError',
            'runtime_getState',
            'runtime_getTypeRegistry',
            'runtime_getType',
            'runtime_getCustomTypes',
            'runtime_addCustomType',
            'runtime_setCustomTypes',
            'runtime_removeCustomType',
            'runtime_resetCustomTypes',
            'runtime_getBlock',
            'runtime_createSignaturePayload',
            'runtime_createExternalSignerPayload',
            'runtime_createExtrinsic',
            'runtime_submitExtrinsic',
            'runtime_getPaymentInfo',
            'keypair_create',
            'keypair_inspect',
            'keypair_sign',
            'keypair_verify'
        ]

    def get_request_param(self, params):
        try:
            return params.pop(0)
        except IndexError:
            raise ValueError("Not enough parameters provided")

    def init_type_registry(self, custom_type_registry=None):

        if settings.TYPE_REGISTRY_FILE:
            type_registry = load_type_registry_file(settings.TYPE_REGISTRY_FILE)
        else:
            type_registry = {}

        if custom_type_registry:
            type_registry.update(custom_type_registry)

        self.substrate = SubstrateInterface(
            url=settings.SUBSTRATE_RPC_URL,
            ss58_format=settings.SUBSTRATE_ADDRESS_TYPE,
            type_registry_preset=settings.TYPE_REGISTRY,
            type_registry=custom_type_registry
        )

        if settings.DEBUG:
            print('Custom types at init: ', custom_type_registry)
            self.substrate.debug = True

    def init_request(self, params=None):

        if params:
            self.block_hash = self.get_request_param(params)
            if type(self.block_hash) is int:
                self.block_hash = self.substrate.get_block_hash(self.block_hash)

    def on_post(self, req, resp):
        self.block_hash = None
        self.metadata_decoder = None
        self.runtime_version = None

        self.substrate.request_id = req.media.get('id')

        method = req.media.get('method')
        params = req.media.get('params', [])

        # Check request requirements
        if not req.media.get('jsonrpc'):
            resp.media = {
                "error": {
                    "code": -32600,
                    "message": "Unsupported JSON-RPC protocol version"
                },
                "id": req.media.get('id')
            }
        elif not method:
            resp.media = {
                "error": {
                    "code": -32601,
                    "message": "Method not found"
                },
                "id": req.media.get('id')
            }
        elif method not in self.methods:
            # Default pass through request to Substrate RPC
            resp.media = self.substrate.rpc_request(method, params)
        else:
            resp.status = falcon.HTTP_200
            try:

                # Process methods
                if method == 'runtime_getBlock':
                    self.init_request(params)

                    block = self.substrate.get_block(block_hash=self.block_hash)

                    if block:

                        block['extrinsics'] = [extrinsic.value for extrinsic in block['extrinsics']]
                        block['header']["digest"]["logs"] = [log.value for log in block['header']["digest"]["logs"]]

                    response = {
                        "jsonrpc": "2.0",
                        "result": block,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getState':
                    # Init params
                    storage_params = None

                    # Process params
                    module = self.get_request_param(params)
                    storage_function = self.get_request_param(params)
                    if params:
                        storage_params = self.get_request_param(params)

                    self.init_request(params)

                    # Get response
                    obj = self.substrate.query(
                        module=module,
                        storage_function=storage_function,
                        params=storage_params,
                        block_hash=self.block_hash
                    )
                    response = {'result': obj.value if obj else None}

                elif method == 'runtime_getMetadata':
                    # Process params
                    self.init_request(params)

                    # Get response
                    response = self.substrate.get_runtime_metadata(block_hash=self.block_hash)

                elif method in ['runtime_createSignaturePayload', 'runtime_createExternalSignerPayload']:
                    account = self.get_request_param(params)
                    call_module = self.get_request_param(params)
                    call_function = self.get_request_param(params)
                    call_params = self.get_request_param(params)
                    tip = self.get_request_param(params) or 0
                    era = self.get_request_param(params)

                    self.init_request(params)

                    try:
                        # Create call
                        call = self.substrate.compose_call(
                            call_module=call_module,
                            call_function=call_function,
                            call_params=call_params,
                            block_hash=self.block_hash
                        )

                        nonce = self.substrate.get_account_nonce(account) or 0

                        if isinstance(era, dict) and 'current' not in era and 'phase' not in era:
                            # Retrieve current block id
                            era['current'] = self.substrate.get_block_number(self.substrate.get_chain_head())

                        if method == 'runtime_createExternalSignerPayload':
                            include_call_length = True
                        else:
                            include_call_length = False

                        # Generate signature payload
                        signature_payload = self.substrate.generate_signature_payload(
                            call=call,
                            nonce=nonce,
                            tip=tip,
                            era=era,
                            include_call_length=include_call_length
                        )

                        response = {
                            "jsonrpc": "2.0",
                            "result": {
                                'signature_payload': str(signature_payload),
                                'nonce': nonce,
                                'era': era
                            },
                            "id": req.media.get('id')
                        }
                    except ValueError as e:
                        response = {
                            "jsonrpc": "2.0",
                            "error": {
                                "code": -999,
                                "message": str(e)
                            },
                            "id": req.media.get('id')
                        }
                elif method in ['runtime_submitExtrinsic', 'runtime_createExtrinsic']:
                    account = self.get_request_param(params)
                    call_module = self.get_request_param(params)
                    call_function = self.get_request_param(params)
                    call_params = self.get_request_param(params)
                    tip = self.get_request_param(params) or 0
                    era = self.get_request_param(params)
                    crypto_type = int(self.get_request_param(params) or 1)
                    signature = self.get_request_param(params)

                    self.init_request(params)

                    try:
                        # Create call
                        call = self.substrate.compose_call(
                            call_module=call_module,
                            call_function=call_function,
                            call_params=call_params,
                            block_hash=self.block_hash
                        )

                        nonce = self.substrate.get_account_nonce(account) or 0

                        # Create keypair with only public given given in request
                        keypair = Keypair(ss58_address=account, crypto_type=crypto_type)

                        if isinstance(era, dict) and 'current' in era:
                            era['current'] = int(era['current'])

                        # Create extrinsic
                        extrinsic = self.substrate.create_signed_extrinsic(
                            call=call,
                            keypair=keypair,
                            nonce=nonce,
                            signature=signature,
                            tip=tip,
                            era=era
                        )

                        if method == 'runtime_createExtrinsic':
                            result = str(extrinsic.data)
                        else:
                            # Submit extrinsic to the node
                            extrinsic_result = self.substrate.submit_extrinsic(
                                extrinsic=extrinsic
                            )
                            result = {
                                "extrinsic_hash": extrinsic_result.extrinsic_hash,
                                "block_hash": extrinsic_result.block_hash,
                                "finalized": extrinsic_result.finalized,
                            }

                        response = {
                            "jsonrpc": "2.0",
                            "result": result,
                            "id": req.media.get('id')
                        }
                    except ValueError as e:
                        response = {
                            "jsonrpc": "2.0",
                            "error": {
                                "code": -999,
                                "message": str(e)
                            },
                            "id": req.media.get('id')
                        }
                    except SubstrateRequestException as e:
                        response = {
                            "jsonrpc": "2.0",
                            "error": e.args[0],
                            "id": req.media.get('id')
                        }
                elif method == 'runtime_getPaymentInfo':

                    account = self.get_request_param(params)
                    call_module = self.get_request_param(params)
                    call_function = self.get_request_param(params)
                    call_params = self.get_request_param(params)

                    # Create call
                    call = self.substrate.compose_call(
                        call_module=call_module,
                        call_function=call_function,
                        call_params=call_params
                    )

                    # Create keypair with only public given given in request
                    keypair = Keypair(ss58_address=account)

                    response = {
                        "jsonrpc": "2.0",
                        "result": self.substrate.get_payment_info(call=call, keypair=keypair),
                        "id": req.media.get('id')
                    }

                elif method == 'runtime_getMetadataModules':

                    self.init_request(params)

                    response = {
                        "jsonrpc": "2.0",
                        "result": self.substrate.get_metadata_modules(block_hash=self.block_hash),
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getMetadataCallFunctions':

                    self.init_request(params)

                    call_list = self.substrate.get_metadata_call_functions(block_hash=self.block_hash)

                    response = {
                        "jsonrpc": "2.0",
                        "result": call_list,
                        "id": req.media.get('id')
                    }

                elif method == 'runtime_getMetadataCallFunction':

                    param_call_module = self.get_request_param(params)
                    param_call_module_function = self.get_request_param(params)

                    self.init_request(params)

                    result = self.substrate.get_metadata_call_function(
                        module_name=param_call_module,
                        call_function_name=param_call_module_function,
                        block_hash=self.block_hash
                    )

                    response = {
                        "jsonrpc": "2.0",
                        "result": result.value,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getMetadataEvents':

                    self.init_request(params)

                    event_list = self.substrate.get_metadata_events(block_hash=self.block_hash)

                    response = {
                        "jsonrpc": "2.0",
                        "result": event_list,
                        "id": req.media.get('id')
                    }

                elif method == 'runtime_getMetadataEvent':

                    param_call_module = self.get_request_param(params)
                    param_call_module_event = self.get_request_param(params)

                    self.init_request(params)

                    result = self.substrate.get_metadata_event(
                        module_name=param_call_module,
                        event_name=param_call_module_event,
                        block_hash=self.block_hash
                    )

                    response = {
                        "jsonrpc": "2.0",
                        "result": result,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getMetadataConstants':

                    self.init_request(params)

                    constant_list = self.substrate.get_metadata_constants(block_hash=self.block_hash)

                    response = {
                        "jsonrpc": "2.0",
                        "result": constant_list,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getMetadataConstant':

                    module_name = self.get_request_param(params)
                    constant_name = self.get_request_param(params)

                    self.init_request(params)

                    result = self.substrate.get_metadata_constant(
                        module_name=module_name,
                        constant_name=constant_name,
                        block_hash=self.block_hash
                    )

                    response = {
                        "jsonrpc": "2.0",
                        "result": result,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getMetadataStorageFunctions':
                    self.init_request(params)

                    storage_list = self.substrate.get_metadata_storage_functions(block_hash=self.block_hash)

                    response = {
                        "jsonrpc": "2.0",
                        "result": storage_list,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getMetadataStorageFunction':

                    module_name = self.get_request_param(params)
                    storage_name = self.get_request_param(params)

                    self.init_request(params)

                    result = self.substrate.get_metadata_storage_function(
                        module_name=module_name,
                        storage_name=storage_name,
                        block_hash=self.block_hash
                    )

                    response = {
                        "jsonrpc": "2.0",
                        "result": result.value,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getMetadataErrors':

                    self.init_request(params)

                    error_list = self.substrate.get_metadata_errors(block_hash=self.block_hash)

                    response = {
                        "jsonrpc": "2.0",
                        "result": error_list,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getMetadataError':

                    module_name = self.get_request_param(params)
                    error_name = self.get_request_param(params)

                    self.init_request(params)

                    result = self.substrate.get_metadata_error(
                        module_name=module_name,
                        error_name=error_name,
                        block_hash=self.block_hash
                    )

                    response = {
                        "jsonrpc": "2.0",
                        "result": result,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getTypeRegistry':

                    self.init_request(params)

                    result = self.substrate.get_type_registry(block_hash=self.block_hash)

                    if result:
                        result = list(result.values())

                    response = {
                        "jsonrpc": "2.0",
                        "result": result,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getType':

                    type_string = self.get_request_param(params)
                    self.init_request(params)

                    response = {
                        "jsonrpc": "2.0",
                        "result": self.substrate.get_type_definition(type_string, block_hash=self.block_hash),
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_addCustomType':

                    type_string = self.get_request_param(params)
                    type_definition = self.get_request_param(params)

                    # Retrieve current custom type registry
                    custom_type_registry = self.cache_region.get('CUSTOM_TYPE_REGISTRY')

                    if not custom_type_registry:
                        custom_type_registry = {
                            'types': {

                            }
                        }

                    custom_type_registry['types'][type_string] = type_definition

                    # TODO Try to decode given type definition

                    # Store updated custom type registry
                    self.cache_region.set('CUSTOM_TYPE_REGISTRY', custom_type_registry)

                    if settings.DEBUG:
                        print('Custom types updated to: ', custom_type_registry)

                    # Update runtime configuration
                    RuntimeConfiguration().update_type_registry(custom_type_registry)

                    response = {
                        "jsonrpc": "2.0",
                        "result": "Type registry updated",
                        "id": req.media.get('id')
                    }

                elif method == 'runtime_setCustomTypes':

                    custom_types = self.get_request_param(params)

                    if type(custom_types) is not dict:
                        raise ValueError('custom types must be in format: {"type_string": "type_definition"}')

                    custom_type_registry = {
                        'types': custom_types
                    }

                    # Store updated custom type registry
                    self.cache_region.set('CUSTOM_TYPE_REGISTRY', custom_type_registry)

                    # Reset runtime configuration
                    RuntimeConfiguration().clear_type_registry()
                    self.init_type_registry(custom_type_registry)

                    if settings.DEBUG:
                        print('Custom types updated to: ', custom_type_registry)

                    response = {
                        "jsonrpc": "2.0",
                        "result": "Type registry updated",
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_resetCustomTypes':

                    custom_type_registry = None

                    # Store updated custom type registry
                    self.cache_region.set('CUSTOM_TYPE_REGISTRY', custom_type_registry)

                    # Reset runtime configuration
                    RuntimeConfiguration().clear_type_registry()
                    self.init_type_registry()

                    if settings.DEBUG:
                        print('Custom types cleared')

                    response = {
                        "jsonrpc": "2.0",
                        "result": "Custom types cleared",
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_removeCustomType':

                    type_string = self.get_request_param(params)

                    # Retrieve current custom type registry
                    custom_type_registry = self.cache_region.get('CUSTOM_TYPE_REGISTRY')

                    if custom_type_registry and type_string in custom_type_registry.get('types', {}):
                        del custom_type_registry['types'][type_string]

                        # Store updated custom type registry
                        self.cache_region.set('CUSTOM_TYPE_REGISTRY', custom_type_registry)

                        # Reset runtime configuration
                        RuntimeConfiguration().clear_type_registry()
                        self.init_type_registry(custom_type_registry)

                        result = '"{}" removed from custom type registry'.format(type_string)

                    else:
                        result = '"{}" not found in custom type registry'.format(type_string)

                    response = {
                        "jsonrpc": "2.0",
                        "result": result,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_getCustomTypes':

                    custom_type_registry = self.cache_region.get('CUSTOM_TYPE_REGISTRY')

                    if custom_type_registry:
                        result = custom_type_registry.get('types')
                    else:
                        result = {}

                    response = {
                        "jsonrpc": "2.0",
                        "result": result,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_decodeScale':

                    type_string = self.get_request_param(params)
                    scale_hex_bytes = self.get_request_param(params)

                    self.init_request(params)

                    result = self.substrate.decode_scale(
                        type_string=type_string,
                        scale_bytes=scale_hex_bytes,
                        block_hash=self.block_hash
                    )

                    response = {
                        "jsonrpc": "2.0",
                        "result": result,
                        "id": req.media.get('id')
                    }
                elif method == 'runtime_encodeScale':

                    type_string = self.get_request_param(params)
                    value = self.get_request_param(params)

                    self.init_request(params)

                    result = self.substrate.encode_scale(
                        type_string=type_string,
                        value=value,
                        block_hash=self.block_hash
                    )

                    response = {
                        "jsonrpc": "2.0",
                        "result": result,
                        "id": req.media.get('id')
                    }
                elif method == 'keypair_create':

                    word_count = self.get_request_param(params) or 0
                    crypto_type = int(self.get_request_param(params) or 1)

                    mnemonic = Keypair.generate_mnemonic(word_count)

                    keypair = Keypair.create_from_mnemonic(
                        mnemonic=mnemonic, ss58_format=settings.SUBSTRATE_ADDRESS_TYPE, crypto_type=crypto_type
                    )

                    response = {
                        "jsonrpc": "2.0",
                        "result": {
                            'ss58_address': keypair.ss58_address,
                            'public_key': keypair.public_key,
                            'private_key': keypair.private_key,
                            'mnemonic': keypair.mnemonic,
                        },
                        "id": req.media.get('id')
                    }
                elif method == 'keypair_inspect':

                    mnemonic = self.get_request_param(params)
                    crypto_type = int(self.get_request_param(params) or 1)

                    keypair = Keypair.create_from_mnemonic(
                        mnemonic=mnemonic, ss58_format=settings.SUBSTRATE_ADDRESS_TYPE, crypto_type=crypto_type
                    )

                    response = {
                        "jsonrpc": "2.0",
                        "result": {
                            'ss58_address': keypair.ss58_address,
                            'public_key': keypair.public_key,
                            'private_key': keypair.private_key,
                            'mnemonic': keypair.mnemonic,
                        },
                        "id": req.media.get('id')
                    }
                elif method == 'keypair_sign':
                    mnemonic = self.get_request_param(params)
                    data = self.get_request_param(params)
                    crypto_type = int(self.get_request_param(params) or 1)

                    keypair = Keypair.create_from_mnemonic(
                        mnemonic=mnemonic, ss58_format=settings.SUBSTRATE_ADDRESS_TYPE, crypto_type=crypto_type
                    )
                    signature = keypair.sign(data)

                    response = {
                        "jsonrpc": "2.0",
                        "result": {'signature': signature},
                        "id": req.media.get('id')
                    }

                elif method == 'keypair_verify':
                    account_address = self.get_request_param(params)
                    data = self.get_request_param(params)
                    signature = self.get_request_param(params)
                    crypto_type = int(self.get_request_param(params) or 1)

                    keypair = Keypair(
                        ss58_address=account_address,
                        ss58_format=settings.SUBSTRATE_ADDRESS_TYPE,
                        crypto_type=crypto_type
                    )
                    result = keypair.verify(data, signature)

                    response = {
                        "jsonrpc": "2.0",
                        "result": {'verified': result},
                        "id": req.media.get('id')
                    }

                elif method == 'rpc_methods':

                    response = self.substrate.rpc_request(method, params)

                    # Add additional implemented method
                    response['result']['methods'] = sorted(response['result']['methods'] + self.methods)

                else:
                    raise NotImplementedError('Method \'{}\' not implemented yet'.format(method))
            except (ValueError, NotImplementedError) as e:
                response = {
                    "error": {
                        "code": -999,
                        "message": str(e)
                    },
                    "id": req.media.get('id')
                }
            except (InvalidScaleTypeValueException, RemainingScaleBytesNotEmptyException) as e:
                response = {
                    "error": {
                        "code": -998,
                        "message": "Decoding error, given SCALE-value or type registry might be invalid "
                    },
                    "id": req.media.get('id')
                }
            resp.media = response
Beispiel #3
0
def main(path, wait_for_inclusion=False, nonce=0):
    with open(path) as json_file:
        test_adresses = json.load(json_file)

    custom_type_registry = load_type_registry_file("types.json")
    print(custom_type_registry)
    substrate = SubstrateInterface(url="ws://127.0.0.1:9944/",
                                   address_type=32,
                                   type_registry=TYPES,
                                   type_registry_preset='robonomics')

    # substrate = SubstrateInterface(
    #     url="ws://127.0.0.1:9944/",
    #     address_type=32,
    #     type_registry=TYPES,
    # )

    # Set block_hash to None for chaintip
    # block_hash = None

    # Retrieve extrinsics in block
    # result = substrate.get_runtime_block(block_hash=block_hash)

    # for extrinsic in result['block']['extrinsics']:

    #     if 'account_id' in extrinsic:
    #         signed_by_address = ss58_encode(address=extrinsic['account_id'], address_type=2)
    #     else:
    #         signed_by_address = None

    #     print('\nModule: {}\nCall: {}\nSigned by: {}'.format(
    #         extrinsic['call_module'],
    #         extrinsic['call_function'],
    #         signed_by_address
    #     ))

    #     for param in extrinsic['params']:

    #         if param['type'] == 'Address':
    #             param['value'] = ss58_encode(address=param['value'], address_type=2)

    #         if param['type'] == 'Compact<Balance>':
    #             param['value'] = '{} DOT'.format(param['value'] / 10**12)

    #         print("Param '{}': {}".format(param['name'], param['value']))

    # Storage call examples
    # print("\n\nCurrent Account info: {} DOT".format(
    #     substrate.get_runtime_state(
    #         module='System',
    #         storage_function='Account',
    #         params=['4GmqwyTi37bbwgWHiamoi7uCnebxuhj9Mmo2rCcjPgjF4Nag']
    #     ).get('result')
    # ))

    # print("Balance @ {}: {} DOT".format(
    #     block_hash,
    #     substrate.get_runtime_state(
    #         module='Balances',
    #         storage_function='FreeBalance',
    #         params=['4GmqwyTi37bbwgWHiamoi7uCnebxuhj9Mmo2rCcjPgjF4Nag'],
    #         block_hash=block_hash
    #     ).get('result')
    # ))
    nonce = int(nonce)
    while True:
        for indx, row in enumerate(test_adresses['keys']):
            for address, mnemonic in row.items():
                # Create, sign and submit extrinsic example
                # mnemonic = Keypair.generate_mnemonic()
                # mnemonic = "pave small hub weapon jewel dream net canvas mirror nurse delay they"
                keypair = Keypair.create_from_mnemonic(mnemonic, 32)

            # nonce = substrate.get_account_nonce(address)
            # nonce = substrate.get_account_nonce(address)
            print("Nonce: ", nonce)
            # keypair = Keypair(
            #     ss58_address='4GQJvwgJwZ1U8j776kmawm5wccE9ZSRFCuH1GnxyCEuGWqL4',
            #     public_key='0xba3f1ff4f7894070afc1dc88551f47c3d76e4b9a2847fbd045c571b998623c62',
            #     address_type=32
            # )

            # keypair = Keypair.create_from_private_key(
            #     '0x24dcd65948fe301e27eab1456df0c60ea6884f7eef9eb4e55b329a1a785eb43f',
            #     public_key='0xba3f1ff4f7894070afc1dc88551f47c3d76e4b9a2847fbd045c571b998623c62',
            #     ss58_address='4GQJvwgJwZ1U8j776kmawm5wccE9ZSRFCuH1GnxyCEuGWqL4',
            #     address_type=32
            # )

            print("Created address: {}".format(keypair.ss58_address))
            nonce = substrate.get_account_nonce(keypair.ss58_address)
            print(nonce)
            call = substrate.compose_call(
                'Datalog',
                'record',
                call_params={
                    'record':
                    '0x516d6178673336614b68345a41547342796f427133384b454b5a6743674366657934344b68746452426477764d41',
                })

            # call = substrate.compose_call(
            #     call_module='Launch',
            #     call_function='launch',
            #     call_params={
            #         # 'date': '0x01',
            #         'Parameter': False,
            #     }
            # )

            # call = substrate.compose_call(
            #     call_module='Balances',
            #     call_function='transfer',
            #     call_params={
            #         'dest': '4Ca9DE2ghDH4jQofEpRAhnQpdFejgVi3zVvkAo2QwsXFJvWA',
            #         'value': 5 * 10**3
            #     }
            # )
            print('create extrinsic')
            extrinsic = substrate.create_signed_extrinsic(call=call,
                                                          keypair=keypair,
                                                          nonce=nonce)
            # extrinsic = substrate.create_unsigned_extrinsic(call=call)

            try:
                print('try to send')
                result = substrate.submit_extrinsic(
                    extrinsic, wait_for_inclusion=wait_for_inclusion)

                print('Extrinsic "{}" included in block "{}"'.format(
                    result['extrinsic_hash'], result.get('block_hash')))

                print(result)

            except SubstrateRequestException as e:
                print("Failed to send: {}".format(e))

        nonce += 1