十分鍾教你開發EOS智能合約


這是一篇轉載的文章,文章是在一個公眾號上看到的,文章地址為https://mp.weixin.qq.com/s/OniYBJ6zbjxPrQYlZMhRWQ

EOS環境搭建和啟動節點

下面從EOS入門的環境搭建、編譯運行一個智能合約、發送一些Aigsen,給大家做一些展示,希望能讓非技術人員也有一些收獲。

首先下載EOS環境搭建和啟動節點。這一步其實還是比較簡單的,但是對於非技術人員,最大的障礙就是,現在用EOS,不管是在MacOS還是Linux,基本都是在命令行下操作,這一點和以太坊還是不太一樣。因為以太坊有一個瀏覽器插件,可以用一些圖形化的IDE去操作,這樣對非技術人員或者前端人員,可能他不太熟悉這個命令行命令的人都是比較友好的。

EOS環境的搭建和節點啟動分為以下兩步:

第一步:用Git克隆,下載EOS的源代碼

使用命令:

git clonehttps://github.com/EOSIO/eos --recursive 
  • 1

下載源代碼,時間會比較長,大概1-3小時,另外,下載編譯對計算機內存要求最少要有8GB。

下載編譯之后,里面有三個應用程序,這三個應用程序也都是命令行的:

1、Cleos;

2、Nodeos;

3、Keosd。

這三個應用程序之間有什么關系呢?我們現在使用的前端,怎么使用EOS呢?

-Cleos,它是一個命令行程序。在前端使用EOS是通過Cleos輸入命令,給EOS下達指令。

-Nodeos,其實它就是挖礦客戶端。在啟動Nodeos之后,它自然就會產生區塊。

-Keosd,它是在后端啟動。它的目的主要是管理錢包,可以創建私鑰。

為什么分成Nodeos和Keosd?

我理解的是,Keosd可以認為是個輕客戶端,因為有時候只需要進行錢包操作,不需要挖礦,就可以啟動Keosd。

第二步:節點啟動

在第一步下載編譯都做完之后,就可以啟動一個節點開始愉快的挖礦了!下面是啟動節點的命令:

cd build/programs/nodeos 
./nodeos -e -p eosio –plugin eosio::wallet_api_plugin –plugineosio::chain_api_plugin –plugin eosio::account_history_api_plugin

整個EOS是插件式結構,需要有一個主程序,其它像錢包管理、區塊鏈等都是一個插件。

輸入上邊命令后啟動了一個節點,同時啟動了一些插件,會打印一些基本信息,以及挖礦的信息。

EOS創建和管理錢包

節點啟動后我們要做的第一件事兒是什么呢?就是我們首先要有賬號,但是有賬號的前提是什么呢?倒不是先創建賬號,而是先要有自己的一組私鑰,有了私鑰才能有賬號,有賬號的前提還是要有錢包。所以,最開始我們是創建錢包,錢包是用來管理我們的密鑰的。

第一步:創建錢包

使用命令:Cleos wallet create,就可以創建一個錢包。像以太坊、比特幣這些已經比較成熟了,使用一些客戶端可以去創建錢包。

如果你想用不同的參數,可以在命令后邊加上-N,-N指定你的錢包名稱是另外一個錢包名稱,可以創建不同的錢包,然后每個錢包都可以管理一組密鑰。

第二步:創建一組秘鑰

創建好錢包,就可以創建一組密鑰,創建命令為:

cleos create key
  • 1

第三步:秘鑰導入錢包

在第二步創建的密鑰,只是生成一組公鑰、私鑰,還需要把公鑰、私鑰導入錢包,才能讓錢包把公鑰和秘鑰管理起來。

導入命令為:

cleos wallet import
  • 1

可以在命令后面指定錢包,這樣就可以把第二步創建的一組公鑰、私鑰直接導入指定的錢包。

第四步:查看錢包中的秘鑰

使用以下命令就可以查看是不是成功的把秘鑰導入錢包了:

cleos wallet keys
  • 1

