Skip to content

Commit

Permalink
Merge pull request CryptozombiesHQ#12 from loomnetwork/lesson-2-updates
Browse files Browse the repository at this point in the history
updates to lesson 2
  • Loading branch information
lukezhangstudio authored Jan 18, 2018
2 parents 71ac1e7 + d2ea4eb commit 389f07a
Show file tree
Hide file tree
Showing 16 changed files with 102 additions and 104 deletions.
5 changes: 3 additions & 2 deletions zh/2/00-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: 僵尸攻击人类
header: 所以,你需要晋级至第二课!
roadmap: roadmap2.jpg
---

厉害了,我的人类! 你比我设想的更会编程!
第二课中你会学到如何通过喂养其他生物,增加你僵尸军团的数量
在这一课中,我们会使用到一些高级的Solidity概念,所以你一定要先完成第一课。
第二课中,你会学到如何通过吞噬其他生物,扩张你的僵尸军团
在这一课里,我们会使用到一些高级的Solidity概念,所以你一定要先完成第一课。
20 changes: 10 additions & 10 deletions zh/2/1-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ material:
answer: 1
---

在第一课中,我们创建了一个命名的函数用来生成僵尸 ,并且将它放置在我们区块链的僵尸数据库中
在第二课里,我们会让我们的app更加像一个游戏: 让它支持多用户,并且采用更加有趣--而不仅仅随机--的方式,来生成僵尸,
在第一课中,我们创建了一个命名函数用来生成僵尸,并且将它放入区块链上的僵尸数据库中
在第二课里,我们会让我们的app看起来更像一个游戏: 它得支持多用户,并且采用更加有趣--而不仅仅随机--的方式,来生成新的僵尸。

我们如何生成新的僵尸呢?通过让僵尸“喂食”其他生物
如何生成新的僵尸呢?通过让现有的僵尸猎食其他生物

## 僵尸喂食
## 僵尸猎食

僵尸喂食的时候, 它会用病毒侵入宿主, 这些病毒会将宿主变为新的僵尸,加入你的军团。系统会通过宿主和侵入僵尸的DNA计算出新僵尸的DNA
僵尸猎食的时候, 僵尸病毒侵入猎物, 这些病毒会将猎物变为新的僵尸,加入你的Solidity。系统会通过猎物和猎食者僵尸的DNA计算出新僵尸的DNA

僵尸最喜欢喂食什么样的物种呢
僵尸最喜欢猎食什么物种呢
等你学完第二课就知道了!

# 小测试
# 实战演习

右边是一个简单的喂食展示。点击一个“人”,试试看僵尸喂食的时候会发生什么?
可见,新僵尸的DNA是通过从原来的僵尸的DNA, 加上宿主的DNA计算得来的
右边是一个简单的猎食演示。点击一个“人”,看看僵尸猎食的时候会发生什么?
可见,新僵尸的DNA是通过从原来的僵尸的DNA, 加上猎物的DNA计算得来的

学完这一章,请点击“下一章”, 我们让游戏支持多玩家模式
学完这一章,请点击“下一章”, 我们该让游戏支持多玩家模式了
32 changes: 17 additions & 15 deletions zh/2/10-interactingcontracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,21 +95,21 @@ material:
}
---

是时候喂喂我们的僵尸了! 那僵尸最喜欢吃什么呢
是时候让我们的僵尸去捕猎! 那僵尸最喜欢的食物是什么呢

Crypto僵尸喜欢吃的是...

** CryptoKitties!** 😱😱😱

(正经点,我可不是开玩笑😆)

为了做到这一点,我们要读出CryptoKitties智能合约中的kittyDna。这些数据是公开存储在区块链中的。区块链是不是很酷?
为了做到这一点,我们要读出CryptoKitties智能合约中的kittyDna。这些数据是公开存储在区块链上的。区块链是不是很酷?

别担心 - 我们的游戏并不会伤害到任何真正的CryptoKitty。 我们只读取* CryptoKitties数据,但是无法物理上删除它
别担心 - 我们的游戏并不会伤害到任何真正的CryptoKitty。 我们只读取* CryptoKitties*数据,但却无法物理上删除它。

##与其他合约交互
##与其他合约的交互

如果我们的合约需要和区块链上的其他的合约对话,则需要先定义一个** _interface_ **(接口)。
如果我们的合约需要和区块链上的其他的合约会话,则需先定义一个** _interface_ **(接口)。

先举一个简单的栗子。 假设在区块链上有这么一个合约:

Expand All @@ -128,9 +128,9 @@ contract LuckyNumber {
}
```

这是个简单的合约,您可以用它存储自己的幸运号码,并与您的以太坊地址关联。 这样其他人就可以使用这个地址查找您的幸运号码了
这是个很简单的合约,您可以用它存储自己的幸运号码,并将其与您的以太坊地址关联。 这样其他人就可以通过您的地址查找您的幸运号码了

现在假设我们有一个外部合约,使用`getNum`函数来读取其中的数据
现在假设我们有一个外部合约,使用`getNum`函数可读取其中的数据

首先,我们定义“LuckyNumber”合约的** _interface_ **

Expand All @@ -141,17 +141,19 @@ contract NumberInterface {
}
```

请注意,这个过程看起来像在定义一个合同,不同的是,首先,我们只声明了要与之交互的函数 - 在本例中为`getNum` - 而且,我们没有使用到任何关于函数或状态的变量。
请注意,这个过程虽然看起来像在定义一个合约,但其实内里不同:

其次,我们并没有用大括号(`{``}`)定义函数体,我们只是用分号(`;`)来结束函数声明。这使它看起来像一个合约框架
首先,我们只声明了要与之交互的函数 - 在本例中为`getNum` - 在其中我们没有使用到任何关于函数或状态的变量

编译器就是靠这些特征知道它是一个接口的
其次,我们并没有使用大括号(`{``}`)定义函数体,我们单单用分号(`;`)结束了函数声明。这使它看起来像一个合约框架

在我们的app代码中使用这个接口,我们的合约就知道其他合约的函数是怎么样的,如何调用它们,以及期待什么类型的响应
编译器就是靠这些特征认出它是一个接口的

在下一课中,我们将真实地调用其他合约的函数。目前我们只要声明一个为调用CryptoKitties合约而准备的接口就行了
在我们的app代码中使用这个接口,合约就知道其他合约的函数是怎样的,应该如何调用,以及可期待什么类型的返回

# 小测试
在下一课中,我们将真正调用其他合约的函数。目前我们只要声明一个接口,用于调用CryptoKitties合约就行了。

# 实战演习

我们已经为你查看过了CryptoKitties的源代码,并且找到了一个名为`getKitty`的函数,它返回所有的加密猫的数据,包括它的“基因”(我们的僵尸游戏要用它生成新的僵尸)。

Expand Down Expand Up @@ -186,9 +188,9 @@ function getKitty(uint256 _id) external view returns (
}
```

这个函数看起来跟我们习惯的函数不太一样。 它竟然返回了...一堆不同的值! 如果您使用过Javascript之类的编程语言,一定会感到奇怪 - 在Solidity中,您可以让一个函数返回多个值。
这个函数看起来跟我们习惯的函数不太一样。 它竟然返回了...一堆不同的值! 如果您用过Javascript之类的编程语言,一定会感到奇怪 - 在Solidity中,您可以让一个函数返回多个值。

现在我们知道这个函数章什么样的,我们可以用它来创建一个接口
现在我们知道这个函数长什么样的了,就可以用它来创建一个接口

1.定义一个名为`KittyInterface`的接口。 请注意,因为我们使用了`contract`关键字, 这过程看起来就像创建一个新的合同一样。

Expand Down
9 changes: 5 additions & 4 deletions zh/2/11-interactingcontracts2.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ contract NumberInterface {
function getNum(address _myAddress) public view returns (uint);
}
```
我们可以在合同中这样使用:

我们可以在合约中这样使用:

```
contract MyContract {
Expand All @@ -138,10 +139,10 @@ contract MyContract {
}
```

通过这种方式,只要将您合约的功能设置为“公共”或“外部”,它们就可以与以太坊区块链上的任何其他合同进行交互。
通过这种方式,只要将您合约的可见性设置为“公共”或“外部”,它们就可以与以太坊区块链上的任何其他合同进行交互。

#小测验

我们来建个自己的合约去读取智能CryptoKitties合约的内容吧
我们来建个自己的合约去读取另一个智能合约--CryptoKitties的内容吧

