Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[jp] Lesson 10 translate #742

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions jp/10/00-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: "Truffleを使ってDAppsをデプロイする"
header: "Truffleを使ってDAppsをデプロイする"
roadmap: roadmap.jpg
path: solidity_advanced
position: 2
publishedOn: Cryptozombies
---

スマートコントラクトをデプロイする方法を教えると約束したことを覚えているか?

時間はかかったが、ついにその時が来たぞ!

このレッスンでは **_Truffle_** を使って **_Ethereum_** にデプロイする方法を学ぶのだ。

加えて、お前のスマートコントラクトを **_Loom_** にデプロイする方法も伝授するぞ😎。

なぜ **_Loom_** かだと?結局ところ、 **_イーサリアム_** は最高に安全なネットワークだ。

ああ、我々はそこについて異論はない。しかしだ。イーサリアムは取引のたびに _ガス_ を消費するだろう。するとお前のユーザーは取引ごとにフィー(手数料)を支払わなければならないのだ。しかもユーザーは取引が完了するまでに最低でも10秒待たなければならない。

一言で言えば、 **_イーサリアム上の全ての取引は、平等にセキュリティの保証を受けている_** ということだ。ユーザー向けのDAppやゲームなんかだと、このセキュリティレベルは必要ないだろう。実際、ユーザーエクスペリエンスを損なうだけなのだ。

**_Loom_** 上では、ユーザーははるかにスピーディーかつガス代のかからない取引ができる。ユーザー向けのDAppやゲームには最適じゃないか。

話は終わりだ!とりかかるぞ😉
53 changes: 53 additions & 0 deletions jp/10/01.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: イントロダクション
actions: ['答え合わせ', 'ヒント']
requireLogin: true
material:
terminal:
help:
You should probably run `npm install truffle -g`.
commands:
"npm install truffle -g":
hint: npm install truffle -g
output: |
/usr/local/bin/truffle -> /usr/local/lib/node_modules/truffle/build/cli.bundled.js
+ [email protected]
added 81 packages from 311 contributors in 5.104s
---

もしお前が **CryptoZombies** を始めたばかりなら、ビギナー向けの6レッスンを先に受けることを勧める。時間をかけてでもスマートコントラクトの開発に慣れるのだ。そこを飛ばすと、このレッスンは非常に厳しいものになるぞ。

## 欠けたピース

お前は前のレッスンをクリアしたということだな。素晴らしいじゃないか!お前はすでにDAppsを構築する技術をほぼ習得したということだ。

しかし!重要なピースがまだ欠けているぞ。

そうだ…お前は **_スマートコントラクトをデプロイする方法_** を学ばねばなるまい。

フロントエンド開発の経験があれば、 *WebpackやGulp、Browserify* などの開発者を楽にするツールに慣れているだろう。

では **Solidity** の開発者はどんなツールを使っているのか?

## Truffle

**_Truffle_** は最も有名なブロックチェーン開発のフレームワークだ。その理由は、便利機能が満載だからだ:

- スマートコントラクトのコンパイルを簡素化
- ABI自動生成
- スマートコントラクトのテストを統合 - **Mocha** や **Chai** をサポートしているぞ!
- 複数のネットワークをサポート - コードはRinkeby、 **_Ethereum_** 、そして **_Loom_** にもデプロイできる。これについては後ほど説明してやろう。

`npm` と `node` をすでにインストールしているなら、 **Truffle** をグローバルインストールするのだ。

# さあテストだ

まずは、新しいターミナルウインドウを立ち上げ、`CryptoZombies`というディレクトリを作成し、`cd`でディレクトリの中に入るのだ。

1. さあ、 **Truffle** をグローバルインストールするぞ。

> 注: ここに`npm`でパッケージをグローバルインストールするコマンドを示すぞ:

```bash
npm install package_name -g
```
87 changes: 87 additions & 0 deletions jp/10/02.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
title: Getting Started with Truffle
actions: ['答え合わせ', 'ヒント']
requireLogin: true
material:
terminal:
help: |
First, you should probably run `truffle init`. Next, execute `npm install truffle-hdwallet-provider`
commands:
"truffle init":
hint: truffle init
output: |
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

