成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

EOS入門指南PART8——智能合約入門實(shí)戰(zhàn)

Sike / 1754人閱讀

摘要:這里的是封裝的,返回中,當(dāng)前索引的迭代器之后遍歷該迭代器,就可以獲得所有某個(gè)特定值的所有數(shù)據(jù)。

上一章我們細(xì)致地學(xué)習(xí)了

索引和迭代器的關(guān)系;

如何生成和使用索引以及迭代器

介紹了multi_index的相關(guān)操作

相信大家對(duì)multi_index已經(jīng)有了比較全面的理論理解以及掌握了一些基礎(chǔ)的操作。這一章將會(huì)教大家如何完整地構(gòu)建一個(gè)智能合約,并在合約中直觀地操作multi_index。

摘要
這一章主要以實(shí)操為主,會(huì)有較大篇幅的代碼,希望大家最好可以照著文章自己操作一遍。

這一章將會(huì)以一個(gè)簡(jiǎn)單的智能合約例子,簡(jiǎn)單了解一個(gè)完整的EOS智能合約長(zhǎng)什么樣。希望大家通過(guò)這一章的學(xué)習(xí),不僅可以有能力構(gòu)建一個(gè)簡(jiǎn)單的智能合約,并且對(duì)multi_index在EOS智能合約中的重要性,會(huì)有更加深刻的認(rèn)識(shí)。

頭文件:*.hpp

C++的源代碼文件分為兩類:頭文件(Header file)和源文件(Source code file)。

頭文件用于存放對(duì)類型定義、函數(shù)聲明、全局變量聲明等實(shí)體的聲明,作為對(duì)外接口;

源程序文件存放類型的實(shí)現(xiàn)、函數(shù)體、全局變量定義;

我們先來(lái)看頭文件里的代碼:

#include 
#include 
#include 
using namespace eosio;
using std::string;

最前面按慣例都是import,接著往下看:

class app : public contract {
public:
    using contract::contract;

    app(account_name self)
            : contract(self) {}

    // @abi action
    void hello(const account_name account);

    // @abi action
    void create(const account_name account,
                const string&      username,
                uint32_t           age,
                const string&      bio);

    // @abi action
    void get(const account_name account);

    // @abi action
    void update(const account_name account,
                const string&      username,
                uint32_t           age,
                const string&      bio);

    // @abi action
    void remove(const account_name account);

    // @abi action
    void byage(uint32_t age);

    // @abi action
    void agerange(uint32_t young, uint32_t old);

這里定義了源文件里的方法接口,接下來(lái)就到了最核心的multi_index的相關(guān)定義:

private:
    // @abi table profile i64
    struct profile {
        account_name    account;
        string          username;
        uint32_t        age;
        string          bio;

        account_name primary_key() const { return account; }
        uint64_t     by_age() const { return age; }

        EOSLIB_SERIALIZE(profile, (account)(username)(age)(bio))
    };

    typedef eosio::multi_index< N(profile), profile,
            // N(name of interface)
            indexed_by< N(age),
                        const_mem_fun
            >
    > profile_table;

};

這里定義了multi_index表的結(jié)構(gòu) (struct profile),主鍵以及按年齡的索引定義。(上一章詳細(xì)講過(guò))

最后再加上EOSIO_ABI的聲明:

EOSIO_ABI(app, (hello)(create)(get)(update)(remove)(byage)(agerange))

這里只需要簡(jiǎn)單地把所有方法串聯(lián)在一起就可以了。

上述可以看到hpp頭文件里的內(nèi)容很簡(jiǎn)單,只包含了最簡(jiǎn)單的變量和接口的聲明。而與之配套的*.cpp文件就要復(fù)雜一些,里面對(duì)這些接口都做了具體的實(shí)現(xiàn)。

源文件

首先肯定是引用頭文件:

