FC2ブログ

Solidity環境の準備で手こずっている話

どうも、ぺろりんです。

前回のつづきとして、「はじめてのブロックチェーン・アプリケーション Ethereumによるスマートコントラクト開発入門」3章に入ってスマートコントラクトの開発環境として「Solidity」という言語の環境を整えようとしているんですが、案の定(笑)なかなか上手くいかず詰まりました。

さしあたっての妥協案として「Browser-Solidityをオンラインで使う」という方法が一応は上手くいきそうになってきたので、またすぐ詰まりそうだという不安は置いておいて、環境としてはしばらくこの方向で進んで行きたいかと思います。
ダメそうだったらまた考えますw

というわけで今回は、まずどんな感じで詰まっていたかという話と、「Browser-Solidityをオンラインで使う」やり方をここにまとめておきます。
Solidityの使い方に関しては、たぶんよくご存知の方からするとそれじゃダメだろってとこがあるのではと思っているので、そういう感想の方はぜひともメールフォームからご連絡いただけると非常に助かります。。


上手くいかないところ

理解が浅すぎてだいぶ色々問題が起こっていますw
棚卸ししてみるとだいたいこんな感じです。

コンパイルできない話

まず初めにやったのが、前回まで使っていたVM(仮想マシン)の環境で、いつもの教科書通りにSolidityのコンパイラをインストールしました。

で、本にある「Gethにsolcのパスをセット」するところまでは上手くいきました。

しかし、この次のコンパイルするところが上手くいかない。。
> sourceCompiled = eth.compile.solidity(source)


メモり損ねて記憶があいまいですが、たしか参考に挙げたリンク先にある以下のエラーが出てた気がします。
Error: The method eth_getCompilers does not exist/is not available
at web3.js:3104:20
at web3.js:6191:15
at web3.js:5004:36
at :1:1


教科書の注意書きで、Gethのバージョンが1.6以降はコンパイルが上手くいかないと書いているのですが、この本ではGethをインストールするときにv1.5.5にバージョンを切り替えていて、この通りにやっているのでコンパイルも上手くいくかと思っていたのですが、ちょっとよくわからない。

これだと上手くいきそうにないのと、教科書の先を見るとBrowser-Solidityを使っていたので、Browser-Solidityが出てくるあたりまでスキップしてこの環境を整えることにしました。

(参考)
go-ethereum(geth)でSolidityのコンパイルが出来ない場合(Qiita)


Browser-Solidityをローカルで上手く使えない話

さて、ここでも教科書べったりでやってみたのですが、まずはVM環境ではなく、VM Playerを載せているWindows 10でBrowser-Solidityをインストールしてみました。

が、「Environment」で「Web3 Provider」を選ぶところで無事死亡w



理解が浅いまま進んでいるのが原因ですが、「Web3 Provider Endpoint」がよくわからん。
どのIPアドレスを設定すべきかよくわからず、とりあえずlocalhostにしてみるも上手くいかず。


このあと「172.0.0.1」を試してみるも、やっぱりダメ。

参考に挙げたリンク先に「go-ethereum/gethがOS上にインストール済みであることを前提にしています。」と書いてあるのを見かけて、gethをインストールしたVM Player上のLinux(Ubuntu)ではなく、その外の(gethをインストールしていない)Windows 10でやっていたので「デスヨネー」となりました。

というわけで、VM Player上のLinux(Ubuntu)で再度同じことをやってみることにしました。

(参考)
Etherum Browser-Solidityを利用したコントラクト開発・デプロイ・実行(Qiita)


VMを作り直したらgethをビルドできない話

VM Player上のLinux(Ubuntu)でやろうとしたら、Browser-Solidityをデフォルトで入っているFirefoxで開くと固まる……w
Firefoxだと重いのかなーと、Chromeを入れて試してみることに。

すると、Chromeさんがインストールできない!
色々試した結果、最新バージョン(今回はv18.04で、以前のは過去記事を見るとv16.04)のUbuntuで仮想マシンを作り直してみたら、Chromeのインストールはできました。
ついでに言うとVM Ware Toolsも上手く入らない……(こっちはVM Playerのバージョンの問題……?)

仮想マシンを作り直してしまったので再度Geth環境を整えて、その上でBrowser-Solidityをインストールする必要があります。

なのでGethをまたインストールしました。
ところが!今度は「make geth」でビルドできないw
(VM Ware Toolsが上手くいってないせいでゲストOSとの間でコピペができないっぽいため画像で)


Go言語のバージョンが低いと怒られている感じがするんですが、実際バージョン確認するとこんな感じ。


これだけ見ると1.10みたいにも見えるんですが、「.」の後ろは「じゅう」ではなくて「いちぜろ」なのかな……?

