EOS的資料永續性(下)
上文EOS-Data-Persistence/" rel="nofollow,noindex" target="_blank">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,但為了它的工作,我們的合同需要一些小的宣告。
在upsert
和erase
函式之上新增以下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 5f78f9aea400783342b41a989b1b4821ffca006cd76ead38ebdf97428559daa05152 bytes727 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: 003f787824c7823b2cc8210f34daed592c2cfa66cbbfd4b904308b0dfeb0c811152 bytes692 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: 0a690e21f259bb4e37242cdb57d768a49a95e39a83749a02bced652ac4b3f4ed104 bytes1623 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工具鏈、賬戶與錢包、發行代幣、智慧合約開發與部署、使用程式碼與智慧合約互動等核心知識點,最後綜合運用各知識點完成一個便籤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的以太坊應用,包括賬戶管理、狀態與交易、智慧合約開發與互動、過濾器和交易等。
匯智網原創翻譯,轉載請標明出處。這裡是原文