我覺得不太懂技術的非技術人員,可能以后也要懂技術,因為你最后玩比特幣,也會了解什么是私鑰、什么是公鑰、什么是256位的二進制賬號。大家剛開始可能學起來比較痛苦,可能也要逐漸有個習慣的過程。

這樣就都做完了,我創建了一組密鑰,密鑰包括公鑰和私鑰,然后我把這組公鑰又放到剛才我創建的錢包里面了。

創建好錢包、密鑰之后,接下來我們可以做什么事兒呢?

EOS創建和管理賬號

創建好錢包、密鑰之后,接下來你就可以創建賬號了,賬號是什么?賬號保存在區塊鏈上的人類可讀的標志符。

創建賬號的命令:

$ cleos createaccount eosio ${new_account} ${owner_key} ${active_key}
  • 1

其中eosio是超級用戶,需要靠超級用戶來創建其它的新用戶,eosio后面就是你的新用戶的用戶名。

除了新的賬號之外,命令后面還有兩個key:

1、Owner key

2、Active key

Owner key是什么意思呢?Owner key表示分配給新賬號的一個Owner認證的公鑰。Active key是分配給新賬號一個Active認證的一個公鑰。

至於這兩個認證,我后面會給詳細介紹,這是兩個主要的權限。我創建一個賬號,如果這個賬號要有Owner的權限和Active的權限,就必須要用這兩個key才能實現。

我們來總結一下剛才的操作,我們剛才操作是調用Cleoscreate account創建了一個賬號,這個賬號的命名規則遵守下邊兩個規則:

1、小於13個字符;

2、僅包含這些字符:.12345abcdefghijklmnopqrstuvwxyz

另外,剛才給大家說到Owner key和Active key的概念。Owner key的概念就是你賬號的所有控制權限,你只要有了Owner key,你可以對這個賬號的任何東西做任何的事兒,這是它的所有控制權。

而Active key只掌握了你的賬號資金的訪問權限,也就是你如果有了Active這個權限的話,你可以對這個賬號的資金進行轉移,但是你不能轉移這個賬號的所有權,或者不能做超過這個Active權限其它的權利。

如果簡單的理解,Owner key就是對這個賬號的最高權限,Active只是用來轉移資金而已。這也是與以太坊智能合約開發的一個區別,以太坊賬號的權限其實沒有這么細分,它就只有一個賬號,我只要有這個賬號的公鑰和私鑰,我就可以做任何事情。

EOS的權限和許可

對於EOS的權限和許可,分得非常細。

「Permission」我沒有翻譯成權限,我這里覺得它更像一種叫做「許可」,它是一個操作允許的權限,可以建立很多permission。比如允許你轉賬,允許你發微博或者允許你做其他事。它是通過permission來控制你的操作,可能不同的用戶有不同的permission。

Threshold是某個許可需要的閾值。比如你要做一件事兒,它可能有個閾值,這個閾值是一個量化,你必須要達到這個閾值才可以進行相應的操作。

Weight表示權重。賬號必須對應某個許可擁有的權重,就是你的權重要大於你的閾值,然后這件事兒你就可以做。

在permission許可里面有兩種許可:

-owner許可;

-active許可。

這兩個叫native(原生)的permission,另外還有public的permission。

下面通過兩個例子來解釋他們之間的關系與區別:

permission account weight weight
owner     1
  EOS61chK8GbH4ukWcbom8HgK95AeUfP8MBPn7XRq8FeMBYYTgwmcX 1  
active     1
  EOS61chK8GbH4ukWcbom8HgK95AeUfP8MBPn7XRq8FeMBYYTgwmcX 1  

第一個例子, owner許可的閾值是1,它里面有一個賬號,這個賬號是用它的公鑰來代表的,然后這個賬號的權重是1,這樣你的權重是大於等於閾值的,所以可以用owner的賬號和權限。

active許可里面有一個賬號,它的權重也是等於這個閾值,所以可以用active的賬號和權限。

這兩個賬號,一個是有owner權限,一個是有active權限,因為它們的權重和閾值是大於等於這個值的,對應的賬號與權限都是可以使用的。

