Skip to content

Commit

Permalink
Merge pull request CryptozombiesHQ#36 from duydcoco/master
Browse files Browse the repository at this point in the history
第一章全部翻译完成
  • Loading branch information
mattkanwisher authored Jan 30, 2018
2 parents 68affa8 + f76d736 commit 9be7e98
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 67 deletions.
10 changes: 5 additions & 5 deletions en/1/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ material:
function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
// and fire it here
}
}
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
Expand Down Expand Up @@ -58,7 +58,7 @@ material:
function _createZombie(string _name, uint _dna) private {
uint id = zombies.push(Zombie(_name, _dna)) - 1;
NewZombie(id, _name, _dna);
}
}
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
Expand Down Expand Up @@ -91,10 +91,10 @@ function add(uint _x, uint _y) public {
}
```

Your app front-end could then listen for the event. A javascript implementation would look something like:
Your app front-end could then listen for the event. A javascript implementation would look something like:

```
YourContract.IntegersAdded(function(error, result) {
YourContract.IntegersAdded(function(error, result) {
// do something with result
}
```
Expand All @@ -105,6 +105,6 @@ We want an event to let our front-end know every time a new zombie was created,

1. Declare an `event` called `NewZombie`. It should pass `zombieId` (a `uint`), `name` (a `string`), and `dna` (a `uint`).

2. Modify the `_createZombie` function to fire the `NewZombie` event after adding the new Zombie to our `zombies` array.
2. Modify the `_createZombie` function to fire the `NewZombie` event after adding the new Zombie to our `zombies` array.

3. You're going to need the zombie's `id`. `array.push()` returns a `uint` of the new length of the array - and since the first item in an array has index 0, `array.push() - 1` will be the index of the zombie we just added. Store the result of `zombies.push() - 1` in a `uint` called `id`, so you can use this in the `NewZombie` event in the next line.
4 changes: 2 additions & 2 deletions zh/1/datatypes.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ material:
##### 例子:
```
contract Example {
// This will be stored permanently in the blockchain
// 这个无符号整数将会永久的被保存在区块链中
uint myUnsignedInteger = 100;
}
```
Expand All @@ -39,7 +39,7 @@ contract Example {

## 无符号整数: `uint`

`uint` 无符号数据类型, 指 **其值不能是负数**而且是整数 `int`
`uint` 无符号数据类型, 指 **其值不能是负数**对于有符号的整数存在名为 `int`的数据类型

> 注: Solidity中, `uint` 实际上是 `uint256`代名词, 一个256位的无符号整数。你也可以定义位数少的uints — `uint8`, `uint16`, `uint32`, 等.. 但一般来讲你愿意使用简单的`uint` 除非在某些特殊情况下,这我们后面会讲。
Expand Down
10 changes: 5 additions & 5 deletions zh/1/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ material:
function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
// 这里触发事件
}
}
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
Expand Down Expand Up @@ -58,7 +58,7 @@ material:
function _createZombie(string _name, uint _dna) private {
uint id = zombies.push(Zombie(_name, _dna)) - 1;
NewZombie(id, _name, _dna);
}
}
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
Expand Down Expand Up @@ -91,7 +91,7 @@ function add(uint _x, uint _y) public {
}
```

你的 app 前端可以监听这个事件。JavaScript 实现如下:
你的 app 前端可以监听这个事件。JavaScript 实现如下:

```
YourContract.IntegersAdded(function(error, result) {
Expand All @@ -101,9 +101,9 @@ YourContract.IntegersAdded(function(error, result) {

# 测试一把

我们想每当一个僵尸创造出来时,我们的前端都能听到这个事件,并将它显示出来。
我们想每当一个僵尸创造出来时,我们的前端都能监听到这个事件,并将它显示出来。

1. 定义一个 `事件` 叫做 `NewZombie`. 它可以含有 `zombieId` (`uint`), `name` (`string`), 和 `dna` (`uint`).
1. 定义一个 `事件` 叫做 `NewZombie`. 它有3个参数: `zombieId` (`uint`), `name` (`string`), 和 `dna` (`uint`).

2. 修改 `_createZombie` 函数使得当新僵尸造出来并加入`zombies`数组后,生成事件`NewZombie`

Expand Down
6 changes: 3 additions & 3 deletions zh/1/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function eatHamburgers(string _name, uint _amount) {
}
```

这是一个称作为 `eatHamburgers` 的函数,它接受两个参数:一个 `string` 和 一个 `uint`。现在函数本身还是空的
这是一个名为 `eatHamburgers` 的函数,它接受两个参数:一个 `string`类型的 和 一个 `uint`类型的。现在函数内部还是空的

> 注:: 习惯上函数里的变量都是以(`_`)开头 (但不是硬性规定) 以区别全局变量。我们整个教程都会沿用这个习惯。
Expand All @@ -67,6 +67,6 @@ eatHamburgers("vitalik", 100);

在我们的应用里,我们要能创建一些僵尸,让我们写一个函数做这件事吧!

1. 建立一个函数 `createZombie`. 它接受两个输入变量: **名字** (类型`string`), 和 **__dna_** (类型`uint`)。
1. 建立一个函数 `createZombie`. 它有两个参数: **_name** (类型为`string`), 和 **__dna_** (类型为`uint`)。

暂时让函数空着——我们在后面会增加内容。
暂时让函数空着——我们在后面会增加内容。
6 changes: 3 additions & 3 deletions zh/1/functions2.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ material:
}
---

Solidity 定义的函数的属性缺省为`公共`。 这就意味着任何一方 (或其它合约) 都可以调用你的合约里的函数
Solidity 定义的函数的属性默认为`公共`。 这就意味着任何一方 (或其它合约) 都可以调用你合约里的函数

显然,不是什么时候都需要这样,而且这样的合约易于受到攻击。 所以将自己的函数定义为`私有`是一个好的编程习惯,只有当你需要外部世界调用它时才将它设置为`公共`

Expand All @@ -63,10 +63,10 @@ function _addToArray(uint _number) private {

这意味着只有我们合约中的其它函数才能够调用这个函数,给 `numbers` 数组添加新成员。

可以看到,在函数名字后面使用关键字 `private` 即可。和函数的输入参数类似, 私有函数的名字用(`_`)起始.
可以看到,在函数名字后面使用关键字 `private` 即可。和函数的参数类似, 私有函数的名字用(`_`)起始.

# 测试一把

我们的合约的`createZombie` 的缺省属性是公共,这意味着任何一方都可以调用它去创建一个僵尸。 咱们来把它变成私有吧!
我们合约的函数`createZombie` 的默认属性是公共的,这意味着任何一方都可以调用它去创建一个僵尸。 咱们来把它变成私有吧!

1.`createZombie` 为私有函数,不要忘记遵守命名的规矩哦!
12 changes: 6 additions & 6 deletions zh/1/functions3.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ material:
function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
}
}
function _generateRandomDna(string _str) private view returns (uint) {
Expand Down Expand Up @@ -73,30 +73,30 @@ Solidity 里,函数的定义里可包含返回值的数据类型(如本例中

上面的函数实际上没有改变 Solidity 里的状态,即,它没有改变任何值或者写任何东西。

这种情况下我们可以把函数定义为 **_view_**, 意味着它只读取数据但不更改数据:
这种情况下我们可以把函数定义为 **_view_**, 意味着它只能读取数据不能更改数据:

```
function sayHello() public view returns (string) {
```

Solidity 还支持 **_pure_** 函数, 表明这个函数甚至都没有接触程序里的数据,例如:
Solidity 还支持 **_pure_** 函数, 表明这个函数甚至都不能访问程序里的数据,例如:

```
function _multiply(uint a, uint b) private pure returns (uint) {
return a * b;
}
```

这个函数甚至都没有读程序里的状态 — 它的返回值完全取决于它的输入参数,在这种情况下我们把函数定义为 **_pure_**.
这个函数甚至都不能读取程序里的状态 — 它的返回值完全取决于它的输入参数,在这种情况下我们把函数定义为 **_pure_**.

> 注:可能很难记住何时把函数标记为 pure/view。 幸运的是, Solidity 编辑器会给出提示,提醒你使用这些修饰符。
# 测试一把

我们想建立一个帮助函数,它根据一个字符串随机生成一个DNA数据。

1. 建立一个`private` 函数,命名为 `_generateRandomDna`。它只接收一个输入变量`_str` (类型`string`), 返回一个`uint`类型的数值。
1. 创建一个`private` 函数,命名为 `_generateRandomDna`。它只接收一个输入变量`_str` (类型`string`), 返回一个`uint`类型的数值。

2. 此函数只读取我们合约中的一些变量,所以标记为`view`

3. 函数本身暂时空白,以后我们再添加代码。
3. 函数内部暂时留空,以后我们再添加代码。
20 changes: 10 additions & 10 deletions zh/1/keccak256.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ material:
function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
}
}
function _generateRandomDna(string _str) private view returns (uint) {
// 这里开始
Expand All @@ -46,7 +46,7 @@ material:
function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
}
}
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
Expand All @@ -56,11 +56,11 @@ material:
}
---