#include 
void app::hello(account_name account) {
    print("Hello ", name{account});
}
1. 添加數(shù)據(jù)
void app::create(const account_name account,
                     const string&      username,
                     uint32_t           age,
                     const string&      bio) {
    require_auth(account);

    profile_table profiles(_self, _self);

    auto itr = profiles.find(account);

    eosio_assert(itr == profiles.end(), "Account already exists");

    profiles.emplace(account, [&](auto& p) {
        p.account  = account;
        p.username = username;
        p.age      = age;
        p.bio      = bio;
    });
}

require_auth語(yǔ)句和以太坊中的require(msg.sender == xxx)類似,都對(duì)調(diào)用者的身份做了限制。

profile_table是一種類型,可以理解成表示multi_index表,后面的profiles(_self, _self)才是真正構(gòu)建一個(gè)multi_index表的實(shí)例。profiles里的兩個(gè)參數(shù)依次就是我們前面提到過(guò)的codescope,分別表示表的擁有賬戶以及代碼層次結(jié)構(gòu)的范圍標(biāo)識(shí)符(已經(jīng)忘記的小伙伴可以翻看上一章內(nèi)容)。

當(dāng)profiles表實(shí)例化完成之后,緊接著就是插入數(shù)據(jù)。關(guān)于插入數(shù)據(jù)的操作上一章我們有過(guò)詳細(xì)的介紹,這里就不再贅述了。主要注意防止主鍵重復(fù)的操作。

2. 根據(jù)主鍵獲取相關(guān)信息
void app::get(const account_name account) {
    profile_table profiles(_self, _self);

    auto itr = profiles.find(account);

    eosio_assert(itr != profiles.end(), "Account does not exist");

    print("Account: ", name{itr->account}, " , ");
    print("Username: ", itr->username.c_str(), " , ");
    print("Age: ", itr->age , " , ");
    print("Bio: ", itr->bio.c_str());
}

這里也很簡(jiǎn)單,先把multi_index表實(shí)例化,之后要求查詢的結(jié)果不能為空 (即itr != profiles.end()),如果不為空的話,就返回主鍵對(duì)應(yīng)的其他字段的信息。

這些操作都是通過(guò)我們上一章介紹過(guò)的迭代器來(lái)完成。

3. 根據(jù)主鍵更新信息
void app::update(const account_name account,
                     const string&      username,
                     uint32_t           age,
                     const string&      bio) {
    require_auth(account);

    profile_table profiles(_self, _self);

    auto itr = profiles.find(account);

    eosio_assert(itr != profiles.end(), "Account does not exist");

    profiles.modify(itr, account, [&](auto& p) {
        p.username = username;
        p.age      = age;
        p.bio      = bio;
    });
}

和之前的操作類似,確保主鍵不為空的情況下,更新該主鍵對(duì)應(yīng)的其他字段的信息。

4. 根據(jù)主鍵刪除數(shù)據(jù)
void app::remove(const account_name account) {
    require_auth(account);

    profile_table profiles(_self, _self);

    auto itr = profiles.find(account);

    eosio_assert(itr != profiles.end(), "Account does not exist");

    profiles.erase(itr);
    print(name{account} , " deleted!");
}
5. 通過(guò)自定義的自定義索引實(shí)現(xiàn)查詢

前面四個(gè)介紹的都是主鍵相關(guān)的增刪改查的操作,別忘了我們?cè)谏弦徽轮羞€曾經(jīng)定義過(guò)自定義索引by_age(),即以年齡為條件進(jìn)行篩選。具體實(shí)現(xiàn)如下:

