EOS系列 - WASM智能合約 - 內置方法

EOS系列 - 智能合約進階

1.eosio::same_payer

第一個只是一個常量表達式,可在修改多索引表的條目時使用。當使用eosio::same_payer時,將要使用的新RAM(如果有的話)分配給已經爲表項支付的相同帳戶。

用法:

statstable.modify( st, eosio::same_payer, [&]( auto& s ) {
    s.supply += quantity;
});

它在[multi_index.hpp]中定義,只是空的name(value:0),""_nname(0)的常量表達式,某些開發人員仍在使用該表達式來表示相同的付款人。

2.get_first_receiver,get_self()

contracts.hpp中定義的 get_selfget_first_receiver,返回正在運行的動作的執行上下文的一部分。 (在EOSIO.CDT 1.6中,get_first_receiver的實現是爲了支持舊的get_code,現在已棄用。)get_self方法返回當前正在運行代碼的合同,而get_first_receiver返回的帳戶位於動作源自。除非涉及通過require_recipient發出的通知,否則這兩個帳戶是相同的。

例如,偵聽“ eosio.token”的“轉移”操作的通知,“ get_self()”將返回您的合同部署到的帳戶,而“ get_first_receiver()”將返回“ eosio.token”帳戶。這是因爲該操作是由向與您的合同帳戶有關的“ eosio.token”帳戶發送“轉移”操作的帳戶發起的。

用法:

[[eosio::on_notify("eosio.token::transfer")]] void cryptoship::transfer(name from, name to, const asset &quantity,
                          string memo) {
  print(get_self()); // cryptoship
  print(get_first_receiver()); // eosio.token
}

3.action_wrapper

對於許多用例,需要從合同代碼向另一個合同發送新操作。這是合同之間能夠積極溝通的唯一途徑。再說一次,有很多方法可以做到這一點,但是最優雅的方法之一是使用eosio::action_wrapper。它爲特定智能合約代碼的特定操作創建“操作模板”,然後可使用該模板來調用此操作。

第一個參數是動作名稱,第二個參數是動作的方法_declaration_。

用法

eosio.token標頭在eosio.token.hpp header file中定義了其所有動作的動作包裝/include/eosio.token/eosio.token.hpp):

  [[eosio::action]]
  void create( name   issuer,
              asset  maximum_supply);

  [[eosio::action]]
  void issue( name to, asset quantity, string memo );

  [[eosio::action]]
  void retire( asset quantity, string memo );

  [[eosio::action]]
  void transfer( name    from,
                name    to,
                asset   quantity,
                string  memo );

  // ...

  using create_action = eosio::action_wrapper<"create"_n, &token::create>;
  using issue_action = eosio::action_wrapper<"issue"_n, &token::issue>;
  using retire_action = eosio::action_wrapper<"retire"_n, &token::retire>;
  using transfer_action = eosio::action_wrapper<"transfer"_n, &token::transfer>;
  // ...

現在,我們可以通過包含此頭文件將內聯動作發送到任何eosio.token合同。

要注意的重要一點是,只需要包含帶有聲明的頭文件。這意味着,即使對於實施細節未知的封閉源合同,也可以輕鬆編寫動作包裝。僅需要編寫聲明,即動作簽名,可以從ABI獲得。

使用eosio-cpp-I標誌包含頭文件的附加include目錄。

包含頭文件後,將發送** inline **傳輸操作,如下所示:

#include <eosio_token/include/eosio_token.hpp>

// can specify the contract to send the action to as first argument
token::transfer_action payout("eosio.token"_n, {get_self(), "active"_n});
// transfer arguments are now passed as postional arguments
payout.send(get_self(), to, quantity, memo);

使用to_action方法對延時交易也適用:

token::transfer_action payout("eosio.token"_n, {get_self(), "active"_n});

transaction t{};
t.actions.emplace_back(payout.to_action(get_self(), to, quantity, memo));
t.delay_sec = 10;
t.send(0 /* sender id */, get_self(), false);

4. EOSIO時間類別time_point, time_point_sec, microseconds

EOSIO庫在time.hpp header中定義了兩個日期類。 time_point_sec類是標準的UNIX時間戳,將1970年1月1日以來的秒數存儲在uint32_t中,time_point具有更精確的精度,將經過的微秒(不是毫秒)存儲在uint64_t中。 。 在這兩個類別之間進行轉換很容易。

爲了與時間進行算術運算,人們使用了“微秒”類,該類帶有有用的輔助工具,例如“秒”,“分鐘”或“小時”。

用法

eosio::time_point tp = eosio::current_time_point();
eosio::time_point_sec tps = eosio::current_time_point();
eosio::microseconds micros = tp.time_since_epoch();
uint64_t count_micros = micros.count();
uint32_t count_seconds = tps.sec_since_epoch();

// no more 60*60*24*1e6
const auto MICROSECONDS_IN_DAY = hours(24);
count_micros += MICROSECONDS_IN_DAY;
// no more 60*60*24
count_seconds += hours(24).to_seconds();

eosio::time_point_sec lastGame = /* ... */;
check((eosio::time_point_sec)(current_time_point() + minutes(1)) >= lastGame,
      "last game not finished");

使用microseconds類及其幫助器可以避免使用諸如const auto SECONDS_PER_DAY = 60 * 60 * 24之類的任何常量,從而使代碼更易於推理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章