如何让 `_generateRandomDna` 函数返回一个(半) 随机的 `uint`?
如何让 `_generateRandomDna` 函数返回一个全(半) 随机的 `uint`?

Ethereum 内部有一个散列函数`keccak256`,它用了SHA3版本。一个散列函数基本上就是把一个字符串转换为一个256位的16进制数字。字符串的一个微小变化会引起散列数据极大变化。

这在 Ethereum 中有很多应用,但是现在我们只是用它造一个假想的随机数
这在 Ethereum 中有很多应用,但是现在我们只是用它造一个伪随机数

例子:

Expand All @@ -82,18 +82,18 @@ keccak256("aaaac");
```
uint8 a = 5;
uint b = 6;
// 将会跑出错误,因为 a * b 返回 uint, 而不是 uint8:
uint8 c = a * b;
// 将会抛出错误,因为 a * b 返回 uint, 而不是 uint8:
uint8 c = a * b;
// 我们需要将 b 转换为 uint8:
uint8 c = a * uint8(b);
uint8 c = a * uint8(b);
```

上面, `a * b` 返回类型是 `uint`, 但是我们试图保存为`uint8`类型, 这回造成潜在的错误。如果把它的数据类型转换为`uint8`, 就可以了,编译器也不会出错。
上面, `a * b` 返回类型是 `uint`, 但是当我们尝试用`uint8`类型接收时, 就会造成潜在的错误。如果把它的数据类型转换为`uint8`, 就可以了,编译器也不会出错。

