EOSIO Developer Portal 解説 最短でHello World!

  • 2020.02.04
  • 2020.02.26
  • EOS
EOSIO Developer Portal 解説 最短でHello World!

はじめに


本記事ではEOSのスマートコントラクトの開発環境を構築し、Helloworldコントラクトを作成し、実行する体験を行います。

本記事はUbuntu18.04上で環境構築を行っていきます。

本記事は、過去にコンセンサス・ベイスが主宰していたオンラインサロンの記事です。記事は2017年~2018年にかけて執筆されたため、一部は、既に古くなっている可能性があります。あらかじめご了承ください。

関連する記事

EOSIO Developer Portal 解説 最短でHello World!
EOSIO Developer Portal 解説 独自トークンの発行 第1回
EOSIO Developer Portal 解説 独自トークンの発行 第2回
EOSIO Developer Portal 解説 独自トークンの発行 第3回
EOSIO Developer Portal 解説 データの永続化とインラインアクション 第1回
EOSIO Developer Portal 解説 データの永続化とインラインアクション 第2回
EOSIO Developer Portal 解説 データの永続化とインラインアクション 第3回

EOSとは


EOSとはスケーラブルな分散型アプリケーションプラットフォームです。競合としてイーサリアムが挙げられますが、EOSはイーサリアムにおけるスケーラビリティ問題をイーサリアムとは別の方法で解決しようとしています。

EOSで特徴的なのはDelegated Proof of Stake(DPOS)というコンセンサスアルゴリズムです。

DPOSはネットワーク参加者の投票によってブロック生成者を選び、その選ばれたブロック生成者が実際にブロックを作成していくという仕組みのコンセンサスアルゴリズムです。

PoWとは違い、計算力を必要としないので、ブロックの生成間隔は単なる変数であり、この変数を小さくすることで、秒間に処理できるトランザクションを増やすことができます。(セキュリティ上の問題が指摘される場合もある)

イントロダクション


ここからは、EOS developersの資料に従って進行していきます。
https://developers.eos.io/eosio-home/docs/introduction

この資料から学べるのは以下のことです。

・どのようにしてノードを立ち上げるか?
・ウォレットと秘密鍵の管理
・アカウントの作成
・コントラクトを作る
・コントラクトの編集
・コントラクトのデプロイ

EOSのコントラクトはC++によって書かれるので、若干のC++の知識を要求されますが、本記事のHelloworldに関しては、その知識がなくても理解できると思います。

HelloWorldまでの環境構築

Dockerのインストール


EOSのノードはDocker上で動作するので、まずDockerをインストールします。

$ sudo apt-get update
 
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
 
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
 
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable test edge"
 
$ sudo apt-get update
 
$ sudo apt-get install docker-ce

なお、macOS / WindowsへのDockerインストールは下記の公式サイトから可能です。https://www.docker.com/get-started

ちゃんとインストールされたかどうかを確認します。
$ docker --version

作業ディレクトリの作成


任意のディレクトリに作業ディレクトリを作成します。今後の作業はこのディレクトリ内で行います。

$ mkdir contracts
$ cd contracts

ディレクトリのフルパスを控えておきます。
$ pwd

ノードの立ち上げ


EOSIOのDockerイメージをダウンロードします。
$ docker pull eosio/eos:v1.4.2

dockerに引数を渡してノードを起動します。フルパスと書いている部分は先程の作業ディレクトリのフルパスを入れてください。
$ docker run --name eosio \
>  --publish 7777:7777 \
>  --publish 127.0.0.1:5555:5555 \
>  --volume フルパス:フルパス \
>  --detach \
>  eosio/eos:v1.4.2 \
>  /bin/bash -c \
>  "keosd --http-server-address=0.0.0.0:5555 & exec nodeos -e -p eosio --plugin eosio::producer_plugin --plugin eosio::chain_api_plugin --plugin eosio::history_plugin --plugin eosio::history_api_plugin --plugin eosio::http_plugin -d /mnt/dev/data --config-dir /mnt/dev/config --http-server-address=0.0.0.0:7777 --access-control-allow-origin=* --contracts-console --http-validate-host=false --filter-on='*'"

※例えば「–volume /home/user1/contracts:/home/user1/contracts」と記述すれば、「docker run」の後、docker外で「/home/user1/contracts/」配下にファイルやフォルダを生成すると、dockerコンテナ内にもファイルやフォルダが自動複製される様になります。

