Polka链的宠物项目2合约代码--by Skyh0714

1. 添加模块

分析项目结构

u

听说runtime才是模块内容
substrate-package/substratekitties/runtime/src 中加入substratekitties.rs
image.png

直接在这个文件写入程序框架

use support::{decl_storage, decl_module};

pub trait Trait: system::Trait {}

decl_storage! {
    trait Store for Module<T: Trait> as KittyStorage {
        // Declare storage and getter functions here
    }
}

decl_module! {
    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
        // Declare public functions here
    }
}

另外要在lib.rs三处加入模块, 我看到有类似template模块就在下面加了

// #1
/// Used for the module template in `./template.rs`
mod template;
// Add this line
mod substratekitties;

// #2
/// Used for the module template in `./template.rs`
impl template::Trait for Runtime {
    type Event = Event;
}
// Add this line
impl substratekitties::Trait for Runtime {

}

// #3
construct_runtime!(
    pub enum Runtime with Log(InternalLog: DigestItem<Hash, AuthorityId, AuthoritySignature>) where
        Block = Block,
        NodeBlock = opaque::Block,
        UncheckedExtrinsic = UncheckedExtrinsic
{
                // Used for the module template in `./template.rs`
        TemplateModule: template::{Module, Call, Storage, Event<T>},
        Substratekitties: substratekitties::{Module, Call, Storage}, //Add

});

这样就可以运行了:

./scripts/build.sh
cargo build --release

编译只把新增加的编译出来


image.png

我打算再写多些功能些

2. 学习Rust (可跳过,直接看代码)

Substrate 本身支持 Rust 中可用的所有原始类型(boolu8u32 等)以及一些 Substrate 中的特定自定义类型 (AccountId, Balance, Hash, and more...)
要存储这些基本存储值,你需要导入 support::StorageValue

// 导入
use support::{decl_storage, decl_module, StorageValue, dispatch::Result};
use system::ensure_signed;

// 声明
decl_storage! {
    trait Store for Module<T: Trait> as Example {
        MyU32: u32;
        MyBool get(my_bool_getter): bool;
    }
}
// put
<MyU32<T>>::put(1337);
// get
let my_bool = <MyBool<T>>::get();
let also_my_bool = Self::my_bool_getter();

函数的第一个参数始终是 origin。 origin 包含有关调用来源的信息。通常分为三组:由外部帐户签名的 public 调用。允许仅由治理系统进行的 root 调用。允许仅由块作者和验证者进行的 inherent 调用。
函数必须返回 support::dispatch 模块中的 Result 类型。这意味着成功的函数调用将始终返回 Ok(()),否则应捕获可能导致问题的任何错误并返回 Err()

system module 中有三个方便的调用函数 ensure_signed, ensure_root 和 ensure_inherent,可以调用三者中匹配的函数并返回一个结果
我们可以使用 system 中的 ensure_signed() 函数来检查 origin,并 "ensure" 消息是由有效帐户签名的。

decl_module! {
    pub struct Module<T: Trait> for enum Call where origin: T::Origin {

        fn my_function(origin, input_bool: bool) -> Result {
            let _sender = ensure_signed(origin)?;

            <MyBool<T>>::put(input_bool);

            Ok(())
        }
    }
}

默认的 runtime 模板包含一组 modules,这些 modules 暴露出了你开发区块链需要涉及的类型。在你开发了更多 module 后,你甚至会自己构造新类型并暴露给 runtime 的其他部分。
我们将使用 3 种 substrate 特定类型:AccountId, Balance, Hash
我们的 module 本身不能访问这些类型,但我们可以通过让 module 的 Trait 继承定义了这些类型的 module 来轻松获取访问权限。在当前情况下,balances module 有我们需要的一切东西:

// 定义
decl_storage! {
    trait Store for Module<T: Trait> as Example {
        SomeValue get(some_value_getter): map u32 => u32;
        MyValue: map T::AccountId => u32;
    }
}
// 插入
<SomeValue<T>>::insert(key, value);
// 查询
let my_value = <SomeValue<T>>::get(key);
let also_my_value = Self::some_value_getter(key);

3. 运行程序1

use support::{decl_storage, decl_module, StorageMap, dispatch::Result};
use system::ensure_signed;

pub trait Trait: balances::Trait {}