というわけでGo言語のバージョンを変えたいんですが、この辺の扱いが不慣れすぎてまったく上手くできず(;´Д`)
これは参考リンクあたりを見ながら上手くいかないかなぁ。

ひとまず、仕方ないので代替案として、オンライン上でBrowser-Solidityを動かしてみることにしました。

(参考)
PINE64(Ethereumのマイニング、geth導入成功)(ねこめも)


Browser-Solidityをオンラインで使う

これはようやく上手くいきました(少なくとも、目的のコードが動いた)。
そんなわけで、途中のトラブルシューティングをはさみつつ、上手くいったところまでの手順を書いておきます。

まず、Browser-Solidity (Remix) のページに行きます。


とりあえずデフォルトで入っているballot.solはいらないのでファイル名横の「×」ボタンで消して、「+」ボタンからSample.solという名前のファイルを作ってみます。




ためしに教科書に載っていたテストコードを入れてコンパイルしてみます。


このままコンパイルすると、警告が4つ出てきます。


内容としては次の2種類です。
Static Analysis raised 3 warning(s) that requires your attention.

browser/Sample.sol:<何行目か>:<何文字目か>: Warning: No visibility specified. Defaulting to "public".
function <関数名>(<引数>){
^
Spanning multiple lines.


警告は出ていてもデプロイはできるようですが、気持ち悪いので対応したいところ。
調べてみると、「Warning: No visibility specified.」の方はどうも「visibility」という設定がないと警告が出るようです。(エラー内容そのままですが)

よくわからないままですが、調べた先の情報を参考に「visibility」として「public」(入れる位置は画像の位置が正しそう)というのを入れて再度コンパイル。
3つあった「Warning: No visibility specified.」という警告は消えましたが、残り1つが消えない。。


内容的に、「Warning: No visibility specified.」が消えたら消えるのかと思ったのですが。
これもよくわからないのでいったん放置。


「Run」タブの「Environment」で「JavaScript VM」を選びます。
これを選ぶことで、オンライン上で仮想環境を作ってデプロイできるようです。


「Deploy」を押してみます。



この状態でデプロイ成功みたいです。


下のプロンプトを見てみると(エディタ部分との境目くらいに広げるための矢印が出てくる)、contractAddress とかが割り当てられていることがわかります。(左の三角を押すと詳細が見られます)





文字入力部分に「"Hello, World!"」(「"」は必須のようです)を入れて「setGreeting」を押すと、プロンプトのところがさらに進みます。



「greeting」と「say」も押してやると、プロンプトにもこいつらに関する処理結果が返されて、「greeting」と「say」のところにも「Hello, World!」が出てきます。



ここまでで、場当たり的(というか力ずく?)にではありますが、一応は教科書にあるコードをBrowser-Solidity上で動かせました。

(参考)
手軽に“Solidity”言語でスマートコントラクト開発、開発環境「Remix」ってどう使う?(@IT)
Ethereum のスマートコントラクト実行環境を整える(Qiita)
【堅牢なスマートコントラクト開発のためのブロックチェーン】エラー改善メモ”No visibility specified. Defaulting to “public”.”(ICG -I can't graduate-)
Remixとbrowser-solidityの使い方(たったひとりのIT事業部。)


まとめ

紆余曲折のすえ、さしあたりローカルのオフライン環境でSolidityを使うことはあきらめ、オンライン上でBrowser-Solidityを使って勉強を続けることにしました。
オンライン上でVM環境を動かすには、Browser-Solidityの「Run」タブにある「Environment」で「JavaScript VM」を選べばいけそうです。

この環境でできそうなところを、前回のつづきとして、「はじめてのブロックチェーン・アプリケーション Ethereumによるスマートコントラクト開発入門」に沿ってすすんでみたいと思います。
またすぐ詰まりそうな気がしますが……w

Solidityの公式ドキュメントも読みつつちゃんとできるといいな。。

次回は「既存コントラクトへのアクセス」をBrowser-Solidity(Remix)からやってみます。

テーマ : プログラミング
ジャンル : コンピュータ

Keyword : ブロックチェーン イーサリアム Ethereum Solidity Browser-Solidity

Ethereumテストネットワークで送金してみる(続き)

どうも、ぺろりんです。

「はじめてのブロックチェーン・アプリケーション Ethereumによるスマートコントラクト開発入門」のつづきです。

前回はアカウント0からアカウント1へEthereumを送金してみました。
今回は、coinbase(=アカウント0)ではないアカウントから送金することで、手数料が発生する動きを見てみます。


Ethereumの送金手数料

送金にはGasという手数料がかかるのでした。

前回の送金ではcoinbaseであるアカウント0から送金したため実質的に見えなかったのですが、実際にはトランザクションの実行にはGasという手数料がかかっています。

たとえばcoinbaseではないアカウント1からアカウント2へ5[ETH]を送金してから2つのアカウントで残高確認してみると、こんな結果になりました。
> web3.fromWei(eth.getBalance(eth.accounts[1]),"ether")

4.99958
> web3.fromWei(eth.getBalance(eth.accounts[2]),"ether")

5

これを見ると、送り先のアカウント2には5[ETH]が確かに届いていますが、送り主のアカウント1に残っているのは5(=10-5)[ETH]よりも少ないです。

アカウント0の残高を見てると、この減った0.00042[ETH]はcoinbase(=アカウント0)に報酬として支払われていることが分かります。
> web3.fromWei(eth.getBalance(eth.accounts[0]),"ether")
1065.00042


「eth.getTransaction」と「eth.getBlock」というコマンドを使ってみると、手数料がどうなったか見えてきます。
というわけで、これらのコマンドを見てみましょう。

いちおう復習しておくと、前回と同じくアカウントをアンロックして「eth.sendTransaction」を実行して出てくるトランザクションIDを引数にして、まず「eth.getTransaction」を見るとこんな感じ。
> eth.getTransaction("0xdb06571f2f55e5adf9fd9949d81bef7385ddfdf73258b7e90de9312e5b3bb17c")
{
blockHash: "0xd401634e5373f73507f93658798a2204180b7018145ccc40c1951a15c8e29d7d",
blockNumber: 210,
from: "0x3a8e6c0304c761b88feeefb5cdefe27ced28d620",
gas: 90000,
gasPrice: 20000000000,
hash: "0xdb06571f2f55e5adf9fd9949d81bef7385ddfdf73258b7e90de9312e5b3bb17c",
input: "0x",
nonce: 0,
r: "0xf18b45285396c04ead1f4e7ed318df6e398f626fb5b0150e8d4f56e80c6ad735",
s: "0x61e82c4d16863c8186884ed09ecdd1974a8f7d8a5ecefd9758991aedd6bab86a",
to: "0xecac305a22ac002107cdac420e24042d430bcb26",
transactionIndex: 0,
v: "0x1b",
value: 5000000000000000000
}


さらに、ここで出てきたblockNumberの210を引数にしてブロックを見るとこんな内容になっています。
> eth.getBlock(210)
{
difficulty: 141844,
extraData: "0xd783010505846765746887676f312e362e32856c696e7578",
gasLimit: 109320930,
gasUsed: 21000,
hash: "0xd401634e5373f73507f93658798a2204180b7018145ccc40c1951a15c8e29d7d",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
mixHash: "0x77f99c1901f72d3eaad2f5aea85dce821471f8d23a1f1f7e92853cc04d116417",
nonce: "0x3671259b945c8662",
number: 210,
parentHash: "0x0cd16490e3ceba375792cffd22f9ed4b4eecd6712485820f47ed04456de0fc66",
receiptsRoot: "0x895e49c7c281cdf956cd75f726596d7d3e7b68a9f08b462dfb1469ede1d2f812",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 651,
stateRoot: "0x369a09f8fbb36aa7a7010f16bb8643cfda6dad78d861696cc5647939f38088a7",
timestamp: 1528018266,
totalDifficulty: 28692719,
transactions: ["0xdb06571f2f55e5adf9fd9949d81bef7385ddfdf73258b7e90de9312e5b3bb17c"],
transactionsRoot: "0x64f4d635547183f729941c809ba518280f8d426e8fdf509d392eb7f5d87f7f7f",
uncles: []
}


ここで注目するのは以下の2つです。
・「eth.getTransaction」の「gasPrice」
・「eth.getBlock」の「gasUsed」

以前お勉強したように、gasPriceというのが1Gasあたりの値段[wei]でした。
上述したコマンドの結果から、今はこれが20000000000[wei]とわかります。
で、使用されたGasが何[Gas]かというのは「gasUsed」で分かり、今は21000[Gas]と読み取れます。
(「eth.getTransaction」の「gas」は支払い可能な最大Gasを表す)

なので結局、手数料として
 gasPrice×gasUsed=20000000000[wei/Gas]×21000[Gas]
 =420000000000000[wei]=0.00042[ETH]
が支払われることになって、先ほどアカウントの残高を確認したときにアカウント1からcoinbase(=アカウント0)に移った0.00042[ETH]と一致します。

アカウント0から他のアカウントに送金したときには支払元のアカウント0は(今の場合)coinbaseなので、「手数料は支払元から引かれる」ことと、「手数料はcoinbaseに支払われる」ことから、自分から引いた手数料を自分が報酬としてもらうことになって、結果として差引0になります。
…というのが前回やったアカウント0からの送金でした。


まとめ

今回は、アカウント間の送金で、Gasと名付けられた手数料が送金元の残高から引かれ、coinbaseアカウントに報酬として支払われる動きを見ました。

送金元がcoinbaseの場合には、自分で払って自分がもらうため、実質手数料がかかってないようになっているのが前回の状況でした。

今回見たのはこんな感じです。

Ethereumテストネットワークで送金してみる

どうも、ぺろりんです。

「はじめてのブロックチェーン・アプリケーション Ethereumによるスマートコントラクト開発入門」でのお勉強のつづきで、今回はテストネットで送金してみます。
あと、途中で出てきたコマンド(eth.getTransaction)の出力についてちょっと調べています。

前回はアカウントを作ってマイニングしたのでした。

送金は
 送金元アカウントのロック解除→送金→マイニング
という手順でやっていきます。

ではやってみましょう。


テストネットでのEthereum送金

送金元アカウントのロック解除

まずはアカウントのロック解除をする必要があります。
アンロックせずに送金コマンドをたたくと、こんな感じで怒られます。
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")})
Error: account is locked
at web3.js:3119:20
at web3.js:6023:15
at web3.js:4995:36
at :1:1


教科書によると、トランザクション発行が有料なので、誤送金を防ぐためデフォルトでは送金できないようにロックされているそうです。
アンロックには「personal.unlockAccount(〈ロック解除したいアカウント〉,〈パスフレーズ〉,〈アンロック有効時間(秒)〉)」コマンドを使います。
引数のパスフレーズとアンロック有効時間は省略可能です。
アンロック有効時間を「0」にするとそのGethプロセス起動中ずっとアンロック状態になります。

たとえば、「アカウント0を100秒アンロックする」という内容をやってみるとこんな感じ。
> personal.unlockAccount(eth.accounts[0],"pass0",100)
true



送金

ロックが解除できたので、「eth.sendTransaction」コマンドで送金してみましょう。
引数は、
 from:送金元アドレス
 to:送金先アドレス
 value:送金額[wei]
を指定します。

アカウント0からアカウント1に10[ETH]送金すると、プロンプトにトランザクションIDか返されます。
> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")})
"0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0"


送金トランザクションの発効後にマイニングしておらず、まだブロックが生成されていないため、この時点では今しがた送金したトランザクションを含むブロックがありません。
なので、まだ送金が完了しておらず、アカウント1の中身は0のままです。
> eth.getBalance(eth.accounts[1])
0


この状態でさきほど送金時に返ってきたトランザクションIDを入れてトランザクションの内容を確認してみると、実際、ブロック番号(blockNumber)がnullになっています。
> eth.getTransaction("0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0")
{
blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
blockNumber: null,
from: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
gas: 90000,
gasPrice: 20000000000,
hash: "0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0",
input: "0x",
nonce: 0,
r: "0xc0a41f36a050c8ea2e2b2ccd6b85a749b40c1dc375c907340231b16d76b23a7f",
s: "0xa74113934ecf97130083a377728534ec8a1c7917e098f69e6fa8bb082ed7040",
to: "0x3a8e6c0304c761b88feeefb5cdefe27ced28d620",
transactionIndex: null,
v: "0x1c",
value: 10000000000000000000
}



マイニング

マイニングしてブロックを生成し、上でやった送金を完了させましょう。
マイニングはminer.start(〈マイニングするスレッド数〉)で始めるのでした。
> miner.start(1)
true


マイニング開始からしばらくは、「eth.pendingTransactions」で保留中のトランザクションを見てみると先ほど送金しようとしたものが出てきます。
> eth.pendingTransactions

[{
blockHash: null,
blockNumber: null,
from: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
gas: 90000,
gasPrice: 20000000000,
hash: "0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0",
input: "0x",
nonce: 0,
r: "0xc0a41f36a050c8ea2e2b2ccd6b85a749b40c1dc375c907340231b16d76b23a7f",
s: "0xa74113934ecf97130083a377728534ec8a1c7917e098f69e6fa8bb082ed7040",
to: "0x3a8e6c0304c761b88feeefb5cdefe27ced28d620",
transactionIndex: null,
v: "0x1c",
value: 10000000000000000000
}]


しばらくマイニングを続けながら「eth.pendingTransactions」を連打していると、そのうち結果が空になります。
この時点でマイニングをやめてOKです(やめるのは「miner.stop()」コマンドでした)。
> eth.pendingTransactions
[]



送金確認

先ほど送金したトランザクションIDの内容を見てみましょう。
今度はブロック番号(197)が発番されています。
> eth.getTransaction("0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0")
{
blockHash: "0x3ea566f775e49f4f58c7932713042b511ac60ecb9469b3d0558ab3663723eeba",
blockNumber: 197,
from: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
gas: 90000,
gasPrice: 20000000000,
hash: "0xc0d2389ef187b3d6b5d88c88f301ab6ccac16a4439d38e4102a8c8c473f316d0",
input: "0x",
nonce: 0,
r: "0xc0a41f36a050c8ea2e2b2ccd6b85a749b40c1dc375c907340231b16d76b23a7f",
s: "0xa74113934ecf97130083a377728534ec8a1c7917e098f69e6fa8bb082ed7040",
to: "0x3a8e6c0304c761b88feeefb5cdefe27ced28d620",
transactionIndex: 0,
v: "0x1c",
value: 10000000000000000000
}


fromに送金元、toに送金先、valueに10[ETH]=10000000000000000000[wei]が入っています。(r,s,vにつては後述)
一応アカウントのIDを確認しておきましょうか。
> eth.accounts[0]
"0x8ade49123c81461e676fd2f8f2eb31885cdb07e0"
> eth.accounts[1]
"0x3a8e6c0304c761b88feeefb5cdefe27ced28d620"


「eth.getBlock(〈ブロック番号〉)」で192番のブロックを見てみるとこんな感じです。
 eth.getBlock(192)
{
difficulty: 141158,
extraData: "0xd783010505846765746887676f312e362e32856c696e7578",
gasLimit: 111260474,
gasUsed: 0,
hash: "0xbcd39cbb3854b49a2b99d8e00f8d0990637fff7acb3b571bf2092ef80513d768",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
mixHash: "0xcddd957dbba5b47b9343e55db72c65880351163733b6fbe86ab5d6c9fd28689f",
nonce: "0x37e12cf34c23c215",
number: 192,
parentHash: "0xee5743b3a3bdfb7c4fff360717ebb32e8a8051971172570c7dcba81da327f2e9",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 537,
stateRoot: "0xc7336773e050bc12a068699f4b91cb2f93c6b302664ddf575c70041c774b0af6",
timestamp: 1523976539,
totalDifficulty: 26144279,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}


miner(マイナー)はcoinbaseアカウントのアカウント0になっていますね。

ちなみにマイニングをやめた時点でのブロック数は209です。
ペンディングが0になってすぐマイニングやめたつもりですが、意外と進行はやいw
> eth.blockNumber
209


興味本位で確認。。
209番目のブロックが今ある最後なので、このブロックには中身がありますが、210番目のブロック内容を見てみるとnullになります。

209番目のブロック内容。
> eth.getBlock(209)
{
difficulty: 141913,
extraData: "0xd783010505846765746887676f312e362e32856c696e7578",
gasLimit: 109427792,
gasUsed: 0,
hash: "0x0cd16490e3ceba375792cffd22f9ed4b4eecd6712485820f47ed04456de0fc66",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x8ade49123c81461e676fd2f8f2eb31885cdb07e0",
mixHash: "0x8ad56f8971fa16c901d3817837e19730f29a675daa38ad87c286cea60e768653",
nonce: "0x24014e4b135603da",
number: 209,
parentHash: "0xc8d6a2fde67cdd873ca2a69c1ee74f2e2b1b2624d4eed144de86499c2da5c47f",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 537,
stateRoot: "0xe194838290483fbaae5659796477b4614555d307ccd4ec4b2cae90ccd2aaa566",
timestamp: 1528010828,
totalDifficulty: 28550875,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}


210番目のブロック内容。
> eth.getBlock(210)
null



eth.getTransactionの出力内容

「eth.getTransaction」コマンドで出力されたパラメータの意味でよくわからないところがあったので、かるく調べてみました。
どこかというと、「r」、「s」、「v」というの。なんだこれ。

調べた結果、どうやらECDSA署名という、トランザクションの署名に使うアルゴリズムで出てくるパラメータのもよう。
ECDSAというのはDSAというアルゴリズムの改良版だそう。
数学的なところを見ると時間がかかりそうなので置いておきます。。
ご興味のある方は、参考に挙げたあたりのURLをたどっていただけるともっと色々書いています。

数学的なところは、ひと通り勉強したらまた戻ってくるかも。

(参考)
ecrecoverでpublic keyが一意に定まる理由(アルゴリズムとかオーダーとか)
EthereumのTransactionHashの計算方法(アルゴリズムとかオーダーとか)
どうしてECDSA署名から公開鍵が復元できるのか?(Develop with pleasure!)
What does v, r, s in eth_getTransactionByHash mean?(StackExchange)
ECDSA: (v, r, s), what is v?(StackExchange)
ECDSA - 用語解説辞典(【公式】NTTPC)
楕円曲線DSA(Wikipedia)


まとめ

さて、今回はEthereumのテストネットワーク上で送金をしてみました。

今回のポイントは次の2点かなと思います。
(1)はじめにアカウントのロック解除をしないといけない
(2)マイニングしないと送金が完了しない

本を見ながらとかじゃないと1時間くらいハマる自信がある…w

あと、おまけで「eth.getTransaction」コマンドで出力されるr,s,vというパラメータの意味を調べました。
こいつらはECDSAという署名アルゴリズムで計算されるパラメータでしたが今回深くは触れませんw

と、こんな感じの内容でした。
次回は送金手数料の動きを見てみます。
ではでは。

Ethereumアカウントの種類とDAG(ファイル)を理解する

どうも、ぺろりんです。

今回は、マイニングしてみたところの記事で別途調べると予告した「アカウント」と「DAG(ファイル)」について調べましたので、そのまとめを書きます。

技術的な詳細をもっと調べて理解したいところですが、調べてみると時期尚早感があったので、これはコントラクトなんかにちゃんと触れてからまた戻ってこれたらいいなと思っています。
なので、今回は技術的な詳細には踏み込み過ぎない程度に調べた結果をまとめました。
一応、参考に挙げたリンクをたどっていただくともう少し詳細が書いていたりするのでご参考ください。

なお、理解が間違っていたりしたらメールフォームからこっそり教えていただけると幸いです。


EOAとContract account

EOA (Externally-owned Account:外部所有アカウント)

ユーザーと紐づくアカウント。コードは持たず、秘密鍵によって管理される。
ユーザーはEOAを通してブロックチェーンとやり取りする。
EOAは、宛先をEOA or Contract Accountとしてトランザクションを生成できる。宛先がEOAの場合は送金、宛先がContract Accountの場合は送金 or コントラクト(・コード)の実行をする。


Contract Account(コントラクト・アカウント)

ユーザーに紐づかないアカウント。ユーザーが持つことはできず、ブロックチェーン上に存在するアカウント。
コントラクト(・コード)のアドレス。オブジェクト指向言語での「クラス」に似たものというイメージらしい。
Contract Account自身はトランザクションを生成できない。(あくまでトリガーはEOA)


EOAとContract accountの違い

両者の違いとしてポイントになるようなのは、今回調べた感じだと
(1) ユーザーと結びつくか?
(2) トランザクションを生成できるか?
という2点のように思います。

(参考)
トランザクションレベルで理解する。イーサリアムの具体的な仕組みを解説(ZOOM)
技術者向け Ethereum(イーサリアム)の基礎知識(block-chain.jp)
スマートコントラクトを作成し実行する(Ethereum入門)


DAG

DAGって何?

Directed Acyclic Graph(有向非巡回グラフ)のことです。
マルとマルを線で結んだものを「グラフ」と呼ぶのですが、この線に向きを付けて矢印にしたものが「“有向”グラフ」で、しかも閉路になっていないようなもの(“非巡回”)のことです。


詳しくは「グラフ理論」という数学のおはなしをググってみてください。「グラフ理論」自体は私もあまり知りません。。

この考えをマイニングのアルゴリズムに応用するためにあるのが、イーサリアムをマイニングするときに出てきたDAGファイルというやつです。

DAGを使った取引の仕組みは、参考に挙げた2つ目のリンクが個人的にわかりやすかったです。

DAGファイルをどう使うのかは、今回は調べきれずよくわからなかったです。だれか教えてw

(参考)
有向非巡回グラフ(Wikipedia)
DAG型暗号通貨のすすめ ブロックチェーンを代替しうる新技術(BTCN)


何のためにある?

マイニングにASIC(Application Specific Integrated Circuit)耐性を持たせるために、DAGファイルが作成されます。

(参考)
技術者向け Ethereum(イーサリアム)の基礎知識(block-chain.jp)


ASIC耐性とは?

ASICというのはその名の通り「特定用途のために作られた集積回路」のことで、用途をしぼって必要最低限の機能だけを1つのチップにまとめ、しぼった特定の用途に関しては汎用チップよりも高速だったり低消費電力だったりで動作できるようなチップです。

そして「ASIC耐性」とは、こういった専用のICチップを持った人(特定の人)がマイニングで有利にならないよう、「ASICを作れない」もしくは「ASICを使う意味がない(ASICを使ってもマイニングで有利にならない)」という性質のことです。

(参考)
ASIC(Wikipedia)
ASIC(IT用語辞典)
ASIC耐性とは(とってもやさしいビットコイン)


なぜASIC耐性が必要?

ASIC耐性がない(=ASICが有効)と「中央集権化を助長する可能性があり、これを防ぐためにASIC耐性が必要」と考えるからです。

なぜ中央集権化を嫌うかというと、ブロックチェーン技術はそもそも「“分散システムで”うまく合意形成できる」というのが売りで、中央集権化というのはこれに反するからです。
中央集権的な構造でないことにより、“第三者の承認なし”でAさんとBさんのやり取りが「確かに正しく行われた」ことが合意されるわけです。
“第三者の承認なし”というのが肝です。

ASIC耐性がなければ、ASICを使う人がマイニングにおいて有利になります。
ASICを使う人たちのコミュニティにより寡占が起こると、51%攻撃のリスクも生じます。

ただし、Bitcoinのように「ASICを使わないと実質的にマイニング不可能」な状況は悪意あるマイナーの参入障壁になっていたり、ASIC耐性がないことが完全に悪いというわけでもありません。

ASIC耐性を持たせるかどうかは賛否両論あるようで、たとえばTwitter上で以下のようなアンケートがありました。



(参考)
ASICマイニング排斥の動き!ASICの性能と問題点とは(MoneyToday)
ブロックチェーンの安全性を脅かす「51%攻撃」の仕組みと実態(ZOOM)
ASICマイニング戦争|ユーザーはASICを許容すべきか否か (CoinPost)


なぜDAGでASIC耐性になる?

DAGにより計算が複雑化されるからです。

ASICというのは「やることを絞る」ことで性能を上げますが、DAGの考えを取り入れることで計算が複雑化し、高性能な計算ができる分野だけでは計算し切れないようにします。
単純な計算だからこそ特化して性能を上げられるのに、せっかく性能を上げた専門分野の計算だけではマイニングできないよう計算を複雑化し、「このような複雑な計算のためのASICはコストがかかり過ぎて作るメリットがない」状況を作ります。

これにより、「ASICを使う意味がない(ASICを使ってもマイニングで有利にならない)」状況になり、すなわちこれはASIC耐性なわけです。

(参考)
Ethash DAG(ethereum/wiki)
Dagger Hashimoto(ethereum/wiki)
Ethashとは?(ETHEREUM JAPAN)
暗号通貨 ハッシュ関数を学ぶ その1 SHA Ethash(草コイン、おかわりください)
ASIC耐性とは(とってもやさしいビットコイン)


まとめ

今回は、過去の記事でよくわからなかった「アカウント」と「DAG」について調べてみました。

ざくっというと、アカウントはユーザーと結びついてトランザクションを生成できる「EOA」と、ユーザーとは結び付かずトランザクションを生成できない「コントラクト・アカウント」という2種類がありました。
「コントラクト・アカウント」はコントラクト・コードを実行するために必要なもののようです。

DAGは、これ自身は数学のグラフ理論で出てくる概念で、Ethereum(やブロックチェーン)の文脈では「この概念を応用した取引の仕組みが実装されている」というおはなしでした。
では何のためにかというと、「ASIC耐性」という、ブロックチェーンの(マイニングで)中央集権化を防ぐための性質を、そのブロックチェーンに持たせるためでした。
ASIC耐性の要不要については賛否両論あるようです。

とまぁ、現段階ではこのへんの理解にとどめて先へ進んでみようかと思います。
ではでは。

batchOverflowの記事(Medium)の日本語訳

どうも、ぺろりんです。

4/22に掲載されたMediumの「New batchOverflow Bug in Multiple ERC20 Smart Contracts (CVE-2018–10299)」という記事の拙訳を載せておきます。

日本語訳があれば他の方の役にも立つかなというのと、個人的な勉強をかねて。
誤訳などありましたらメールフォームからお知らせいただけるととても助かります。

なお、本文や図などは上記リンク先(元記事)をご参照ください。

調べた内容についてはこちらの記事へ。


拙訳

EOSトークン[注1]に対する私たの以前の努力に基づいて、イーサリアム(ERC-20[注2])に基づいたトークン送金を自動的に探査および解析するシステムを開発してきました。特に、私たちのシステムでは何かしらの疑わしい送金(たとえば、明らかにおかしい大量のトークンを含むようなもの)が起きると自動的に警告を出します。

特に、2018年4月22日の午前03:28:52(UTC)、普通でないBEC[注3]トークンの送金について私たちのシステムが警告を上げました(図1)。この特定のトランザクションでは、
0x8000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000

(16進数で「0」が63個。実際、たしかにこういう大量のトークン送金が同じビューティーチェーン(BeautyChain)のコントラクトで同じ量という内容の送金が2つありましたが、アドレスは2つで違っていました)という極めて大量のBECトークンを誰かが送金していました。

この異常により、私たちは即座に関連するスマートコントラクトのコードを調査する必要に駆られました。このような送金はコントラクトに関するこれまで知られていない脆弱性を利用した「野放し状態の」攻撃によるものだと、私たちの調査で明らかになりました。推敲のうえ、この脆弱性をバッチオーバーフロー(batchOverflow)と呼ぶことにしました。バッチオーバーフローは基本的に古典的な整数のオーバーフロー問題であるというのが私たちの指摘です。以下では、バッチオーバーフローという脆弱性についてもう少し詳しく調べてみます。

脆弱な関数はbatchTransferの中にあり、そのコードは図2に示した内容です。257行目で示しているように、ローカル変数amountはcntと_valueの積として計算されます。2つ目のパラメータ_valueは、
0x8000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000

(63個の「0」がつく)という256ビットの整数値をとれます。極めて大きな_valueとともに2つの_receiversをbatchTransfer()に渡すことで、ローカル変数amountをオーバーフローさせて0にできます。値が0になったamountをもって攻撃者は258–259行目にある値の正常性チェックを通過し、261行目の引き算が無関係になります。最終的に興味ある部分は次のところです:262–265行目に示したように、攻撃者がびた一文支払うことなく、2つの_receiversによるbalanceに極めて大きな値の_valueが足されることになります!

これにより、私たちはこのシステムをさらに走らせて他のコントラクトでも調査および解析しました。結果として、数十以上のERC20コントラクトがbatchOverflowへの脆弱性を持つことが分かりました。実証のため、私たちの検証用コードとして1つの脆弱なコントラクト(どの取引でも交換できないもの)を用いたトランザクションを成功させました(図3)。

このブログ執筆時より、これらの脆弱なコントラクトをもつチームと連絡をとる努力もしてきました。しかしながら、イーサリアムのブロックチェーンでうたわれる「コードこそ法である(code-is-law[注4])」という原則により、このように脆弱なコントラクトに対処するための場所で、慣習的によく知られたセキュリティ対応のやり方がありません!さらに、これらのトークンに関連する潜在的な値に対し、不運にもセキュリティチームとは独立した第三者のような私たちは、多くの取引にある脆弱なトークンによる交換を停止するような対応をとれる立場にありません。幸い、実質午後4:12(GMT+8)にOKEx[注5]が、batchOverflowの影響を受けるトークンであるBeautyChain (BEC)の引き出しと取引を一時停止するというアナウンスを出しました。しかし他の交換でも同様の対応が必要で、batchOverflowに対して脆弱な他の取引可能なトークンがまだ残っています!オフライン取引サービスによる非中央集権的な交換の存在は、それらはまだ攻撃者によるトークンのロンダリングを止められていないという更なる問題を突き付けるかもしれません。

また私たちはさらに、深刻な複雑性にも直面しているかもしれません。特に、このように脆弱なコントラクトを実行することによって、攻撃者が大量のトークンを所有することは非常にありそうなことです。この攻撃者[注6]が暗号通貨取引所に行き、このトークンをETH, BTC, さらにはUSDと交換しはじめたらどうでしょうか?きわめて大量のトークン(ありそうなのは流通している全供給量よりも大きい値)を持つことで、攻撃者が暗号通貨間の価格を簡単に操作できてしまうでしょう。これはつい最近の先月はじめに起きた、犯人がBinance[注7]の顧客アカウントを操作し、アカウントから別のアカウントに売却することでViacoin[注8]の価格をつり上げたというBinance事件[1:Medium記事の引用文献を参照のこと]をすぐに思い起こさせます。


[注1] EOSトークン…イオスという仮想通貨のことみたいです。参考に挙げたCoinOtakuの記事によると「企業の業務サポートで使われることを目的とした、スマートコントラクトを利用して分散型アプリケーションを作ることに特化している仮想通貨」だそうです。
(参考)
公式サイト
仮想通貨EOS(イオス・EOS)とは?特徴・買い方・取引所・将来性・チャート・マイニング・ニュースを解説(CoinOtaku)

[注2] ERC-20…Ethereum Request for Comments: Token Standard #20という、イーサリアムベースで作るトークンの技術的な統一規格。この規格に準拠することで、別々のトークンでも同じウォレットで扱えたりする。
(参考)
ERC20(Wikipedia)
ERC20とは<初心者向け>(とってもやさしいビットコイン)
ERC20とは?仮想通貨の名前じゃない?対応するウォレットまで完全解説!(CoinOtaku)

[注3] BEC…Beauty Ecosystem Coinというプラットフォームのことらしい。詳しくは参考に挙げたあたりなどをご参照のこと。
(参考)
公式サイト
仮想通貨Beauty Ecosystem Coin(BEC)のAirdrop(無料配布)に参加 テレグラム利用で簡単に貰えるぞ(仮想通貨で自由を買うブログ)
OKEX上場中のBeautyChain(BEC)がエアドロップを開始(スーファミ世代の仮想通貨ブログ)

[注4] code-is-law(コード・イズ・ロー)…コードがすべてで、(イーサリアムという世界は)コードという自然法則によってできている、というような考え方です。個人的には法「律」というよりも法「則」のニュアンスなのかなと思っています。この(イーサリアムという)世界の自然法則なのでこれは変えられる(変えるべき)ものではないという考え方です。イーサリアムクラシック(ethereum classic)はこっち寄りの考え。
(参考)
イーサリアムクラシック(ethereum classic)とは~イーサリアムが分裂してできた新たな仮想通貨の全貌~(MOBLOCK)
イーサリアムクラシックとは?イーサリアムから誕生した背景や違いを紹介(nanairo)
イーサリアムクラシックが支持され価値がなくならない理由(Code is Law とは)(墨汁の暗号通貨速報)

[注5] OKEx…中国にある仮想通貨取引所の1つ。
(参考)
公式サイト
OKEx(オーケーイーエックス)の特徴やメリット/デメリット、口座開設方法をわかりやすく解説!(MOBLOCK)
海外取引所OKEx(オーケーイーエックス)の登録方法・使い方【画像で解説!】(はじめてのビットコイン)

[注6] ここの「she」ってたぶん直前の文にある「an attacker」のことかと思ったんですが、攻撃者って女性名詞なのだろうか…?教えてエライ人。。
[注7] Binance…中国の仮想通貨取引所の1つ。
(参考)
公式サイト
BINANCE(バイナンス)の登録,入金方法と使い方|アプリが使いやすい手数料激安の取引所(ゼロからはじめるビットコイン)
中国の取引所 Binance (バイナンス) の登録方法を解説(いますぐ始める仮想通貨投資)

[注8] Viacoin…仮想通貨の1つ。詳細は参考に挙げたところなどをご参照のこと。
(参考)
Viacoin 相場チャート (VIA/JPY)(CoinGecko)
仮想通貨Viacoin(VIA)の将来性と詳細|Lightning Network対応済みコイン(兼業主夫ふくろうの「好きなことで生きていく?」)
仮想通貨VIA(Viacoin)とは?特徴や将来性・取引所での買い方 (仮想通貨で稼ぐサイトCOINZ)

プロフィール

ぺろりん

Author:ぺろりん
最近仮想通貨が楽しくなってきました。
基本的な技術をちゃんと知りたいなぁと思いつつ、まったりお勉強していこうかと思います。

twitter:ぺろりん@ぶろっくちぇーん

カテゴリ
最新記事
最新コメント
月別アーカイブ
カレンダー
10 | 2018/11 | 12
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
メールフォーム

名前:
メール:
件名:
本文: