最小構成のEthereum Tokenのprivatenetへの登録

Ethereum上のSmart Contractで必要最低限な機能を持つTokenを実装し、
privatenetに登録してメソッドを呼び出すところまでやってみたので、その内容を共有したいと思います。

## Contractの実装

まずは、[本家のtoken解説記事](https://www.ethereum.org/token)を見ながら進めます。

**最小構成**は以下のコードのようです。  
こちらをもとに機能をたしていこうと思います。

> MINIMUM VIABLE TOKEN
> The token contract is quite complex. But in essence a very basic token boils down to this:

```
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) {
        if (balanceOf[msg.sender] < _value) throw;           // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
    }
}
```

### solidityのversionについて

ソースコードの冒頭に以下のような記述をするみたいです。

[こちらの記事@Qiita](http://qiita.com/tomohata/items/09b06b9756c7c2fee5b9)にもあるように

> Solidity versionが0.4.9だと一部記述が変更されているので注意。

だそうです。

```
pragma solidity ^0.4.8;
```

#### インストールされたversionの確認

```
$ solc --version
solc, the solidity compiler commandline interface
Version: 0.4.11+commit.68ef5810.Linux.g++
```

-> いったん`^0.4.11`で記述してみる。


### 最小限のものをデプロイ

gethプロセスおよびremixのサーバープロセスを立ち上げておきます。  
（私はここでは、docker使って立ち上げています。）
結局以下のように実装しました。

```
pragma solidity ^0.4.11;

contract TestKumanoToken {
    /* 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 TestKumanoToken(
        uint256 initialSupply
        ) {
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
    }

    /* Send coins */
    function transfer(address _to, uint256 _value) {
        if (balanceOf[msg.sender] < _value) throw;           // Check if the sender has enough
        if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
        balanceOf[msg.sender] -= _value;                     // Subtract from the sender
        balanceOf[_to] += _value;                            // Add the same to the recipient
    }
}
```

- remixのContractタブにて`initialSupply`に適当に`10000`をいれて「Create」ボタンを押下します。

```
callback contain no result Error: authentication needed: password or unlock
```

というエラーがでる。。。


Web3 deployの箇所で from が web3.eth.accounts[0] となっている。。。  
つまり gethのメインアカウントをunlockしておかにとダメなようだ。。。

**Web3 deploy**

```
var initialSupply = /* var of type uint256 here */ ;
var test_kumano_token_sol_testkumanotokenContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"}],"payable":false,"type":"constructor"}]);
var test_kumano_token_sol_testkumanotoken = test_kumano_token_sol_testkumanotokenContract.new(
   initialSupply,
   {
     from: web3.eth.accounts[0], // <- ここ！
     data: '省略', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })
```

**geth consoleにて**

account[0]をunlockします。

```
> personal.unlockAccount(eth.accounts[0])
Unlock account 0xaa41331cdaac5b64189c9369f65baf6964387ec9
Passphrase: hit accounts[0] password & hit enter.
true
```


**retry**

再度「Create」ボタンを押してみます。

```
callback contain no result Error: insufficient funds for gas * price + value
```

ぐぐぐ・・・

なるほど・・でも確かにaccounts[0]の所持金が0ethなので、ただでContractは公開できませんよね。。。

**geth consoleにて**

採掘を行います。
***※ genesis.jsonのdifficultyを低めに設定しておき、miningしやすくしておきます。***

```
> miner.start()
true
```

ほどよいころあい（2分後くらい？）で、採掘を終了しておきます。

```
> miner.stop()
true
```

45 etherくらいたまったところで（mainネットで45eth欲しい^^）

**re: retry**

再度×2「Create」ボタンを押して見ます。

```
callback contain no result Error: invalid sender
```

ぐぐぐぐぐぐぐ・・・


**genesis.jsonのconfigを修正**

どうも立ち上げている`geth`の起動オプションと`genesis.json`の`config.chainId`が一致していないためにおきている模様

[go ethereum - Invalid sender error on private chain - Ethereum Stack Exchange](https://ethereum.stackexchange.com/questions/13498/invalid-sender-error-on-private-chain/15375)

**genesis.json**

```
  "config": {
    "chainId": 15, // <- ここをnetworkidに合わせて、geth initし直し
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
```

**re: re: retry**

> Waiting for transaction to be mined...

成功しました。

transactionを送信したので、miningを再開させて、とりこんでいきます。

```
> miner.start()
true
// eth.blockNumberみながらblockがすすんだらminer.stop()する
```

-> `0xa066c8e327d706af04966f78e5bec3403851a124`のアドレスにデプロイされました。


### Contractを実行

**geth consoleにて**

```
> var test_kumano_token_sol_testkumanotokenContract = eth.contract([{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"}],"payable":false,"type":"constructor"}]).at('0xa066c8e327d706af04966f78e5bec3403851a124')
> test_kumano_token_sol_testkumanotokenContract.balanceOf(eth.accounts[0])
10000
```

途中で少し予期しないエラーに阻まれましたが・・・
無事Tokenの最小構成である`TestKumanoToken Contract`を privatenetに登録し、ownerのtoken保有数を確認することができました。

以上になります。