permission account weight threshold
owner     2
  @bob 1  
  @stracy 1  
active     2
  @bob 1  
  @stracy 1  
publish     2
  @bob 2  
  @stracy 2  

第二個例子,除了owner的permission之外,你還可以有一個publish permission。它們之間有什么區別呢?

當你創建任何一個賬號,這個賬號都有owner的許可和active的許可。其他的許可就是你可以自己定義,來讓不同的用戶,擁有不同的許可組合,這樣就可以很靈活的去管理不同的賬號。

所以這一點,EOS考慮的比較比較細致一點,但是以太坊或者比特幣沒有做到這么細致,以太坊或者比特幣擁有一個賬號就可以做任何事情。

這里面再細一點來講,這里面的owner的閾值是R,bob賬號的權重只有1,stracy賬號的權重也只有1,如果它倆單獨的去獲得owner許可相關的操作,它們是獲得不了的。但是,如果bob和stracy加起來大於等於2,就是這兩個賬號聯合起來大於等於2的,這兩個賬號就可以做這個操作的,其實這有點像投票。

我覺得這個權限或許可的限制,和我們傳統的操作系統是不太一樣的。我們傳統的操作系統好像沒有這種聯合簽名可以達到兩個權重來執行owner的相關操作。

active這也是一樣的,如果bob賬號是1,stracy賬號是1,如果active需要的閾值是1的話, bob賬號和stracy賬號是單獨都可以做active許可相關的操作,就是轉移資金。

另外,publish就是一個定制化許可。我們每個用戶也可以定義自己某些允許的一些操作。publish這里面的閾值是2,bob賬號是2,stracy賬號是2,這兩個賬號也可以單獨做publish許可相關的操作。而publish的權限可能是比如發布一些消息、發布一些微博的操作。

通過以上兩個例子,給大家展示了EOS對權限設置的設計有多細致。

EOS智能合約

EOS的智能合約里面有一個action(動作)和transaction(交易)的概念。

對於我們以太坊開發者來說,基本上只有transaction的概念。如果我只要執行一種操作,而且是只讀操作,就不需要簽名。如果需要划資金,有一些寫的操作,那就需要用戶用公鑰對這個操作去簽名,然后pos的一個transaction,這是以太坊的概念。

對於EOS,它多了一個action的概念,action其實它也是對一個智能合約中的某個函數的調用。transaction是由一個或者多個action組合而成的關系,就是在一個transaction里,可以包含多個action,這樣你可以在一個transaction里簽一次名,就可以調多個函數,做一組操作。

部署智能合約

部署智能合約的示例代碼如下:

$ cleos set contract eosio build/contracts/eosio.bios -p eosio
  • 1

其中,eosio是要部署的賬號,就是你用哪個賬號去部署智能合約;

build/contracts/eosio.bios表示的是路徑;

eos.bios是生成一個智能合約的目錄。

運行Token合約

第一步,Token智能合約部署,代碼如下:

cleos set contracteosio.token build/contracts/eosio.token -p eosio.token
  • 1

第二步,調用create函數,代碼如下:

$ cleos push actioneosio.token create ‘[ “eosio”, “1000000000.0000 EOS”, 0, 0, 0]’ -p eosio.token
  • 1

調用create函數,設定到幣的最大數目,開始創建我的token。

怎么調用一個action呢?我們都是通過cloes命令行調用action,不過后面跟的參數不一樣。push action,這兩個都是固定的,后面是合約的名稱。

eosio是賬號名,后面數字表示設定token總量是10億,幣的名稱是EOS幣,后面有3個0,代表的是三個參數:can freeze、can recall、can whitelist。這3個參數設置為0,一共傳了5個參數,通過這樣的方法,去調用整個的合約create的函數。

第三步,轉移100個pdj幣到user用戶,代碼如下:

$cleos push actioneosio.token issue '[ "user", "100.0000 EOS","memo" ]' -p eosio
  • 1

Issue這個操作是用來發幣,它后面跟了3個參數:

一個是user,表示這個幣發給誰;

數字表示要給這個用戶轉多少錢,我這里轉了100多個user的token;