void app::byage(uint32_t age) {
    print("Checking age: ", age, "
");
    profile_table profiles(_self, _self);

    // get an interface to the "profiles" containter
    // that looks up a profile by its age
    auto age_index = profiles.get_index();

    auto itr = age_index.lower_bound(age);

    for(; itr != age_index.end() && itr->age == age; ++itr) {
        print(itr->username.c_str(), " is ", itr->age, " years old
");
    }
}

這里我們使用了在頭文件里定義過(guò)的名為age的index,重新得到了一張以age排序的multi_index。

這里的lower_bound是EOS封裝的API,返回age_index中,當(dāng)前索引≥age的迭代器;之后遍歷該迭代器,就可以獲得所有age某個(gè)特定值的所有數(shù)據(jù)。

lower_bound相對(duì)應(yīng)的,就是upper_bound方法,用法和lower_bound類似。如下就實(shí)現(xiàn)了同時(shí)指定age上下限的查詢:

void app::agerange(uint32_t young, uint32_t old) {
    profile_table profiles(_self, _self);

    auto age_index = profiles.get_index();

    auto begin = age_index.lower_bound(young);
    auto end   = age_index.upper_bound(old);

    for_each(begin, end, [&](auto& p) {
        print(p.username.c_str(), " is ", p.age, " years old
");
    });
}
合約部署

把前文中所有的hpp和cpp的代碼片段拼接成完整的hpp和cpp文件進(jìn)行編譯:

#使用 -o 生成wast文件和wasm文件
eosiocpp -o ./app.wast ./app.cpp
#使用 -g 生成abi文件
eosiocpp -g ./app.abi ./app.cpp

生成wast和abi文件的詳細(xì)內(nèi)容我們之前章節(jié)介紹過(guò)了,這里也不贅述了。這時(shí)我們的當(dāng)前文件夾下會(huì)出現(xiàn)app.wastapp.abi文件。

部署合約:

cleos set contract eosio ./ ./app.wast app.abi -p eosio@active

(該命令前文也詳細(xì)介紹過(guò)每個(gè)參數(shù)的含義,詳情參考第五篇)

下圖為成功部署合約的畫(huà)面:

合約調(diào)用 1. 查看表內(nèi)容
cleos get table eosio eosio profile

通過(guò)上述指令查看表中的內(nèi)容,參數(shù)eosio eosio profile分別表示前文提到過(guò)的code、scope和表名。

結(jié)果如下圖:

因?yàn)樵陬^文件里聲明過(guò),可以看到該表已存在,但是內(nèi)容為空。

2. 插入數(shù)據(jù)

執(zhí)行如下命令往表中插入數(shù)據(jù),然后再次查詢:

// 插入
cleos push action eosio create "["eosio","hammer","25","programmer"]" -p eosio@active
// 再次查詢
cleos get table eosio eosio profile

這時(shí)就可以看到表中保存了我們剛插入的一條數(shù)據(jù)。

還記得我們?cè)?jīng)創(chuàng)建過(guò)一個(gè)叫做testeosio的賬戶么?我們?cè)偈褂媚莻€(gè)賬戶往表中插入一條數(shù)據(jù)(記得先unlock錢包哦):

// 切換賬號(hào)插入數(shù)據(jù)
cleos push action eosio create "["testeosio","maggie","23","waitress"]" -p testeosio@active
// 查詢
cleos get table eosio eosio profile

這時(shí)我們可以看到:

數(shù)據(jù)確實(shí)添加進(jìn)入表中了。

傳入數(shù)據(jù)的第一個(gè)參數(shù)必須是調(diào)用該方法的賬戶名,還記得代碼中的require_auth么?

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/24295.html