# 测试一把

`_generateRandomDna` 函数添加代码! 它应该完成如下功能:

1. 第一行代码取`_str``keccak256`散列值,伪随机十六进制数。类型转换为`uint`, 最后保存在类型为 `uint` 变量 `rand`
1. 第一行代码取`_str``keccak256`散列值,伪随机十六进制数。类型转换为`uint`, 最后保存在类型为 `uint` 名为 `rand`的变量中

2. 我们只想让我们的DNA的长度为16位 (还记得 `dnaModulus`?)。所以第二行代码应该`return` 上数值一部分 (`%`) `dnaModulus`.
2. 我们只想让我们的DNA的长度为16位 (还记得 `dnaModulus`?)。所以第二行代码应该`return` 上面计算的数值对 `dnaModulus`求余数(`%`).
4 changes: 2 additions & 2 deletions zh/1/lessonoverview.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ material:
* 工厂会有一个函数能产生新的僵尸
* 每个僵尸会有一个随机的独一无二的面孔

在后面的课程里,我们会增加功能。比如,让僵尸能攻击人类或其它僵尸! 但是在实现这些好玩的功能之前,我们先要加入生出新僵尸的基本功能
在后面的课程里,我们会增加功能。比如,让僵尸能攻击人类或其它僵尸! 但是在实现这些好玩的功能之前,我们先要实现创建僵尸这样的基本功能

