Skip to content

Commit

Permalink
chinese lesson 2
Browse files Browse the repository at this point in the history
  • Loading branch information
lukezhangstudio committed Jan 17, 2018
1 parent 292445b commit 5150fec
Show file tree
Hide file tree
Showing 15 changed files with 194 additions and 186 deletions.
14 changes: 5 additions & 9 deletions zh/2/00-overview.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
---
title: Zombies Attack Their Victims
header: So, you've made it to Lesson 2!
title: 僵尸攻击人类
header: 所以,你需要晋级至第二课!
roadmap: roadmap2.jpg
---

Impressive, human! You're a better coder than I thought.

Lesson 2 will teach you how to **multiply your zombie army by feeding on other lifeforms**.

In this lesson we will cover some more advanced Solidity concepts, so it's highly
recommended that you complete Lesson 1 before starting.
厉害了,我的人类! 你比我设想的更会编程!
第二课中你会学到如何通过喂养其他生物,增加你僵尸军团的数量
在这一课中,我们会使用到一些高级的Solidity概念,所以你一定要先完成第一课。
25 changes: 11 additions & 14 deletions zh/2/1-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,21 @@ material:
answer: 1
---

In lesson 1, we created a function that takes a name, uses it to generate a random zombie, and adds that zombie to our app's zombie database on the blockchain.
在第一课中,我们创建了一个命名的函数用来生成僵尸 ,并且将它放置在我们区块链的僵尸数据库中。
在第二课里,我们会让我们的app更加像一个游戏: 让它支持多用户,并且采用更加有趣--而不仅仅随机--的方式,来生成僵尸,

In lesson 2, we're going to make our app more game-like: We're going to make it multi-player, and we'll also be adding a more fun way to create zombies instead of just generating them randomly.
我们如何生成新的僵尸呢?通过让僵尸“喂食”其他生物!

How will we create new zombies? By having our zombies "feed" on other lifeforms!
## 僵尸喂食

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

When a zombie feeds, it infects the host with a virus. The virus then turns the host into a new zombie that joins your army. The new zombie's DNA will be calculated from the previous zombie's DNA and the host's DNA.
僵尸最喜欢喂食什么样的物种呢?
等你学完第二课就知道了!

And what do our zombies like to feed on most?
# 小测试

To find that out... You'll have to complete lesson 2!
右边是一个简单的喂食展示。点击一个“人”,试试看僵尸喂食的时候会发生什么?
可见,新僵尸的DNA是通过从原来的僵尸的DNA, 加上宿主的DNA计算得来的。

# Put it to the test

There's a simple demo of feeding to the right. Click on a human to see what happens when your zombie feeds!

You can see that the new zombie's DNA is determined by your original zombie's DNA, as well as the host's DNA.

When you're ready, click "Next chapter" to move on, and let's get started by making our game multi-player.
学完这一章,请点击“下一章”, 我们让游戏支持多玩家模式。
50 changes: 26 additions & 24 deletions zh/2/10-interactingcontracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,23 +95,24 @@ material:
}
---

It's time to feed our zombies! And what do zombies like to eat most?
是时候喂喂我们的僵尸了! 那僵尸最喜欢吃什么呢?

Well it just so happens that CryptoZombies love to eat...
Crypto僵尸喜欢吃的是...

**CryptoKitties!** 😱😱😱
** CryptoKitties** 😱😱😱

