EOS的数据持久性(下)

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

内容简介:上文与前面的步骤类似,在地址簿中创建一个公共方法,确保包含ABI声明和针对操作的参数用户进行测试的require_auth,以验证只有记录的所有者可以修改其帐户。实例化表。在

上文 EOS的数据持久性(上) 中提到,如果用户想要完全删除记录怎么办?我们接着来看下面的步骤:

第8步:从表中删除记录

与前面的步骤类似,在地址簿中创建一个公共方法,确保包含ABI声明和针对操作的参数用户进行测试的require_auth,以验证只有记录的所有者可以修改其帐户。

//c++
void erase(account_name user){
      require_auth(user);
    }

实例化表。在 addressbook 中,每个帐户只有一个记录。使用 find 设置 iterator

//c++
...
    void erase(account_name user){
      require_auth(user);
      address_index addresses(_self, _self);
      auto iterator = addresses.find(user);
    }
...

合约不能删除不存在的记录,因此在继续之前断言记录确实存在。

//c++
...
    void erase(account_name user){
      require_auth(user);
      address_index addresses(_self, _self);
      auto iterator = addresses.find( user );
      eosio_assert(iterator != addresses.end(), "Record does not exist");
    }
...

最后,调用 erase 方法,擦除迭代器iterator。

//c++
...
    void erase(account_name user){
      require_auth(user);
      address_index addresses(_self, _self);
      auto iterator = addresses.find( user );
      eosio_assert(iterator != addresses.end(), "Record does not exist");
      addresses.erase(iterator);
    }
...

合约现在基本完成。 用户可以创建,修改和删除记录。但是,合约还没有为编译做好准备。

第9步:准备ABI

完成以下步骤以完成合约。

9.1 EOSIO_ABI

在文件的底部,使用EOSIO_ABI宏程序,传递合约的名称,以及我们的单独操作“upsert”。

此宏程序处理 wasm 用于将调用分派给我们的合约中的特定方法的应用处理程序。

将以下内容添加到 addressbook.cpp 的底部将使我们的 cpp 文件与EOSIO的wasm解释器兼容。未能包含此声明可能会在部署合约时导致错误。

//c++
EOSIO_ABI( addressbook, (upsert) )

9.2 ABI action 声明

eosio.cdt 包含一个ABI Generator,但为了它的工作,我们的合同需要一些小的声明。

upserterase 函数之上添加以下C++11声明:

//c++
[[eosio::action]]

上述声明将提取操作的参数,并在生成的ABI文件中创建必要的ABI结构描述。

9.3 ABI表声明

向表中添加ABI声明。修改合约私有区域中定义的以下行:

//c++
struct person {

改成这样:

//c++
struct [[eosio::table]] person {

[[eosio.table]] 声明将向ABI文件添加必要的描述。

现在我们的合约已经准备好了。

以下是我们的 addressbook 合约的最终状态:

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

using namespace eosio;

class addressbook : public eosio::contract {

public:
  using contract::contract;

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

  [[eosio::action]]
  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 {
      std::string changes;
      addresses.modify(iterator, 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;
      });
    }
  }

  [[eosio::action]]
  void erase(account_name user){
    // require_auth(user);
    address_index addresses(_self, _self);
    auto iterator = addresses.find( user );
    eosio_assert(iterator != addresses.end(), "Record does not exist");
    addresses.erase(iterator);
  }

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;

};

EOSIO_ABI( addressbook, (upsert)(erase) )

第10步:编译合约

从终端执行以下命令:

//shell
eosio-cpp -o addressbook.wasm addressbook.cpp --abigen

第11步:部署合约

为合约创建一个帐户,执行以下 shell 命令:

//shell
cleos create account eosio addressbook YOUR_PUBLIC_KEY

部署 addressbook 合约。

//shell
cleos set contract addressbook CONTRACTS_DIR/addressbook

结果:

//Result
5f78f9aea400783342b41a989b1b4821ffca006cd76ead38ebdf97428559daa0  5152 bytes  727 us
#         eosio <= eosio::setcode               {"account":"addressbook","vmtype":0,"vmversion":0,"code":"0061736d010000000191011760077f7e7f7f7f7f7f...
#         eosio <= eosio::setabi                {"account":"addressbook","abi":"0e656f73696f3a3a6162692f312e30010c6163636f756e745f6e616d65046e616d65...
warning: transaction executed locally, but may not be confirmed by the network yet    ]

第12步:测试合约

在表中添加一行:

//shell
cleos push action addressbook upsert '["alice", "alice", "liddell", "123 drink me way", "wonderland", "amsterdam"]' -p alice@active

结果:

////Result
executed transaction: 003f787824c7823b2cc8210f34daed592c2cfa66cbbfd4b904308b0dfeb0c811  152 bytes  692 us
#   addressbook <= addressbook::upsert          {"user":"alice","first_name":"alice","last_name":"liddell","street":"123 drink me way","city":"wonde...

检查alice是否无法为其他用户添加记录。

//shell
cleos push action addressbook upsert '["bob", "bob", "is a loser", "doesn't exist", "somewhere", "someplace"]' -p alice@active

正如预期的那样,我们合约中的 require_auth 阻止了alice创建/修改另一个用户的行。

//Result
Error 3090004: Missing required authority
Ensure that you have the related authority inside your transaction!;
If you are currently using 'cleos push action' command, try to add the relevant authority using -p option.

查询爱丽丝的记录。

//shell
cleos get table addressbook addressbook people -k alice

结果:

//Result
{
  "rows": [{
      "key": "3773036822876127232",
      "first_name": "alice",
      "last_name": "liddell",
      "street": "123 drink me way",
      "city": "wonderland",
      "state": "amsterdam"
    }
  ],
  "more": false
}

测试看到爱丽丝可以删除记录。

//shell
cleos push action addressbook erase '["alice"]' -p alice@active

结果:

//Result
executed transaction: 0a690e21f259bb4e37242cdb57d768a49a95e39a83749a02bced652ac4b3f4ed  104 bytes  1623 us
#   addressbook <= addressbook::erase           {"user":"alice"}
warning: transaction executed locally, but may not be confirmed by the network yet    ]

检查记录是否已删除:

//shell
cleos get table addressbook addressbook people -k alice

结果:

//Result
{
  "rows": [],
  "more": false
}

看起来不错!

总结下

你已经学习了如何配置表,实例化表,创建新行,修改现有行以及如何使用迭代器。你已经学习了如何针对空迭代器结果进行测试,以及如何配置合约的ABI。

文中调用的各种eos方法可以参考:EOS.IO C语言API手册。

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

分享一个交互式的在线编程实战, 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的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。

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


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

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

Programming in Haskell

Programming in Haskell

Graham Hutton / Cambridge University Press / 2007-1-18 / GBP 34.99

Haskell is one of the leading languages for teaching functional programming, enabling students to write simpler and cleaner code, and to learn how to structure and reason about programs. This introduc......一起来看看 《Programming in Haskell》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具