無事に起動したかどうかを確かめます。
$ docker logs --tail 10 eosio

次のようなログが出力されれば成功です。
1929001ms thread-0   producer_plugin.cpp:585       block_production_loo ] Produced block 0000366974ce4e2a... #13929 @ 2018-05-23T16:32:09.000 signed by eosio [trxs: 0, lib: 13928, confirmed: 0]
1929502ms thread-0   producer_plugin.cpp:585       block_production_loo ] Produced block 0000366aea085023... #13930 @ 2018-05-23T16:32:09.500 signed by eosio [trxs: 0, lib: 13929, confirmed: 0]
1930002ms thread-0   producer_plugin.cpp:585       block_production_loo ] Produced block 0000366b7f074fdd... #13931 @ 2018-05-23T16:32:10.000 signed by eosio [trxs: 0, lib: 13930, confirmed: 0]
1930501ms thread-0   producer_plugin.cpp:585       block_production_loo ] Produced block 0000366cd8222adb... #13932 @ 2018-05-23T16:32:10.500 signed by eosio [trxs: 0, lib: 13931, confirmed: 0]
1931002ms thread-0   producer_plugin.cpp:585       block_production_loo ] Produced block 0000366d5c1ec38d... #13933 @ 2018-05-23T16:32:11.000 signed by eosio [trxs: 0, lib: 13932, confirmed: 0]
1931501ms thread-0   producer_plugin.cpp:585       block_production_loo ] Produced block 0000366e45c1f235... #13934 @ 2018-05-23T16:32:11.500 signed by eosio [trxs: 0, lib: 13933, confirmed: 0]
1932001ms thread-0   producer_plugin.cpp:585       block_production_loo ] Produced 
block 0000366f98adb324... #13935 @ 2018-05-23T16:32:12.000 signed by eosio [trxs: 

Dockerコンテナ内に入る方法/ウォレットの確認


次のコマンドを入力すれば、dockerコンテナ(eosio)内にbash-shellでログインする事が出来ます。
$ docker exec -it eosio bash



(なお、docker execコマンドでは任意のシェルを指定できますが、EOS公式サイトの手順ではbashが使用されているため、本記事でもそれにならいシェルをbashに指定しています。)

$ docker exec -it eosio bash
#

次のコマンドを入力すると、以下のような結果が出力されます。
# cleos --wallet-url http://127.0.0.1:5555 wallet list
Wallets:
[]

最後に一旦dockerコンテナ(eosio)から出ます。
# exit
$

エイリアスの設定


cleosコマンドは、dockerコンテナ(eosio)内にインストールされているため、dockerの外側からは実行できません。そこでエイリアスを設定し、dockerコンテナ(eosio)内に入らなくてもcleosコマンドが使える様にします。

エイリアス設定の為、vimでbashrcファイルを編集します。

$ vim ~/.bashrc

.bashrcファイルの末尾に以下のコードを追加します。
alias cleos='docker exec -it eosio /opt/eosio/bin/cleos --url http://127.0.0.1:7777 --wallet-url http://127.0.0.1:5555'
 
※Linux(Ubuntu)環境でdocker実行に sudo が必要な場合:
alias cleos='sudo docker exec -it eosio /opt/eosio/bin/cleos --url http://127.0.0.1:7777 --wallet-url http://127.0.0.1:5555'

bashrcの変更を適用します。
$ source ~/.bashrc

うまく設定できていれば、eosioのDockerコンテナに入らなくても、外からcleosコマンドが実行できます。
$ cleos wallet list
Wallets:
[]

CDTのインストール


CDTはEOSのコントラクトの開発環境です。それではCDTをインストールして行きます。
$ wget https://github.com/eosio/eosio.cdt/releases/download/v1.3.2/eosio.cdt-1.3.2.x86_64.deb
$ sudo apt install ./eosio.cdt-1.3.2.x86_64.deb

※macOSをお使いの場合は、Homebrewを使ってインストールできます。
$ brew tap eosio/eosio.cdt
$ brew install https://raw.githubusercontent.com/EOSIO/homebrew-eosio.cdt/50f00447765854f6e4e3b2d4ef36324cc38e5362/eosio.cdt.rb

その他のOSでのインストール方法は下記のページをご覧ください。

EOS Developers – Install the CDT

