天天看點

EOS系列 - WASM智能合約 - 特性

構造函數

addressbook(name receiver, name code, datastream<const char*> ds):contract(receiver, code, ds) {}

#單例表(code和scope都用receiver的表)也可在初始化清單中執行個體化
singleton_example( name receiver, name code, datastream<const char*> ds ) :
         contract(receiver, code, ds),
         singleton_instance(receiver, receiver.value)
         {}
           

内置函數

  • 權限檢測函數
    • require_auth(name)

      : 必須具有某權限, 沒有就不會往下執行
    • require_auth2(user.value, "active"_n.value)

      : 指定必須某賬戶的某種權限
    • has_auth(name)

      : 判斷是否具有某權限, 傳回 true | false .

      eosio::check(eosio::has_auth(...), ...)

  • get_self

    : 擷取合約名稱, 合約部署者
  • get_code

    |

    get_first_receiver()

    : 部署此合約的帳戶名稱
  • require_recipient(name)

    : 發出通知, 将action複制到發件人
    • 調用

      require_recipient

      将一個帳戶添加到 require_recipient 集合并確定這些帳戶收到正在執行的action的通知
  • check( is_account( oracleClient ), "Must have a valid oracleClient" )

    : 斷言
  • is_account(name)

    賬号是否存在

EOSIO 名稱類

  • 适用于所有 EOSIO 編碼的名稱(帳戶、操作、表等)
  • uint64_t

    在區塊鍊上編碼為 64 位無符号整數 ( )。
  • 前 12 個字元(如果有)

    base32

    使用以下字元編碼:

    .

    ,

    1-5

    ,

    a-z

  • 第 13 個字元(如果适用)

    base16

    使用以下字元編碼:

    .

    ,

    1-5

    ,

    a-j

例子:

auto eosio_user = eosio::name{user};  //encodes user string to eosio::name object
auto user_str = user_name_obj.to_string(); //decodes eosio::name obj to string
auto standard_account = "standardname"_n;  //encodes literal string to eosio::name
auto non_standard_account = ".standard"_n; //encodes literal string to eosio::name
           

内聯操作

内聯操作在調用者操作的相同範圍和權限内工作, 内聯操作保證在同一個事務中執行

eosio.code

權限

eosio.code

權限是一種僞權限,用于增強安全性,并使合約能夠執行内聯action。

例如: 為了從

addressbook

發送内聯action,請将

eosio.code

權限添加到合約帳戶

addressbook

的active權限中, 否則會報錯

Authorization failure with inline action sent to self

#權重限
cleos set account permission addressbook active --add-code

#删權限
cleos set account permission addressbook active --remove-code
           

内聯action-本合約内

需要

eosio.code

action(
    //permission_level,		一個權限級别結構(需要将`eosio.code`權限添加到合約帳戶的active權限中)
    //code,					要調用的合約,部署合約的帳戶(使用eosio::name類型初始化)
    //action,				action(使用eosio::name類型初始化)
    //data					傳遞給action的資料,與被調用的action相關的位置元組。
).send();

action(
    permission_level{get_self(),"active"_n},
    get_self(),
    "notify"_n,
    std::make_tuple(user, name{user}.to_string() + message)
).send();
           

可通過

./cleos get actions addressbook

指令檢視

内聯action-外部合約

使用

action_wrapper

, 需要

eosio.code

#A合約内聲明
[[eosio::action]] void count(name user, std::string type){
    //可在此限定隻有哪個賬戶/合約才能授權該指令
	require_auth(name("addressbook")); //隻有addressbook合約才能成功執行此操作
	...
}
using count_action = action_wrapper<"count"_n, &abcounter::count>;

#B合約内調用A合約
abcounter::count_action count("abcounter"_n, {get_self(), "active"_n});
count.send(user, type);
           

可通過

cleos get table abcounter abcounter counts --lower alice --limit 1

檢視統計結果

建立自定義權限

介紹權限

EOS系列 - WASM智能合約 - 特性
/*The authority JSON object*/
{
  "threshold"       : 100,    /*An integer that defines cumulative signature weight required for authorization*/
  "keys"            : [],     /*An array made up of individual permissions defined with an EOS PUBLIC KEY*/
  "accounts"        : []      /*An array made up of individual permissions defined with an EOS ACCOUNT*/
}

