EOS踩坑記


EOS踩坑記

1、每個account只能更新自己的contract,即使兩個account的秘鑰相同,也不允許

  如下,使用alice的權限來更新james的contract。會返回 Missing required authority錯誤。

cleos set contract james /home/ubuntu/contracts/hello/jameshello -p alice@active

  應該改為:

cleos set contract james /home/ubuntu/contracts/hello/jameshello -p james@active

 

2、contract class 名可以與 account 名不一致。如,以下調用是OK的。

cleos set contract james /home/ubuntu/contracts/hello/xhello -p james@active

 

3、一個account只能有一個contract。

  例如,hello 賬戶有一個hi函數,set contract,此時abi 為:

    

  此時,有一個xhello contract,內含一個 hi2 函數,將xhello合約提交。

cleos set contract hello /home/ubuntu/contracts/hello/xhello -p hello@active

  則 hello 賬戶的 abi 會變為:

    

  可以看見,原有的hi action不見了。

 

4、contract class 名、目錄名、文件名必須一致

  1)如下,文件名為hello,目錄名為xhello,兩者不一致。

  

cleos set contract james /home/ubuntu/contracts/hello/xhello -p james@active

  執行后,會返回找不到文件錯誤。

  

  2)如下,contract class名為 jameshello,而目錄名為hello。

  

cleos set contract james /home/ubuntu/contracts/hello/hello -p james@active

  雖然可以成功發布合約,但合約的abi是空的,也就是實際等於沒有發布成功。

  

 

5、任意account都有權調用他人的contract。如,下面用bob的權限調用james的hi action,是合法的,不論兩者的公鑰是否相同。

cleos push action james hi '["bob"]' -p bob@active

 

6、require_auth(name n)

  Verifies that @ref name exists in the set of provided auths on a action. Fails if not found.

  檢測name是否在通過-p提供的名單里。

  可以用於限制每個account在調用action時,只能修改自身相關信息。例如:

[[eosio::action]]
void hi( name user )
{
    require_auth(user);
     print("Hello, ", user);
}

 

7、contract 類中的 get_self()方法、_self。

  1)_self 是 contract 類的一個 protected member,其類型為 name,可以知道,它存的是一個賬號。

  

  2)_self的賦值來源於 receiver,所以_self就是receiver。

  

  3)get_self() 返回的就是 _self,也就是receiver,也就是一個account。

  

  

8、symbol_code

  symbol_code 是一個 class.

    

  只含有一個 uint64_t value 成員變量。

    

  symbol_code 將長度為7以內(包括7)的字符串 encode 為 uint64_t value。(注意 uint64_t可以存儲8個byte)

 

9、symbol

  symbol 是一個class

    

  只包括一個成員變量

    

  通過構造函數可以看到 symbol可以存儲8個Byte,上文的symbol_code使用了7個Byte,所以symbol可以將symbol_code存儲在自身,並且額外加了一個precision字段。

    

   symbol_code 指的是 TOKEN Name,如DICE、EOS。

   precision 指的是一個TOKEN的精度,比如 100000000.0000,上限是1億,precision是4。

 

10、asset

  下面的命令可以調用 eosio.token 的action,創建一個新的TOKEN.

cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active

  而 asset 代表的就是 "1000000000.0000 SYS"。

  asset 是一個class。他只有2個成員變量,amount對應上述命令的 1000000000.0000, 而symbol則代碼SYS,以及精度4。

    

 

11、multi_index

  multi_index 是一個class,意為可以包含多個索引的table。eosio.cdt源碼中有一個完整的示例:

 *  #include <eosiolib/eosio.hpp>
 *  using namespace eosio;
 *  class mycontract: contract {
 *    struct record {
 *      uint64_t    primary;
 *      uint64_t    secondary_1;
 *      uint128_t   secondary_2;
 *      uint256_t   secondary_3;
 *      double      secondary_4;
 *      long double secondary_5;
 *      uint64_t primary_key() const { return primary; }
 *      uint64_t get_secondary_1() const { return secondary_1; }
 *      uint128_t get_secondary_2() const { return secondary_2; }
 *      uint256_t get_secondary_3() const { return secondary_3; }
 *      double get_secondary_4() const { return secondary_4; }
 *      long double get_secondary_5() const { return secondary_5; }
 *    };
 *    public:
 *      mycontract(name receiver, name code, datastream<const char*> ds):contract(receiver, code, ds){}
 *      void myaction() {
 *        auto code = _self;
 *        auto scope = _self;
 *        multi_index<"mytable"_n, record,
 *          indexed_by< "bysecondary1"_n, const_mem_fun<record, uint64_t, &record::get_secondary_1> >,
 *          indexed_by< "bysecondary2"_n, const_mem_fun<record, uint128_t, &record::get_secondary_2> >,
 *          indexed_by< "bysecondary3"_n, const_mem_fun<record, uint256_t, &record::get_secondary_3> >,
 *          indexed_by< "bysecondary4"_n, const_mem_fun<record, double, &record::get_secondary_4> >,
 *          indexed_by< "bysecondary5"_n, const_mem_fun<record, long double, &record::get_secondary_5> >
 *        > table( code, scope);
 *      }
 *  }
 *  EOSIO_DISPATCH( mycontract, (myaction) )
