技術

SolidityでEthereumスマートコントラクト開発をはじめたときに困ったこと

現在、テックアカデミー(TechAcademy)のスマートコントラクトコースを受講中でして、 Solidity でEthereum(イーサリアム)のスマートコントラクトの開発をやっています。

実際に、開発がはかどるまでに私が遭遇したトラブルや、これはと思ったことをまとめました。

同じ問題にぶつかった人の参考になれれば、幸いです。

トラブルは全て環境周りにあるのですが、一応、環境と言語仕様でパートを分けました。

スマートコントラクトの開発環境の準備で困ったこと

というわけで、まずは環境構築編です。

自分でいうのも何ですが、私はこれまでインフラエンジニアとして長年働いてきたので、環境の構築にはかなり慣れています。いろんなトラブルにも遭遇してきましたので、対応力もそれなりにあります。

その私でも、結構手こずることがあったので、スマートコントラクトの環境構築は難易度が高いと思います。

Gethのコマンド履歴が出てこない問題

現象 Gethのターミナルで、↑↓キー押しても、コマンド履歴が出てこない。
tmuxの編集モードみたいに、カーソルが動く。
原因 不明。Windows版、特有の現象っぽい。
対応 解消しなかった。Linuxを使うことで回避。

まず最初にぶち当たった問題です。

Geth とは、Go Ethereum の略称で、 Ethereum のプログラムの動作環境にあたります。Java でいう JDK のようなものです。まずはこのGethをインストールして環境を構築する必要があります。

Linuxにインストールするのが簡単なのですが、メインPC内でも開発環境を整えたいと思い、Windows にインストールしました。

インストール自体は問題なかったのですが、実際に動かして見るとどうもターミナルの挙動がおかしいです。矢印キーを押しても、コマンドの履歴が出てこないで、カーソルが動きます。カーソルが動いたところで、何ができるというわけではないのですが、、、

最初はそういう仕様かと思ったのですが、どうもそうでないみたいです。Ubuntu にもインストールしてみたら、こちらは通常通りコマンド履歴がでてきました。

どうやらWindows版のみの問題らしいです。ターミナルの問題かと思って、コマンドプロンプトの他、 Git Bash などでも試したのですが変わらずでした。

めんどくさくなったので、ろくに調査もせずに解決を諦めました。自宅のUbuntu は、24時間稼働中で起動の手間などは特にかからないので、Ubuntu を使うことにしました。

外部サーバのGethに接続出来ない問題

現象 AWS Cloud9 に建てた Geth に Mist や Remix から接続できない。
原因 ISP(プロバイダ)によるポート制限
対応 ポートを変更して、Gethを起動

今回、最も意外な原因で解決に時間がかかった問題でした。

Mist で、rpcオプションでAWSサーバを指定しても、Disconnectと出て接続できませんでした。ローカルには接続出来るので、Mistのrpcオプションや、Geth起動時のオプションかと思い、いろいろ調べました。

テックアカデミーのメンターは、同じ環境に接続できるというので、起動コマンドは正しいと仮定して、次は自宅のルータやFWなどいろいろ調べました。それもで原因はわからず。

まさか回線!? と思って、ノートPCでスマフォのSIM経由で接続を試みると、接続出来る! この時点で、プロバイダを疑いました。問い合わせすると、案の上の回答。

上記のポートは、丸の内のNTT局内で弊社の判断で閉じております。

弊社のネットワーク監視と警視庁サイバーポリスの治安情勢などを参考にして、
判断しています。

安定運用とお客様が犯罪に巻き込まれないようにするための措置とお考え下さい。

結局、portを8545から8575に変更することで接続できるようになりました。

Mist同期されない問題

現象 Mist上でデプロイしたトランザクションが処理されない
Remix上でデプロイして、送金などをしてもMist上の残高が更新されない
原因 不明
対応 解消していない。Remix中心で、Mistをほとんど使わなくなった。

Mist 上でコントラクトをデプロイしても、トランザクションが処理されたり、されなかったりします。(マイニングはちゃんと走らせています)

トランザクションが走って送金処理されても、Mist上の各アカウントの残高の表示は変わらない現象が起きています。Geth上で残高確認すると、ちゃんと更新されているので、MistとGethの同期に問題がありそうです。Mistのターミナルをみると、notification系のエラーをはいていました。

Geth上でコマンドで確認すればいいので、それほど困ることはないので、無視していました。

そのうち、Remix がメインになってMistはあまり使わないようになり、より困らなくなりました。というわけで放置、問題は未解消のままです。

Remixがローカルにインストールできない問題

