Reading about the mutability, I implemented the following piece of code in my substrate chain:
use support::{decl_module, decl_storage, dispatch::Result, ensure, StorageMap};
use system::ensure_signed;
pub trait Trait: balances::Trait {}
decl_storage! {
trait Store for Module<T: Trait> as KittyStorage {
Value: map u64 => Option<T::AccountId>;
}
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn set_value(origin, value: u64) -> Result {
let sender = ensure_signed(origin)?;
ensure!(!<Value<T>>::exists(value), "key already exists");
<Value<T>>::insert(value, sender);
Ok(())
}
}
}
and then changed the code to this:
use support::{decl_module, decl_storage, dispatch::Result, StorageMap};
use system::ensure_signed;
pub trait Trait: balances::Trait {}
decl_storage! {
trait Store for Module<T: Trait> as KittyStorage {
Value: map u64 => T::AccountId;
}
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn set_value(origin, value: u64) -> Result {
let sender = ensure_signed(origin)?;
<Value<T>>::insert(value, sender);
Ok(())
}
}
}
As you can see, in the second code, the value can be changed/overwritten. My intention was to know about the changes in the source code. I am running the demo substrate chain and to my surprise, the behavior of the substrate chain didn't change at all.
In the official documentation, it is mentioned:
Smart contracts must consciously implement upgradeability while parachains will have the ability to swap out their code entirely through a root command or via the governance pallet.
I did not purge my existing chain but had rebuilt it using the following commands:
./scripts/build.sh
cargo build --release
./target/release/substratekitties --dev
To rephrase, my substrate chain didn't change its behavior (I cannot overwrite the value) even though I changed the code and rebuilt it without purging the existing chain.
Initial Code: immutable key-value pairs in storage value Final Code: mutable key-value pairs in storage value
Initial Chain: immutable key-value Final Chain: immutable key-value
Is this expected? If yes, whats the quote(aforementioned from the docs about parachains) about? If no, how can I change the behavior of my substrate chain without purging it?
I did not purge my existing chain
TLDR: That's why you didn't notice the change. Purge your chain and start over and you will see the change.
Substrate compiles the runtime to wasm and stores the wasm on chain. This facilitates the forkless upgrade process. Although you recompiled your node, the existing chain data still had the old wasm runtime in its genesis block, and thus that old runtime was used. In order to see the change you have two options.
system::set_code
. This will perform an on-chain runtime upgrade and your changes will take effect.