# enable_metadata_hash.rs - source
Source of the Rust file `docs/sdk/src/guides/enable_metadata_hash.rs`.

#
pezkuwi_sdk_docs/guides/
enable_metadata_hash.rs

    1//! # Enable metadata hash verification
    2//!
    3//! This guide will teach you how to enable the metadata hash verification in your runtime.
    4//!
    5//! ## What is metadata hash verification?
    6//!
    7//! Each FRAME based runtime exposes metadata about itself. This metadata is used by consumers of
    8//! the runtime to interpret the state, to construct transactions etc. Part of this metadata are the
    9//! type information. These type information can be used to e.g. decode storage entries or to decode
    10//! a transaction. So, the metadata is quite useful for wallets to interact with a FRAME based
    11//! chain. Online wallets can fetch the metadata directly from any node of the chain they are
    12//! connected to, but offline wallets can not do this. So, for the offline wallet to have access to
    13//! the metadata it needs to be transferred and stored on the device. The problem is that the
    14//! metadata has a size of several hundreds of kilobytes, which takes quite a while to transfer to
    15//! these offline wallets and the internal storage of these devices is also not big enough to store
    16//! the metadata for one or more networks. The next problem is that the offline wallet/user can not
    17//! trust the metadata to be correct. It is very important for the metadata to be correct or
    18//! otherwise an attacker could change them in a way that the offline wallet decodes a transaction
    19//! in a different way than what it will be decoded to on chain. So, the user may sign an incorrect
    20//! transaction leading to unexpected behavior.
    21//!
    22//! The metadata hash verification circumvents the issues of the huge metadata and the need to trust
    23//! some metadata blob to be correct. To generate a hash for the metadata, the metadata is chunked,
    24//! these chunks are put into a merkle tree and then the root of this merkle tree is the "metadata
    25//! hash". For a more technical explanation on how it works, see
    26//! [RFC78](https://pezkuwi-fellows.github.io/RFCs/approved/0078-merkleized-metadata.html). At compile
    27//! time the metadata hash is generated and "baked" into the runtime. This makes it extremely cheap
    28//! for the runtime to verify on chain that the metadata hash is correct. By having the runtime
    29//! verify the hash on chain, the user also doesn't need to trust the offchain metadata. If the
    30//! metadata hash doesn't match the on chain metadata hash the transaction will be rejected. The
    31//! metadata hash itself is added to the data of the transaction that is signed, this means the
    32//! actual hash does not appear in the transaction. On chain the same procedure is repeated with the
    33//! metadata hash that is known by the runtime and if the metadata hash doesn't match the signature
    34//! verification will fail. As the metadata hash is actually the root of a merkle tree, the offline
    35//! wallet can get proofs of individual types to decode a transaction. This means that the offline
    36//! wallet does not require the entire metadata to be present on the device.
    37//!
    38//! ## Integrating metadata hash verification into your runtime
    39//!
    40//! The integration of the metadata hash verification is split into two parts, first the actual
    41//! integration into the runtime and secondly the enabling of the metadata hash generation at
    42//! compile time.
    43//!
    44//! ### Runtime integration
    45//!
    46//! From the runtime side only the
    47//! [`CheckMetadataHash`](pezframe_metadata_hash_extension::CheckMetadataHash) needs to be added to
    48//! the list of signed extension:
    49#![doc = docify::embed!("../../templates/teyrchain/runtime/src/lib.rs", template_signed_extra)]
    50//!
    51//! > **Note:**
    52//! >
    53//! > Adding the signed extension changes the encoding of the transaction and adds one extra byte
    54//! > per transaction!
    55//!
    56//! This signed extension will make sure to decode the requested `mode` and will add the metadata
    57//! hash to the signed data depending on the requested `mode`. The `mode` gives the user/wallet
    58//! control over deciding if the metadata hash should be verified or not. The metadata hash itself
    59//! is drawn from the `RUNTIME_METADATA_HASH` environment variable. If the environment variable is
    60//! not set, any transaction that requires the metadata hash is rejected with the error
    61//! `CannotLookup`. This is a security measurement to prevent including invalid transactions.
    62//!
    63//! <div class="warning">
    64//!
    65//! The extension does not work with the native runtime, because the
    66//! `RUNTIME_METADATA_HASH` environment variable is not set when building the
    67//! `pezframe-metadata-hash-extension` crate.
    68//!
    69//! </div>
    70//!
    71//! ### Enable metadata hash generation
    72//!
    73//! The metadata hash generation needs to be enabled when building the wasm binary. The
    74//! `bizinikiwi-wasm-builder` supports this out of the box:
    75#![doc = docify::embed!("../../templates/teyrchain/runtime/build.rs", template_enable_metadata_hash)]
    76//!
    77//! > **Note:**
    78//! >
    79//! > The `metadata-hash` feature needs to be enabled for the `bizinikiwi-wasm-builder` to enable
    80//! > the
    81//! > code for being able to generate the metadata hash. It is also recommended to put the metadata
    82//! > hash generation behind a feature in the runtime as shown above. The reason behind is that it
    83//! > adds a lot of code which increases the compile time and the generation itself also increases
    84//! > the compile time. Thus, it is recommended to enable the feature only when the metadata hash is
    85//! > required (e.g. for an on-chain build).
    86//!
    87//! The two parameters to `enable_metadata_hash` are the token symbol and the number of decimals of
    88//! the primary token of the chain. These information are included for the wallets to show token
    89//! related operations in a more user friendly way.