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

R4R: Translate doc clients to chinese. #4129

Merged
merged 3 commits into from
Apr 17, 2019
Merged
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
1 change: 1 addition & 0 deletions .pending/improvements/gaiarest/4129-Translate-doc-c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#4129 Translate doc clients to chinese.
19 changes: 19 additions & 0 deletions docs/translations/cn/clients/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# 客户端

本节说明包含区块链 SDK 的客户端的信息。

> *注*:此部分仍在开发中。

##轻客户端

轻客户端使用户能够与您的应用程序进行交互,且无需下载整个状态历史记录,但具有良好的安全性。

- [轻客户端概述](./lite/README.md)
- [启动轻客户端服务器](./lite/getting_started.md)
- [轻客户端规范](./lite/specification.md)

##其他客户端

- [区块链 SDK 的 CLI](./cli.md)
- [服务提供商文档](./service-providers.md)

4 changes: 4 additions & 0 deletions docs/translations/cn/clients/cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# CLI

> TODO: Rewrite this section to explain how CLI works for a generic SDK app.

60 changes: 60 additions & 0 deletions docs/translations/cn/clients/lite/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# 轻客户端概览

**点击[这里](https://cosmos.network/rpc/)查看Cosmos SDK 轻客户端 RPC 文档**

## 简介

轻客户端允许客户端(例如移动电话)从任何全节点接收区块链状态的证明。 轻客户端不必信任任何全节点,因为他们能够验证他们收到的任何证明,因此全节点不能对网络状态撒谎。

轻客户端可以用最低的带宽、计算和存储资源提供与全节点相同的安全性。 同时,它还可以根据用户的配置提供模块化功能。 这些出色的功能允许开发人员构建完全安全、高效且可用的移动应用、网站或任何其他应用程序,而无需部署或维护任何完整的区块链节点。

### 什么是轻节点

Cosmos SDK 轻节点(Gaia-lite)分为两个独立的组件。 第一个组件对于任何基于 Tendermint 的应用程序都是通用的,它处理区块头相关的安全性和连接性,并验证来自全节点的证明与本地可信验证人集合的对比。 此外,它暴露与任何Tendermint 核心节点完全相同的API。 第二个组件专用于 Cosmos Hub(`gaiad`),它作为查询端点工作,并公开特定于应用程序的功能,这些功能可以是任意的。 针对应用程序状态的所有查询都必须通过查询端点。 查询端点的优点是它可以验证应用程序返回的证据。

### 高层体系结构

想要为 Cosmos Hub(或任何其他 zone)构建第三方客户端应用程序的应用程序开发人员,应根据其规范 API 构建。 该API 是多个部分的组合。 所有 zone 都必须暴露ICS0(TendermintAPI)。 除此之外,任何 zone 都可以自由选择模块 API的任意组合,具体取决于状态机使用的模块。 Cosmos Hub最初将支持[ICS0](https://cosmos.network/rpc/#/ICS0) (TendermintAPI)、 [ICS1](https://cosmos.network/rpc/#/ICS1) (KeyAPI)、 [ICS20](https://cosmos.network/rpc/#/ICS20) (TokenAPI)、 [ICS21](https://cosmos.network/rpc/#/ICS21) (StakingAPI)、 [ICS22](https://cosmos.network/rpc/#/ICS22) (GovernanceAPI) 和 [ICS23](https://cosmos.network/rpc/#/ICS23) (SlashingAPI)。

![high-level](../../../../clients/lite/pics/high-level.png)

预计所有应用程序仅依赖于 Gaia-lite 运行。 Gaia-lite 是唯一一款围绕 zone API 提供稳定性保证的软件。

### 对比

ABCI 的全节点与其轻客户端的区别在于以下方面:

| | Full Node | 轻客户端 | Description |
| ------------------------------- | --------------- | ------------- | ------------------------------------------------------------ |
| 执行并验证交易 | Yes | No | 全节点将执行并验证所有交易,而Gaia-lite则不会 |
| 验证和存储区块 | Yes | No | 全节点将验证并保存所有块,而Gaia-lite则不会 |
| 参与共识 | Yes | No | 只有当全节点是验证人时,它才会参与共识。 Lite节点永远不会参与共识。 |
| 带宽开销 | 巨大 | 很小 | 全节点将接收所有块。 如果带宽有限,它将落后于主网络。 更重要的是,如果碰巧是验证人,它将减缓共识过程。 轻客户端需要很少的带宽, 只有在提供本地请求时,才会占用带宽。 |
| 计算资源 | 巨大 | 很小 | 全节点将执行所有交易并验证所有块,这需要大量的计算资源 |
| 存储资源 | 巨大 | 很小 | 全节点将保存所有块和 ABCI 状态,而Gaia-lite只保存验证人集合和一些检查点。 |
| 电力资源 | 巨大 | 很小 | 全节点必须在具有高性能并能一直运行的机器上部署,因此功耗将是巨大的。 Gaia-lite可以部署在与用户应用程序相同的机器上,也可以部署在独立但性能较差的机器上。 此外,Lite客户端可以在必要时随时关闭。所以Gaia-lite只消耗很少的功率,即使移动设备也能满足功率需求。 |
| 提供的 APIs | 所有cosmos APIs | 部分模块 APIs | 全节点支持所有cosmos API。 Gaia-lite 根据用户的配置提供模块化API。 |
| 安全等级 | 高 | 高 | 全节点将自行验证所有交易和块。 轻型客户端无法执行此操作,但它可以查询来自其他全节点的任何数据并独立验证数据。 因此,全节点和轻型客户端都不需要信任任何第三方节点,它们都可以实现高安全性。 |

根据上表,Gaia-lite 可以满足所有用户的功能和安全需求,但只需要很少的带宽、计算、存储和电力资源。

## 安全实现

### 可信验证人集合

Gaia-lite的基本设计理念遵循两个规则:

1. **不信任任何区块链节点,包括验证人节点和其他全节点**
2. **只信任整个验证人集合**

原始的可信验证人集应该预先放置到其信任库中,通常这个验证人集来自 genesis 文件。 在运行时期间,如果 Gaia-lite 检测到不同的验证人集,它将验证它并将可信的验证人集保存到信任库中。

![validator-set-change](../../../../clients/lite/pics/validatorSetChange.png)

### 信任传播

从上面的小节中,我们了解了如何获得可信验证器集以及 LCD 如何跟踪验证人集演化。 验证人集是信任的基础,信任可以传播到其他区块链数据,例如块和交易。 传播架构如下所示:

![change-process](../../../../clients/lite/pics/trustPropagate.png)

通常,通过可信验证人集,轻客户端可以验证包含所有预提交数据和块头数据的每个提交块。 此时块哈希、数据哈希和应用哈希是可信的。 基于此和默克尔证明,所有交易数据和 ABCI 状态也可以被验证。
23 changes: 23 additions & 0 deletions docs/translations/cn/clients/lite/getting_started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# 入门

要启动 REST 服务器,我们需要指定以下参数:

| 参数 | 类型 | 默认值 | 必填 | 描述 |
| ----------- | --------- | ----------------------- | ----- | ---------------------------- |
| chain-id | string | null | true | 要链接全节点的 chain id |
| node | URL | "tcp://localhost:46657" | true | 要链接全节点的地址和端口号 |
| laddr | URL | "tcp://localhost:1317" | true | 提供 REST 服务的地址和端口号 |
| trust-node | bool | "false" | true | 是否信任 LCD 连接的全节点 |
| trust-store | DIRECTORY | "$HOME/.lcd" | false | 保存检查点和验证人集的目录 |

示例:

```bash
gaiacli rest-server --chain-id=test \
--laddr=tcp://localhost:1317 \
--node tcp://localhost:26657 \
--trust-node=false
```

有关Gaia-Lite RPC的更多信息,请参阅 [swagger documentation](https://cosmos.network/rpc/)

183 changes: 183 additions & 0 deletions docs/translations/cn/clients/lite/specification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# 规范

该规范描述了如何实现 LCD。 LCD 支持模块化 API。 目前,仅支持ICS0(TendermintAPI),ICS1(密钥API)和ICS20(Key API)。 如有必要,后续可以包含更多API。

## 构建并验证 ABCI 状态的证明

众所周知,基于 cosmos-sdk 的应用程序的存储包含多个子库。 每个子目录由 IAVL 存储实现。 这些子组件由简单的 Merkle 树组成。 创建树时,我们需要从这些子库中提取名字、高度和存储根哈希以构建一组简单的 Merkle 叶节点,然后计算从叶节点到根的哈希。 简单 Merkle 树的根哈希是 AppHash,它将包含在块头中。

![Simple Merkle Tree](../../../../clients/lite/pics/simpleMerkleTree.png)

正如我们在[LCD信任传播](https://github.com/irisnet/cosmos-sdk/tree/bianjie/lcd_spec/docs/spec/lcd#trust-propagation)中所讨论的那样,可以通过检查针对可信验证人集的投票权来验证 AppHash。 这里我们只需要建立从 ABCI 状态到 AppHash 的证明。 证据包含两部分:

* IAVL 证明
* 子库到 AppHash 的证明

### IAVL 证明

证明有两种类型:存在证明和缺席证明。 如果查询密钥存在于 IAVL 存储中,则它返回键值及其存在证明。 另一方面,如果密钥不存在,那么它只返回缺席证明,这可以证明密钥肯定不存在。

### IAVL 存在证明

```go
type CommitID struct {
Version int64
Hash []byte
}

type storeCore struct {
CommitID CommitID
}

type MultiStoreCommitID struct {
Name string
Core storeCore
}

type proofInnerNode struct {
Height int8
Size int64
Version int64
Left []byte
Right []byte
}

type KeyExistsProof struct {
MultiStoreCommitInfo []MultiStoreCommitID // 所有子库提交id
StoreName string // 当前子库名字
Height int64 // 当前子库提交高度
RootHash cmn.HexBytes // 此 IAVL 树的根哈希
Version int64 // 此 IAVL 树中 key-value 的版本号
InnerNodes []proofInnerNode // 从根节点到 key-value 叶子节点的路径
}
```

存在证据的数据结构如上所示。 构建和验证存在证明的过程如下所示:

![Exist Proof](../../../../clients/lite/pics/existProof.png)

构建证明的步骤:

* 从根节点访问IAVL树
* 记录 InnerNodes 中的访问节点
* 找到目标叶节点后,将叶节点版本赋值给证明版本
* 将当前 IAVL 树高赋值给证明高度
* 将当前 IAVL 树根哈希赋值给证明根哈希
* 将当前的子目录名称赋值给证明 StoreName
* 从 multistore 读取指定高度的 commitInfo 并将其赋值给证明 StoreCommitInfo

验证证明的步骤:

* 使用证明版本中的键、值构建叶节点
* 计算叶节点哈希
* 将哈希值分配给第一个 innerNode 的 rightHash,然后计算第一个 innerNode 哈希值
* 传播哈希计算过程。 如果先前的 innerNode 是下一个 innerNode 的左子节点,则将先前的 innerNode 散列分配给下一个 innerNode 的左散列。否则,将先前的 innerNode 散列分配给下一个innerNode的右散列
* 最后 innerNode 的哈希应该等于此证明的根哈希, 否则证明无效。

### IAVL 缺席证明

众所周知,所有 IAVL 叶节点都按每个叶节点的密钥排序。 因此,我们可以在 IAVL 树的整个密钥集中计算出目标密钥的位置。 如下图所示,我们可以找到左键和右键。 如果我们可以证明左键和右键肯定存在,并且它们是相邻的节点,那么目标密钥肯定不存在。

![Absence Proof1](../../../../clients/lite/pics/absence1.png)

如果目标密钥大于最右边的叶节点或小于最左边的叶子节点,则目标密钥肯定不存在。

![Absence Proof2](../../../../clients/lite/pics/absence2.png)![Absence Proof3](../../../../clients/lite/pics/absence3.png)

```go
type proofLeafNode struct {
KeyBytes cmn.HexBytes
ValueBytes cmn.HexBytes
Version int64
}

type pathWithNode struct {
InnerNodes []proofInnerNode
Node proofLeafNode
}

type KeyAbsentProof struct {
MultiStoreCommitInfo []MultiStoreCommitID
StoreName string
Height int64
RootHash cmn.HexBytes
Left *pathWithNode // Proof the left key exist
Right *pathWithNode //Proof the right key exist
}
```

以上是缺席证明的数据结构。 构建证据的步骤:

* 从根节点访问IAVL树
* 获取整个密钥集中密钥的对应索引(标记为INDEX)
* 如果返回的索引等于0,则右索引应为0,且左节点不存在
* 如果返回的索引等于整个密钥集的大小,则左节点索引应为INDEX-1,且右节点不存在
* 否则,右节点索引应为INDEX,左节点索引应为INDEX-1
* 将当前 IAVL 树高赋值给证明高度
* 将当前 IAVL 树根哈希赋值给证明根哈希
* 将当前的子目录名称赋值给证明 StoreName
* 从 multistore 读取指定高度的 commitInfo 并将其赋值给证明 StoreCommitInfo

验证证明的步骤:

* 如果只存在右节点,请验证其存在的证明,并验证它是否是最左侧的节点
* 如果仅存在左节点,请验证其存在的证据,并验证它是否是最右侧的节点
* 如果右节点和左节点都存在,请验证它们是否相邻

### Substores 到 AppHash 的证明

在验证了 IAVL 证明之后,我们就可以开始验证针对 AppHash 的 substore 证明。 首先,迭代 MultiStoreCommitInfo 并通过证明 StoreName 找到 substore commitID。 验证 commitID 中的哈希是否等于证明根哈希,如果不相等则证明无效。 然后通过 substore name 的哈希对 substore commitInfo 数组进行排序。 最后,使用所有 substore commitInfo 数组构建简单的 Merkle 树,并验证 Merkle 根哈希值是否等于appHash。

![substore proof](../../../../clients/lite/pics/substoreProof.png)

```go
func SimpleHashFromTwoHashes(left []byte, right []byte) []byte {
var hasher = ripemd160.New()

err := encodeByteSlice(hasher, left)
if err != nil {
panic(err)
}

err = encodeByteSlice(hasher, right)
if err != nil {
panic(err)
}

return hasher.Sum(nil)
}

func SimpleHashFromHashes(hashes [][]byte) []byte {
// Recursive impl.
switch len(hashes) {
case 0:
return nil
case 1:
return hashes[0]
default:
left := SimpleHashFromHashes(hashes[:(len(hashes)+1)/2])
right := SimpleHashFromHashes(hashes[(len(hashes)+1)/2:])
return SimpleHashFromTwoHashes(left, right)
}
}
```

## 根据验证人集验证区块头

上面的小节中经常提到 appHash,但可信的appHash来自哪里? 实际上,appHash 存在于区块头中,因此接下来我们需要针对 LCD 可信验证人集验证特定高度的区块头。 验证流程如下所示:

![commit verification](../../../../clients/lite/pics/commitValidation.png)

当可信验证人集与区块头不匹配时,我们需要尝试将验证人集更新为此块的高度。 LCD 有一条规则,即每个验证人集的变化不应超过1/3投票权。 如果目标验证人集的投票权变化超过1/3,则与可信验证人集进行比较。 我们必须验证,在目标验证人集之前是否存在隐含的验证人集变更。 只有当所有验证人集变更都遵循这条规则时,才能完成验证人集的更新。

例如:

![Update validator set to height](../../../../clients/lite/pics/updateValidatorToHeight.png)

* 更新到 10000,失败,变更太大
* 更新到 5050,失败,变更太大
* 更新至 2575,成功
* 更新至 5050,成功
* 更新到 10000,失败,变更太大
* 更新至 7525,成功
* 更新至 10000,成功
Loading