今回はこのeosio.cdtのうち、C++で記述されたソースをコンパイルするためのeosio-cppを主に使用します。下記コマンドでcdtが正常にインストールされたか確認しましょう。
$ eosio-cpp --version
eosio-cpp version 1.3.2

このように、eosio-cppのバージョンが表示されれば成功です。

開発用ウォレットの作成


次のコマンドを入力します。
$ cleos wallet create --to-console

次のようなメッセージが出れば成功です。一番下の行の文字列がウォレットのパスワードなので、控えておきます。
Creating wallet: default
Save password to use in the future to unlock this wallet.
Without password imported keys will not be retrievable.
"PW5Kewn9L76X8Fpd....................t42S9XCw2"

次にウォレットを開きます。
$ cleos wallet open

次のようなメッセージが出れば成功です。
Opened: default

ウォレットのリストを確認します。
$ cleos wallet list

次のようなメッセージが出れば成功です。
Wallets:
[
  "default"
]

次にウォレットをアンロックします。次のコマンドを入力したあと、先程控えておいたパスワードを入力します。
$ cleos wallet unlock
password: 

次にまたウォレットのリストを確認してみます。
$ cleos wallet list


ウォレットの表示が少し変わっていることがわかります。
Wallets:
[
  "default *"
]

次に公開鍵をウォレットから取得します。
$ cleos wallet create_key

次のようなメッセージが出れば成功です。公開鍵が表示されるので、控えておきます。
Created new private key with a public key of: "EOS8PEJ5FM42xLpHK...X6PymQu97KrGDJQY5Y"

次に開発者キーをウォレットに取り込みます。
$ cleos wallet import
private Key: 

開発者キーを入力するように要求されます。
ドキュメント上で公開されている開発者キーは

5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3

なのでこれを入力します。

次のようなメッセージが出れば成功です。

private key: imported private key for: EOS6MRy…..ET5GDW5CV

※なお、本番環境ではこの開発者キーは絶対に使用しないようご注意ください。アカウントへのアクセスを失うなど重大な事態に陥る危険性があります。

テスト用アカウントの作成


テスト用にbobとaliceの2つのアカウントを作成します。以下のコマンドを入力します。

(Googleドキュメントの表示の都合で改行しているように見えることがありますが、$ 以下のコマンドはそれぞれ一行で入力、実行してください)

$ cleos create account eosio bob YOUR_PUBLIC_KEY
 
$ cleos create account eosio alice YOUR_PUBLIC_KEY

*YOUR_PUBLIC_KEY の部分には$cleos wallet create_key コマンドで生成した公開鍵を入力してください。

次のようなメッセージが出れば成功です。
executed transaction: 40c605006de...  200 bytes  153 us
#         eosio <= eosio::newaccount            {"creator":"eosio","name":"alice","owner":{"threshold":1,"keys":[{"key":"EOS5rti4LTL53xptjgQBXv9HxyU...
warning: transaction executed locally, but may not be confirmed by the network yet    ]

Hello World!


EOSの最小構成のコントラクトを実行していきます。まずcontractsディレクトリ以下にhelloディレクトリを作成します。そしてコントラクトのファイルを作成します。
$ mkdir hello
$ cd hello
$ touch hello.cpp

次にhello.cppをお好みのエディタで開いて次のソースコードを入力します。
#include 
#include 
 
using namespace eosio;
 
class hello : public contract
{
 public:
   using contract::contract;
 
   [[eosio::action]] void hi(name user) {
       require_auth(user);
       print("Hello, ", name{user});
   }
};
EOSIO_DISPATCH(hello, (hi))

次にこのコードをコンパイルします。
$ eosio-cpp -o hello.wasm hello.cpp --abigen

コンパイルに成功すると、.abi, .wasmという拡張子のファイルが新たに生成されます。

下記コマンドで確認してみましょう。
$ ls -l
hello.abi
hello.cpp
hello.wasm

次にコントラクト実行用のアカウントを作成します。公開鍵の部分には先程控えておいた公開鍵を入力します。
$ cleos create account eosio hello 公開鍵 -p eosio@active

次にコントラクトをブロックチェーン上に公開します。contractsのフルパスには、作業領域のフルパスを入力します。
$ cleos set contract hello contractsのフルパス/hello -p hello@active

