溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

EOS開(kāi)發(fā)中區(qū)塊鏈數(shù)據(jù)怎么實(shí)現(xiàn)持久性

發(fā)布時(shí)間:2021-12-29 14:17:26 來(lái)源:億速云 閱讀:141 作者:iii 欄目:互聯(lián)網(wǎng)科技

本篇內(nèi)容介紹了“EOS開(kāi)發(fā)中區(qū)塊鏈數(shù)據(jù)怎么實(shí)現(xiàn)持久性”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

第1步:創(chuàng)建一個(gè)新目錄

之前,你創(chuàng)建了一個(gè)合約目錄,現(xiàn)在就在那里開(kāi)始。

//shell
cd CONTRACTS_DIR

為我們的合約創(chuàng)建一個(gè)新目錄并進(jìn)入目錄:

//c++
mkdir addressbook
cd addressbook

第2步:創(chuàng)建并打開(kāi)一個(gè)新文件

//c++
touch addressbook.cpp

在你喜歡的編輯器中打開(kāi)文件。

第3步:編寫(xiě)擴(kuò)展標(biāo)準(zhǔn)類(lèi)并包含EOSIO

在之前的教程中,你創(chuàng)建了一個(gè)hello world合約,并學(xué)習(xí)了基礎(chǔ)知識(shí)。你將熟悉下面的結(jié)構(gòu),該類(lèi)已分別命名為addressbook。

//c++

#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
using namespace eosio;

class addressbook : public eosio::contract {
  public:
       
  private: 
  
};

第4步:為表創(chuàng)建數(shù)據(jù)結(jié)構(gòu)

在配置和實(shí)例化表之前,需要編寫(xiě)表示地址簿數(shù)據(jù)結(jié)構(gòu)的結(jié)構(gòu)。 將此視為“schema”。 由于它是一個(gè)地址簿,該表將包含人,因此創(chuàng)建一個(gè)名為“person”的struct。

//c++
struct person {};

定義multi_index表的模式時(shí),需要使用唯一值作為主鍵。

對(duì)于此合約,請(qǐng)使用類(lèi)型為account_name的名為“key”的字段。此合約將為每個(gè)用戶提供一個(gè)唯一條目,因此該密鑰將是基于用戶的account_name保證一致性且有唯一值。

//c++
struct person {
	account_name key; 
};

由于該合約是地址簿,因此可能應(yīng)該為每個(gè)條目或人員存儲(chǔ)一些相關(guān)的詳細(xì)信息。

//c++
struct person {
 account_name key;
 string first_name;
 string last_name;
 string street;
 string city;
 string state;
};

ok。基本schema架構(gòu)現(xiàn)已完成。接下來(lái),定義一個(gè)primary_key方法,該方法將由multi_index迭代器使用。每個(gè)multi_index架構(gòu)都需要一個(gè)主鍵。要實(shí)現(xiàn)此目的,只需創(chuàng)建一個(gè)名為primary_key()的方法,并返回一個(gè)值,在本例中為結(jié)構(gòu)中定義的成員key。

//c++
struct person {
 account_name key;
 string first_name;
 string last_name;
 string street;
 string city;
 string state;
 
 uint64_t primary_key() const { return key; }
};

步驟5:配置多索引表

現(xiàn)在已經(jīng)使用結(jié)構(gòu)定義了表的模式,我們需要配置表。需要對(duì)eosio::multi_index構(gòu)造函數(shù)進(jìn)行命名和配置,以使用我們之前定義的結(jié)構(gòu)。

//c++
typedef eosio::multi_index<N(people), person> address_index;
  • 我們把N(N(base32 X),用于從X的base32編碼的字符串解釋生成編譯時(shí)uint64_t)命名為表。該表包含許多不同的個(gè)體“persons”,因此將表命名為“people”。

  • 傳入上一步中定義的單person結(jié)構(gòu)

  • 聲明此表的類(lèi)型。此類(lèi)型將用于稍后實(shí)例化此表。

//c++
//configure the table
typedef eosio::multi_index<N(people), person> address_index;

使用上述multi_index配置,有一個(gè)名為peoplemulti_index表,該表基于使用struct person的該表的單個(gè)行的模式或數(shù)據(jù)結(jié)構(gòu)。

到目前為止,我們的文件應(yīng)該是這樣的。

//c++

#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>

using namespace eosio;

class addressbook : public eosio::contract {

  public:

  private:
    struct [[eosio::table]] person {
      account_name key;
      std::string first_name;
      std::string last_name;
      std::string street;
      std::string city;
      std::string state;

      uint64_t primary_key() const { return key; }
    };

    typedef eosio::multi_index<N(people), person> address_index;

};

第6步:構(gòu)造函數(shù)

使用C++類(lèi)時(shí),你應(yīng)該創(chuàng)建的第一個(gè)公共方法是構(gòu)造函數(shù)。

我們的構(gòu)造函數(shù)將負(fù)責(zé)最初設(shè)置合約。

EOSIO合約擴(kuò)展了合約類(lèi)。使用合約范圍初始化我們的父合約類(lèi)。我們的構(gòu)造函數(shù)傳遞的范圍參數(shù)是正在部署合約的區(qū)塊鏈上的帳戶。

//c++
addressbook(account_name self): contract(self){}

第7步:向表中添加記錄

以前,多索引表的主鍵被定義為強(qiáng)制執(zhí)行此合約將僅為每個(gè)用戶存儲(chǔ)一條記錄。為了使其全部工作,需要建立一些關(guān)于設(shè)計(jì)的假設(shè)。

  • 授權(quán)修改通訊簿的唯一帳戶是用戶。

  • 我們表的primary_key是唯一的,基于用戶名。

  • 對(duì)于可用性,合約應(yīng)該能夠通過(guò)單個(gè)操作創(chuàng)建和修改表行。

