構造函數
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)
-
: 判斷是否具有某權限, 傳回 true | false .has_auth(name)
eosio::check(eosio::has_auth(...), ...)
-
-
: 擷取合約名稱, 合約部署者get_self
-
|get_code
: 部署此合約的帳戶名稱get_first_receiver()
-
: 發出通知, 将action複制到發件人require_recipient(name)
- 調用
将一個帳戶添加到 require_recipient 集合并確定這些帳戶收到正在執行的action的通知require_recipient
- 調用
-
: 斷言check( is_account( oracleClient ), "Must have a valid oracleClient" )
-
賬号是否存在is_account(name)
EOSIO 名稱類
- 适用于所有 EOSIO 編碼的名稱(帳戶、操作、表等)
-
在區塊鍊上編碼為 64 位無符号整數 ( )。uint64_t
- 前 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
該
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
檢視統計結果
建立自定義權限
介紹權限
/*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
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
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
- 使用
訓示“不廣播”和“将交易作為 json 傳回”的選項-d -j
-
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
-
- 使用