(Yes, I'm serious 😆 )
(正经点,我可不是开玩笑😆)

In order to do this we'll need to read the kittyDna from the CryptoKitties smart contract. We can do that because the CryptoKitties data is stored openly on the blockchain. Isn't the blockchain cool?!
为了做到这一点,我们要读出CryptoKitties智能合约中的kittyDna。这些数据是公开存储在区块链中的。区块链是不是很酷?

Don't worry — our game isn't actually going to hurt anyone's CryptoKitty. We're only *reading* the CryptoKitties data, we're not able to actually delete it 😉
别担心 - 我们的游戏并不会伤害到任何真正的CryptoKitty。 我们只读取* CryptoKitties数据,但是无法物理上删除它

## Interacting with other contracts
##与其他合约交互

For our contract to talk to another contract on the blockchain that we don't own, first we need to define an **_interface_**.
如果我们的合约需要和区块链上的其他的合约对话,则需要先定义一个** _interface_ **(接口)。

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

Let's look at a simple example. Say there was a contract on the blockchain that looked like this:

```
contract LuckyNumber {
Expand All @@ -127,33 +128,34 @@ contract LuckyNumber {
}
```

This would be a simple contract where anyone could store their lucky number, and it will be associated with their Ethereum address. Then anyone else could look up that person's lucky number using their address.
这是个简单的合约,您可以用它存储自己的幸运号码,并与您的以太坊地址关联。 这样其他人就可以使用这个地址查找您的幸运号码了。

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

Now let's say we had an external contract that wanted to read the data in this contract using the `getNum` function.
首先,我们定义“LuckyNumber”合约的** _interface_ **

First we'd have to define an **_interface_** of the `LuckyNumber` contract:

```
contract NumberInterface {
function getNum(address _myAddress) public view returns (uint);
}
```

Notice that this looks like defining a contract, with a few differences. For one, we're only declaring the functions we want to interact with — in this case `getNum` — and we don't mention any of the other functions or state variables.
请注意,这个过程看起来像在定义一个合同,不同的是,首先,我们只声明了要与之交互的函数 - 在本例中为`getNum` - 而且,我们没有使用到任何关于函数或状态的变量。

Secondly, we're not defining the function bodies. Instead of curly braces (`{` and `}`), we're simply ending the function declaration with a semi-colon (`;`).
其次,我们并没有用大括号(`{``}`)定义函数体,我们只是用分号(`;`)来结束函数声明。这使它看起来像一个合约框架。

So it kind of looks like a contract skeleton. This is how the compiler knows it's an interface.
编译器就是靠这些特征知道它是一个接口的。

By including this interface in our dapp's code our contract knows what the other contract's functions look like, how to call them, and what sort of response to expect.
在我们的app代码中使用这个接口,我们的合约就知道其他合约的函数是怎么样的,如何调用它们,以及期待什么类型的响应。

We'll get into actually calling the other contract's functions in the next lesson, but for now let's declare our interface for the CryptoKitties contract.
在下一课中,我们将真实地调用其他合约的函数。目前我们只要声明一个为调用CryptoKitties合约而准备的接口就行了。

# Put it to the test
# 小测试

We've looked up the CryptoKitties source code for you, and found a function called `getKitty` that returns all the kitty's data, including its "genes" (which is what our zombie game needs to form a new zombie!).
我们已经为你查看过了CryptoKitties的源代码,并且找到了一个名为`getKitty`的函数,它返回所有的加密猫的数据,包括它的“基因”(我们的僵尸游戏要用它生成新的僵尸)。

The function looks like this:
该函数如下所示:

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

The function looks a bit different than we're used to. You can see it returns... a bunch of different values. If you're coming from a programming language like Javascript, this is different — in Solidity you can return more than one value from a function.
这个函数看起来跟我们习惯的函数不太一样。 它竟然返回了...一堆不同的值! 如果您使用过Javascript之类的编程语言,一定会感到奇怪 - 在Solidity中,您可以让一个函数返回多个值。

Now that we know what this function looks like, we can use it to create an interface:
现在我们知道这个函数章什么样的,我们可以用它来创建一个接口:

1. Define an interface called `KittyInterface`. Remember, this looks just like creating a new contract — we use the `contract` keyword.
1.定义一个名为`KittyInterface`的接口。 请注意,因为我们使用了`contract`关键字, 这过程看起来就像创建一个新的合同一样。

2. Inside the interface, define the function `getKitty` (which should be a copy/paste of the function above, but with a semi-colon after the `returns` statement, instead of everything inside the curly braces.
2.在interface里定义了`getKitty`函数(不过是复制/粘贴上面的函数,但在`returns`语句之后用分号,而不是大括号内的所有内容。
13 changes: 6 additions & 7 deletions zh/2/11-interactingcontracts2.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,14 @@ material:
}
---

Continuing our previous example with `NumberInterface`, once we've defined the interface as:
继续前面`NumberInterface`的例子,我们既然将接口定义为:

```
contract NumberInterface {
function getNum(address _myAddress) public view returns (uint);
}
```

We can use it in a contract as follows:
我们可以在合同中这样使用:

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

In this way, your contract can interact with any other contract on the Ethereum blockchain, as long they expose those functions as `public` or `external`.
通过这种方式,只要将您合约的功能设置为“公共”或“外部”,它们就可以与以太坊区块链上的任何其他合同进行交互。

# Put it to the test
#小测验

Let's set up our contract to read from the CryptoKitties smart contract!
我们来建个自己的合约去读取智能CryptoKitties合约的内容吧!

1. I've saved the address of the CryptoKitties contract in the code for you, under a variable named `ckAddress`. In the next line, create a `KittyInterface` named `kittyContract`, and initialize it with `ckAddress` — just like we did with `numberContract` above.
1.我已经将代码中CryptoKitties合约的地址保存在一个名为`ckAddress`的变量中。在下一行中,请创建一个名为`kittyContract`的KittyInterface,并用`ckAddress`初始化 - 就像我们为`numberContract`所做的一样。
18 changes: 9 additions & 9 deletions zh/2/12-multiplereturns.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ material:
}
---

This `getKitty` function is the first example we've seen that returns multiple values. Let's look at how to handle them:
`getKitty`是我们所看到的第一个返回多个值的函数。我们来看看是如何处理的:

```
function multipleReturns() internal returns(uint a, uint b, uint c) {
Expand All @@ -145,18 +145,18 @@ function getLastReturnValue() external {
}
```

# Put it to the test
# 小测试

Time to interact with the CryptoKitties contract!
是时候与CryptoKitties合约交互起来了!

Let's make a function that gets the kitty genes from the contract:
让我们定义一个函数,从kitty 合约中获取它的基因:

1. Make a function called `feedOnKitty`. It will take 2 `uint` parameters, `_zombieId` and `_kittyId`, and should be a `public` function.
1.创建一个名为`feedOnKitty`的函数。它需要2个`uint`类型的参数,`_zombieId``_kittyId`,这是一个`public`类型的函数。

2. The function should first declare a `uint` named `kittyDna`.
2.函数首先要声明一个名为`kittyDna``uint`

> Note: In our `KittyInterface`, `genes` is a `uint256` — but if you remember back to lesson 1, `uint` is an alias for `uint256` — they're the same thing.
  >注意:在我们的KittyInterface中,`genes`是一个`uint256`类型的变量,但是如果你记得,我们在第一课中提到过,`uint``uint256`的别名,也就是说,它们是一回事。

3. The function should then call the `kittyContract.getKitty` function with `_kittyId` and store `genes` in `kittyDna`. Remember — `getKitty` returns a ton of variables. (10 to be exact — I'm nice, I counted them for you!). But all we care about is the last one, `genes`. Count your commas carefully!
3.这个函数接下来使用了 _kittyId 参数,去调用`kittyContract.getKitty`函数,并将返回的 `genes`存储在`kittyDna`中。记住 - `getKitty`会返回一大堆变量。 (确切地说10个 - 我已经为你数过了,不错吧!)。但是我们只关心最后一个--“基因”。数逗号的时候小心点哦!

4. Finally, the function should call `feedAndMultiply`, and pass it both `_zombieId` and `kittyDna`.
4.最后,函数调用了`feedAndMultiply`,传了`_zombieId``kittyDna`两个参数。
30 changes: 17 additions & 13 deletions zh/2/13-kittygenes.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,20 @@ material:
}
---

Our function logic is now complete... but let's add in one bonus feature.
我们的功能逻辑主体已经完成了...现在让我们来添一个奖励功能吧。

Let's make it so zombies made from kitties have some unique feature that shows they're cat-zombies.
这样吧,给从小猫制造出的僵尸有添加些特征,以显示他们是猫僵尸。

To do this, we can add some special kitty code in the zombie's DNA.
要做到这一点,咱们在新僵尸的DNA中添加一些特殊的小猫代码。

If you recall from lesson 1, we're currently only using the first 12 digits of our 16 digit DNA to determine the zombie's appearance. So let's use the last 2 unused digits to handle "special" characteristics.
还记得吗,第一课中我们提到,我们目前只使用16位DNA的前12位数来指定僵尸的外观。所以现在我们可以使用最后2个数字来处理“特殊”的特征。

We'll say that cat-zombies have `99` as their last two digits of DNA (since cats have 9 lives). So in our code, we'll say `if` a zombie comes from a cat, then set the last two digits of DNA to `99`.
这样吧,把猫僵尸DNA的最后两个数字设定为“99”(因为猫有9条命)。所以在我们这么来写代码:`如果`这个僵尸是一只猫变来的,就将它DNA的最后两位数字设置为`99`

## If statements

If statements in Solidity look just like javascript:
## if 语句

if语句的语法在 Solidity中,与在javascript差不多:
```
function eatBLT(string sandwich) public {
// Remember with strings, we have to compare their keccak256 hashes
Expand All @@ -157,16 +157,20 @@ function eatBLT(string sandwich) public {
}
```

# Put it to the test
# 小测试

Let's implement cat genes in our zombie code.
让我们在我们的僵尸代码中实现小猫的基因。

1. First, let's change the function definition for `feedAndMultiply` so it takes a 3rd argument: a `string` named `species`
1.首先,我们修改下`feedAndMultiply`函数的定义,给它传入第三个参数:一条名为`species`的字符串

2. Next, after we calculate the new zombie's DNA, let's add an `if` statement comparing the `keccak256` hashes of `species` and the string `"kitty"`
2.接下来,在我们计算出新的僵尸的DNA之后,添加一个`if`语句来比较`species`和字符串``kitty``的keccak256`哈希值

3. Inside the `if` statement, we want to replace the last 2 digits of DNA with `99`. One way to do this is using the logic: `newDna = newDna - newDna % 100 + 99;`.
`if`语句中,我们想用`99`替换DNA的最后两位数字。一种方法是使用逻辑:`newDna = newDna - newDna100 + 99;`

> Explanation: Assume `newDna` is `334455`. Then `newDna % 100` is `55`, so `newDna - newDna % 100` is `334400`. Finally add `99` to get `334499`.
3.`if`语句中,我们用`99`替换了新僵尸DNA的最后两位数字。可以这么做:`newDna = newDna - newDna%100 + 99;`

 >解释:假设`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”`作为最后一个参数。
18 changes: 8 additions & 10 deletions zh/2/14-wrappingitup.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ material:
answer: 1
---

That's it, you've completed lesson 2!
至此,你已经学完第二课了!

You can check out the demo to the right to see it in action. Go ahead, I know you can't wait until the bottom of this page 😉. Click a kitty to attack, and see the new kitty zombie you get!
查看下→_→的演示,看看他们怎么运行起来得吧。继续,你肯定等不及看完这一页😉。点击小猫,攻击!看到你斩获一个新的小猫僵尸了吧!

## Javascript implementation
## Javascript 实现

Once we're ready to deploy this contract to Ethereum we'll just compile and deploy `ZombieFeeding` — since this contract is our final contract that inherits from `ZombieFactory`, and has access to all the public methods in both contracts.
我们只用编译和部署`ZombieFeeding`,就可以将这个合约部署到以太坊了。 - 因为我们最终完成的这个合约继承自`ZombieFactory`,并且它可以访问自己和父辈合约中的所有public方法。

Let's look at an example of interacting with our deployed contract using Javascript and web3.js:
我们来看一个与我们的刚部署的合约进行交互的例子, 这个例子使用了Javascript和web3.js

```
var abi = /* abi generated by the compiler */
Expand Down Expand Up @@ -56,10 +56,8 @@ ZombieFactory.NewZombie(function(error, result) {
})
```

# Give it a try!
选择一只你想吃的小猫。你自家僵尸的DNA会和小猫的DNA结合,生成一个新的小猫僵尸加入你的军团!

Select the kitty you want to feed on. Your zombie's DNA and the kitty's DNA will combine, and you'll get a new zombie in your army!
看到新僵尸上那可爱的猫咪腿了么?这是新僵尸最后DNA中最后两位数字“99”的功劳!

Notice those cute cat legs on your new zombie? That's our final `99` digits of DNA at work 😉

You can start over and try again if you want. When you get a kitty zombie you're happy with (you only get to keep one), go ahead and proceed to the next chapter to complete lesson 2!
你想要的话随时可以重新开始。能捕获一只猫咪僵尸,你一定很高兴吧!(不过你只能持有一只),继续前进到下一章,完成第二课吧!
Loading

0 comments on commit 5150fec

Please sign in to comment.