1.我已经将代码中CryptoKitties合约的地址保存在一个名为`ckAddress`的变量中。在下一行中,请创建一个名为`kittyContract`的KittyInterface,并用`ckAddress`初始化 - 就像我们为`numberContract`所做的一样。
1.我已经将代码中CryptoKitties合约的地址保存在一个名为`ckAddress`的变量中。在下一行中,请创建一个名为`kittyContract`的KittyInterface,并用`ckAddress`为它初始化 - 就像我们为`numberContract`所做的一样。
8 changes: 4 additions & 4 deletions zh/2/12-multiplereturns.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,18 @@ function getLastReturnValue() external {
}
```

# 小测试
# 实战演习

是时候与CryptoKitties合约交互起来了!

让我们定义一个函数,从kitty 合约中获取它的基因:
我们来定义一个函数,从kitty 合约中获取它的基因:

1.创建一个名为`feedOnKitty`的函数。它需要2个`uint`类型的参数,`_zombieId``_kittyId`,这是一个`public`类型的函数。

2.函数首先要声明一个名为`kittyDna``uint`

  >注意:在我们的KittyInterface中,`genes`是一个`uint256`类型的变量,但是如果你记得,我们在第一课中提到过,`uint``uint256`的别名,也就是说,它们是一回事
  >注意:在我们的KittyInterface中,`genes`是一个`uint256`类型的变量,但是如果你记得,我们在第一课中提到过,`uint``uint256`的别名,也就是说它们是一回事

3.这个函数接下来使用了 _kittyId 参数,去调用`kittyContract.getKitty`函数,并将返回的 `genes`存储在`kittyDna`中。记住 - `getKitty`会返回一大堆变量。 (确切地说10个 - 我已经为你数过了,不错吧!)。但是我们只关心最后一个--“基因”。数逗号的时候小心点哦!

4.最后,函数调用了`feedAndMultiply`传了`_zombieId``kittyDna`两个参数。
4.最后,函数调用了`feedAndMultiply`并传入了`_zombieId``kittyDna`两个参数。
7 changes: 2 additions & 5 deletions zh/2/13-kittygenes.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,14 @@ material:
if语句的语法在 Solidity中,与在javascript差不多:
```
function eatBLT(string sandwich) public {
// Remember with strings, we have to compare their keccak256 hashes
// to check equality
// 看清楚了,当我们比较字符串的时候,需要比较他们的 keccak256 哈希码
if (keccak256(sandwich) == keccak256("BLT")) {
eat();
}
}
```

# 小测试
# 实战演习

让我们在我们的僵尸代码中实现小猫的基因。

Expand All @@ -171,6 +170,4 @@ function eatBLT(string sandwich) public {

 >解释:假设`newDna``334455`。那么`newDna%100``55`,所以`newDna - newDna%100`得到`334400`。最后加上`99`可得到`334499`

4. Lastly, we need to change the function call inside `feedOnKitty`. When it calls `feedAndMultiply`, add the parameter `"kitty"` to the end.

4.最后,我们修改了`feedOnKitty`中的函数调用。当它调用`feedAndMultiply`时,增加了`“kitty”`作为最后一个参数。
6 changes: 3 additions & 3 deletions zh/2/14-wrappingitup.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ material:

## Javascript 实现

我们只用编译和部署`ZombieFeeding`,就可以将这个合约部署到以太坊了。 - 因为我们最终完成的这个合约继承自`ZombieFactory`并且它可以访问自己和父辈合约中的所有public方法
我们只用编译和部署`ZombieFeeding`,就可以将这个合约部署到以太坊了。 - 我们最终完成的这个合约继承自`ZombieFactory`因此它可以访问自己和父辈合约中的所有public方法

我们来看一个与我们的刚部署的合约进行交互的例子, 这个例子使用了Javascript和web3.js:

Expand Down Expand Up @@ -56,8 +56,8 @@ ZombieFactory.NewZombie(function(error, result) {
})
```

选择一只你想吃的小猫。你自家僵尸的DNA会和小猫的DNA结合,生成一个新的小猫僵尸加入你的军团
选择一只你想猎食的小猫。你自家僵尸的DNA会和小猫的DNA结合,生成一个新的小猫僵尸,加入你的军团

看到新僵尸上那可爱的猫咪腿了么?这是新僵尸最后DNA中最后两位数字“99”的功劳!

你想要的话随时可以重新开始。能捕获一只猫咪僵尸,你一定很高兴吧!(不过你只能持有一只),继续前进到下一章,完成第二课吧!
你想要的话随时可以重新开始。捕获了一只猫咪僵尸,你一定很高兴吧!(不过你只能持有一只),继续前进到下一章,完成第二课吧!
18 changes: 7 additions & 11 deletions zh/2/2-mappings.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,33 +80,29 @@ material:

我们通过给数据库中的僵尸指定“主人”, 来支持“多玩家”模式。

