为什么即使更改了底层链的源代码,存储值的可变性行为也没有变化?

Why there are no changes in the mutability behaviour of storage values even after changing the source code of the 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(())
        }
    }
}

然后将代码更改为:

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(())
        }
    }
}

如您所见,在第二个代码中,该值可以是changed/overwritten。我的目的是了解源代码的变化。我是 运行 演示 substrate 链,令我惊讶的是,substrate 链的行为根本没有改变。

官方文档中提到:

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.

我没有清除我现有的链,而是使用以下命令重建了它:

./scripts/build.sh
cargo build --release
./target/release/substratekitties --dev

换句话说,即使我更改了代码并在没有清除现有链的情况下重建它,我的底层链也没有改变它的行为(我无法覆盖该值)。

初始代码:存储值中的不可变键值对 最终代码:存储值中的可变键值对

初始链:不可变键值 最终链:不可变键值

这是预期的吗?如果是,引述(前面提到的关于平行链的文档)是关于什么的? 如果不是,我如何在不清除它的情况下改变我的底物链的行为?

I did not purge my existing chain

TLDR:这就是您没有注意到更改的原因。清除你的链条并重新开始,你会看到变化。

Substrate 将运行时编译为 wasm 并将 wasm 存储在链上。这有助于无叉升级过程。尽管您重新编译了您的节点,但现有的链数据在其创世块中仍然具有旧的 wasm 运行时,因此使用了旧的运行时。要查看更改,您有两个选择。

  1. 清除链条并完全重新开始
  2. 对您的运行时进行额外更改,增加 spec_version。您已经构建了新的运行时,使用 sudo(或任何其他链上治理托盘)调用 system::set_code。这将执行链上运行时升级,您的更改将生效。