EOS的数据持久性(上)

栏目: C++ · 发布时间: 5年前

内容简介:本教程假定你已经完成了要了解数据持久性,请编写一个简单的智能合约,作为地址记录。虽然这个用例由于各种原因而不太适合作为生产智能合约,但开始学习数据持久性如何在EOSIO上运行而不被与eosio的之前,你创建了一个合约目录,现在就在那里开始。

本教程假定你已经完成了 EOS开发从智能合约开始

要了解数据持久性,请编写一个简单的智能合约,作为地址记录。虽然这个用例由于各种原因而不太适合作为生产智能合约,但开始学习数据持久性如何在EOSIO上运行而不被与eosio的 multi_index 功能无关的业务逻辑分心,这也算的上一个很好的合约。

第1步:创建一个新目录

之前,你创建了一个合约目录,现在就在那里开始。

//shell
cd CONTRACTS_DIR

为我们的合约创建一个新目录并进入目录:

//c++
mkdir addressbook
cd addressbook

第2步:创建并打开一个新文件

//c++
touch addressbook.cpp

在你喜欢的编辑器中打开文件。

第3步:编写扩展标准类并包含EOSIO

在之前的教程中,你创建了一个hello world合约,并学习了基础知识。你将熟悉下面的结构,该类已分别命名为 addressbook

//c++

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

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

第4步:为表创建数据结构

在配置和实例化表之前,需要编写表示地址簿数据结构的结构。 将此视为“schema”。 由于它是一个地址簿,该表将包含人,因此创建一个名为“person”的 struct

//c++
struct person {};

定义 multi_index 表的模式时,需要使用唯一值作为主键。

对于此合约,请使用类型为 account_name 的名为“key”的字段。此合约将为每个用户提供一个唯一条目,因此该密钥将是基于用户的 account_name 保证一致性且有唯一值。

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

由于该合约是地址簿,因此可能应该为每个条目或人员存储一些相关的详细信息。

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

ok。基本 schema 架构现已完成。接下来,定义一个 primary_key 方法,该方法将由 multi_index 迭代器使用。每个 multi_index 架构都需要一个主键。要实现此目的,只需创建一个名为 primary_key() 的方法,并返回一个值,在本例中为结构中定义的成员 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:配置多索引表

现在已经使用结构定义了表的模式,我们需要配置表。需要对 eosio::multi_index 构造函数进行命名和配置,以使用我们之前定义的结构。

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

使用上述 multi_index 配置,有一个名为 peoplemulti_index 表,该表基于使用 struct person 的该表的单个行的模式或数据结构。

到目前为止,我们的文件应该是这样的。

//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步:构造函数

使用C++类时,你应该创建的第一个公共方法是构造函数。

我们的构造函数将负责最初设置合约。

EOSIO合约扩展了合约类。使用合约范围初始化我们的父合约类。我们的构造函数传递的范围参数是正在部署合约的区块链上的帐户。

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

第7步:向表中添加记录

以前,多索引表的主键被定义为强制执行此合约将仅为每个用户存储一条记录。为了使其全部工作,需要建立一些关于设计的假设。

primary_key

在eosio中,区块链具有唯一的帐户,因此在此特定用例中, account_name 是作为 primary_key 的理想候选者。 account_name 类型是 uint64_t

接下来,为用户定义添加或更新记录的操作。此操作需要接受此操作需要能够放置(创建)或修改的任何值。

格式化定义以使其更容易阅读。为了简化用户体验和界面,有一个方法负责创建和修改行。因此,将其命名为“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
) {}

早些时候,有人提到只有用户才能控制自己的记录,因为这个合约是选择加入的。为此,请使用 eosio.cdt 提供的 require_auth 方法。此方法接受一个参数,即 account_name 类型,并断言执行交易的帐户等于提供的值。

//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 );
}

实例化表。之前,配置了 multi_index 表,并将其声明为 address_index 。要实例化一个表,请考虑这两个必需参数:

_self
//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 );
}

接下来,查询迭代器,将其设置为变量,因为此迭代器将被多次使用。

//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);
}

安全性已经建立并且表格实例化了,太棒了!

接下来,编写用于创建或修改表的逻辑。检测特定用户是否已存在。

为此,请通过传递 user 参数来使用表的 find 方法。 find 方法将返回一个迭代器。使用该迭代器对 end 方法进行测试。 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 在表中创建记录。此方法接受两个参数,即此记录的范围“scope”和回调函数。

emplace 方法的回调函数必须使用lamba来创建接口。在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
  }
}

接下来,处理“upsert”函数的修改或更新。使用 modify 方法,传递一些参数

  • 前面定义的迭代器,在调用此操作时设置为声明的用户。
  • 范围“scope”或“ram payer”ram消费者,在这种情况下是用户,如先前在提出该合约的设计时所决定的那样。
  • 回调函数用于处理表的修改。
//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;
   });
  }
}

地址簿合约现在具有一个功能操作,如果该记录尚不存在,将允许用户在表中创建一行,如果已存在则修改它。

但是如果用户想要完全删除记录呢?

======================================================================

分享一个交互式的在线编程实战, EOS智能合约与DApp开发入门

EOS教程

本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。

  • java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在 Java 代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  • java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在 Php 代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  • 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发进阶教程,主要是介绍使用node.js、 mongodb 、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • python以太坊,主要是针对 python 工程师使用web3.py进行区块链以太坊开发的详解。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。

汇智网原创翻译,转载请标明出处。这里是 原文


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数学与泛型编程

数学与泛型编程

[美]亚历山大 A. 斯捷潘诺夫(Alexander A. Stepanov)、[美]丹尼尔 E. 罗斯(Daniel E. Rose) / 爱飞翔 / 机械工业出版社 / 2017-8 / 79

这是一本内容丰富而又通俗易懂的书籍,由优秀的软件设计师 Alexander A. Stepanov 与其同事 Daniel E. Rose 所撰写。作者在书中解释泛型编程的原则及其所依据的抽象数学概念,以帮助你写出简洁而强大的代码。 只要你对编程相当熟悉,并且擅长逻辑思考,那么就可以顺利阅读本书。Stepanov 与 Rose 会清晰地讲解相关的抽象代数及数论知识。他们首先解释数学家想要解决......一起来看看 《数学与泛型编程》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具