0

In default Substrate-Node-Template I want to make some actions inside validate_transaction function which is located in runtime/src/lib.rs:

fn validate_transaction(
            source: TransactionSource,
            tx: <Block as BlockT>::Extrinsic,
            block_hash: <Block as BlockT>::Hash,
        ) -> TransactionValidity {...}

What I'm trying to do, is to take tx parameter and extract Call Value by:

            if tx.signature.is_none() {
                //Do Something
            }else {
                let function_result = &tx.function;
            };

This function_result variable has type 'Call' with value of

Call::Mypallet(Call::my_custom_function { content: [123, 32, 9, 34, 110, 101, 116]} I want to get content as a final result. But can not somehow communicatie with "Call" type. How can i extract the content field from there?

2 Answers 2

0

Take a look at code snippets in Substrate like this one:

fn test_blocks(
    genesis_config: &GenesisConfig,
    executor: &NativeElseWasmExecutor<ExecutorDispatch>,
) -> Vec<(Vec<u8>, Hash)> {
    let mut test_ext = new_test_ext(genesis_config);
    let mut block1_extrinsics = vec![CheckedExtrinsic {
        signed: None,
        function: Call::Timestamp(pallet_timestamp::Call::set { now: 0 }),
    }];
    block1_extrinsics.extend((0..20).map(|i| CheckedExtrinsic {
        signed: Some((alice(), signed_extra(i, 0))),
        function: Call::Balances(pallet_balances::Call::transfer {
            dest: bob().into(),
            value: 1 * DOLLARS,
        }),
    }));
    let block1 =
        construct_block(executor, &mut test_ext.ext(), 1, GENESIS_HASH.into(), block1_extrinsics);

    vec![block1]
}

Basically the onion should look like this:

  1. The "runtime Call" enum will have an item Call::PalletName
  2. That item will have entries which match the "pallet Call" enum, which will have items like Call::extrinsic_name. You can differentiate the runtime and pallet call by accessing the pallet call like: pallet_name::Call::extrinsic_name.
  3. From there you have access to the parameters of the call.

So, here is some pseudo code:

fn extract_content_from_call(call: Call) -> Option<ContentType> {
    let pallet_call: pallet_name::Call = match call {
        Call::MyPallet(pallet_call) => pallet_call,
        _ => return None,
    };

    let content: ContentType = match pallet_call {
        pallet_name::Call::my_custom_function { content } => content,
        _ => return None,
    };

    Some(content)
}
1
  • Thank you very much! It's what I was looking for! Commented May 2, 2022 at 12:07
0

You can match on tx.function:

            match tx.function {
                Call::Balances(..) => {
                    Executive::validate_transaction(source, tx, block_hash)
                }
                _ => {
                    todo!("");
                }
            }
1
  • Thank you for your reply! So, as you can see, i added an example. So, can you advise on the next step to extract data? My final step is to decode the data this Extrinsic has. If i use match tx.function {Call::Balances(..)) how would i get into the next layer of the call(pls. see the description) to reach the Call::my_custom_function.content? Commented Apr 29, 2022 at 14:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.