decl_storage! {
    trait Store for Module<T: Trait> as KittyStorage {
        Value: map T::AccountId => u64;
    }
}

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(sender, value);

            Ok(())
        }
    }
}

运行程序

./scripts/build.sh
cargo build --release
./target/release/substratekitties purge-chain --dev
#再启动
./target/release/substratekitties --dev

https://polkadot.js.org/apps/#/extrinsics
extrinsics这里能看到自己方法

image.png

chain_state这里可以看到输出变量
image.png

4. 高级Rust

定义struct, 并在struct中使用泛型,
自定义的 Encode 和 Decode traits,你需要从 parity_codec_derive crate 中导入它们
#[derive(...)]。这是 Rust 编译器提供的属性,允许基本地实现某些 trait。第二行,
#[cfg_attr(feature = "std", derive(Debug))] 对 Debug trait 做了同样的事情,但仅在使用“标准”库时启用,即在编译本机二进制文件而不是 Wasm 的时候。

use runtime_primitives::traits::{As, Hash};
use parity_codec::{Encode, Decode};
// 定义
#[derive(Encode, Decode, Default, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct MyStruct<A, B> {
    some_number: u32,
    some_generic: A,
    some_other_generic: B,
}
// 存储
decl_storage! {
    trait Store for Module<T: Trait> as Example {
        MyItem: map T::AccountId => MyStruct<T::Balance, T::Hash>;
    }
}
// 插入
decl_module! {
    pub struct Module<T: Trait> for enum Call where origin: T::Origin {
        fn create_struct(origin, value: u32, balance: T::Balance, hash: T::Hash) -> Result {
            let sender = ensure_signed(origin)?;

            let new_struct = MyStruct {
                some_number: value,
                some_generic: balance,
                some_other_generic: hash,
            };

            <MyItem<T>>::insert(sender, new_struct);
            Ok(())
        }
    }
}
// 初始化 T::Hash 和 T::Balance
let hash_of_zero = <T as system::Trait>::Hashing::hash_of(&0);
let my_zero_balance = <T::Balance as As<u64>>::sa(0);

Substrate 不直接支持字符串。Runtime 存储用于存储 runtime 运行的业务逻辑的状态。它不是存储 UI 所需的一般数据。如果你确实需要将一些任意数据存储到 runtime,你总是可以创建一个 bytearray(Vec<u8>),但更合乎逻辑的做法是将哈希值存储到 IPFS 之类的服务中,然后获取数据用于 UI 展示。这超出了本次研讨会的范围,但可能会在以后为你的 kitty 添加其他元数据

5 运行程序2

use support::{decl_storage, decl_module, StorageMap, dispatch::Result};
use system::ensure_signed;
use runtime_primitives::traits::{As, Hash};
use parity_codec::{Encode, Decode};

#[derive(Encode, Decode, Default, Clone, PartialEq)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct Kitty<Hash, Balance> {
    id: Hash,
    dna: Hash,
    price: Balance,
    gen: u64,
}

pub trait Trait: balances::Trait {}

decl_storage! {
    trait Store for Module<T: Trait> as KittyStorage {
        OwnedKitty get(kitty_of_owner): map T::AccountId => Kitty<T::Hash, T::Balance>;
    }
}

decl_module! {
    pub struct Module<T: Trait> for enum Call where origin: T::Origin {

        fn create_kitty(origin) -> Result {
            let sender = ensure_signed(origin)?;

            let new_kitty = Kitty {
                id: <T as system::Trait>::Hashing::hash_of(&0),
                dna: <T as system::Trait>::Hashing::hash_of(&0),
                price: <T::Balance as As<u64>>::sa(0),
                gen: 0,
            };

            <OwnedKitty<T>>::insert(&sender, new_kitty);

            Ok(())
        }
    }
}

重新运行

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

首先注册结构,在Setting>developer页面输入保存

{
    "Kitty": {
        "id": "H256",
        "dna": "H256",
        "price": "Balance",
        "gen": "u64"
    }
}
image.png

在extrinsics创建


image.png

chainstate
就能看到你生成的kittyies


image.png

今天学习了rust基本语法和substrate基本操作, 基本是创建变量, map, 定义和生成struct, 下次再通过区块链共同学习rust更多

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容