View Code

    第一個參數是擁有這張表的account,第二個參數是 scope。

    

   find參數可以用來根據主鍵查找。

    

  下面是 eosio.token 中的使用代碼:

     stats statstable( _self, sym.code().raw() );
     auto existing = statstable.find( sym.code().raw() );
     eosio_assert( existing == statstable.end(), "token with symbol already exists" );

     statstable.emplace( _self, [&]( auto& s ) {
         s.supply.symbol = maximum_supply.symbol;
         s.max_supply    = maximum_supply;
         s.issuer        = issuer;
     });

 

12、SEND_INLINE_ACTION

  SEND_INLINE_ACTION 是eosio.cdt的action.hpp中定義的一個宏.

    

  在 eosio.token 中的使用如下:
    

  第一個參數是 account(也即 contract),第二個參數是 action name,第三個參數是權限。之后的參數全部傳遞給 action。

  可以看一下 transfer 函數的原型。

    

 

13、require_recipient

  這個方法用於通知 notify_account,當前調用方法以某些參數被調用。

    

  例如,在transfer(from,to,quantity,memo)中調用了

    require_recipient(from)

    require_recipient(to)

  則from、to分別會擁有一條執行了transfer() action的記錄:

    

  這只是一條記錄,並不說明 transfer被多執行了兩次。

    

14、multi_index 中的 scope

  multi_index 類似於數據庫中的Table,struct 定義了Row的結構。

  為了提升多線程讀寫性能,eos加入了 scope概念,scope是一個 uint64_t。一個scope下包含多個row。所以形成了 Table-Scope-Row 的結構。

    

  在 eosio.token 示例中,分別使用 symbol.code().raw() 作為 scope,以及使用 owner.value 賬戶名作為 scope。

 

  從第2個索引起,the name is less important as you will pass the getter name into the typedef.

 

15、code 是發布合約的account. 詳情參考[3]

16、permission_level  

  permission_level 是一個 struct,只包含 name actor; name permission; 兩個字段。

   

 

17、eosio.code

  面臨的問題:

    比如alice調用智能合約contract1.test,一開始alice看過contract1.test的邏輯,發現它只是一個打印函數,並不會調用其他合約。所以alice以自己active的權限alice@active去執行contract1.test。

    但是contract1的擁有者某一天可能偷偷更改了test的實現,在test函數中調用eosio.token的transfer函數以alice@active權限就可以取走alice的EOS.

  解決方案:

    為了解決權限亂用問題,EOS新增了eosio.code這個特殊權限。采用eosio.code后,contract1.test要以alice@active去調用eosio.token,必須得到alice的授權,即必須在alice@active里添加contrac1@eosio.code授權.

$cleos set account permission alice active '{"threshold": 1,"keys": [{"key":"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", "weight":1}],"accounts": [{"permission":{"actor":"contract1","permission":"eosio.code"},"weight":1}]}' owner -p alice@owner

  account_1:alive : 1 account_2@eosio.code 的含意為:當account_1調用account_2的合約代碼時,account_2可以以account_1.alive 權限去調用外部 contract action.

  更詳細資料可見[參考4].

 

18、The primary key of the object in the eosio::multi_index container must be a unique unsigned 64-bit integer. The objects in the eosio::multi_index container are sorted by the primary key index in ascending order of the unsigned 64-bit integer primary key.

  

  A key differentiator of the EOSIO persistence services over other blockchain infrastructures is its Multi-Index iterators. Unlike some other blockchains that only provide a key-value store, EOSIO Multi-Index tables allow a contract developer to keep a collection of objects sorted by a variety of different key types, which could be derived from the data within the object. This enables rich retrieval capabilities. Up to 16 secondary indices can be defined, each having its own way of ordering and retrieving table contents.

 

19、eosio.system

  eos區塊鏈啟動時,默認有一個eosio account,該賬戶默認會 set eosio.system contract. 

  通過執行以下命令,可以看到 eosio是有 setcode、setabi 等 eosio.system中的action的。

cleos get abi eosio

  

 

20、eosio.bios

  In a public blockchain, this contract will manage the staking and unstaking of tokens to reserve bandwidth for CPU and network activity, and memory for contracts.

 

21、eosio::history_api_plugin

  nodeos 啟動時只有加載了這個插件,才能執行 get accounts pub-key 命令.

cleos get accounts EOSXXXXXXXXXXXXXXXXXXXX

   詳細見參考[6].

 

22、Future versions of this contract may allow other parties to buy symbol names automatically.

  EOS的SYMBOL未來將會采取體售賣的形式。

 

23、

 

 

參考:

1、https://developers.eos.io/eosio-home/docs/your-first-contract

2、https://developers.eos.io/eosio-home/docs/token-contract

3、https://developers.eos.io/eosio-home/docs/data-persistence

4、https://blog.csdn.net/itleaks/article/details/80557560

5、https://developers.eos.io/eosio-cpp/docs/db-api

6、https://developers.eos.io/eosio-cpp/docs/introduction-to-smart-contracts


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM