Ethereum入門　〜シンプルなSmart ContractをRinkeby Networkにデプロイ〜

#はじめに
localにsolcやmochaをインストールし、terminalからRinkeby Networkに簡単なスマートコントラクトをデプロイしてみます。

#Rinkebyにデプロイ
##各種インストール

```
$mkdir inbox
$cd inbox/
$npm init
```
npm initを押すと下記のように出ますが、全てEnterでOKです。

>ackage name: (inbox) 
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 



するとpackage.jsonがinbox内にインストールされます。

```
$ls
package.json
```

次にsolcをインストールします。

```$npm install --save solc```

mochaインストール

```
npm install --save mocha ganache-cli web3@1.0.0-beta.26
```


次にtruffle-hdwallet-providerをインストール
この時にversion指定をしないと上手く動作しなかったので@0.0.3をインストールした方が良いです。

```
npm install --save truffle-hdwallet-provider@0.0.3
```
参考
https://stackoverflow.com/questions/50201353/unhandledpromiserejectionwarning-error-the-contract-code-couldnt-be-stored-p


##infuraでURL取得
https://infura.io/
signupすると登録したメールアドレスに各種ネットワークのURLが送付されてきます。<img width="464" alt="Screen Shot 2018-07-05 at 17.26.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/200669/83a8e5aa-f9da-d753-6c24-9bc17099de2a.png">




##コード

ディレクトリ構成はこのような形です。

```
inbox
├── compile.js
├── contracts
│   └── Inbox.sol
├── deploy.js
├── node_modules
│   ├── abstract-leveldown
│   ├── ... 
│   └── ...
├── package-lock.json
├── package.json

```




```compile.js
const path = require('path');
const fs = require('fs');
const solc = require('solc');

const inboxPath = path.resolve(__dirname, 'contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxPath, 'utf8');

module.exports = solc.compile(source,1).contracts[':Inbox'];
```

スマートコントラクトはメッセージを登録する簡単なものです。

```Inbox.sol
pragma solidity ^0.4.17;

contract Inbox{
    string public message;

    function Inbox(string initialMessage) public {
        message = initialMessage;
    }

    function setMessage(string newMessage) public {
        message = newMessage;
    }
}

```

```deploy.js
const HDWalletProvider = require('truffle-hdwallet-provider');
const Web3 = require('web3');
const { interface, bytecode } = require('./compile');

const provider = new HDWalletProvider(

'twelve word mnemonic...', //Metamaskのニーモニックを記入
'https://rinkeby.infura.io/...' //infraで取得したURLを記入
);

const web3 = new Web3(provider);

const deploy = async () => {
    const accounts = await web3.eth.getAccounts();

    console.log('Attempting to deploy from account', accounts[0]);
    const result = await new web3.eth.Contract(JSON.parse(interface))
        .deploy({data: bytecode, arguments: ['Hi there!'] })
        .send({ gas: '1000000', from: accounts[0] });

    console.log('Contract deployed to', result.options.address);
    
};
deploy();

```

package.json　のtestを"mocha"に変更します。

```package.json
{
  "name": "inbox",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "mocha"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "ganache-cli": "^6.1.4",
    "mocha": "^5.2.0",
    "solc": "^0.4.24",
    "truffle-hdwallet-provider": "0.0.3",
    "web3": "^1.0.0-beta.26"
  }
}

```


##デプロイ

`node deploy.js`

```
Attempting to deploy from account 0x686...
Contract deployed to 0xE4365...
```
このように出力されれば成功です。

rinkebyのネットワークで確認する事ができます。
https://rinkeby.etherscan.io/

<img width="1210" alt="Screen Shot 2018-07-05 at 17.21.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/200669/ed183b00-252e-12e2-2a54-a03d094fe093.png">



#終わりに
terminalからRinkeby Networkにデプロイする事が出来ました。
自分でもよく分かってないところが多いので、引き続き勉強します。


#参考にさせて頂きました
[Ethereum and Solidity: The Complete Developer's Guide](https://www.udemy.com/ethereum-and-solidity-the-complete-developers-guide/learn/v4/overview)