丸の内で働くブロックチェーンエンジニアのブログ

丸の内でブロックチェーンエンジニアとして働いています。勉強している技術情報やニュースを紹介します。

Ethereumで仮想通貨を発行する(2)

この記事ではMac OS Sierra 10.12.4を使っています。

前回はgethの環境構築まで実施しました。

Ethereumで仮想通貨を発行する(1) - 丸の内で働くブロックチェーンエンジニアのブログ

今回は仮想通貨コントラクトの発行を行います。

RPCオプションを設定してgethを起動、アドレスを作成する

rpcオプションを追加してgethを起動します。 前回の最後のコマンドでgethを起動していたら、再起動します。

rpcオプションを設定することで、gethのコンソールからだけでなく、HTTP経由でリクエストの受け口を設定することができます。(rpcはremote procedure callの略)

これを設定しないと、後から仮想通貨コントラクトを実行するためのbrowser-solidityからローカルネットワークへの接続ができなくなってしまいます。

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」を設定すると、全てのアクセスを受け付けます。(よしなに割り振ってくれます)

ローカルネットワークなので、「*」など雑に指定しておりますが、本当はIPアドレスなどをきちんと設定した方が良いです。

consoleが起動したら新しいアカウントを作成します。 personal.newAccountの引数はパスワードです。 "first","second"というパスで2つアドレスを作成します。

personal.newAccount("first")
0x4351987e308450b8e6d2c46031add1f4e4a4f330

personal.newAccount("second")
0xa7dc9556fdd013545ba496dd981422eaa53a0a62

eth.accountsでアドレスができている事を確認します。

eth.accounts
["0x4351987e308450b8e6d2c46031add1f4e4a4f330", "0xa7dc9556fdd013545ba496dd981422eaa53a0a62"]

確認後、後ほど実施するマイニングのために、 マイニング報酬受け取り用アドレスを設定します。

miner.setEtherbase(eth.accounts[0]) #マイニング報酬受け取り用アドレスを設定
eth.coinbase #マイニング報酬受け取り用アドレスの確認
"0x4351987e308450b8e6d2c46031add1f4e4a4f330"

ローカルのテストネットワークでマイニングを実施する

最初に作ったアドレスの残高と、このネットワークのブロックが0であることを確認します。

> eth.getBalance(eth.accounts[0])  #アドレス残高0
0

> eth.blockNumber #ブロック高0
0

マイニングを開始します。 引数1はマイニングのためのスレッドの数です。成功するとtrueが帰ってきて、ログが流れます。

> 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

報酬を確認します。

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のリポジトリからbrowser-solidityを落としてきてinstallします。

開発時の安定版として提供されているのはgh-pagesブランチであるため、git clone後にブランチを切り替えます。

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が開かれます。

f:id:naomasabit:20170909234330p:plain

右側のEnvironmentでWeb3 Providerを選択します。 どこに接続するか聞かれるので、localhostを選択しましょう。 ポート番号はgethのデフォルト、8545を指定します。

f:id:naomasabit:20170909234446p:plain

右側の「account」にローカルのアカウントが出てくれば成功です。 ずっとマイニングしっぱなしだったのでetherがかなり溜まっていますね。

f:id:naomasabit:20170910011123p:plain

browser-solidityで仮想通貨コントラクトを発行する

さて、ついにやっと仮想通貨を発行します。

まずはローカルネットワークのアドレスを使うためにgethからアカウントのアンロックを行います。 personal.unlockAccountの第1引数はアカウント、第2引数はパスフレーズ、第3引数はアンロックする秒数です。 第3引数のデフォルトは300(5分)で、0を設定すると無限になります。 アカウントのアンロックもセキュリティ上あまりよろしくはないので、開発時限定として気をつけてください。

personal.unlockAccount(eth.accounts[0],"first")
true

browser-solidityにEthereum公式チュートリアルから仮想通貨コントラクトコードから持ってきて貼り付けます。 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の代金、変数や関数のボックスが右下に現れます。

うまくいかない場合は、コンソール側でマイニングが走っているか確認してみてください。

f:id:naomasabit:20170910011154p:plain

balanceOfに実行したアドレスを設定してクリックし、実行してみます。 アドレスは"(ダブルクォート)で囲んで設定します。

f:id:naomasabit:20170910011220p:plain

MyToken100000単位ができていることが確認できますね。 あっけない感じですが、最低限のコイン発行は完了しました。

発行した仮想通貨を送金する

右下のtransfer関数に、「送り先アドレス」、「送金金額」を設定して実行します。 送り先アドレスには二つ目に作ったアドレス、送金金額には20000単位を設定します。 しばらくしてマイニングが完了すると送金結果が出てきます。

f:id:naomasabit:20170910002610p:plain

balanceOfを先ほど同様に確認すると、1つ目のアドレスから20000単位へり、2つ目のアドレスに20000単位増えていることが確認できます。

1つ目のアドレス(20000単位減って80000単位) f:id:naomasabit:20170910011420p:plain

2つ目のアドレス(20000単位増加) f:id:naomasabit:20170910011407p:plain

送金もできることが確認できましたね。

感想

Ethereumで、最低限の機能に限ればこれだけでも通貨は発行できます。 Dappsと組み合わせて作成を行い、流通のプラットフォームとなるプロジェクトをいかに設計し、通貨としての機能をいかに使わせるシステムにするかが肝となると考えています。

そんなわけで近々、Dappの開発に関して(勉強して)記事を書きたいと思います。

参考サイト

Ethereum公式 トークン発行

browser-solidityのgithubリポジトリ

gethのコマンドオプション