Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ethereumをさわって実感するブロックチェーンハンズオン

mogiken
July 14, 2018

 Ethereumをさわって実感するブロックチェーンハンズオン

Gethの基本から学びます. geth 1.8.x対応

mogiken

July 14, 2018
Tweet

More Decks by mogiken

Other Decks in Technology

Transcript

  1. 6 6 Bitcoinで使われているブロック チェーンは通貨だけではなく広くサー ビスとして使われつつあります。管理 サーバー無しで。。 Swarm クラウドファンディングのプラットフォーム Storjcoin X

    分散型ストレージサービス Gems 分散型メッセンジャーアプリ LTBcoin 「Let's Talk Bitcoin」というビットコインのPodcastサービスの広告枠の利用等 に使用
  2. 10 講師 Gashfara,Inc.代表   デジタルハリウッド大学院客員講師 茂木健一 [email protected]  [email protected]  http://facebook.com/mogiken http://www.slideshare.net/mogiken1  自己紹介

    [プロフィール/実績] もぎ・けんいち•青山学院大学大学院卒。Gashfara,Inc.代表。本社はハワイですが出社したことな し。ホノルルマラソンには参加w 青山学院大学大学院卒:エニックスでオリジナルゲーム制作(Z80アセンブラ CP/M)、SmallTalk で人工知能開発(企業買収)。 (株)東洋情報システム退社後、(株)エイチアイ、グランスフィア(株)、(株)ファッション ウォーカー(えびもえのEC)など数社のベンチャー企業の立ち上げ・創業期に参画し、ガシュファ ラ・インクをUSで起業。システム開発ではゲーム、TOL(ツタヤオンライン)の立ち上げ。動画配 信システム(USENのGate01:Gyaoの前進)、電子マネーシステム(Bitcash)、ECフルフィルメ ントシステムなど、多彩な分野を経験。IT関連教育では1998年ころからデジハリの2.5階に間借 りしながら教育コンテンツ作成(JIB社)。Brew、Java、セキュリティーなどの講師として活躍。 現在、(株)HUGGを設立し、スマホのカップル向けSNSサービス[HUGG]をグローバルに展開。㈱ テクノモバイルにて技術サポート。 【著書】 BREWプログラミング実践バイブル [共著] (インプレス)、PHP逆引き大全 516の極意[共著](秀 和システム)
  3. 12 6 Ethereumとは ・ブロックチェーンを使った分散アプリケー ションプラットフォームです。 ・Bitcoinのように仮想通貨の送金のみならず、 仮想通貨を使ったアプリケーションの実行環境 を提供します。→Contract ・通貨単位:ether ・Bitcoinと同じように取引が可能です。

    ・プライベートネットワークでも実行可能。ト ランザクションDBのかわりに使うことができ る。プライベート上のetherは取引不可能。 参考 https://www.gitbook.com/book/a-mitani/mastering-ethereum/details 
  4. 13 6 ブロックチェーンとは ・この解説が一番わかり易い。 http://www.slideshare.net/cookle/ 5-58379474  こまかいロジックはBitcoinのソースコードを 読むのが正解らしい。。。 ※ポイントは。。。。 チェーンの改ざんを抑止するためにハッシュ値の計算(マイニング)

    する難しさを定期的に調整しているが、調整が間に合わないような高速 演算できる環境を持ち込まれると長いチェーンを作成されてしまい、改 ざんできる余地がある。→完璧ではない。十分難しい状態のまま。
  5. 16 Windows Macの場合: 下記の手順でDocker環境を作成します。 1.Docker Toolboxのインストール。Docker for mac,winでもOK。 https://www.docker.com/products/docker-toolbox  から DockerToolboxをダウンロードしてインストールしてください。デフォルトの

    ままインストールを進めてOKです。 インストールされたDocker Quickstart Terminalを起動して下記のような ターミナルが表示されればインストールはOKです。exitで終了できます。 ※MacOS Sierraの場合はこれを参考  http://qiita.com/Ryosuke-Hujisawa/items/67f9dff2fadd729165dc  2.コンテナethertestを作成。exitで終了します。 docker run -it --name "ethertest" --entrypoint="/bin/sh" ethereum/ client-go exit でぬけます
  6. 17 6 テストネットに接続しましょう 自分だけのテスト用の環境テストネットに接続しましょう。参考 https://goo.gl/zcG2rZ   1.Docker環境の人は下記のコマンドでログインできます。 docker start ethertest

    docker attach ethertest 2.gethデータのフォルダーを「~/gethdata」のように作成しましょう。ここにブ ロックチェーンやアカウント情報が保存されます。 mkdir ~/gethdata 3.下記のコマンドを実行するとコンソールで操作できるgethが起動します。これが ノードです。exitと入力すると終了します。 geth --networkid "10" --datadir "~/gethdata" --dev --nodiscover console  ※networkid : テストネットの番号です。適当でOK。    datadir : 上記で作成したフォルダーの場所です。    dev: 開発用の設定。gasは常に0.マイニングなどが早い。参考:https://goo.gl/OXFN6u     console : コンソール付きで起動します。&をつければバックグラウンドで動作できます。     nodiscover:ほかのネットワークにつなげないようにする。 ※本番ネットはここを参考に接続できます。 http://book.ethereum-jp.net/first_use/connect_to_livenet.html  exitでconsoleを抜けます 4.このコンソールを使ってさまざまな操作ができます。 コマンド一覧:http://qiita.com/toshikase/items/fa7a826db483177d1e80  
  7. 18 6 Contract作成の環境設定 1.solc(コンパイラ)をインストール。★めちゃ時間がかかります。OSで実行します。 exitでconsoleを抜けます。   Docker環境(Windows,Mac)の場合 apk --update add git

    git clone https://github.com/ethereum/solidity.git cd solidity ./scripts/install_deps.sh mkdir build && cd build cmake .. make cp -p solc/solc /usr/bin solc --version →メッセージが表示されればOK. コマンドがなくなってます WindowsとおなじくDockerがおすすめ
  8. 19 6 アカウントを作成しましょう 1.コンソールを使い下記のコマンドを入力して2名のアカウントを作成しま しょう。gethのconsoleを起動しましょう。 personal.newAccount("hogehoge01")  パスワードhogehoge01のアカウントのIDが表示されます。 → “0x955f0634c54ecf1ea1bb219fbafbc11d7aedc268” AさんのID personal.newAccount("hogehoge02") パスワードhogehoge02のアカウントのIDが表示されます。

    → “0x9620dd004b3715210b30690ec95589ec9830f3bc” BさんのID 2.作成した全アカウントを確認します。初期アカウントが1つ作成済みです。 パスワードは”” eth.accounts →["0x52edac494f5ecc6399754df8a615353374bcdf44","0x955f 0634c54ecf1ea1bb219fbafbc11d7aedc268", "0x9620dd004b3715210b30690ec95589ec9830f3bc"]
  9. 23 6 送金トランザクションを確認しましょう 全体構造 parentHash hash nonce Transaction TransactionReceipt Block

    stateRoot parentHash hash nonce Transaction TransactionReceipt stateRoot parentHash hash nonce Transaction TransactionReceipt stateRoot 参考: WhitePaper: https://goo.gl/7R8TL5   YellowPage https://goo.gl/A6H4oL  スニペット  https://goo.gl/9Fw2qb  https://goo.gl/9Scucd  transactionsRoot transactionsRoot transactionsRoot
  10. 24 6 1.送金時のトランザクションIDからトランザクションの状態を確認しましょう。 eth.sendTransactionを実行したときの結果のアドレスがトランザクションIDです。 eth.getTransaction("0x2f571ed1c11f721db7a5dca8d071352d338448b 0e9264a6fe524fa47b3b0fb09") → {  blockHash: "0x1c5f0241b80ca16205b99b2833da4c7a323784fa218290785791430c12f191ea",

    blockNumber: 4, from: "0x955f0634c54ecf1ea1bb219fbafbc11d7aedc268", gas: 90000, gasPrice: 21142503856, hash: "0x2f571ed1c11f721db7a5dca8d071352d338448b0e9264a6fe524fa47b3b0fb09", input: "0x", nonce: 0, r: "0x21bcb629404fd66dce492928f022ccd60ce32612df3cee6110af79bd65eed5d4", s: "0x112f50f9a1c9ecf21010598f0b04a1c74d1e38f2675b7f029cdc1796a2138010", to: "0x9620dd004b3715210b30690ec95589ec9830f3bc", transactionIndex: 0, v: "0x1b", value: 5000000000000000000 }
  11. 25 6 2.主な項目です。 blockHash & blockNumber:このトランザクションを含んだブロックのヘッダ・ ハッシュとブロック高を示しています。まだこのトランザクションを含んだブロック が採掘されていないときには、これらのフィールドは空の状態で表示されます。 hash:トランザクションID gas:トランザクションの処理時のgasの使用量の「最大値」を示しています。(実

    際のトランザクション処理時のgasの使用量ではないので、注意してください。 gasPrice:トランザクションの処理時に採掘者に支払う1 gas 当たりの手数料 (wei)を示しています。 from & to & value:それぞれ、トランザクションにより送金する送金元、宛先、 送金額(wei)を示しています。
  12. 26 6 3.このトランザクションの詳細レシートを確認しましょう。hash値(トランザク ションID)でレシートが確認できます。マイニングされるまで作成されない。 eth.getTransactionReceipt("0x2f571ed1c11f721db7a5dca8d071352d338448b0e9264a6f e524fa47b3b0fb09") → { blockHash: "0x1c5f0241b80ca16205b99b2833da4c7a323784fa218290785791430c12f191ea",

    blockNumber: 4, contractAddress: null, cumulativeGasUsed: 21000, from: "0x955f0634c54ecf1ea1bb219fbafbc11d7aedc268", gasUsed: 21000, logs: [], logsBloom: "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", root: "0x39f372967a04790d5f9d03be5bf43e17d3e76ced6b13cf6fcb3c21a90b612624", to: "0x9620dd004b3715210b30690ec95589ec9830f3bc", transactionHash: "0x2f571ed1c11f721db7a5dca8d071352d338448b0e9264a6fe524fa47b3b0fb09", transactionIndex: 0 } contractAddress...contractのトランザクションの時にアドレスがセット gasUsed...使われたgas
  13. 28 6 4.このトランザクションのブロックを見てみましょう. 参考:eth.blockNumberの結果 が最終ブロックです。 eth.getBlock(4) -> { difficulty: 131072,

    extraData: "0xd783010501846765746887676f312e372e33856c696e7578", gasLimit: 4712388, gasUsed: 21000, hash: "0x1c5f0241b80ca16205b99b2833da4c7a323784fa218290785791430c12f191ea", logsBloom: "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0x955f0634c54ecf1ea1bb219fbafbc11d7aedc268", mixHash: "0xd53177889fc004fe809409045c318bc7506d2a2fa610d32cdb2b1b1ce7730002", nonce: "0x76d2a8cd7fb50d0d", number: 4, parentHash: "0xe23f79fb6a7747ed3965c53e8ccf8a2b11dacee75aff81af30cd834afc2b4eb9", receiptsRoot: "0x189025d0b71a0d06f4e72c54e1d0c768375314b9422f0fa02b99c9bd58740638", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 649, stateRoot: "0x8cf12f49b25835524c65c9f37db282715f813c53ab9a7561d2d57a1ed6ea4f06", timestamp: 1479893472, totalDifficulty: 655360, transactions: ["0x2f571ed1c11f721db7a5dca8d071352d338448b0e9264a6fe524fa47b3b0fb09"], transactionsRoot: "0x075d3b93f7daa5d9c185d0bb4a6227f77e6937d8040c052d7fdee001263819e2", uncles: [] }
  14. 29 5.主な項目です。 difficulty...採掘の難しさです。 hash...このブロック番号のハッシュ値 miner...採掘したアカウント nonce...採掘されたときのnonce値。採掘では、このブロックのhash値になるようにnonce値を 計算します。 number ... このブロックの番号

    parentHash...前のブロックのhash値.つまりブロック3のhash値になる。 timestamp...作成日時 transactions...このブロックに含まれるトランザクションの配列 stateRoot...ここにパトリシア木構造で残高などが保存されている https://goo.gl/SQuYg2  receiptsRoot...レシートのパトリシア木構造 transactionsRoot...トランザクションのパトリシア木構造。このブロックのトランザクションの概 要が入っている。 全体構造はビットコインのこの解説がわかりやすい。 https://goo.gl/wpnEeS  6
  15. 31 6 Contractの作成手順 1.Contractの作成 Solidity言語でコントラクト・コードをプログラミングします。solcを使って コードをコンパイルします。 2.Contractをブロックチェーンへ登録 コンパイル結果を用いて、Contract を生成するトランザクションを Ethereumネットワークに送信する。そのトランザクションを受信した採掘者

    は、トランザクションをブロックチェーンに登録する(=Contractをブロッ クチェーンに登録する)。この時Contractのアドレスが発行される。 3.Contractへアクセス Contractを利用するユーザーは、Contract作成者からContractへのアクセ ス情報の取得します。その情報をもとにContractへアクセスし、コントラク ト・コードの実行等を行う。値が変更になるメソッドを実行する時は、ブロッ クチェーンへの登録が必要になります。値を参照するだけでは登録の必要はあ りません。
  16. 32 1.Solidyで下記のプログラムを作成します。値のsetとgetを行います。  参考: https://book.ethereum-jp.net/first_use/contract.html   6 Contractの作成 pragma solidity ^0.4.6;

    contract SingleNumRegister { uint storedData; function set(uint x) { storedData = x; } function get() view returns (uint retVal) { return storedData; } }
  17. 33 1.Solcコマンドを使ってContractをコンパイルします。 echo "pragma solidity ^0.4.6; contract SingleNumRegister { uint

    storedData; function set(uint x) { storedData = x; } function get() view returns (uint retVal) { return storedData; }}" | solc - --abi --bin →ソースをコンパイル (前記プログラムを改行なしで指定します) 下記のような結果が表示されます。 Binaryが実行コード、ABIがABI情報というContractのインターフェース情報 です。 この2つを使ってContractをブロックチェーンに登録します 6 Contractのコンパイル Binary: 608060405234801561001057600080fd5b5060ec8061001f6000396000f3006080604052600436106049576000357c0100000 000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c14608 5575b600080fd5b348015605957600080fd5b50608360048036036020811015606e57600080fd5b8101908080359060200190 92919050505060ad565b005b348015609057600080fd5b50609760b7565b6040518082815260200191505060405180910390 f35b8060008190555050565b600080549050905600a165627a7a72305820eabfb8cc9a0c39d32f29a2fad207aa7f1538a27db22 39235b3f267c63b67c9db0029 Contract JSON ABI [{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs": [],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs": [{"name":"retVal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
  18. 34 6 Contractをブロックチェーンへ登録 1.gethを起動 geth --networkid "10" --datadir "~/gethdata" --dev

    --nodiscover console 2.ABI情報を変数に登録。 var contractAbiDefinition =[{"constant":false, "inputs": [{"name":"x","type":"uint256"}],"name":"set","outputs": [],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs": [],"name":"get","outputs": [{"name":"retVal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"} ] 3.コントラクトを作成。メモリー上のみ。 var sourceCompiledContract = eth.contract(contractAbiDefinition) 4.実行コードを変数に登録。 var sourceCompiledCode = "608060405234801561001057600080fd5b5060ec8061001f6000396000f3006080604 052600436106049576000357c0100000000000000000000000000000000000000000 000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146085575 b600080fd5b348015605957600080fd5b50608360048036036020811015606e5760008 0fd5b810190808035906020019092919050505060ad565b005b348015609057600080 fd5b50609760b7565b6040518082815260200191505060405180910390f35b8060008 190555050565b600080549050905600a165627a7a72305820eabfb8cc9a0c39d32f29a 2fad207aa7f1538a27db2239235b3f267c63b67c9db0029"
  19. 35 6 Contractをブロックチェーンへ登録 5.登録者をunlock。Etherが0では登録できない。 personal.unlockAccount(eth.accounts[0],"",60000) 6.コントラクトを作成するトランザクションを投げる。コードは0xをつけない とエラー。 var contract =

    sourceCompiledContract.new({from:eth.accounts[0], data: "0x"+sourceCompiledCode , gas: 1000000}) → fullhash=0x240934ec11de43b074aaa607bbe498cf117ec17ede56 5f9ba11157e1cb20d9e4 FullhashがトランザクションID。coinbaseのアカウントでブロックチェーンに登 録。Unlockが必要。 contractでマイニングの状態がわかる。
  20. 36 6 7.contractの中身を確認しましょう。採掘されてブロックチェーンに登録さ れると、 address:に値がセットされます。 transactionHashは前頁の登録時のトランザクションの値です。 addressが 登録されたコントラクトのアドレスです。 contract →

    { abi: [{ constant: false, inputs: [{...}], name: "set", outputs: [], payable: false, stateMutability: "nonpayable", type: "function" }, { constant: true, inputs: [], name: "get", outputs: [{...}], payable: false, stateMutability: "view", type: "function" }], address: "0x25bfc344ad63686c2eb8bc25335d908f7c3d46ad", transactionHash: "0x240934ec11de43b074aaa607bbe498cf117ec17ede565f9ba11157e1cb20d9e4", allEvents: function(), get: function(), set: function() }
  21. 37 6 Contractにアクセスしましょう 1.Contractを使うためにはContractのaddressとABI情報(Contractの仕 様書みたいなもの)が必要です。 addressは前頁のaddress値 ABI情報は変数contractAbiDefinitionの値を確認しましょう。 contractAbiDefinition → [{

    constant: false, inputs: [{ name: "x", type: "uint256" }], name: "set", outputs: [], payable: false, type: "function" }, { constant: true, inputs: [], name: "get", outputs: [{ name: "retVal", type: "uint256" }], payable: false, type: "function" }]
  22. 38 2.下記のようにcontractにアクセスするための変数cntを作成しましょう。 address部分は自分のcontractの値で。 var cnt = eth.contract(contractAbiDefinition).at("0x25bfc344ad63686c2eb 8bc25335d908f7c3d46ad") 3.coinbaseがcontractのset関数を実行するには下記のように実行します。 6をセットしています。値が変化するのでブロックチェーンへの登録が必要で

    す。つまり採掘が必要です。 personal.unlockAccount(eth.accounts[0],"",60000) cnt.set.sendTransaction(6,{from:eth.accounts[0]}) →fullhash=0x0d892e531b767acd18b4dc551c0dc023d0e6f8feb 5faf58bd5e7689707cdd51b 4.採掘されると下記の実行で値6が表示されます cnt.get() →6