EOS智能合約開發及授權

環境描述:

閱讀本文前,假定您已經能夠啟動單節點EOSIO node,如果還不能正確操作,請參考官方WIKI:https://developers.eos.io/eosio-nodeos/docs/autobuild-script

操作系統:MAC OS 10.13.X,EOSIO版本號:V1.1.3

自定義合約開發與測試,在單節點操作,流程更簡單,效果相同,因此以下操作流程都是在沒有部署eosio.system合約的環境中進行。

操作步驟:

1.啟動EOS環境,創建兩組key

啟動NODE:

nodeos --data-dir tmpdata -e -p eosio --plugin eosio::wallet_api_plugin --plugin eosio::chain_api_plugin--plugin eosio::history_api_plugin --max-transaction-time=1000(避免超時設置1000)

創建KEY:

cleos create key

2.使用創建的public_key,創建eosio.token用戶,創建部署合約賬戶cactus,轉賬賬戶from:

create account eosio eosio.token EOS6JowfuTT7CZe4ResHqNvEWAnuYjCT68gw97KxsHY99sUk2t1j8 EOS6JowfuTT7CZe4ResHqNvEWAnuYjCT68gw97KxsHY99sUk2t1j8

create account eosio cactus EOS6JowfuTT7CZe4ResHqNvEWAnuYjCT68gw97KxsHY99sUk2t1j8 EOS6JowfuTT7CZe4ResHqNvEWAnuYjCT68gw97KxsHY99sUk2t1j8

create account eosio from EOS6JowfuTT7CZe4ResHqNvEWAnuYjCT68gw97KxsHY99sUk2t1j8 EOS6JowfuTT7CZe4ResHqNvEWAnuYjCT68gw97KxsHY99sUk2t1j8

2.1解鎖錢包:

cleos wallet unlock --password PW5JCM32pkoqwfNwfMnLih8Gh5s5edbQyys6vP3Ci9NxL2x6EKecq

2.2導入私鑰:

導入用戶private_key:

cleos wallet import --private-key 5JC3dp6z2imXiAnq4M4JAQXetRntU23QLoFNZJxwBB1yxPVsSW3

導入eosio的private_key:

cleos wallet import --private-key 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3

3.發布eosio.token合約到eosio.token

3.1cd到eosio目錄/build/programs/cleos

cleos set contract eosio.token ../../contracts/eosio.token

3.2創建代幣:

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

3.3發行代幣

cleos push action eosio.token issue '["eosio","1000000000.0000 SYS","issue"]' -p eosio

至此,基礎工作完畢,可以先把node節點停掉,開始編寫自定義轉賬合約。


4.創建自定義轉賬合約cactus.token.cpp

打開源碼目錄contracts,新建目錄cactus.token,創建源碼文件cactus.token.cpp,此合約使用了inline_action的方式調用eosio.token合約的transfer函數,inline action具體來說就是一個智能合約的代碼調用另外一個智能合約的函數。action(xx).send(),具體參數的含義是:Action(permssion_level, other_contract_account_name, method, args)

action(permission_level{from, N(active)}, 
             N(eosio.token), N(transfer), 
             std::make_tuple(from, to,quantity,std::string("cactus transfer"))).send();

此處,合約調用eosio.token transfer方法從from的賬戶轉賬,因此必須獲得用戶from的active權限,否則不能操作,具體授權在8處詳述。

注意:目錄名稱與主文件名稱相同,部署合約時使用目錄名進行部署

namespace cactus {
    class msig : public eosio::contract {
    public:
        using contract::contract;
        msig(account_name self)
                : eosio::contract(self), mtranses(_self, _self), wits(_self, _self),cts(_self, _self) {}
        //@abi action
        void transfer(account_name from, account_name to, asset quantity) {
            auto quant_after_fee = quantity;
            eosio_assert(is_account(from), "to account does not exist");
            eosio_assert(quantity.is_valid(), "invalid quantity");
            eosio_assert(quantity.amount > 0, "must withdraw positive quantity");
            require_auth(from);
            action(
                    permission_level{from, N(active)},
                    N(eosio.token), N(transfer),
                    std::make_tuple(from, _self, quantity, std::string("cactus transfer"))
            ).send();
            cts.emplace(_self, [&](auto &a) {
                a.id = cts.available_primary_key();
                a.from = from;
                a.to = to;
                a.amount = quantity.amount;
            });
        }

5.根據cactus.token.cpp生成cactus.token.wast及cactus.token.wasm,cactus.token.abi文件

cd 到eosio主目錄/contracts/cactus.token/

生成cactus.token.wast、cactus.token.wasm文件,虛擬機加載使用

eosiocpp -o cactus.token.wast cactus.token.cpp

生成cactus.token.abi文件

eosiocpp -g cactus.token.abi cactus.token.cpp

執行此命令將文件夾cactus.token copy到build/contracts/

cp -R ../cactus.token ../../build/contracts/

6.重新啟動node節點:

nodeos --data-dir tmpdata -e -p eosio --plugin eosio::wallet_api_plugin --plugin eosio::chain_api_plugin--plugin eosio::history_api_plugin --max-transaction-time=1000(避免超時設置1000)

7.部署合約

部署自定義合約到賬戶cactus,此時終端cd eosio主目錄/build/contracts :

cleos set contract cactus cactus.token

可以看到輸出內容如下圖所示

contracts.jpg

8.授權
8.1 eosio.code內部權限
dawn4.0后新增的內部特殊權限eosio.code,用來加強inline action的安全性,當cactus.token智能合約代碼通過action.send調用eosio.token智能合約時,cactus.token代碼是拿不到任何私鑰的,也就沒法為聲明的權限簽名,即沒辦法證明該智能合約具備action聲明的權限from@active。此時系統代碼做安全性保障,因而系統提出了一個虛擬權限eosio.code。具體邏輯執行時,權限檢驗邏輯(controller.authorization_manager) ,cactus.transfer已經具備cactus@eosio.code權限。然后authorization_manager只需檢驗from@active是否授權給cactus@eosio.code即可。通過這種虛擬的權限證明解決了合約調用合約的權限檢測問題。

如圖標紅處,校驗合約部署賬戶的eosio.code權限,以避免inline action調用時出現安全問題。

contracts.jpg

8.2合約賬戶授權

智能合約cactus.token要調用eosio.token合約中transfer,將from的代幣轉出,必須得到from的授權,但是合約執行又需要使用合約部署賬戶的eosio.code權限才能操作,因此必須把from@active權限賦予cactus@eosio.code才能執行;

cleos set account permission from active '{"threshold" : 1, "keys" : [{"key":"EOS5CoAP5TqEzvzVjdhCfDrhffZ7JdpN7dnxgEqjAoVd2n4vRa5Zb","weight":1}], "accounts" : [{"permission":{"actor":"cactus","permission":"eosio.code"},"weight":1}]}' owner -p from@owner

執行結果:

contracts.jpg

8.3查看A的權限信息:

cleos get account from

執行結果如圖所示

contracts.jpg

9.使用合約進行轉賬

cleos push action cactus transfer '["from","cactus","10.0000 SYS"]' -p from

操作結果:


contracts.jpg

至此,自定義合約轉賬的編碼和授權操作結束。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容