/*Set Permission with Key*/
{
  "permission" : {
    "key"           : "EOS8X7Mp7apQWtL6T2sfSZzBcQNUqZB7tARFEm9gA9Tn9nbMdsvBB",
    "permission"    : "active"
  },
  weight            : 25      /*Set the weight of a signature from this permission*/
}

/*Set Permission with Account*/
{
  "permission" : {
    "account"       : "sandwich",
    "permission"    : "active"
  },
  weight            : 75      /*Set the weight of a signature from this permission*/
}

//例如
'{"threshold":1,"keys":[{"key":"EOS8X7Mp7apQWtL6T2sfSZzBcQNUqZB7tARFEm9gA9Tn9nbMdsvBB","weight":1}],"accounts":[{"permission":{"actor":"acc2","permission":"active"},"weight":50}]}'
           

給賬戶添加自定義權限

./cleos set account permission alice upsert '{"threshold":1,"keys":[{"key":"EOS63gKbqNRZjboQyfXBJPijZHNr1GtXJu5eCan3e6iSqN7yP5nFZ","weight":1}],"accounts":[]}' owner -p [email protected]
           

将操作action的權限連結到自定義的權限

将調用

upsert

操作的授權與新建立的

upsert

權限關聯起來:

cleos set action permission alice addressbook upsert upsert
           

on_notify

屬性

on_notify

當且僅當從指定的合約和指定的動作發送通知時,使用屬性注釋action可確定任何傳入通知被轉發到帶注釋的action。

callback

類回調回調函數可以采用這種方法

[[eosio::on_notify("VALID_EOSIO_ACCOUNT_NAME::VALID_EOSIO_ACTION_NAME")]]

//例如
[[eosio::on_notify("eosio.token::transfer")]]

[[eosio::on_notify("eosio.token::transfer")]]
void on_token_transfer(name from, name to, assert quantity, std::string memo) {
   // do something on eosio.token contract's transfer action from any account to the account where the contract is deployed.
}

[[eosio::on_notify("*::transfer")]]
void on_any_transfer(name from, name to, assert quantity, std::string memo) {
   // do something on any contract's transfer action from any account to the account where the contract is deployed.
}
           

測試

#轉賬時會觸發
./cleos transfer han hodl '0.0001 SYS' 'Hodl!' -p [email protected]

#觸發後檢視表中資料
./cleos get table hodl han balance
           

單例表

eosio::singleton

eosio::singleton

是 code和scope都用receiver的單例表, 底層還是

eosio::multi_index

#聲明
using singleton_type = eosio::singleton<"testtable"_n, testtable>;
singleton_type singleton_instance;

#在合約的構造函數初始化清單中進行初始化
singleton_example( name receiver, name code, datastream<const char*> ds ) :
         contract(receiver, code, ds),
         singleton_instance(receiver, receiver.value)  // (code, scope)
         {}

#用法
singleton_instance.get_or_create(name, def) //擷取存儲在單例表中的值。如果它不存在,它将使用指定的預設值建立一個新的
singleton_instance.set(value, name)			//為單例表設定新值 (name:為存儲的新值支付的帳戶)
singleton_instance.exists					//檢查單例表是否存在
singleton_instance.get						//擷取存儲在單例表中的值。如果不存在則抛出異常
           

筆記

  • RAM 是 EOSIO 區塊鍊上的持久系統資源,不屬于 Staking 機制的範圍。
  • 選擇不使用 DPoS,則不需要系統資源
  • 智能合約
    • 可以在基于 EOSIO 的區塊鍊上部署無法修改的智能合約
    • 表中有資料時不能修改其資料結構。如果您需要以任何方式更改表的資料結構,首先需要删除其所有行
    • EOSIO 能夠按多達 16 個索引對表進行排序, 二級索引需要是數字字段
    • 可以在B合約内讀取A合約内的表内容
      • producers_table ptable("eosio"_n, name("eosio").value);

  • 建立和連結自定義權限
    • 建立自定義權限時,該權限将始終在父權限下建立。
  • cleos
    • 使用

      -d -j

      訓示“不廣播”和“将交易作為 json 傳回”的選項
      • cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p [email protected] -d -j

    • 檢視token資訊
      • ./cleos get currency balance eosio.token bob SYS

      • ./cleos get currency stats eosio.token SYS

繼續閱讀