I am using Substrate V3 (using decl_storage) and have an existing storage defined like this:

pub Foo get(fn get_foo) config(): map hasher(blake2_128_concat) u32 => H160;

I would like to change this into:

pub Foo get(fn get_foo) config(): map hasher(blake2_128_concat) H160 => u32;

After reading about storage migration, I am planning to use StorageKeyIterator to iterate over the old values and drain it:

    for (idx, address) in StorageKeyIterator::<u32, H160, Blake2_128Concat>::
            new(b"PalletName", b"Foo").drain() {

        <Foo>::insert(address, index);

My questions are:

  • Is this the correct approach?
  • Can I reuse the same storage name for old and new value (Foo)?


1 Answer 1


Maybe, there are several ways to achieve this target.

First, you can define a new Storage(or prefix) which we call it tmp, after you write all the data into this tmp storage, you can use move_prefix to rename tmp to your original storage name.

Second, you can use the unhash api to do more dangerous business, ref to unhash. Use unhash, you just construct the storage key, and storage value and put_raw.

As, you can see, above two approach have their own benefits and drawbacks, choose one and test seriously.

At last, no matter when you want to do storage migration, make sure you have test it with try-runtime thoroughly.

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.