在eosio中,區(qū)塊鏈具有唯一的帳戶,因此在此特定用例中,account_name是作為primary_key的理想候選者。account_name類(lèi)型是uint64_t。

接下來(lái),為用戶定義添加或更新記錄的操作。此操作需要接受此操作需要能夠放置(創(chuàng)建)或修改的任何值。

格式化定義以使其更容易閱讀。為了簡(jiǎn)化用戶體驗(yàn)和界面,有一個(gè)方法負(fù)責(zé)創(chuàng)建和修改行。因此,將其命名為“upsert”,即“update”和“insert”的組合。

//c++

void upsert(
  account_name user, 
  std::string first_name, 
  std::string last_name, 
  std::string street, 
  std::string city, 
  std::string state
) {}

早些時(shí)候,有人提到只有用戶才能控制自己的記錄,因?yàn)檫@個(gè)合約是選擇加入的。為此,請(qǐng)使用eosio.cdt提供的require_auth方法。此方法接受一個(gè)參數(shù),即account_name類(lèi)型,并斷言執(zhí)行交易的帳戶等于提供的值。

//c++
void upsert(account_name user, std::string first_name, std::string last_name, std::string street, std::string city, std::string state) {
  require_auth( user );
}

實(shí)例化表。之前,配置了multi_index表,并將其聲明為address_index。要實(shí)例化一個(gè)表,請(qǐng)考慮這兩個(gè)必需參數(shù):

  • “code”,代表合約的帳戶??梢酝ㄟ^(guò)作用域_self變量訪問(wèn)此值。

  • 定義合約付款人的范圍“scope”,該用例中的合約負(fù)責(zé)支付ram費(fèi)用。

//c++
void upsert(account_name user, std::string first_name, std::string last_name, std::string street, std::string city, std::string state) {
  require_auth( user );
  address_index addresses(_self, _self );
}

接下來(lái),查詢迭代器,將其設(shè)置為變量,因?yàn)榇说鲗⒈欢啻问褂谩?/p>

//c++
void upsert(account_name user, std::string first_name, std::string last_name, std::string street, std::string city, std::string state) {
  require_auth( user );
  address_index addresses(_self, _self );
  auto iterator = addresses.find(user);
}

安全性已經(jīng)建立并且表格實(shí)例化了,太棒了!

接下來(lái),編寫(xiě)用于創(chuàng)建或修改表的邏輯。檢測(cè)特定用戶是否已存在。

為此,請(qǐng)通過(guò)傳遞user參數(shù)來(lái)使用表的find方法。find方法將返回一個(gè)迭代器。使用該迭代器對(duì)end方法進(jìn)行測(cè)試。end方法是“null”的別名。

//c++
void upsert(account_name user, std::string first_name, std::string last_name, std::string street, std::string city, std::string state) {
  require_auth( user );
  auto iterator = addresses.find( user );
  address_index addresses(_self, _self );
  if( addresses.find( user ) == addresses.end() )
  {
    //The user isn't in the table
  }
  else {
    //The user is in the table
  }
}

使用multi_index方法emplace在表中創(chuàng)建記錄。此方法接受兩個(gè)參數(shù),即此記錄的范圍“scope”和回調(diào)函數(shù)。

emplace方法的回調(diào)函數(shù)必須使用lamba來(lái)創(chuàng)建接口。在body中分配行的值和提供給upsert的值。

//c++
void upsert(account_name user, std::string first_name, std::string last_name, std::string street, std::string city, std::string state) {
  require_auth( user );
  address_index addresses(_self, _self );
  auto iterator = addresses.find( user );
  if( iterator == addresses.end() )
  {
		addresses.emplace(user, [&]( auto& row ) {
      row.key = user;
      row.first_name = first_name;
      row.last_name = last_name;
      row.street = street;
      row.city = city;
      row.state = state;
    });
  }
  else {
    //The user is in the table
  }
}

接下來(lái),處理“upsert”函數(shù)的修改或更新。使用modify方法,傳遞一些參數(shù)

  • 前面定義的迭代器,在調(diào)用此操作時(shí)設(shè)置為聲明的用戶。

  • 范圍“scope”或“ram payer”ram消費(fèi)者,在這種情況下是用戶,如先前在提出該合約的設(shè)計(jì)時(shí)所決定的那樣。

  • 回調(diào)函數(shù)用于處理表的修改。

//c++
void upsert(account_name user, std::string first_name, std::string last_name, std::string street, std::string city, std::string state) {
  require_auth( user );
  address_index addresses(_self, _self );
  auto iterator = addresses.find( user );
  if( iterator == addresses.end() )
  {
   addresses.emplace(user, [&]( auto& row ) {
     row.key = user;
     row.first_name = first_name;
     row.last_name = last_name;
     row.street = street;
     row.city = city;
     row.state = state;
   });
  }
  else {
   addresses.modify(iterator, user, [&]( auto& row ) {
     row.first_name = first_name;
     row.last_name = last_name;
     row.street = street;
     row.city = city;
     row.state = state;
   });
  }
}

地址簿合約現(xiàn)在具有一個(gè)功能操作,如果該記錄尚不存在,將允許用戶在表中創(chuàng)建一行,如果已存在則修改它。

“EOS開(kāi)發(fā)中區(qū)塊鏈數(shù)據(jù)怎么實(shí)現(xiàn)持久性”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

eos
AI