Compile: truffle compile
Migrate: truffle migrate
Test contracts: truffle test
"npm install truffle-hdwallet-provider":
hint: npm install truffle-hdwallet-provider
output: |
+ [email protected]
added 1 package from 1 contributor and audited 71402 packages in 5.612s
found 0 vulnerabilities
---

**Truffle** のインストールが終わったら、次は`truffle init`コマンドを叩いて、我々のプロジェクトを初期化するぞ。このコマンドは、フォルダーと設定ファイルを以下のような構成で作成してくれる:

```
├── contracts
├── Migrations.sol
├── migrations
├── 1_initial_migration.js
└── test
truffle-config.js
truffle.js
```

Contracts, migrations, tests... ややこしいな😟

心配するな。 **Truffle** の使い方を学んでいるからと言って、ゾンビに脳みそを食べられたりしない。この章では **Truffle** のデフォルトのプロジェクト構成を紹介する。一旦 **Truffle** の使い方を知ってしまえば、スマートコントラクトのデプロイなんて朝飯前になるぞ。

## Truffleのデフォルトのディレクトリー構成

さあ、`CryptoZombies`ディレクトリーの中で`truffle init`コマンドを叩いて、いくつかのディレクトリーとJavaScript、Solidityのファイルを作成するのだ。詳しく見ていくぞ:

- **_contracts_**: ここに我々のスマートコントラクトのコードを全て置く。コードを整理するには、`contracts/tokens`というように子フォルダーを作成すればいい😉。

> 注: `truffle init`コマンドは自動的に`Migrations.sol`という名前のコントラクトとそれに対応するマイグレーションファイルを作成する。この説明は後だ。

- **_migrations_**: ここにはJavaScriptで書かれたマイグレーションファイルが置かれている。 **Truffle** がスマートコントラクトにデプロイする際の設定が書かれているぞ。

- **_test_**: ここにテストコードを置く。テストコードはJavaScript か Solidityで書かなければならない。コントラクトはデプロイしたら変更できないことを覚えているか?デプロイ前にスマートコントラクトをテストすることが不可欠だ。

- **_truffle.js_** and **_truffle-config.js_**: ここにはデプロイ用のネットワーク設定ファイルが置かれている。`truffle.js` と `truffle-config.js`の内容は同じだ。Windows環境では`truffle.js` と `truffle.exe`が同じフォルダーにあると競合してしまう。お前がWindowsを使っているなら、`truffle.js`を削除し、`truffle-config.js`をデフォルトの設定ファイルにするのだ。詳しく知りたければ<a href="https://truffleframework.com/docs/truffle/reference/configuration" target=_blank>Truffleの公式ドキュメント</a>を訪ねるといい。


こんなディレクトリー構成を使わなければならないのか?不慣れだし、ややこしく見える…

それには2つ理由がある。1つ目は、これらのフォルダーの名前を変えてしまうと、 **Truffle** が期待通りに動かなくなる。

2つ目は、この構成ルールに従うことで、他の開発者がお前のプロジェクトを理解しやすくなるということだ。標準のフォルダー構成とコーディング規則を使えば、配布したりチームメンバを変えたりした時に役立つだろう。


## truffle-hdwallet-provider

このレッスンでは、 _Infura_ を使ってコードを **_Ethereum_** にデプロイする。この方法を使えば、アプリを動かすのに **_Ethereum_** のノードやウォレットを独自にセットアップする必要がなくなるのだ。
しかし、安全面から、 _Infura_ は秘密鍵の管理をしない。つまり、我々に代わって取引に署名することはできないということだ。**Truffle** に署名を要求するスマートコントラクトをデプロイするためには、 `truffle-hdwallet-provider` というツールを使うぞ。このツールの唯一の目的は、取引に署名処理を施すことだ。

> 注: もしかしたら前の章で `truffle-hdwallet-provider` を次のようなコマンドを叩いてインストールしなかったことを不思議に思っているかもしれない:

```JavaScript
npm install truffle truffle-hdwallet-provider
```

そう…`truffle init`コマンドを叩くには、空のディレクトリーである必要があるのだ。もし1つでもファイルが存在すれば、エラーになってしまう。従って、手順通りに`truffle init`をした後に`truffle-hdwallet-provider`をインストールしなければならないのだ。


# さあテストだ

1. `truffle init`コマンドを叩け。先ほど説明したようなディレクトリー構成を作ってくれるだろう。

2. `npm install truffle-hdwallet-provider`コマンドを叩け。
115 changes: 115 additions & 0 deletions jp/10/03.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
title: ソースコードをコンパイルする
actions: ['答え合わせ', 'ヒント']
requireLogin: true
material:
terminal:
help:
You should probably run `truffle compile`.
commands:
"truffle compile":
hint: truffle compile
output: |
Compiling ./contracts/Migrations.sol...
Compiling ./contracts/CryptoZombies.sol...
Compiling ./contracts/erc721.sol...
Compiling ./contracts/ownable.sol...
Compiling ./contracts/safemath.sol...
Compiling ./contracts/zombieattack.sol...
Compiling ./contracts/zombiefactory.sol...
Compiling ./contracts/zombiefeeding.sol...
Compiling ./contracts/zombiehelper.sol...
Compiling ./contracts/zombieownership.sol...
Writing artifacts to ./build/contracts
---

おめでとう!プロジェクト構成を整え、`truffle-hdwallet-provider`をセットアップできた。さあ、我々のコントラクトをコンパイルするぞ。

なぜコンパイルが必要か、聞きたいか?

_Ethereumの仮想マシン_ はSolidityで書かれたソースコードを直接理解することはできない。従って、コンパイラーを動かし、機械が読める **_bytecode_** に翻訳する必要があるのだ。次に、仮想マシンがバイトコードを実行し、我々のスマートコントラクトが要求するアクションの数々を実行する。

バイトコードがどんな感じか興味があるか?少し見てみるか:

```
"0x60806040526010600155600154600a0a6002556201518060035566038d7ea4c6800060085560006009556046600a55336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1..."
```

この通り、人間どもにとってバイトコードは現実のゾンビと同じくらい理解しがたいものだろう!

## Solidityのコンパイラーを使用する

Solidityのコンパイラーの話をするなら、開発者達が用意してくれた気の利いた機能について言及せねばなるまい。

`SafeMath`に含まれる`add`関数の定義を次のように修正する:

```
function add(uint16 a, uint16 b) internal returns (uint16) {
uint16 c = a + b;
assert(c >= a);
return c;
}
```

この関数をコンパイルすると、Solidityのコンパイラーは次のような **_警告_** を発するであろう:

```
safemath.sol:110:11: Warning: Function state mutability can be restricted to pure
function add(uint16 a, uint16 b) internal returns (uint16) {
^ (Relevant source part starts here and spans across multiple lines).
```

コンパイラーが言わんとしていることは、この関数はブロックチェーンに読み書きしないから`pure`修飾子を使用せよということだ。

なぜ重要かって?

そう、`pure` や `view`関数はガスを節約できるのであった。関数がブロックチェーンの状態を変更しないのであれば、マイニングする必要がないのだ。言ってしまえば、`pure` や `view`関数は無料で`呼べる`。


## CryptoZombies- The Game

覚えているか?我々はロジックを`ZombieOwnership.sol`という名のスマートコントラクトに書いたであろう。

うーむ…ゲームにとってイケてる名前とは言い難い。

幸運にも、名前は問題にならない。継承すれば、同じアクションと機能を持つスマートコントラクトを、任意の名前で作れるからな。

さあ、`CryptoZombies`という名前の新たなコントラクトを、`ZombieOwnership.sol`を継承して作成するぞ:

```solidity
pragma solidity ^0.4.24;

import "./zombieownership.sol";

contract CryptoZombies is ZombieOwnership
{

}
```

