CheckMetadataHash Presentation 2024
Metadata for offline signers
Bastian Köcher
Core Dev @ Polkadot
Status Quo
- Ledger:
- Hard coded each runtime
- Relied on
transaction_version
to be bumped when TX format changed
- Polkadot Vault
- Required the entire metadata to be transferred to the device (~500KB+)
- Metadata was signed by some central entity 🤮
Why Metadata?
- Contains all the information for constructing a transaction
- Type information
- Calls
- Signed extensions
Problems with Metadata
- Metadata is too big
- Does not fit onto a ledger device
- Takes too long to transfer
- Contains also information on all the storage types, docs etc
Chunk the Metadata
- Each type is their own chunk
- Each call is their own chunk, referencing the type chunks
- Reduces the size to some kilobytes per transaction
Merkleize the Metadata
- Each chunk is a leaf node
- Put all together into one tree
- Calculate the root hash of this tree => Metadata hash
How does it work?
- Online wallet generates a proof of all type/call nodes
- Proof is send/streamed alongside the transaction to the signer
- Signer uses type/call nodes in the proof to decode and show the transaction
How does it work?
- Signer includes the metadata hash in the transaction and signs
- Runtime checks on inclusion if the metadata hash matches the current on chain hash
- If not, it rejects the transaction
Integration
In your runtime:
pub type SignedExtra = (
frame_system::CheckNonZeroSender<Runtime>,
...
frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
);
Integration
In your build.rs
:
fn main() {
substrate_wasm_builder::WasmBuilder::init_with_defaults()
.enable_metadata_hash("UNIT", 12)
.build();
}
Questions?
- More info