要做到这一点,我们需要2个新的数据类型:“映射”和“地址”。
如此一来,我们需要引入2个新的数据类型:“映射”和“地址”。

## 地址

以太坊区块链由** _ 账户号 _ **组成,您可以把它想象成银行账户。一个帐户的余额是** _以太_ **(在以太坊区块链上使用的币种),您可以和其他帐户之间支付和接受以太币,就像您的银行帐户可以电汇资金到其他银行帐户一样。
以太坊区块链由** _ account _ **(账户号)组成,您可以把它想象成银行账户。一个帐户的余额是** _以太_ **(在以太坊区块链上使用的币种),您可以和其他帐户之间支付和接受以太币,就像您的银行帐户可以电汇资金到其他银行帐户一样。

每个帐户都有一个“地址”,您可以把它想象成银行账号。这是一个账户唯一的标识符,它看起来是这样的
每个帐户都有一个“地址”,您可以把它想象成银行账号。这是账户唯一的标识符,它看起来长这样

`0x0cE446255506E92DF41614C46F1d6df9Cc969183`

这个地址属于CryptoZombies团队,如果你喜欢CryptoZombies,可以给我们一些以太币!😉)
这是CryptoZombies团队的地址,如果你喜欢CryptoZombies的话,请打赏我们一些以太币!😉)

我们将在后面的课程中介绍地址的细节,现在您只需要了解**地址属于特定用户(或智能合约)的**

所以我们可以指定“地址”作为僵尸拥有者的ID。当用户通过与我们的应用程序交互来创建新的僵尸时,我们将把这些僵尸的所有权设置到调用者的太坊地址名下
所以我们可以指定“地址”作为僵尸主人的ID。当用户通过与我们的应用程序交互来创建新的僵尸时,新僵尸的所有权被设置到调用者的太坊地址名下

##映射

在第1课中,我们看了** _ structs _ **** _ arrays _ **** _映射_ **是另一种在Solidity中存储有组织数据的方法。

这样可以定义一个映射
映射是这样定义的

```
// For a financial app, storing a uint that holds the user's account balance:
mapping (address => uint) public accountBalance;
// Or could be used to store / lookup usernames based on userId
mapping (uint => string) userIdToName;
//对于金融应用程序,用以保存用户账户余额的单元:
mapping (address => uint) public accountBalance;
//或者可以用来通过userId 存储/查找的用户名
Expand All @@ -116,7 +112,7 @@ mapping (uint => string) userIdToName;

映射本质上是存储和查找数据所用的键-值对。在第一个例子中,键是一个“地址”,值是一个“单元”,在第二个例子中,键是一个“单元”,值是一个“字符串”。

# 小测试
# 实战演习

为了存储僵尸的所有权,我们会使用到两个映射:一个记录僵尸拥有者的地址,另一个记录某ID所拥有僵尸的数量。

Expand Down
16 changes: 8 additions & 8 deletions zh/2/3-msgsender.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ material:
}
---

现在我们有了一套映射来记录僵尸的拥有者,我们可以修改`_createZombie`方法来使用它们
现在有了一套映射来记录僵尸的所有权了,我们可以修改`_createZombie`方法来运用它们

为了做到这一点,我们需要使用“msg.sender”。
为了做到这一点,我们要用到“msg.sender”。

## msg.sender

Expand Down Expand Up @@ -113,20 +113,20 @@ function whatIsMyNumber() public view returns (uint) {

使用“msg.sender”很安全,因为它具有以太坊区块链的安全保障 - 除非窃取与以太坊地址相关联的私钥,否则是没有办法修改其他人的数据的。

# 小测验
# 实战演习

让我们修改第1课的`_createZombie`方法,将僵尸的所有权分配给函数调用者
我们来修改第1课的`_createZombie`方法,将僵尸分配给函数调用者吧

1.首先,在我们得到新的僵尸`id`后,更新`zombieToOwner`映射,在`id`下面存入`msg.sender`
1.首先,在得到新的僵尸`id`后,更新`zombieToOwner`映射,在`id`下面存入`msg.sender`

第二,我们为这个“msg.sender”增加`ownerZombieCount`
然后,我们为这个“msg.sender”名下的`ownerZombieCount`加1

跟在javascript中一样, 在Solidity中你也可以用`++`增加`uint`
跟在javascript中一样, 在Solidity中你也可以用`++`使`uint`递增

```
uint number = 0;
number++;
// `number` 现在是 `1`了
```

本章答案,修改两行代码就可以了
修改两行代码即可
Loading

0 comments on commit 389f07a

Please sign in to comment.