次に、スマートコントラクトを全て`./contracts`フォルダーにコピーするぞ。すると、プロジェクトの構成は次のようになるはずだ:

```
.
├── contracts
├── Migrations.sol
├── CryptoZombies.sol
├── erc721.sol
├── ownable.sol
├── safemath.sol
├── zombieattack.sol
├── zombiefactory.sol
├── zombiefeeding.sol
├── zombiehelper.sol
├── zombieownership.sol
├── migrations
└── test
```

これで準備は整った。さあ、我々のプロジェクトをコンパイルしようではないか。

# さあテストだ

1. `truffle compile`コマンドを叩け。このコマンドはビルドされた中間生成物を、`./build/contracts`に置いてくれる。

> 注: この中間生成物は、スマートコントラクトのバージョン、ABIおよび **Truffle** が使用する内部データで構成された「バイトコード」だ。編集するんじゃないぞ。さもないと **Truffle** が正常に動かなくなるぞ。
60 changes: 60 additions & 0 deletions jp/10/04.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
title: マイグレーション
actions: ['答え合わせ', 'ヒント']
requireLogin: true
material:
editor:
language: JavaScript
startingCode:
"./contracts/2_crypto_zombies.js": |
var Migrations = artifacts.require("./Migrations.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};
answer: |
var CryptoZombies = artifacts.require("./CryptoZombies.sol");
module.exports = function(deployer) {
deployer.deploy(CryptoZombies);
};
---

通常であれば、 **_Ethereum_** にデプロイする前の時点で、スマートコントラクトをテストしたくなるだろう。<a href="https://truffleframework.com/ganache" target=”_blank”>Ganache</a>というツールを使って、 **_Ethereum_** のネットワークをローカル環境に構築することができる。

テストは非常に重要ではあるが、その説明には膨大なレッスンが必要となる - だからこのレッスンではデプロイに集中するぞ。テストについて詳しく知りたければ、<a href="http://cryptozombies.io/jp/lesson/10" target=”_blank”>Testing Smart Contracts with Truffle</a>というレッスンを用意しておるぞ。

<!-- TODO: update ^^ link, if needed -->

**_Ethereum_** にデプロイするには、 **マイグレーション** と呼ばれるものを作成しなければならない。

マイグレーションはJavaScriptで書かれ、 **Truffle** が **_Ethereum_** にデプロイする手助けをしておる。`truffle init`コマンドで作成された`Migrations.sol`という名の特別なコントラクトが、お前がコードに加えた変更を追跡していることに注意せよ。このコントラクトは、変更履歴をオンチェーンに保存しておる。従って、同じコードを2度デプロイすることはできないぞ。

## 新しいマイグレーションを作成する

`truffle init`がすでに作成してくれておるファイルを使うぞ - `./contracts/1_initial_migration.js`だ。
中身を見てみようではないか:

```javascript
var Migrations = artifacts.require("./Migrations.sol");
module.exports = function(deployer) {
deployer.deploy(Migrations);
};
```

ものすごく直感的であろう?

1行目で `Migrations` コントラクトと対話したいと **Truffle** に伝えている。

2行目で`deployer`というオブジェクトをパラメータとして受け取る関数をエクスポートしている。このオブジェクトは、お前(開発者)と **Truffle** のデプロイメントエンジンの間のインターフェースとしての役割をしておる。`deployer`は多数の便利機能を提供しているが、このレッスンでは扱わないぞ。 **Truffle** の能力をもっと知りたければ、終わった後で **Truffle** の<a href="https://truffleframework.com/docs/truffle/getting-started/running-migrations" target=”_blank”>ドキュメント</a>をチェックするがいい。

デプロイに必要なものは揃った。新しいファイル `./contracts/2_crypto_zombies.js` を作成し、`./contracts/1_initial_migration.js` の中身をコピペするぞ。

# さあテストだ

1. `./contracts/2_crypto_zombies.js` を次のように編集せよ:

```JavaScript
var CryptoZombies = artifacts.require("./CryptoZombies.sol");
module.exports = function(deployer) {
deployer.deploy(CryptoZombies);
};
```
Loading