最后一個參數是是一個備注,相當於轉賬留言。

第四步、從user用戶轉移25個PDJ幣給tester用戶,代碼如下:

$cleos push actioneosio.token transfer '[ "user", "tester", "25.0000EOS", "m" ]' -p user
  • 1

這是一個轉賬合約的運行過程,先部署合約,然后調用create,可以轉賬,既可以轉到user,也可以從一個user用戶轉到test用戶,整個過程在user wiki文檔上也寫得比較清楚的。

調試智能合約

現在user官方網站推薦的一個調試方法就是print,把信息打印出來。這個必須要我們搭建本地節點,因為如果沒有本地節點,相當於你print打印在別人的節點上,你根本看不到這個打印信息是什么,所以說你必須要搭建一個本地節點。搭建本地節點后,你運行智能合約,就會看到print出來的輸出結果。

EOS智能合約的RPC接口

其實智能合約整個只完成了DApp最核心的一部分,就是基本上和資金有關系的一些關鍵操作,其實大部分的接口、界面,還得我們用JavaScript、HTML去做。

那我們這些DApp其它寫界面的操作,怎么去調用智能合約呢?都是通過user智能合約RPC接口調用,智能合約的RPC接口文檔鏈接是:https://eosio.github.io/eos/group__eosiorpc.htm

RPC的接口我們除了用C++或者用編程的方法去調用一些接口,我們可以用curl這種最簡單的方法去調用這個接口。curl它相當於模擬了一個瀏覽器的操作,我可以向我的運行節點的RPC端口發消息。

這里面我可以給大家展示,我列了3個。

1.get_info:獲得節點信息。

通過調用這個接口,它會返回我運行節點,比如說server version,就是我運行節點這個節點的版本號;head blocknum,是我當前挖到哪個塊了。 
用法:

curl http://127.0.0.1:8888/v1/chain/get_info
  • 1

2.get_block:獲得一個塊的信息。

調用該接口,指定塊號(blocknum),就可以獲得指定塊的詳細信息。

用法:

$ curl http://127.0.0.1:8888/v1/chain/get_block -X POST -d'{"block_num_or_id":5}'
  • 1

3.get_account:獲得某個賬號的信息。

調用這個接口,可以獲得當前我的一個賬號信息

用法:

$ curlhttp://127.0.0.1:8888/v1/chain/get_account -X POST -d'{"account_name":"inita"}'
  • 1
EOS智能合約編程示例:HelloPDJ

下面有一個編程示例,給大家展示一下我怎么樣寫智能合約的。它這個智能合約可以用C語言(一種計算機程序語言)來寫,也可以用C++(一種計算機程序語言)來寫,這里面我就用C++來寫。示例代碼如下:

// hello.cpp源代碼 #include<eosiolib/eosio.hpp> #include <eosiolib/print.hpp> using namespace eosio; class hello : public eosio::contract { public: using contract::contract; /// @abi action void hi( account_name user ) {print( “Hello, ”, name{user} ); } }; EOSIO_ABI( hello, (hi) )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

如果我自己寫了一個智能合約,怎么去編譯和部署呢?編譯的步驟大概是這樣的:

第一步,編譯hello文件

$ eosiocpp -o hello.wasthello.cpp $ eosiocpp -g hello.abihello.cpp
  • 1
  • 2

第二步,創建賬號

$cleos create account eosio hello.codeEOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 ...
  • 1

第三步,部署合約

cleos set contract hello.code../hello -p hello.code
  • 1

第四步,調用合約

cleos push action hello.codehi '["user"]' -p user
  • 1

關於開發的一些感受

最后,我想談談我個人開發EOS智能合約的一些感受,在開發EOS智能合約整個使用和編譯比較流暢,基本沒有碰到問題,感覺系統還是比較穩定可靠的。但是,編寫復雜一點的智能合約感覺無從下手,文檔還是偏少,有些無關大雅的小錯誤。此外,我認為使用C++寫智能合約門檻有點高,不知道未來的走勢如何?


免責聲明!

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



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