I'm writing a custom BlockImport and I need to decode the transactions within the block,as we know a transaction is simply a pallet method call for example store_value(value), but at the point where I'm verifying a block all I got is OpaqueExtrinsic which is the transaction encoded.

How can I take that extrinsic and retrieve the parameter value that was passed when the user called my pallet extrinsic store_value(value)?

Extra: in the following code I'm just iterating over all the block extrinsics:

if let Some(block_extrinsics) = &block.body {
    let mut block_extrinsics = block_extrinsics.iter();
    for extrinsic in block_extrinsics {
             // what to do next ¯\_(ツ)_/¯

1 Answer 1


Substrate is build in the way that the runtime and the node are separate from each other. The node should not be able to interpret transaction as the runtime can upgrade at any point, which may also changes the transaction encoding. A proper solution here would be to define your own runtime api. Something like:

sp_api::decl_runtime_apis! {
    trait CheckExtrinsics<Block: BlockT> {
        fn contains_special_extrinsics(extrinsics: Vec<Block::Extrinsic>) -> bool;

Then in your code you run this:

if let Some(block_extrinsics) = &block.body
    if client.runtime_api().contains_special_extrinsics(block_extrinsics.clone())? {
        // do something

In your runtime you then need to implement the runtime api in whatever way you want.

  • Thanks for the advice but i want to know how to decode the opaque extrinsic to get the values within it
    – dadzerlaze
    Dec 1, 2022 at 9:31
  • As I said, you should not do in your node code. What I have given you above, will give you the values within the extrinsic.
    – bkchr
    Dec 1, 2022 at 14:53
  • you said i need to implement the runtime api in whatever way i want, i dont know any way to decode the Extrinsics to retreive the argument value within an encoded store_value(value) extrinsic, what you have given me above is the proper place to decode it and i agree but it does not show how to actually decode it!
    – dadzerlaze
    Dec 1, 2022 at 15:11
  • On the runtime side you will already get the decoded extrinsic. You will be able to inspect it there as you like. Block::Extrinsic is set to the concrete extrinsic type in your runtime.
    – bkchr
    Dec 2, 2022 at 9:26
  • i tried to follow your solution but the first thing that did not work is using Vec, since std is not allowed in the runtime i had to use a simple array of type [<Block as BlockT>::Extrinsic;length], so i created a simple array that holds one OpaqueExtrinsic but that also for some reason got me an error when trying to pass the argument to contains_special_extrinsics(my_array) which is an argument of type &sp_api::BlockId<...::BlakeTwo256>, sp_runtime::OpaqueExtrinsic>> is missing, even if make the function take one single OpaqueExtrinsic instead of an array the error still is the same
    – dadzerlaze
    Dec 5, 2022 at 8:09

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.