- 第 1 章 区块链
- 第 2 章 以太坊
- 第 3 章 以太坊私链入门
- 第 4 章 以太坊网络
- 第 5 章 geth v1.8.16 命令详解
- 第 6 章 Wallet
- 第 7 章 Token
- 第 8 章 智能合约语言 Solidity v0.5.0
- 第 9 章 Truffle v4.1.8 开发框架
- 第 10 章 web3.js - 1.0.0
- 第 11 章 web3j v3.4.0 - Jave Client
- 11.2. 启动以太坊
- 11.3. Maven pom.xml 文件
- 11.4. Java 与 Solidity 数据类型映射关系
- 11.5. 常量
- 11.6. 连接到服务器获取版本号
- 11.7. 获得以太坊状态信息
- 11.8. 单位转换
- 11.9. 账号管理
- 11.10. Credentials
- 11.11. 交易
- 11.12. 钱包
- 11.13. 智能合约
- 11.14. ERC20合约
- 11.15. Infura
- 11.16. 助记词
- 11.17. 过滤器 (Filter)
- 11.18. Subscription
- 11.19. 解锁账号
- 11.20. IBAN (International Bank Account Number)
- 11.21. Springboot with Ethereum (web3j)
- 第 12 章 web3.py - A python interface for interacting with the Ethereum blockchain and ecosystem.
- 第 14 章 Ethereum Developer APIs
- 第 15 章 infura
- 第 16 章 以太坊案例
- 第 17 章 FAQ
- 17.3. Error: authentication needed: password or unlock
- 17.4. 新增节点后不生效
- 17.5. Unhandled rejection Error: Returned error: The method personal_unlockAccount does not exist/is not available
- 17.6. Error: exceeds block gas limit
- 17.7. Migrations.sol:11:3: Warning: Defining constructors as functions with the same name as the contract is deprecated. Use "constructor(…) { … }" instead.
- 17.8. Exception in thread "main" rx.exceptions.OnErrorNotImplementedException: Invalid response received: okhttp3.internal.http.RealResponseBody@6c25e6c4
- 17.9. 旧版本 Remix(browser-solidity) 本地安装
- 第 18 章 Hyperledger Fabric v2.0.0
- 第 19 章 Hyperledger Fabric 运维
- 第 20 章 Chaincode 链码(智能合约)
- 第 21 章 Hyperledger Fabric Client SDK for Node.js
- 第 22 章 fabric-sdk-java
- 第 24 章 已知 Hyperledger 落地案例
- 第 25 章 Fabric Command
- 第 26 章 Fabric FAQ
- 第 27 章 IPFS(InterPlanetary File System,星际文件系统)
- 第 28 章 IPFS 命令
- 第 29 章 IPFS WebUI
- 第 30 章 IPFS 集群配置
- 第 31 章 IPFS API
- 第 32 章 IPFS Faq
- 第 33 章 EOS
- 第 34 章 EOS 安装
- 第 35 章 CLEOS
- 第 36 章 智能合约开发
- 第 37 章 EOS Dapp 开发
- 第 38 章 FAQ
- 第 39 章 BaaS (Blockchain as a Service) 平台
- 第 40 章 BitCoin
- 第 41 章 其他区块链相关
- 附录 1. 附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
36.7. 智能合约数据库操作 CURD
36.7. 智能合约数据库操作 CURD
为了方便调试合约
找到config.ini中的配置项contracts-console = false 改为 true
[root@netkiller ~]# vim ~/.local/share/eosio/nodeos/config/config.ini # print contract's output to console (eosio::chain_plugin) contracts-console = true
这样 eosio::print() 输出的内容才会显示在控制台上。
36.7.1. 创建一个新项目
eosiocpp -n project
36.7.2. 创建结构体
例如我们需要这样一个数据结构
{ id, description, completed }
结构体定义如下
struct todo { uint64_t id; std::string description; uint64_t completed; uint64_t primary_key() const { return id; } EOSLIB_SERIALIZE(todo, (id)(description)(completed)) };
primary_key() 相当与数据中的主键。
定义一个表
typedef eosio::multi_index<N(todos), todo> todo_table; todo_table todos;
36.7.3. 插入数据操作
void create(account_name author, const uint32_t id, const std::string& description) { todos.emplace(author, [&](auto& new_todo) { new_todo.id = id; new_todo.description = description; new_todo.completed = 0; });
36.7.4. 修改数据操作
void complete(account_name author, const uint32_t id) { auto todo_lookup = todos.find(id); eosio_assert(todo_lookup != todos.end(), "Todo does not exist"); todos.modify(todo_lookup, author, [&](auto& modifiable_todo) { modifiable_todo.completed = 1; }); eosio::print("todo#", id, " marked as complete"); }
36.7.5. 删除数据操作
void destroy(account_name author, const uint32_t id) { auto todo_lookup = todos.find(id); todos.erase(todo_lookup); eosio::print("todo#", id, " destroyed"); }
36.7.6. 完整的合约例子
#include <eosiolib/eosio.hpp> #include <string> namespace eosio { using std::string; class netkiller : public contract { public: netkiller( account_name self ):contract(self){} void create(account_name author, string title, string content); void change(account_name author, uint64_t post_id, string title, string content); void remove(account_name author, uint64_t post_id); void find(uint64_t post_id, account_name author); private: struct da { uint64_t post_id; account_name poster; string title; string content; uint64_t primary_key()const { return post_id; } account_name get_poster() const { return poster; } EOSLIB_SERIALIZE(da, (post_id)(poster)(title)(content)) }; typedef eosio::multi_index<N(data), da, indexed_by<N(byposter), const_mem_fun<da, account_name, &da::get_poster>> > article; }; }
#include "netkiller.hpp" namespace eosio { void netkiller::create(account_name author, string title, string content) { require_auth( author ); article datable( _self, _self); datable.emplace(author, [&]( da & d){ d.title = title; d.content = content; d.post_id = datable.available_primary_key(); d.poster = author; }); } void netkiller::change(account_name author, uint64_t post_id, string title, string content) { require_auth(author); article datable( _self, author); auto post = datable.find(post_id); eosio_assert(post->poster == author, "netkiller"); datable.modify(post, author, [&](auto& p){ if (title != "") p.title = title; if (content != "") p.content = content; }); } void netkiller::remove(account_name author, uint64_t post_id) { require_auth(author); article datable( _self, author); auto post = datable.find(post_id); eosio::print(post->title.c_str()); eosio_assert(post->poster == author, "The author is invlide"); datable.erase(post); } void netkiller::find(uint64_t post_id, account_name author){ article datable(_self, _self); auto post_da = datable.find( post_id); eosio::print("Post_id: ", post_da->post_id, " Post_Tile: ", post_da->title.c_str(), " Content: ", post_da->content.c_str()); auto poster_index = datable.template get_index<N(byposter)>(); auto pos = poster_index.find( author ); for (; pos != poster_index.end(); pos++) { eosio::print("content:", pos->content.c_str(), " post_id:", pos->post_id, " title:", pos->title.c_str()); } } } EOSIO_ABI(eosio::netkiller, (create)(change)(remove)(find))
36.7.6.1. 编译
eosiocpp -o cms.wast cms.cpp eosiocpp -g cms.abi cms.cpp
36.7.6.2. 启动EOS私链开发环境
nodeos -e -p eosio --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin --plugin eosio::wallet_api_plugin
36.7.6.3. 创建合约账号
这里我们创建一个账号,用这个账号部署合约,该账号是合约所有者。
创建秘钥对
[root@netkiller ~]# cleos wallet unlock [root@netkiller ~]# cleos create key Private key: 5HxCWNbTEADKbvdRBgeENXhxReHMQbVuPL5mumDqGCzmkPo5yy3 Public key: EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4
导入私钥
[root@netkiller ~]# cleos wallet import 5HxCWNbTEADKbvdRBgeENXhxReHMQbVuPL5mumDqGCzmkPo5yy3 imported private key for: EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4 [root@netkiller ~]# cleos wallet keys | grep EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4 "EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4",
创建账号 neo
[root@netkiller ~]# cleos create account eosio contract.cms EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4 EOS7WEcxxHcmM7w7DHB56N6qQ2toMrdudYjeDTZb6LtL9g77MXzR4 executed transaction: f04ba09f633dffbf97321c6d2e021192082383908fa690dc40032cd98a1bfd89 200 bytes 390 us # eosio <= eosio::newaccount "0000000000ea305590af0119999b274501000000010003588ecdc868696f500c7782dbf0da3b298830e67ea9b810469819d... warning: transaction executed locally, but may not be confirmed by the network yet
contract.art 就是我们合约账号,我们使用 contract 前缀来区分他是合约账号。
36.7.6.4. 部署合约
[root@netkiller eos]# cleos wallet unlock password: Unlocked: default [root@netkiller eos]# cleos set contract contract.cms cms Reading WAST/WASM from cms/cms.wasm... Using already assembled WASM... Publishing contract... executed transaction: 8a72e29389e170807daaf41e9c9e70ac4eff2f2f129ca22ef55ca9443768dedf 7176 bytes 1311 us # eosio <= eosio::setcode "80250219999b27450000c3770061736d0100000001b2011b60037f7e7e0060027f7e0060057f7e7e7f7f0060047f7e7f7f0... # eosio <= eosio::setabi "80250219999b27459d020e656f73696f3a3a6162692f312e30000506637265617465000306617574686f72046e616d65057... warning: transaction executed locally, but may not be confirmed by the network yet
36.7.6.5. 创建
cleos push action contract.cms create '{"author":"contract.cms","title":"hello","content":"helloworld!!!"}' -p contract.cms [root@netkiller eos]# cleos push action contract.art create '{"author":"contract.art","title":"hello","content":"helloworld!!!"}' -p contract.art executed transaction: b6cab608fb4e7fa17a7f893848f3516e1bfd231769ad7d7226b0a099f309a771 120 bytes 899 us # contract.art <= contract.art::create {"author":"contract.cms","title":"hello","content":"helloworld!!!"} warning: transaction executed locally, but may not be confirmed by the network yet
[root@netkiller eos]# cleos push action contract.cms create '{"author":"neo","title":"hello","content":"helloworld!!!"}' -p neo executed transaction: 90cb81b11386514b450e1a609f0e1e2633f6a4e40d453c127811e5cd33b46a5a 120 bytes 755 us # contract.art <= contract.art::create {"author":"neo","title":"hello","content":"helloworld!!!"} warning: transaction executed locally, but may not be confirmed by the network yet
下面我们来查询一下刚刚插入的数据:
36.7.6.6. 查找
find
[root@netkiller eos]# cleos push action contract.cms find '{"id":0}' -p contract.cms executed transaction: b3cba4d001fcb49a88926be208fa7bee59d557b0ed8a2bd12e65bdd3ff69c61e 104 bytes 486 us # contract.cms <= contract.cms::find {"id":0} >> id: 0 Tile: hello Content: helloworld!!!
query
[root@netkiller eos]# cleos push action contract.cms query '{"author":"contract.cms", "id":0}' -p contract.cms executed transaction: c81a0d21634f4942f7d65dd49efcf5cf7cd739a049968b5f9b0eaad7de4c688c 112 bytes 583 us # contract.cms <= contract.cms::query {"author":"contract.cms","id":0} >> Post_id: 0 Post_Tile: hello Content: helloworld!!!content:helloworld!!! id:0 title:hello
36.7.6.7. 修改
修改表中的数据
[root@netkiller eos]# cleos push action contract.cms change '{"author":"contract.cms","id":0,"title":"word","content":"china"}' -p contract.cms executed transaction: 073205e4e3e30699a81394ee622aa84d568958919801b364d809ff34f4ca8412 120 bytes 553 us # contract.cms <= contract.cms::change {"author":"contract.cms","id":0,"title":"word","content":"china"}
检查数据修改情况
[root@netkiller eos]# cleos push action contract.cms find '{"id":0}' -p contract.cms executed transaction: 300fe2c93cf2cfebcdd0524e0629a96b3011b0592be2119d001f38807c1c378b 104 bytes 498 us # contract.cms <= contract.cms::find {"id":0} >> id: 0 Tile: word Content: china
36.7.6.8. 删除
[root@netkiller eos]# cleos push action contract.cms remove '{"author":"contract.cms","id":0}' -p contract.cms executed transaction: eeee8ff799c58d5e3a246ccec8d80c47599ad947d4581611d9a668abee53c0b5 112 bytes 770 us # contract.cms <= contract.cms::remove {"author":"contract.cms","id":0} >> word
检查被删除的数据,提示 Error 3070002: Runtime Error Processing WASM 表示找不到该记录。
[root@netkiller eos]# cleos push action contract.cms find '{"id":0}' -p contract.cms Error 3070002: Runtime Error Processing WASM
36.7.7. 序列主键
#include <eosiolib/eosio.hpp> using namespace eosio; class vehicle : public eosio::contract { public: /// @abi table struct service_rec { uint64_t pkey; account_name customer; uint32_t date; uint32_t odometer; auto primary_key() const { return pkey; } account_name get_customer() const { return customer; } EOSLIB_SERIALIZE(service_rec, (pkey)(customer)(date)(odometer)) }; typedef multi_index<N(service), service_rec> service_table_type; using contract::contract; /// @abi action void exec(account_name owner, account_name customer) { service_table_type service_table(current_receiver(), owner); uint64_t pkeyf; service_table.emplace(owner, [&](auto &s_rec) { s_rec.pkey = service_table.available_primary_key(); // 主键自增 pkeyf = s_rec.pkey; print(pkeyf);// 打印主键内容 s_rec.customer = customer; s_rec.date = 2000; s_rec.odometer = 100; }); print("Hello, ", name{customer}); service_rec result = service_table.get(pkeyf); print("_", result.pkey); print("_", result.customer); print("_", result.date); print("_", result.odometer); } }; EOSIO_ABI(vehicle, (exec))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论