それでは、コントラクトの動作確認を行っていきましょう。
$ cleos push action hello hi '["bob"]' -p bob@active
executed transaction: e0a031671e9f14ac7e4540bc12a62d2673784afd8df9710dfb61d2733ee513c8 104 bytes  982 us
#         hello <= hello::hi                    {"user":"bob"}
>> Hello, bob
warn  2018-11-11T02:37:45.942 thread-0  main.cpp:482                  print_resultwarning: transaction executed locally, but may not be confirmed by the network yet
 
$ cleos push action hello hi '["bob"]' -p alice@active
Error 3090004: Missing required authority
Ensure that you have the related authority inside your transaction!;
If you are currently using 'cleos push action' command, try to add the relevant authority using -p option.


ここでは、正常ケース
cleos push action hello hi '["bob"]' -p bob@active

と、異常ケース
cleos push action hello hi '[bob"]' -p alice@active

の2つのパラメータでコントラクトを実行しました。このコントラクトの内容について次のセクションで解説します。

HelloWorld!の解説

#include 
#include 
 
using namespace eosio;
 
class hello : public contract
{
 public:
   using contract::contract;
 
   [[eosio::action]] void hi(name user) {
       require_auth(user);
       print("Hello, ", name{user});
   }
};
EOSIO_DISPATCH(hello, (hi))

このコントラクトのコードは、コントラクト実行時に引数を一つ取り、その引数の値が、そのアカウントのユーザ名と同じなら「Hello  ユーザ名」と返すコントラクトです。

ですから、次のコントラクトを実行するとHelloが帰ってきて、
$ cleos push action hello hi '["bob"]' -p bob@active
executed transaction: e0a031671e9f14ac7e4540bc12a62d2673784afd8df9710dfb61d2733ee513c8 104 bytes  982 us
#         hello <= hello::hi                    {"user":"bob"}
>> Hello, bob
warn  2018-11-11T02:37:45.942 thread-0  main.cpp:482                  print_resultwarning: transaction executed locally, but may not be confirmed by the network yet

次のコントラクトを実行するとエラーが帰ってきます。
$ cleos push action hello hi '["bob"]' -p alice@active
Error 3090004: Missing required authority
Ensure that you have the related authority inside your transaction!;
If you are currently using 'cleos push action' command, try to add the relevant authority using -p option.

まとめ


今回は公式のドキュメントをもとに簡単なEOSのコントラクトを体験しました。

また、HelloWorldコントラクトを実行する際に、手数料の支払いやトークンのやり取り等を行っていないことがわかったかと思います。EOSの手数料が無料と言われているのはこういうところから来ているのではないでしょうか。

     

免責事項

本記事に掲載されている記事の内容につきましては、正しい情報を提供することに務めてはおりますが、提供している記事の内容及び参考資料からいかなる損失や損害などの被害が発生したとしても、弊社では責任を負いかねます。実施される際には、法律事務所にご相談ください。

技術・サービス・実装方法等のレビュー、その他解説・分析・意見につきましてはblock-chani.jp運営者の個人的見解です。正確性・正当性を保証するものではありません。本記事掲載の記事内容のご利用は読者様個人の判断により自己責任でお願いいたします。

     

コンセンサス・ベイス(株)とブロックチェーン事業を行なってみませんか?

当サイトを運営するコンセンサス・ベイス株式会社は、2015年設立の国内で最も古いブロックチェーン専門企業です。これまでに、大手企業の顧客を中心に、日本トップクラスのブロックチェーンの開発・コンサルティング実績があります。

ブロックチェーンに関わるビジネスコンサル・システム開発・教育・講演などご希望でしたら、お気軽にお問い合わせください。

     
     

ブロックチェーン学習に最適の書籍の紹介

図解即戦力 ブロックチェーンのしくみと開発がこれ1冊でしっかりわかる教科書

ブロックチェーン イーサリアムへの入り口 第二版 (ブロックチェーン技術書籍)

本書は、ブロックチェーン技術に興味を持ったエンジニアや、その仕組みを学び、自分の仕事に活かしたいビジネスパーソンを対象にして、ブロックチェーンのコア技術とネットワーク維持の仕組みを平易な言葉で解説しています。この本を読んだうえで、実際にコードを書くような専門書、ブロックチェーンビジネスの解説書を読むことで、理解度が飛躍的に高まるでしょう。(はじめにより)

EOSカテゴリの最新記事