0

阅读了可变性,我在我的底层链中实现了以下代码:

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

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

在官方文档中提到:

智能合约必须有意识地实现可升级性,而平行链将能够完全通过根命令或通过治理托盘交换其代码。

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

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

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

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

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

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

4

1 回答 1

1

我没有清除我现有的连锁店

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

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

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