現象 Remixをローカルにインストールしようとしたけど、エラーでインストールできない
原因 不明
対応 諦めた。既存のWebサービスを使うようにした。

RemixはWebサービスがあって、ブラウザとネット環境があれば使えます。ローカルにインストールしたところで、ブラウザベースのIDEであることは変わらないので、使い勝手は変わらないでしょう。

でも実際に業務で使うとなると、外部サービスにソースを置くのはよろしくないので、とりあえずローカルでの使用も体験しとこうと思い、ローカルにある Ubuntu にインストールしようと思いました。

公式 https://github.com/ethereum/remix-ide の README にある通り、コマンドを打っていったのですが、途中でエラーになりインストールできませんでした。

エラー内容は覚えていません。特に詳しく調べもせず、すぐに諦めました。テックアカデミーの講習なのでこだわってもしょうがないと思い、とりえず下記の既存のWebサービスを使うことにしました。

RemixからGethに接続できない問題

現象 Remixで外部Gethに接続しようすると、接続エラー
原因 httpsのRemixを使用していた
対応 httpのRemixを使用するようにして解決

RemixをAWSや自宅のGethに接続しようとすると、下記のエラーが出て接続できませんでした。

Not possible to connect to the Web3 provider. Make sure the provider is running and a connection is open (via IPC or RPC).

またもや接続系のエラーです。ググったっらとりあえず出てくるのは、rpcオプションやrpcdomainオプションが間違っている説ですが、Mistからは接続出来るようになったので原因は違って欲しいと思ってました。そしたら、下記のstackoverflowにありました。

https://stackoverflow.com/questions/48273500/remix-not-possible-to-connect-to-the-web3-provider

Remixはhttpsとhttp版があって、https版だとダメとのこと。

ではなく、

を使うようにしたら接続できました。

Solidityの言語仕様で、まじかと思ったこと

ここからはトラブルではないんですが、Solidityを使ってて、「えっ!?」と思ったことを列挙してみました。

print文やloggerがないんですね

デバッグがわりにconsoleに変数などを出力したいと思ったのですが、print文やloggerはないようです。そういうことをしたい場合は、eventを発生させるっぽいです。

結局、Remixをがっつり使うように成って、変数の状態確認はRemixのGUIでできるので、特に困らなくはなりました。

少数(float)をサポートしていないんですね

Solidityは型宣言言語ですが、少数型(float type)がありません。将来的には固定少数型をサポートするみたいですが、2018年9月現在は使えません。

少数を使いたかったわけではないので、実際に困ったとかはありませんでした。ただ、言語仕様を見てて、えっ!?と思いました。

実際に、使いたくなった場合はどうするんでしょうか? 変数の桁数を変えて回避するぐらいしか思いつきませんが。。。

mappingには、イテレータがないんですね

これは実際に少し困りました。

Solidityは、mappingというkey-value型の変数が使えます。JavaでいうMap、Pythonでいう辞書にあたるものです。それはいいんですが、全要素をループして参照したいということがあったんですが、イテレータや拡張for文は、サポートしていないようです。

結局、インデックス用の変数を用意して回避しました。ちょっとダサいですが、そういうもんだと思うことにします。

乱数生成関数ないんですね

乱数が欲しくなったのですが、Solidityには乱数生成関数がないみたいです。適当な外部の値を参照すれば乱数なんていくらでもできるんですが、スマートコントラクトはその外部参照ができないので、できれば言語側で乱数を用意して欲しいところです。

とりあえずテックアカデミーの課題ではそれほどこだわらなくて良いと勝手に判断して、関数の引数に乱数の元の数値を入れるようにしました。「乱数は呼び出し側で、なんとかせーよ」という思想です。これでいいんだろうか・・・

2018/09/27 追記

これはちょっと恥ずかしい疑問でした。

というのも、Etherreumのコントラクトは、「同じ入力に対して、どのコンピュータで実行されても同じ結果を出力をする」(Deterministic)という決まりがあります。
なので、外部情報の参照や、乱数が生成ができないのは当たり前のことでした。

コーディング環境、実はエディタが一番ですね

Solidityのコーディング環境は、まだまだといったところです。IntellijやVisualStudioと比較するのがいけないのでしょうが。

Remixが定番っぽいですが、やはりブラウザベースだと使いづらいことがあります。(私が慣れていないだけかも知れませんが・・・)

結局、コーディング自体はエディタ(Visual Studio Code)で行い、それをRemixにコピペして、実行やデバッグをしています。


ラーナー
ラーナー
以上、スマートコントラクト開発をはじめてやったときに、私が遭遇したトラブルや疑問でした。参考になれれば、幸いです。

COMMENT

メールアドレスが公開されることはありません。