本篇内容介绍了“EOS开发中区块链数据怎么实现持久性”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
之前,你创建了一个合约目录,现在就在那里开始。
//shell cd CONTRACTS_DIR
为我们的合约创建一个新目录并进入目录:
//c++ mkdir addressbook cd addressbook
//c++ touch addressbook.cpp
在你喜欢的编辑器中打开文件。
在之前的教程中,你创建了一个hello world合约,并学习了基础知识。你将熟悉下面的结构,该类已分别命名为addressbook
。
//c++ #include <eosiolib/eosio.hpp> #include <eosiolib/print.hpp> using namespace eosio; class addressbook : public eosio::contract { public: private: };
在配置和实例化表之前,需要编写表示地址簿数据结构的结构。 将此视为“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; } };
现在已经使用结构定义了表的模式,我们需要配置表。需要对eosio::multi_index
构造函数进行命名和配置,以使用我们之前定义的结构。
//c++ typedef eosio::multi_index<N(people), person> address_index;
我们把N
(N(base32 X),用于从X的base32编码的字符串解释生成编译时uint64_t)命名为表。该表包含许多不同的个体“persons”,因此将表命名为“people”。
传入上一步中定义的单person
结构
声明此表的类型。此类型将用于稍后实例化此表。
//c++ //configure the table typedef eosio::multi_index<N(people), person> address_index;
使用上述multi_index
配置,有一个名为people
的multi_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; };
使用C++类时,你应该创建的第一个公共方法是构造函数。
我们的构造函数将负责最初设置合约。
EOSIO合约扩展了合约类。使用合约范围初始化我们的父合约类。我们的构造函数传递的范围参数是正在部署合约的区块链上的帐户。
//c++ addressbook(account_name self): contract(self){}
以前,多索引表的主键被定义为强制执行此合约将仅为每个用户存储一条记录。为了使其全部工作,需要建立一些关于设计的假设。
授权修改通讯簿的唯一帐户是用户。
我们表的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
。要实例化一个表,请考虑这两个必需参数:
“code”,代表合约的帐户。可以通过作用域_self
变量访问此值。
定义合约付款人的范围“scope”,该用例中的合约负责支付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 ); }
接下来,查询迭代器,将其设置为变量,因为此迭代器将被多次使用。
//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开发中区块链数据怎么实现持久性”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。