1. Naomasa

    Posted

    Naomasa
Changes in title
+Ethereumで仮想通貨を発行する
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,306 @@
+この記事ではMac OS Sierra 10.12.4を使っています
+
+Ethereumは、シンプルなコードで書かれた「コントラクト」を実行することで、様々なネットワークを生み出すことのできるブロックチェーンです。
+
+コントラクトとしては「通貨を発行する」、「税金を払う」、「クラウドセールを実施する」など様々な種類のものを発行することができ、その手軽さと汎用性の高さからAugur,DAO,OmiseGOなどEthereum上でトークンを発行されたプロジェクトは多々あります。
+
+何回かに分けてEthereumで仮想通貨を発行する、というところまでチュートリアルでやってみます。今回はgethの環境構築までを実施します。
+
+# gethのインストール
+
+ethereumのクライアントとして今回はgethをインストールします。goで書かれたEthereumのクライアントでメジャーなものになります。
+
+Mac OSではhomebrewで簡単にインストールできます。
+
+
+```shell-session
+brew tap ethereum/ethereum
+brew install ethereum
+```
+
+ あるいは、ethereumのGitHubrリポジトリよりgit cloneしてビルドする形になります。
+(探せばいくらでもあるのでここは省略)
+
+# genesisファイルの作成
+
+json形式でブロックチェーンの元となる、genesisブロックを作成します。
+genesisブロック例
+
+
+```sh
+
+{
+  "nonce"      : "0x0000000000000099",
+  "alloc"      : {},
+  "coinbase"   : "0x0000000000000000000000000000000000000000",
+  "difficulty" : "0x20000",
+  "extraData"  : "",
+  "gasLimit"   : "0x2fefd8",
+  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
+  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+  "timestamp"  : "0x00"
+}
+
+```
+
+# gethを初期化する
+
+genesisblockができたので、genesisを元にgethによって初期化、フォルダを作成します。
+
+```sh
+geth --datadir $HOME/eth/testnet init $HOME/eth/testnet/genesis.json
+```
+ 
+
+実行後にtreeコマンドを打つと以下のように結果が出ます。自動的にフォルダが作成されて便利ですね。
+
+```sh
+tree
+
+├── genesis.json
+├── geth
+│   └── chaindata
+│       ├── 000002.log
+│       ├── CURRENT
+│       ├── LOCK
+│       ├── LOG
+│       └── MANIFEST-000003
+└── keystore
+
+```
+ 
+
+##RPCオプションを設定してgethを起動する
+
+rpcオプションを追加してgethを起動します。
+rpcオプションを設定することで、gethのコンソールからだけでなく、HTTP経由でリクエストの受け口を設定することができます。(rpcはremote procedure callの略)
+
+これを設定しないと、後から仮想通貨コントラクトを実行するためのbrowser-solidityからローカルネットワークへの接続ができなくなってしまいます。
+
+```sh
+geth --networkid 2222 --nodiscover --maxpeers 0 --datadir $HOME/eth/testnet/ --rpc -rpccorsdomain "*" --rpcaddr "0.0.0.0" console
+```
+
+オプションの説明
+
+* --rpc HTTP-RPC を有効にする
+* --rpccorsdomain RPC接続する接続元のIPアドレス、ポート番号を設定します。「*」を設定すると全ての接続元からアクセスを許可します。
+* --rpcaddr RPC接続の受け口のIPアドレスを設定します。デフォルトはlocalhostで、「0.0.0.0」を設定すると、全てのアクセスを受け付けます。(よしなに割り振ってくれます)
+* --networkid ネットワーク識別子。0~3までは予約済だが、それ以外の数値を設定します
+* --nodiscover 他のノードから検出できないようにするオプション
+* --maxpeers 自分のノードに接続できるノード数。テストなので0を設定します
+* console gethを実行してコンソールを起動する
+
+他のオプションの詳細はEthereumのgithubに載っています。
+
+Ethereumのgithub
+https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options
+ 
+ローカルネットワークなので、「*」など雑に指定しておりますが、本当はIPアドレスなどをきちんと設定した方が良いです。
+
+##アドレスを作成する
+
+consoleが起動したら新しいアドレスを作成します。
+personal.newAccountの引数はパスワードです。
+"first","second"というパスで2つアドレスを作成します。
+
+```sh
+personal.newAccount("first")
+0x4351987e308450b8e6d2c46031add1f4e4a4f330
+
+personal.newAccount("second")
+0xa7dc9556fdd013545ba496dd981422eaa53a0a62
+```
+
+eth.accountsでアドレスができている事を確認します。
+
+```sh
+eth.accounts
+["0x4351987e308450b8e6d2c46031add1f4e4a4f330", "0xa7dc9556fdd013545ba496dd981422eaa53a0a62"]
+```
+
+確認後、後ほど実施するマイニングのために、
+マイニング報酬受け取り用アドレスを設定します。
+
+```sh
+miner.setEtherbase(eth.accounts[0]) #マイニング報酬受け取り用アドレスを設定
+eth.coinbase #マイニング報酬受け取り用アドレスの確認
+"0x4351987e308450b8e6d2c46031add1f4e4a4f330"
+```
+
+## ローカルのテストネットワークでマイニングを実施する
+
+最初に作ったアドレスの残高と、このネットワークのブロックが0であることを確認します。
+
+```sh
+> eth.getBalance(eth.accounts[0]) #アドレス残高0
+0
+
+> eth.blockNumber #ブロック高0
+0
+```
+
+マイニングを開始します。
+引数1はマイニングのためのスレッドの数です。成功するとtrueが帰ってきて、ログが流れます。
+
+```sh
+> miner.start(1)
+true
+
+> I0908 01:27:02.630945 eth/backend.go:475] Automatic pregeneration of ethash DAG ON (ethash dir: /Users/nao/.ethash)
+I0908 01:27:02.630946 miner/miner.go:136] Starting mining operation (CPU=1 TOT=2)
+I0908 01:27:02.631403 eth/backend.go:482] checking DAG (ethash dir: /Users/nao/.ethash)
+I0908 01:27:02.642987 miner/worker.go:516] commit new work on block 1 with 0 txs & 0 uncles. Took 11.628222ms
+I0908 01:27:02.644081 vendor/github.com/ethereum/ethash/ethash.go:259] Generating DAG for epoch 0 (size 1073739904) (0000000000000000000000000000000000000000000000000000000000000000)
+I0908 01:27:03.696831 vendor/github.com/ethereum/ethash/ethash.go:291] Generating DAG: 0%
+
+....
+0909 10:01:52.497921 miner/worker.go:516] commit new work on block 942 with 0 txs & 0 uncles. Took 229.749µs
+I0909 10:01:53.426768 miner/unconfirmed.go:105] 🔗 mined block #937 [3911fcec…] reached canonical chain
+I0909 10:01:53.426836 miner/unconfirmed.go:83] 🔨 mined potential block #942 [aac320ba…], waiting for 5 blocks to confirm
+```
+
+報酬を確認します。
+
+```sh
+eth.getBalance(eth.accounts[0]) #weiで表示
+4.955e+21
+web3.fromWei(eth.getBalance(eth.accounts[0]),"ether") #etherで表示
+4955
+```
+
+先ほどは0でしたが、4955ether溜まっていましたね。
+マイニング報酬のetherが溜まったようです。
+マイニングはこのまま続けておきます。
+
+## browser-solidityからローカルのネットワークに接続する
+
+Ethereumでは、ブラウザ上で開発できるIDEであるbrowser-solidityが存在します。
+自動的なコンパイル、GUIでコントラクト発行テストも実施できる、と便利なIDEになっております。
+
+[githubのリポジトリ](https://github.com/ethereum/browser-solidity)からbrowser-solidityを落としてきてinstallします。
+
+開発時の安定版として提供されているのはgh-pagesブランチであるため、git clone後にブランチを切り替えます。
+
+```sh
+git clone https://github.com/ethereum/browser-solidity.git #masterを落としてくる
+cd browser-solidity #落としてきたフォルダに移動
+git checkout -b gh-pages origin/gh-pages # branchを切り替え
+```
+
+起動後、index.htmlをひらけばbrowser-solidityが開かれます。
+
+<img width="1157" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/85120/633b5e17-6937-0197-d36d-1e605530383a.png">
+
+
+右側のEnvironmentでWeb3 Providerを選択します。
+どこに接続するか聞かれるので、localhostを選択しましょう。
+ポート番号はgethのデフォルト、8545を指定します。
+
+<img width="1155" alt="2.png" src="https://qiita-image-store.s3.amazonaws.com/0/85120/a1209286-c679-a50e-51fa-32f1c95384d8.png">
+
+
+右側の「account」にローカルのアカウントが出てくれば成功です。
+ずっとマイニングしっぱなしだったのでetherがかなり溜まっていますね。
+
+<img width="1385" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/85120/92e33105-9109-deb9-da9a-258c414b22f2.png">
+
+
+## browser-solidityで仮想通貨コントラクトを発行する
+
+さて、ついにやっと仮想通貨を発行します。
+
+まずはローカルネットワークのアドレスを使うためにgethからアカウントのアンロックを行います。
+personal.unlockAccountの第1引数はアカウント、第2引数はパスフレーズ、第3引数はアンロックする秒数です。
+第3引数のデフォルトは300(5分)で、0を設定すると無限になります。
+アカウントのアンロックもセキュリティ上あまりよろしくはないので、開発時限定として気をつけてください。
+
+```sh
+personal.unlockAccount(eth.accounts[0],"first")
+true
+```
+
+browser-solidityに[Ethereum公式チュートリアル](https://www.ethereum.org/token)から仮想通貨コントラクトコードから持ってきて貼り付けます。
+EthereumはSolidityというJavaScriptライクな言語でスマートコントラクトを書いて動かします。
+
+```
+pragma solidity ^0.4.16;
+
+contract MyToken {
+ /* This creates an array with all balances */
+ mapping (address => uint256) public balanceOf;
+
+ /* Initializes contract with initial supply tokens to the creator of the contract */
+ function MyToken(
+ uint256 initialSupply
+ ) {
+ balanceOf[msg.sender] = initialSupply; // Give the creator all initial tokens
+ }
+
+ /* Send coins */
+ function transfer(address _to, uint256 _value) {
+ require(balanceOf[msg.sender] >= _value); // Check if the sender has enough
+ require(balanceOf[_to] + _value >= balanceOf[_to]); // Check for overflows
+ balanceOf[msg.sender] -= _value; // Subtract from the sender
+ balanceOf[_to] += _value; // Add the same to the recipient
+ }
+}
+```
+
+function MyTokenがこのコントラクトのコンストラクタで、initialSupplyを設定して初期のトークンコントラクトを発行します。
+
+二つ目にあるfunction transferが送り先アドレスと金額を設定する送金のための関数です。
+
+今回は100000単位分のトークンを設定してContractを発行します。
+
+browser-solidityの右下にある「Create」にinitialSupplyの引数100000を設定してクリックします。
+
+
+10~20秒ほどして、マイニングが完了すると、使用したgasの代金、変数や関数のボックスが右下に現れます。
+
+うまくいかない場合は、コンソール側でマイニングが走っているか確認してみてください。
+
+<img width="1133" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/85120/6c5fcd8c-0f72-eba5-772f-84fc15c1e790.png">
+
+balanceOfに実行したアドレスを設定してクリックし、実行してみます。
+アドレスは"(ダブルクォート)で囲んで設定します。
+
+<img width="1147" alt="5.png" src="https://qiita-image-store.s3.amazonaws.com/0/85120/8927f4fd-d475-8532-3e8d-414a3384633a.png">
+
+
+MyToken100000単位ができていることが確認できますね。
+あっけない感じですが、最低限のコイン発行は完了しました。
+
+## 発行した仮想通貨を送金する
+
+右下のtransfer関数に、「送り先アドレス」、「送金金額」を設定して実行します。
+送り先アドレスには二つ目に作ったアドレス、送金金額には20000単位を設定します。
+しばらくしてマイニングが完了すると送金結果が出てきます。
+
+<img width="617" alt="6.png" src="https://qiita-image-store.s3.amazonaws.com/0/85120/ea7825cf-ba0c-0562-eaf2-b9183653190d.png">
+
+balanceOfを先ほど同様に確認すると、1つ目のアドレスから20000単位へり、2つ目のアドレスに20000単位増えていることが確認できます。
+
+1つ目のアドレス(20000単位減って80000単位)
+<img width="640" alt="7.png" src="https://qiita-image-store.s3.amazonaws.com/0/85120/3620fada-c5a9-cc78-635e-ac81c0abfcec.png">
+
+2つ目のアドレス(20000単位増加)
+<img width="618" alt="8.png" src="https://qiita-image-store.s3.amazonaws.com/0/85120/9aa3423b-4b02-2af7-0f76-3dceddfee185.png">
+
+送金もできることが確認できましたね。
+
+## 感想
+
+Ethereumで、最低限の機能に限ればこれだけでも通貨は発行できます。
+Dappsと組み合わせて作成を行い、流通のプラットフォームとなるプロジェクトをいかに設計し、通貨としての機能をいかに使わせるシステムにするかが肝となると考えています。
+
+そんなわけで近々、Dappの開発に関して(勉強して)記事を書きたいと思います。
+
+
+## 参考サイト
+
+[Ethereum公式 トークン発行](https://www.ethereum.org/token)
+
+[browser-solidityのgithubリポジトリ](https://github.com/ethereum/browser-solidity:title)
+
+[gethのコマンドオプション](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options:title)