相關(guān)文章

  • Java開(kāi)發(fā)區(qū)塊鏈的三大sdk庫(kù)

    摘要:是企業(yè)與區(qū)塊鏈相遇的地方。的框架旨在成為開(kāi)發(fā)區(qū)塊鏈解決方案的支柱。以太坊,主要是針對(duì)工程師使用進(jìn)行區(qū)塊鏈以太坊開(kāi)發(fā)的詳解。 如果你想將區(qū)塊鏈合并到一個(gè)Java項(xiàng)目中,現(xiàn)在我們來(lái)看看就是這個(gè)細(xì)分領(lǐng)域中三個(gè)最大的OSS玩家。 好的伙計(jì)們,我們都聽(tīng)說(shuō)過(guò)比特幣,以太坊或其他加密貨幣,其中有一些時(shí)髦的名字圍繞著我們常見(jiàn)的新聞,但我們作為Java開(kāi)發(fā)人員知道如何輕松地與這些區(qū)塊鏈技術(shù)進(jìn)行交互嗎?以...

    iKcamp 評(píng)論0 收藏0
  • 區(qū)塊鏈開(kāi)發(fā)中使用的最流行的編程語(yǔ)言

    摘要:我們目前正處于一個(gè)新興的區(qū)塊鏈開(kāi)發(fā)行業(yè)中。,一種在以太坊開(kāi)發(fā)人員中流行的新的簡(jiǎn)單編程語(yǔ)言,因?yàn)樗怯糜陂_(kāi)發(fā)以太坊智能合約的語(yǔ)言。它是全球至少萬(wàn)開(kāi)發(fā)人員使用的世界上最流行的編程語(yǔ)言之一。以太坊,主要是針對(duì)工程師使用進(jìn)行區(qū)塊鏈以太坊開(kāi)發(fā)的詳解。 我們目前正處于一個(gè)新興的區(qū)塊鏈開(kāi)發(fā)行業(yè)中。區(qū)塊鏈技術(shù)處于初期階段,然而這種顛覆性技術(shù)已經(jīng)成功地風(fēng)靡全球,并且最近經(jīng)歷了一場(chǎng)與眾不同的繁榮。由于許多...

    2shou 評(píng)論0 收藏0
  • 工廠模式管理多個(gè)以太坊solidity智能合約

    摘要:在新智能合約的構(gòu)造函數(shù)中,將引用我們的合約工廠的地址。以太坊,主要是針對(duì)工程師使用進(jìn)行區(qū)塊鏈以太坊開(kāi)發(fā)的詳解。以太坊入門教程,主要介紹智能合約與應(yīng)用開(kāi)發(fā),適合入門。這里是原文用工廠模式管理多個(gè)智能合約 我們寫(xiě)了一份小的計(jì)算合約作為Hello World。如果我們可以創(chuàng)建一個(gè)允許用戶創(chuàng)建自己的計(jì)數(shù)器的合約怎么辦? showImg(https://segmentfault.com/img/...

    leone 評(píng)論0 收藏0
  • EOS開(kāi)發(fā)智能合約為何編譯成WebAssembly?

    摘要:許多人正試圖學(xué)習(xí)如何在上開(kāi)發(fā)智能合約。但是,這些智能合約是由編寫(xiě)的,并編譯成,這對(duì)大多數(shù)非程序員來(lái)說(shuō)似乎很奇怪。在這里,你可以將其視為可以在瀏覽器中加載和運(yùn)行的文件。將代碼編譯成的格式編譯代碼有很多種方法。 許多人正試圖學(xué)習(xí)如何在EOS上開(kāi)發(fā)智能合約。但是,這些智能合約是由C++編寫(xiě)的,并編譯成WebAssembly,這對(duì)大多數(shù)非c++程序員來(lái)說(shuō)似乎很奇怪。因此,在深入了解EOS之前,...

    Sunxb 評(píng)論0 收藏0
  • 如何安裝EOS智能合約開(kāi)發(fā)工具包CDT

    摘要:本文簡(jiǎn)單的介紹一下如何安裝智能合約開(kāi)發(fā)工具包,簡(jiǎn)稱,是與智能合約編制相關(guān)的工具集合。對(duì)于初學(xué)者來(lái)說(shuō),可以通過(guò)使用來(lái)編譯智能合約和生成。 本文簡(jiǎn)單的介紹一下如何安裝EOS智能合約開(kāi)發(fā)工具包(Contract Development Toolkit),簡(jiǎn)稱CDT,是與智能合約編制相關(guān)的工具集合。對(duì)于EOSIO初學(xué)者來(lái)說(shuō),可以通過(guò)使用CDT來(lái)編譯智能合約和生成ABI。 從1.3.x開(kāi)始,CD...

    lx1036 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<