## 僵尸DNA如何运作

Expand All @@ -32,7 +32,7 @@ material:
例如,前两位数字是 `83`, 计算僵尸的头型,我们做`83 % 7 + 1` = 7 运算, 此僵尸将被赋予第七类头型。

在右手页面,移动头基因`head gene` 滑块到第七位置(圣诞老人的帽子)可见`83`所对应的特点。
在右边页面,移动头基因`head gene` 滑块到第七位置(圣诞帽)可见`83`所对应的特点。

# 测试一把

Expand Down
2 changes: 1 addition & 1 deletion zh/1/math.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ material:
* 减法: `x - y`,
* 乘法: `x * y`
* 除法: `x / y`
* / 余数: `x % y` _(例如, `13 % 5``3`, 因为13除以5,余3)_
* 取模 / 求余: `x % y` _(例如, `13 % 5``3`, 因为13除以5,余3)_

Solidity 还支持 **_乘方操作_** (如:x 的 y次方) // 例如: 5 ** 2 = 25
```
Expand Down
10 changes: 5 additions & 5 deletions zh/1/puttingittogether.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ material:
function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
}
}
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
Expand Down Expand Up @@ -49,7 +49,7 @@ material:
function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
}
}
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
Expand All @@ -66,14 +66,14 @@ material:

我们就快完成我们的随机僵尸制造器了,来写一个公共的函数把所有的部件连接起来。

写一个公共函数,它有一个变量,用来输入僵尸的名字,之后用它生成僵尸的DNA。
写一个公共函数,它有一个参数,用来接收僵尸的名字,之后用它生成僵尸的DNA。

# 测试一把

1. 建立一个 `public` 函数,命名为` createRandomZombie`. 它将被传入一个变量 `_name` (数据类型是 `string`). _(注: 定义公共函数 `public` 和定义一个私有 `private` 函数的做法一样)_
1. 创建一个 `public` 函数,命名为` createRandomZombie`. 它将被传入一个变量 `_name` (数据类型是 `string`). _(注: 定义公共函数 `public` 和定义一个私有 `private` 函数的做法一样)_

2. 函数的第一行应该调用 `_generateRandomDna` 函数,传入 `_name` 参数, 结果保存在一个类型为 `uint` 的变量里,命名为 `randDna`.

3. 第二行调用 `_createZombie` 函数, 传入参数: `_name``randDna`.

4. 结果应该生成4行代码 (包括函数的结束符号 `}` )。
4. 整个函数应该是4行代码 (包括函数的结束符号 `}` )。
10 changes: 5 additions & 5 deletions zh/1/structs.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: 结构
title: 结构体
actions: ['答案', '提示']
material:
editor:
Expand Down Expand Up @@ -32,7 +32,7 @@ material:
}
---

有时你需要更复杂的数据类型,Solidity 提供了 **结构**:
有时你需要更复杂的数据类型,Solidity 提供了 **结构体**:

```
struct Person {
Expand All @@ -42,14 +42,14 @@ struct Person {
```

结构允许你生成一个更复杂的数据类型,它有多个属性。
结构体允许你生成一个更复杂的数据类型,它有多个属性。

> 注:我们刚刚引进了一个新类型, `string`。 字符串用于保存任意长度的 UTF-8 编码数据。 如: `string greeting = "Hello world!"`
# 测试一把

在我们的程序中,我们将生出一些僵尸!每个僵尸将拥有多个属性,所以这是一个展示结构的完美例子
在我们的程序中,我们将创建一些僵尸!每个僵尸将拥有多个属性,所以这是一个展示结构体的完美例子

1. 建立一个`struct` 命名为 `Zombie`.

2. 我们的 `Zombie` 结构有两个属性`name` (类型为 `string`), 和 `dna` (类型为 `uint`)。
2. 我们的 `Zombie` 结构体有两个属性`name` (类型为 `string`), 和 `dna` (类型为 `uint`)。
Loading

0 comments on commit 9be7e98

Please sign in to comment.