Merge PR #4787: Updated docs build process
@@ -0,0 +1,39 @@
|
||||
# 코스모스 SDK 문서에 오신 걸 환영합니다!
|
||||
|
||||
::: warning
|
||||
번역된 문서는 **참고용**으로 번역되었습니다. 다수의 오타, 오류가 존재할 수 있으며, 영문 업데이트보다 번역이 느리게 진행될 수 있다는 점을 인지하시기 바랍니다.
|
||||
|
||||
코스모스 관련 가장 정확한 정보를 확인하시기 위해서는 영어 원문을 참고하시기 바랍니다.
|
||||
:::
|
||||
|
||||
## 코스모스 SDK 배우기
|
||||
|
||||
### SDK 소개
|
||||
|
||||
만약 코스모스 SDK가 처음이지만 배우고 싶으시다면 여기에서 시작하시는 것을 추천드립니다.
|
||||
|
||||
### SDK 튜토리얼
|
||||
|
||||
직접 해보면서 학습하는 방식을 선호하신다면 SDK 애플리케이션 튜토리얼을 따라하실 수 있습니다. 튜토리얼은 **[SDK 기반 블록체인을](https://github.com/cosmos/sdk-application-tutorial)** 만드는 방법을 처음부터 끝까지 가르쳐 드립니다. 이 과정에서 코스모스 SDK의 기본적인 개념 또한 함께 배우실 수 있습니다.
|
||||
|
||||
## 코스모스 SDK 사용하기
|
||||
|
||||
다음 항목은 실제로 작동하는 SDK 기반 블록체인에 필요한 모든 정보를 포함하고 있습니다.
|
||||
|
||||
>*NOTE*: 코스모스 SDK 지원 문서의 완성도와 정확성을 높이기 위해 해당 문서는 꾸준히 업데이트 되고 있습니다. 혹시 오류나 제안사항이 있으시다면 [코스모스 포럼](https://forum.cosmos.network) 또는 [깃허브 이슈를](https://github.com/cosmos/cosmos-sdk/issues/new) 통해서 알려주시면 감사하겠습니다.
|
||||
|
||||
- [인트로](./intro/README.md): 코스모스 SDK에 대한 high-level 소개 자료
|
||||
- [Gaia](https://github.com/cosmos/gaia/blob/master/docs/translations/kr/README.md): Gaia 애플리케이션(현재 코스모스 허브 명칭)에 대한 모든 문서들이 있습니다. Gaia 테스트넷에 참여하는 방법에 대한 정보
|
||||
- [클라이언트](./clients/README.md): SDK Command-Line Interface 와 SDK 라이트 클라이언트 같은 SDK 클라이언트에 관련한 문서
|
||||
- [스펙](./spec/README.md): SDK와 모듈들에 대한 스펙 정의
|
||||
|
||||
## 코스모스 허브 테스트넷
|
||||
|
||||
`gaia` 애플리케이션(코스모스 허브의 애플리케이션)을 설치하고 퍼블릭 테스트넷에 참가하고 싶으시다면 여기를 클릭해주세요.
|
||||
자체적인 `gaia` 테스트넷을 운영하고 싶으시다면 **[여기](https://github.com/cosmos/gaia/blob/master/docs/translations/kr/join-testnet.md)** 를 클릭해주세요.
|
||||
|
||||
자체적인 `gaia` 테스트넷 운영을 원하시는 경우 **[여기](https://github.com/cosmos/gaia/blob/master/docs/translations/kr/deploy-testnet.md)** 를 확인하세요
|
||||
|
||||
## 기여하기
|
||||
|
||||
코스모스 도큐멘테이션 또는 코드 업데이트 규칙에 관련해서는 [이 파일](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md)을 참고해주세요.
|
||||
@@ -0,0 +1,18 @@
|
||||
# 클라이언트
|
||||
|
||||
이 항목은 SDK 기반 블록체인을 위한 클라이언트에 대한 정보가 포함되어있습니다.
|
||||
|
||||
>*참고*: 이 항목은 작업이 진행중입니다.
|
||||
|
||||
## 라이트 클라이언트(Light-client)
|
||||
|
||||
라이트 클라이언트는 유저가 특정 블록체인 상태 전체를 다운로드 받지 않고도 안전성이 확보될 수 있는 환경에서 블록체인 애플리케이션과 소통할 수 있게 합니다.
|
||||
|
||||
- [라이트 클라이언트 개요](./lite/README.md)
|
||||
- [라이트 클라이언트 서버 구동하기](./lite/getting_started.md)
|
||||
- [라이트 클라이언트 스펙](./lite/specification.md)
|
||||
|
||||
## 다른 클라이언트
|
||||
|
||||
- [SDK 기반 블록체인을 위한 커맨드 라인 기반 인터페이스](./cli.md)
|
||||
- [서비스 제공자 문서](./service-providers.md)
|
||||
@@ -0,0 +1,3 @@
|
||||
# CLI
|
||||
|
||||
> TODO: Rewrite this section to explain how CLI works for a generic SDK app.
|
||||
@@ -0,0 +1,63 @@
|
||||
# 라이트 클라이언트 개요
|
||||
|
||||
**코스모스 SDK 라이트 클라이언트 RPC 문서를 [여기]에서 확인하세요(https://cosmos.network/rpc/)**
|
||||
|
||||
## 소개
|
||||
|
||||
라이트 클라이언트는 핸드폰 같은 클라이언트에서 블록체인 상태(state)에 대한 증거(proof)를 풀노드로부터 전달받을 수 있게 합니다. 라이트 클라이언트는 전송받은 증거에 대한 검증을 자체적으로 수행할 수 있기 때문에 풀노드를 신뢰하지 않아도 되며, 풀노드의 거짓 정보 전달을 확인할 수 있다.
|
||||
|
||||
라이트 클라이언트는 대역폭(bandwidth), 컴퓨터 연산력 그리고 저장공간 측면에서 큰 리소스를 소모하지 않고도 풀노드와 동일한 보안을 제공할 수 있다. 또한 유저의 설정에 따라 모듈화 된 기능성을 제공할 수 있다. 이런 우수한 기능은 개발자들이 풀 블록체인 노드가 없이도 안전하고, 효율적이고, 사용성이 높은 모바일 애플리케이션, 웹사이트 등을 만들 수 있게 한다.
|
||||
|
||||
### 라이트 클라이언트란 무엇인가
|
||||
|
||||
코스모스 SDK 라이트 클라이언트 (Gaia-lite)는 두 가지 요소로 나뉘어 있다. 첫 번째 요소는 모든 텐더민트 기반 애플리케이션들의 기본적인 컴포넌트다. 해당 컴포넌트는 헤더 체인을 따르면서 풀노드가 제공하는 증거를 신뢰할 수 있는 검증인을 통해 확인하는 방식으로 보안과 연결성 측면을 담당한다. 두 번째 요소는 코스모스 허브(`gaiad`)에 고유한 컴포넌트다. 일종의 쿼리 엔드포인트(query endpoint)로써 애플리케이션 특정 기능을 드러내는 역할을 수행한다. 애플리케이션 상태에 대한 모든 쿼리는 쿼리 엔드포인트(query endpoint)를 통해 이루어진다. 쿼리 엔드포인트를 이용하는 것에 가장 큰 장점은 애플리케이션이 리턴하는 증거를 검증할 수 있다는 것이다.
|
||||
|
||||
### 하이레벨 아키텍처(High-level Architecture)
|
||||
|
||||
코스모스 허브(또는 다른 존)를 위한 제삼자 클라이언트 애플리케이션을 만드려고 하는 개발자는 기본 규례적(canonical) API를 기반으로 개발을 해야 합니다. API는 여러 가지 부품으로 이루어져 있습니다. 코스모스 생태계의 모든 존은 기본적으로 ICS0(텐더민트API)를 공개해야 하나, 그 외에 모듈들은 선택 사항입니다. 모든 존은 모듈 API를 도입할 여부를 기능에 따라 선택할 권리가 있습니다.
|
||||
|
||||
기본적으로 코스모스 허브는 [ICS0](https://cosmos.network/rpc/#/ICS0) (텐더민트API), [ICS1](https://cosmos.network/rpc/#/ICS1) (키API), [ICS20](https://cosmos.network/rpc/#/ICS20) (토큰API), [ICS21](https://cosmos.network/rpc/#/ICS21) (스테이킹API),
|
||||
[ICS22](https://cosmos.network/rpc/#/ICS22) (거버넌스API) and [ICS23](https://cosmos.network/rpc/#/ICS23) (슬래싱API)를 도입하고 있습니다.
|
||||
|
||||

|
||||
|
||||
모든 애플리케이션은 Gaia-lite 클라이언트를 기반으로 운영되는 것을 원칙으로 삼습니다. Gaia-lite 외의 소프트웨어는 특정 존 API에 대한 안정성을 보장하지 않습니다.
|
||||
|
||||
### 비교
|
||||
|
||||
ABCI 풀노드는 다음과 같은 항목에서 라이트 클라이언트와 다릅니다:
|
||||
|
||||
|| 풀노드 | 라이트 클라이언트 | 설명|
|
||||
|-| ------------- | ----- | -------------- |
|
||||
| 트랜잭션 검증 및 실행|Yes|No|풀노드는 모든 트랜잭션을 검증하고 실행하지만, 라이트 클라이언트는 모든 트랜잭션을 처리하지 않습니다|
|
||||
| 검증 및 블록 저장|Yes|No|풀노드는 모든 블록을 검증하고 보관하지만, 라이트 클라이언트는 블록 저장을 하지 않습니다|
|
||||
| 합의 절차 참여| Yes|No|검증인 세트에 포함된 풀노드는 합의 절차에 참여하지만, 라이트 클라이언트는 절대로 합의 절차에 참여할 수 없습니다|
|
||||
| 대역폭 사용량|대량|소량|풀노드는 모든 블록을 전달받기 때문에 충분한 대역폭이 확보되지 않는 경우 다른 뒤질 확률이 있습니다. 검증인 풀노드가 낮은 대역폭으로 지연되는 경우 합의 절차 전체가 늦어질 수 있습니다. 라이트 클라이언트는 로컬 호출만을 처리하기 때문에 소량의 대역폭을 사용합니다|
|
||||
| 연산력 사용량|대량|소량|풀노드는 모든 트랜잭션을 처리하며 모든 블록을 검증해야 하기 때문에 대량의 컴퓨터 연산력을 사용합니다.|
|
||||
| 저장 공간 사용량|대량|소량|풀노드는 모든 블록과 ABCI 상태를 저장합니다. 라이트 클라이언트는 검증인 세트와 일부 체크포인트만을 저장합니다.|
|
||||
| 전력 사용량|대량|소량|풀노드는 24시간 돌아가는 고성능 머신 환경이 제공되어야 하기 때문에 대량의 전력을 소모합니다. 라이트 클라이언트의 경우 유저 애플리케이션과 동일한 환경에서 운용될 수 있습니다. 라이트 클라이언트는 모바일 기기 같은 저성능 기기에서도 사용될 수 있습니다. 또한 라이트 클라이언트는 필요에 따라 클라이언트 작동을 출 수 있기 때문에 모바일 기기 같은 저전력 소모를 필요로 하는 환경에서 이용될 수 있습니다.|
|
||||
| API 제공|모든 코스모스 API|모듈 API|풀노드는 모든 코스모스 API를 지원합니다. 라이트 클라이언트는 유저 설정에 따라 모듈 API를 제공합니다.|
|
||||
| 보안|높음|높음|풀노드는 자체적으로 모든 트랜잭션과 블록을 검증합니다. 라이트 클라이언트는 모든 트랜잭션을 검증하지 않지만 다른 풀노드를 통해 데이터를 전달받아 자체적인 검증을 할 수 있습니다. 풀노드와 라이트 클라이언트는 둘 다 제삼자 노드를 신뢰할 필요 없이 데이터 검증이 가능하기 때문에 높은 수준의 보안을 제공합니다|
|
||||
|
||||
위 표와 같이 가이아 라이트 클라이언트는 소량의 대역폭, 연산력, 저장 공간, 전력을 가지고도 유저가 필요로 하는 모든 기능과 보안을 제공합니다.
|
||||
|
||||
## 보안 유지하기
|
||||
|
||||
### 신뢰 가능한 검증인 세트
|
||||
|
||||
가이아 라이트 클라이언트의 디자인 철학은 다음과 같은 원칙을 따릅니다:
|
||||
|
||||
1. **검증인 노드와 다른 풀 노드를 포함한 모든 블록체인 노드를 신뢰하지 않는다**
|
||||
2. **오직 전체적인 검증인 세트(validator set) 만을 신뢰한다**
|
||||
|
||||
초기에 신뢰될 수 있는 검증인 세트(통상 제네시스 파일에 있는 검증인 세트)는 신뢰 저장소(trust store)에 미리 세팅되어야 합니다. 이후, 런타임에서 라이트 클라이언트가 다른 검증인 세트를 발견하게 된다면 클라이언트는 해당 검증인 세트를 별도로 검증한 후 새로운 검증인 세트를 저장소에 보관하게 됩니다.
|
||||
|
||||

|
||||
|
||||
### 신뢰 전파(trust propagation)
|
||||
|
||||
위에 항목에 나열된 바와 같이, 라이트 클라이언트(lcd)는 신뢰할 수 있는 검증인 세트를 별도로 검증합니다. 검증인 세트는 일종의 신뢰의 기반이 되며, 이런 신뢰를 기반으로 블록 정보와 트랜잭션 정보 같은 다른 블록체인 데이터에 신뢰를 전파(propogate)하는데 이용됩니다. 신뢰 전파 아키텍처는 다음과 같습니다.
|
||||
|
||||

|
||||
|
||||
라이트 클라이언트는 통상 신뢰 가능한 검증인 세트를 통해 모든 프리 커밋 정보와 블록 헤더 정보가 포함된 각 블록의 커밋을 검증할 수 있습니다. 이후 블록 해시 값, 데이터 해시 값 그리고 앱해시(appHash)에 대한 신뢰를 파생합니다. 머클 증거(merkle proof)와 위의 정보를 이용해 모든 트랜잭션 데이터와 ABCI의 상태(state)를 검증할 수 있게 됩니다.
|
||||
@@ -0,0 +1,23 @@
|
||||
# REST 서버 시작하기
|
||||
|
||||
REST 서버를 가동하기 위해서는 다음과 같은 파라미터 값을 정의해야 합니다:
|
||||
|
||||
|
||||
| 파라미터 | 형태 | 기본 값 | 필수/선택 | 설명 |
|
||||
| ----------- | --------- | ----------------------- | -------- | ---------------------------------------------------- |
|
||||
| chain-id | string | null | 필수 | 연결할 체인의 chain-id |
|
||||
| node | URL | "tcp://localhost:46657" | 필수 | 연결할 풀노드의 주소 |
|
||||
| laddr | URL | "tcp://localhost:1317" | 필수 | REST 서버를 가동할 주소 |
|
||||
| trust-node | bool | "false" | 필수 | 연결할 풀노드의 신뢰가능 여부 |
|
||||
| trust-store | DIRECTORY | "$HOME/.lcd" | 선택 | 체크포인트와 검증인 세트를 저장할 디렉터리 |
|
||||
|
||||
예를 들어::
|
||||
|
||||
```bash
|
||||
gaiacli rest-server --chain-id=test \
|
||||
--laddr=tcp://localhost:1317 \
|
||||
--node tcp://localhost:26657 \
|
||||
--trust-node=false
|
||||
```
|
||||
|
||||
Gaia-Lite RPC에 대한 추가적인 정보를 원하시면 [Swagger 문서](https://cosmos.network/rpc/)를 확인하세요.
|
||||
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,185 @@
|
||||
# 라이트 클라이언트 스펙
|
||||
|
||||
이 문서는 LCD(Light Client Daemon)을 사용하는 방법을 설명합니다. LCD는 모듈러 API를 지원합니다. 현재 LCD는 ICS0 (텐더민트API), ICS1 (키API)와 ICS20 (토큰API) 만을 지원하는 상태입니다. 추후에 추가 모듈을 지원할 예정입니다.
|
||||
|
||||
## ABCI 상태 빌드/검증하기
|
||||
|
||||
코스모스 SDK 기반 애플리케이션은 멀티-서브스토어(multi-substore)를 이용해 저장을 합니다. 각 서브스토어는 IAVL 스토어를 응용합니다. 서브스토어는 단순한 머클 트리(Merkle tree) 형태로 정렬됩니다. 머클 트리를 만들기 위해서는 각 서브스토어의 이름, 블록 높이 그리고 스토어 루트 해시(store root hash) 필요하며, 이를 기반으로 간단한 머클 가지 노드(Merkle leaf node)를 만들 수 있습니다. 이후 가지 노드를 이용해 해시값을 머클 뿌리(Merkle root)까지 연산하게 됩니다. 단순 머클 트리(simple Merkle tree)의 루트 해시(Root hash)는 블록 헤더에 포함되는 앱 해시(AppHash)입니다.
|
||||
|
||||

|
||||
|
||||
[LCD 신뢰 전파](https://github.com/irisnet/cosmos-sdk/tree/bianjie/lcd_spec/docs/spec/lcd#trust-propagation)에서 설명했던바와 같이, 앱해시는 신뢰할 수 있는 검증인 세트의 보팅파워(총 스테이킹 수량)를 검증하는 방식으로 확인할 수 있습니다. 이 절차에는 ABCI 상태에서부터 앱해시 증거를 찾으면 됩니다. 증거에는 다음과 같은 정보가 포함되어있습니다:
|
||||
|
||||
* IAVL 증거
|
||||
* 섭스토어에서 앱해시까지의 증거
|
||||
|
||||
### IAVL 증거 (IAVL proof)
|
||||
|
||||
증거물에는 두 가지의 종류가 있습니다: 존재 증거(existance proof)와 부재 증거(absence proof). 만약 쿼리 키가 IAVL 스토어에 존재하는 경우 키 밸류(key-value)와 존재 증거를 제공하게 됩니다. 반면, 만약 키가 존재하지 않는다면 해당 키가 존재하지 않는 것을 증명할 수 있는 부재 증거를 제공합니다.
|
||||
|
||||
### IAVL 존재 증거 (IAVL Existance Proof)
|
||||
|
||||
```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 //All substore commitIDs
|
||||
StoreName string //Current substore name
|
||||
Height int64 //The commit height of current substore
|
||||
RootHash cmn.HexBytes //The root hash of this IAVL tree
|
||||
Version int64 //The version of the key-value in this IAVL tree
|
||||
InnerNodes []proofInnerNode //The path from to root node to key-value leaf node
|
||||
}
|
||||
```
|
||||
|
||||
존재 증거의 데이터 형식은 위와 같이 나열되어 있습니다. 존재 증거를 생성하고 검증하는 방식은 다음과 같습니다:
|
||||
|
||||
|
||||

|
||||
|
||||
증거 생성 절차:
|
||||
|
||||
* 루트 노드에서 IAVL 트리를 액세스
|
||||
* 방문 노드(visited node)를 InnerNodes에 기록
|
||||
* 타겟 가지 노드(leaf node)를 찾은 경우, 가지 노드 버전을 증거 버전에 할당
|
||||
* 현재 IAVL 트리 높이(IAVL tree height)를 증거 높이(proof height)에 할당
|
||||
* 현재 IAVL 트리의 루트해시(rootHash)를 증거 루트해시에 할당
|
||||
* 현재 서브스토어 이름을 증거 스토어 이름(proof StoreName)에 할당
|
||||
* db에서 멀티스토어 커밋 정보(multistore commitInfo)를 읽은 후 증거 StoreCommitInfo에 할당
|
||||
|
||||
검증 절차:
|
||||
|
||||
* 키, 값 그리고 증거 버전(proof version)을 이용해 리프 노드(leaf node)를 생성
|
||||
* 리프 노드 해시값을 연산
|
||||
* 해시 값을 innerNoder의 rightHash에 할당한 후, 첫 innnerNode의 해시를 연산
|
||||
* 해시 연산 절차를 전파. 만약 위의 innerNode가 다음 innerNode의 left child(좌측 자녀)인 경우, 해당 innerNode를 다음 innerNode의 좌측 해시로 배정한다. 이 외의 경우, 위의 innerNode 해시를 다음 innerNode의 우측 해시로 배정한다.
|
||||
* 마지막 innerNode의 해시값은 해당 증거의 rootHash와 동일해야 한다. 그렇지 않은 경우, 증거는 무효하다.
|
||||
|
||||
### IAVL 부재 증거(IAVL Absence Proof)
|
||||
|
||||
모든 IAVL 리프 노드는 각 리프노드의 키로 정렬되어있습니다. 그렇기 때문에 IAVL 트리의 전체 키 내의 목표 키 위치를 찾을 수 있습니다. 아래와 같이, 키가 좌측 키 또는 우측 키인지 확인이 가능합니다. 만약 우측 키와 좌측 키의 존재를 증명할 수 있을 경우, 인접 노드(adjecent node) 여부를 증명할 수 있는 것이며 타겟 키가 존재하지 않는다는 것을 증명하게 됩니다.
|
||||
|
||||

|
||||
|
||||
만약 타겟 키가 최우측 리프 노드(right most leaf node) 보다 크거나 또는 최좌측 키(left most key) 보다 작은 경우 타겟 키는 존재하지 않음을 증명합니다.
|
||||
|
||||

|
||||
|
||||
```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 트리를 액세스
|
||||
* 전체 키 세트의 deserved index(INDEX로 표기됨)을 받는다
|
||||
* 만약 받은 인덱스의 값이 0일 경우, 우측 인덱스의 값은 0이며 좌측 노드는 존재하지 않는다
|
||||
* 만약 받은 인덱스의 값이 전체 키 세트의 크기와 동일한 경우, 좌측 노드 인덱스는 INDEX-1 이어야 하며 우측 노드는 존재하지 않는다
|
||||
* 이외의 경우, 우측 노드 인덱스는 INDEX여야 하며 좌측 노드 인덱스는 INDEX-1이다
|
||||
* 현재 IAVL 트리의 높이를 증거 높이에 할당한다
|
||||
* 현재 IAVL 트리의 rootHash를 증거 rootHash로 할당한다
|
||||
* 현재 substore 이름을 증거의 StoreName으로 할당한다
|
||||
* db에서 multistore commitInfo를 읽은 후 증거의 StoreCommitInfo에 할당한다
|
||||
|
||||
증거 검증 절차:
|
||||
|
||||
* 만약 우측 노드만 존재하는 경우, 존재 증거(exist proof)를 검증하여 최좌특 노드인지 확인한다
|
||||
* 만약 우측 노드만 존재하는 경우, 존재 증거(exist proof)를 검증하여 최우측 노드인지 확인한다
|
||||
* 만약 좌측 노드와 우측 노드가 동시에 존재하는 경우, 두 노드가 인접(adjacent)한지 확인한다
|
||||
|
||||
### Substores 증거와 AppHash 증거 확인하기
|
||||
|
||||
IAVL 증거를 검증했다면 substore 증거와 AppHash를 비교하여 검증할 수 있습니다. 우선 MultiStoreCommitInfo를 반복(iterate)하여 proof StoreName을 이용해 서브스토어의 commitID를 찾을 수 있습니다. 여기에서 commitID의 해시가 RootHash의 proof와 동일하다는 것을 검증합니다. 만약 동일하지 않을 경우, 증거는 유효하지 않습니다. 이후 서브스토어 commitInfo 어레이를 서브스토어 이름의 해시 값으로 정렬합니다. 마지막으로, 모든 서브스토어 commitInfo 어레이를 기반으로 단순 머클 트리(simple Merkle tree)를 빌드하여 머클 루트 해시가 앱 해시와 동일한지 검증합니다.
|
||||
|
||||
|
||||

|
||||
|
||||
```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가 신뢰하는 검증인 세트에 검증해야 합니다. 검증 절차는 다음과 같습니다:
|
||||
|
||||

|
||||
|
||||
만약 신뢰 검증인 세트가 블록 헤더와 일치하지 않는 경우, 해당 블록 높이의 검증인 세트로 업데이트를 해야합니다. LCD는 검증인 세트의 변경이 보팅 파워의 1/3을 초과할 수 없다는 규칙을 따릅니다. 만약 타겟 검증인 세트가 현재 신뢰되는 검증인 세트에서 1/3 보팅파워를 초과하는 변화가 있는 경우, 타겟 검증인 세트 전에 숨겨진 검증인 세트 변경이 있었는지 확인해야 합니다. 모든 검증인 세트 변경이 이 규칙을 따를때 검증인 세트 업데이트가 이루어질 수 있습니다.
|
||||
|
||||
예를 들어:
|
||||
|
||||

|
||||
|
||||
* Update to 10000, tooMuchChangeErr
|
||||
* Update to 5050, tooMuchChangeErr
|
||||
* Update to 2575, Success
|
||||
* Update to 5050, Success
|
||||
* Update to 10000,tooMuchChangeErr
|
||||
* Update to 7525, Success
|
||||
* Update to 10000, Success
|
||||
@@ -0,0 +1,115 @@
|
||||
# 서비스 제공자(Service Providers)
|
||||
|
||||
'서비스 제공자'는 코스모스 SDK 기반 블록체인(코스모스 허브도 포함됩니다)과 교류하는 서비스를 엔드유저에게 제공하는 특정 인원/기관을 뜻합니다. 이 문서는 주로 토큰 인터랙션에 대한 정보를 다룹니다.
|
||||
|
||||
다음 항목은 [Light-Client](https://github.com/cosmos/cosmos-sdk/tree/master/docs/interfaces/lite) 기능을 제공하려는 월렛 개발자들에게 해당하지 않습니다. 서비스 제공자는 엔드 유저와 블록체인을 이어주는 신뢰할 수 있는 기관/개인입니다.
|
||||
|
||||
## 보편적 아키텍처 설명
|
||||
|
||||
다음 세가지 항목을 고려해야 합니다:
|
||||
|
||||
- 풀 노드(Full-nodes): 블록체인과의 인터랙션.
|
||||
- REST 서버(Rest Server): HTTP 콜을 전달하는 역할.
|
||||
- REST API: REST 서버의 활용 가능한 엔드포인트를 정의.
|
||||
|
||||
## 풀노드 운영하기
|
||||
|
||||
### 설치 및 설정
|
||||
|
||||
다음은 코스모스 허브의 풀노드를 설정하고 운용하는 방법입니다. 다른 코스모스 SDK 기반 블록체인 또한 비슷한 절차를 가집니다.
|
||||
|
||||
우선 [소프트웨어를 설치하세요](../getting-started/installation.md).
|
||||
|
||||
이후, [풀노드를 운영하세요](../getting-started/join-testnet.md).
|
||||
|
||||
### 커맨드 라인 인터페이스
|
||||
|
||||
다음은 풀노드를 이용할 수 있는 유용한 CLI 커맨드입니다.
|
||||
|
||||
#### 키페어 생성하기
|
||||
|
||||
새로운 키를 생성하기 위해서는 (기본적으로 secp256k1 엘립틱 커브 기반):
|
||||
|
||||
```bash
|
||||
gaiacli keys add <your_key_name>
|
||||
```
|
||||
|
||||
이후 해당 키페어에 대한 비밀번호(최소 8글지)를 생성할 것을 요청받습니다. 커맨드는 다음 4개 정보를 리턴합니다:
|
||||
|
||||
|
||||
- `NAME`: 키 이름
|
||||
- `ADDRESS`: 주소 (토큰 전송을 받을때 이용)
|
||||
- `PUBKEY`: 퍼블릭 키 (검증인들이 사용합니다)
|
||||
- `Seed phrase`: 12 단어 백업 시드키 **이 시드는 안전한 곳에 별도로 보관하셔야 합니다**. 이 시드키는 비밀번호를 잊었을 경우, 계정을 복구할때 사용됩니다.
|
||||
|
||||
다음 명령어를 통해서 사용 가능한 모든 키를 확인할 수 있습니다:
|
||||
|
||||
```bash
|
||||
gaiacli keys list
|
||||
```
|
||||
|
||||
#### 잔고 조회하기
|
||||
|
||||
해당 주소로 토큰을 받으셨다면 다음 명령어로 계정 잔고를 확인하실 수 있습니다:
|
||||
|
||||
```bash
|
||||
gaiacli account <YOUR_ADDRESS>
|
||||
```
|
||||
|
||||
*참고: 토큰이 0인 계정을 조회하실 경우 다음과 같은 에러 메시지가 표시됩니다: 'No account with address <YOUR_ADDRESS> was found in the state'. 해당 에러 메시지는 정상이며 앞으로 에러 메시지 개선이 들어갈 예정입니다.*
|
||||
|
||||
#### CLI로 코인 전송하기
|
||||
|
||||
다음은 CLI를 이용해 코인을 전송하는 명령어입니다:
|
||||
|
||||
```bash
|
||||
gaiacli send --amount=10faucetToken --chain-id=<name_of_testnet_chain> --from=<key_name> --to=<destination_address>
|
||||
```
|
||||
|
||||
플래그:
|
||||
- `--amount`: `<value|coinName>` 포맷의 코인 이름/코인 수량입니다.
|
||||
- `--chain-id`: 이 플래그는 특정 체인의 ID를 설정할 수 있게 합니다. 앞으로 테스트넷 체인과 메인넷 체인은 각자 다른 아이디를 보유하게 됩니다.
|
||||
- `--from`: 전송하는 계정의 키 이름.
|
||||
- `--to`: 받는 계정의 주소.
|
||||
|
||||
#### Help
|
||||
|
||||
이 외의 기능을 이용하시려면 다음 명령어를 사용하세요:
|
||||
|
||||
```bash
|
||||
gaiacli
|
||||
```
|
||||
|
||||
사용 가능한 모든 명령어를 표기하며, 각 명령어 별로 `--help` 플래그를 사용하여 더 자세한 정보를 확인하실 수 있습니다.
|
||||
|
||||
## REST 서버 설정하기
|
||||
|
||||
REST 서버는 풀노드와 프론트엔드 사이의 중계역할을 합니다. REST 서버는 풀노드와 다른 머신에서도 운영이 가능합니다.
|
||||
|
||||
REST 서버를 시작하시려면:
|
||||
|
||||
```bash
|
||||
gaiacli advanced rest-server --node=<full_node_address:full_node_port>
|
||||
```
|
||||
|
||||
플래그:
|
||||
- `--trust-node`: 불리언 값. `true`일 경우, 라이트 클라이언트 검증 절차가 비활성화 됩니다. 만약 `false`일 경우, 절차가 활성화됩니다. 서비스 제공자의 경우 `true` 값을 이용하시면 됩니다. 기본 값은 `true`입니다.
|
||||
- `--node`: 플노드의 주소와 포트를 입력하시면 됩니다. 만약 풀노드와 REST 서버가 동일한 머신에서 운영될 경우 주소 값은 `tcp://localhost:26657`로 설정하시면 됩니다.
|
||||
- `--laddr`: REST 서버의 주소와 포트를 정하는 플래그입니다(기본 값 `1317`). 대다수의 경우에는 포트를 정하기 위해서 사용됩니다, 이 경우 주소는 "localhost"로 입력하시면 됩니다. 포맷은 <rest_server_address:port>입니다.
|
||||
|
||||
|
||||
### 트랜잭션 수신 모니터링
|
||||
|
||||
추천하는 수신 트랜잭션을 모니터링하는 방식은 LCD의 다음 엔드포인트를 정기적으로 쿼리하는 것입니다:
|
||||
|
||||
[`/bank/balance/{account}`](https://cosmos.network/rpc/#/ICS20/get_bank_balances__address_)
|
||||
|
||||
## Rest API
|
||||
|
||||
REST API는 풀노드와 인터랙션이 가능한 모든 엔드포인트를 정의합니다. 다음 [링크](https://cosmos.network/rpc/)에서 확인이 가능합니다.
|
||||
|
||||
API는 엔드포인트의 카테고리에 따라 ICS 스탠다드로 나뉘어집니다. 예를 들어 [ICS20](https://cosmos.network/rpc/#/ICS20/)은 토큰 인터랙션 관련 API를 정의합니다.
|
||||
|
||||
서비스 제공자에게 더 많은 유연성을 제공하기 위해서 미서명 트랜잭션을 생성, [서명](https://cosmos.network/rpc/#/ICS20/post_tx_sign)과 [전달](https://cosmos.network/rpc/#/ICS20/post_tx_broadcast) 등의 다양한 API 엔드포인트가 제공됩니다. 이는 서비스 제공자가 자체 서명 메커니즘을 이용할 수 있게 합니다.
|
||||
|
||||
미서명 트랜잭션을 생성하기 위해서는 (예를 들어 [코인 전송](https://cosmos.network/rpc/#/ICS20/post_bank_accounts__address__transfers))을 생성하기 위해서는 `base_req` body에서 `generate_only` 플래그를 이용하셔야 합니다.
|
||||
@@ -0,0 +1,85 @@
|
||||
# 베이스앱(BaseApp)
|
||||
|
||||
베이스앱(BaseApp)은 코스모스 SDK 애플리케이션이 텐더민트 노드와 소통할 수 있게하는 기본적 ABCI 애플리케이션의 기반을 정의합니다.
|
||||
|
||||
베이스앱은 다수의 내부 컴포넌트로 구성되어있습니다. 이 중 가장 중요한 컴포넌트는 `CommitMultiStore`와 해당 컴포넌트의 내부 상태(internal state)입니다. 내부 상태는 하위 두 개의 서브스테이트(substate)로 구성되어있으며, 두 서브 스테이트는 각자 트랜잭션 실행 단계의 `CheckTx`와 `DeliverTx` 이용됩니다. 블록 커밋 단계에서는 `DeliverTx`만이 유지됩니다.
|
||||
|
||||
베이스앱은 capabilities keys를 통해 스토어에 마운트 되어야 합니다. 핸들러는 키가 부여된 스토어에만 접근할 수 있습니다. 베이스앱은 모든 스토어가 정상적으로 로딩, 캐쉬 그리고 커밋되는 것을 보장합니다. 마운트 된 스토어 중 '메인(`baseApp.MainstoreKey`' 스토어는 최신 블록 헤더 정보를 보관하며, 이를 기반으로 가장 최근 상태(state)를 찾고 불러올 수 있습니다.
|
||||
|
||||
베이스앱은 `AnteHandler`와 `MsgHandler` 두 가지의 핸들러 타입을 받습니다. `AnteHandler`는 논스값 확인, 서명 확인, 수수료 지불 가능 잔고 확인 등 모든 모듈에서 이용되는 트랜잭션 기능의 글로벌 유효성 검증(global validity check)을 수행합니다. `MsgHandler`의 경우 상태 변경(full state transition) 기능을 수행합니다.
|
||||
|
||||
`CheckTx` 단계에서 상태 변경 기능은 `checkTxState`에만 적용되며, 값비싼 스테이트 변경 작업이 실행되기 전에 리턴을 해야합니다(관련 절차 설계는 각 개발자의 자유입니다). 또한 예상 가스 비용을 리턴해야 합니다.
|
||||
|
||||
`DeliverTx` 단계에서는 상태 변경 기능이 블록체인 상태에 적용되며 트랜잭션은 완전하게 실행되어야 합니다.
|
||||
|
||||
베이스앱은 핸들러에게 전달되는 컨텍스트(context)를 관리하는 역할을 합니다. 또한 `CheckTx`와 `DeliverTx`에게 할당되는 스토어와 블록헤더 정보를 제공합니다. 베이스앱은 시리얼화 포맷(serialization format)에 불가지론적(agnostic)입니다.
|
||||
|
||||
## 트랜잭션 라이프 사이클(Transaction Life Cycle)
|
||||
|
||||
트랜잭션은 실행 단계에서 ABCI 스펙 정의에 따라 `CheckTx`와 `DeliverTx`를 거칠 수 있습니다. `CheckTx`는 블록 제안 검증인이 실행하며 모든 풀노드의 텐더민트 멤풀에서 이용됩니다.
|
||||
|
||||
`CheckTx`와 `DeliverTx`는 (정의된 경우) 애플리케이션의 안티핸들러(AnteHandler)를 실행합니다. 여기서 안티핸들러는 메시지-전(pre-message) 검증을 수행하여 계정, 서명 검증, 수수료 삭감, 수수료 수금, 시퀀스 번호 추가 등의 기능을 수행합니다.
|
||||
|
||||
### CheckTx
|
||||
|
||||
`CheckTx`의 실행 단계에서는 안티핸들러(AnteHandler)만이 실행됩니다.
|
||||
|
||||
안티핸들러로 발생하는 상태 변경은 안티핸들러가 실패하여 중단되는 경우를 제외하고는 check-tx 상태의 `CheckTx`의 추후 콜(call)까지 지속됩니다.
|
||||
|
||||
### DeliverTx
|
||||
|
||||
`DeliverTx`의 실행 단계에서는 안티핸들러(AnteHandler)와 핸들러(Handler)가 함께 실행됩니다.
|
||||
|
||||
`DeliverTx`의 트랜잭션 실행 절차는 `CheckTx`와 유사하게 진행됩니다. 다만, 안티핸들러로 발생하는 상태 변경은 핸들러의 프로세싱 로직이 실패하여도 지속됩니다.
|
||||
|
||||
악의적 제안자(proposer)가 안티핸들러를 통과하지 못하는 트랜잭션을 발생할 수 있는 경우가 발생할 수도 있습니다. 이 경우에는 악의적 트랜잭션의 상태 변경은 버려집니다(무시됩니다).
|
||||
|
||||
## 다른 ABCI 메시지
|
||||
|
||||
`CheckTx`와 `DeliverTx` 외에도 베이스앱은 다음과 같은 ABCI 메시지를 처리합니다.
|
||||
|
||||
### Info
|
||||
TODO complete description (추후 업데이트 예정)
|
||||
|
||||
### SetOption
|
||||
TODO complete description (추후 업데이트 예정)
|
||||
|
||||
### Query
|
||||
TODO complete description (추후 업데이트 예정)
|
||||
|
||||
### InitChain
|
||||
TODO complete description (추후 업데이트 예정)
|
||||
|
||||
체인 시동(chain initialization) 단계에서 `InitChain`은 `CommitMultiStore`에 직접적으로 할당되어 있는 시동 로직을 실행합니다. check state와 deliver state는 정의된 ChainID로 시작됩니다.
|
||||
|
||||
참고할 것은 InitChain 이후에 커밋을 실행하지 않습니다. 그렇기 때문에 블록 1의 BeginBlock은 InitChain이 시작한대로 deliver state에서 시작됩니다.
|
||||
|
||||
### BeginBlock
|
||||
TODO complete description (추후 업데이트 예정)
|
||||
|
||||
### EndBlock
|
||||
TODO complete description (추후 업데이트 예정)
|
||||
|
||||
### Commit
|
||||
TODO complete description (추후 업데이트 예정)
|
||||
|
||||
|
||||
## 가스 관리(Gas Management)
|
||||
|
||||
### 가스: InitChain
|
||||
|
||||
InitChain 실행 단계에서 블록 가스 미터는 제네시스 트랜잭션을 처리하기 위하여 무한대 가스 수량을 기준으로 시작됩니다.
|
||||
|
||||
또한, InitChain의 리퀘스트 메시지에는 genesis.json 파일이 정의하는 ConsensusParams가 포함되어있습니다.
|
||||
|
||||
|
||||
### 가스: BeginBlock
|
||||
|
||||
블록 가스 미터는 BeginBlock의 deliver state에서 리셋됩니다. 만약 베이스앱에서 최대 블록 가스가 설정되어있지 않은 경우, 가스 미터는 무한으로 설정됩니다. 최대 블록 가스가 설정되었을 경우, 가스 미터는 `ConsensusParam.BlockSize.MaxGas`를 통해 설정됩니다.
|
||||
|
||||
### 가스: DeliverTx
|
||||
|
||||
특정 트랜잭션이 실행되기 전, `BlockGasMeter`를 우선 확인하여 남은 가스가 있는지 확인합니다. 만약 남은 가스가 없다면 `DeliverTx`는 즉시 에러를 리턴합니다.
|
||||
|
||||
트랜잭션이 처리된 후, 사용된 가스는 (설정된 가스 리밋에 따라) `BlockGasMeter`에서 차감됩니다. 만약 잔류 가스가 가스 미터의 한도를 초과할 경우, `DeliverTx`는 에러를 리턴하고 해당 트랜잭션은 커밋되지 않습니다.
|
||||
|
||||
|
After Width: | Height: | Size: 283 KiB |
|
After Width: | Height: | Size: 186 KiB |
@@ -0,0 +1,15 @@
|
||||
# SDK 소개
|
||||
|
||||
|
||||
|
||||
[Cosmos-SDK](https://github.com/cosmos/cosmos-sdk)는 코스모스 허브 같은 멀티애셋 지분증명(Proof-of-Stake) 블록체인 또는 권한증명(Proof-of-Authority) 같은 블록체인들을 만들 수 있는 하나의 프레임워크입니다.
|
||||
|
||||
코스모스 SDK의 목표는 개발자들이 본인만의 커스텀 블록체인을 처음부터 쉽게 만들고, 이런 블록체인들이 상호호환성을 가질 수 있게 하는 것입니다. 우리는 코스모스 SDK가 [Tendermint](https://github.com/tendermint/tendermint) 기반의 안전한 블록체인 애플리케이션의 npm 프레임워크 같은 역할을 할수 있을 것을 기대하고 있습니다.
|
||||
|
||||
코스모스 SDK는 다음과 같은 원칙에 의거합니다:
|
||||
|
||||
- **구성성:** 누구나 코스모스-SDK 모듈을 만들 수 있다. 또한 이미 만들어진 기존 모듈을 내가 만드려는 블록체인 애플리케이션에 손쉽게 도입할 수 있다.
|
||||
|
||||
- **능력성:** 코스모스-SDK는 능력기반 보안(capabilities-based security)과 수년의 블록체인 스테이트 머신에 대한 고민을 기반으로 만들어졌습니다. 대다수의 개발자들은 본인들의 모듈을 개발할때 제3자의 모듈을 사용해야되는 경우가 많습니다. 코스모스-SDK는 오픈 프레임워크이기 때문에, 일부 악의적인 모듈이 존재할 수 있다는 것을 배제할 수 없습니다. 이런 환경에서는 보안과 안전성을 확보하기 위해 모듈간 인터랙션에서 기본적인 보안 원칙이 존재해야 합니다. 이런 원칙은 오브젝트-능력(object-capabilities) 기반으로 만들어졌습니다. 각 모듈이 다른 모든 모듈들의 액세스 권한 리스트를 관리하기 보다, 각 모듈은 키퍼(Keeper)라는 특수 오브젝트를 도입할 수 있습니다. 이런 '키퍼' 들은 다른 모듈에게 전달되어 사전에 정의된 능력(기능)을 수행할 수 있는 권한을 부여합니다. 예를 들어, 모듈 A의 키퍼가 모듈 B에게 전달되었을 경우, 모듈 B는 사전에 정의되어있는 한정된 모듈 A의 기능을 호출할 수 있습니다. 각 키퍼가 수행할 수 있는 기능은 해당 모듈의 개발자가 정의할 수 있으며, 모듈 기능으로 발생할 수 있는 안전/보안 문제를 감사하는 책임은 각 개발자에게 있습니다. 능력(capability)에 대한 더 자세한 설명은 다음 [링크](./ocap.md)에서 확인하실 수 있습니다.
|
||||
|
||||
### 다음은 [SDK 애플리케이션 아키텍쳐](./sdk-app-architecture.md)에 대해서 알아보겠습니다
|
||||
@@ -0,0 +1,68 @@
|
||||
# 오브젝트-가능성 모델(Object-Capability Model)
|
||||
|
||||
## 개요
|
||||
|
||||
보안을 검토하기 위해서는 특정 위협 모델(threat model)을 검토하는 것으로 시작하는 것이 좋습니다. 우리가 제시하는 모델은 다음과 같습니다:
|
||||
|
||||
> 코스모스-SDK 모듈을 기반으로 만들어진 블록체인 애플리케이션이 활성화된 생태계에는 허점이 있거나 악의적인 모듈이 존재할 수 있다고 전재합니다.
|
||||
|
||||
코스모스 SDK는 오브젝트-가능성 시스템의 토대가 됨으로 이런 문제점을 해결할 수 있습니다.
|
||||
|
||||
> 오브젝트 가능성 시스템의 구조적 속성은 코드 디자인의 모듈화와 안정적인 캡슐화(encapsulation)를 선호합니다.
|
||||
>
|
||||
> 이런 구조적 속성은 오브젝트-가능 프로그램 또는 운영체제의 보안적 속성의 분석을 가능하게 합니다. 정보 플로우 속성(information flow properties) 같은 일부 속성은 특정 오브젝트의 행동을 결정하는 코드의 지식 또는 분석 없이도 오직 오브젝트 레퍼런스와 연결구조만으로 분석이 가능합니다.
|
||||
>
|
||||
> 그렇기 때문에, 악의적인 코드가 포함되있을 확률이 있는 새로운 오브젝트가 소개되더라도 보안적 속성은 지켜질 수 있습니다.
|
||||
>
|
||||
> 이런 구조적 속성은 해당 오브젝트를 통치하는 두가지 법칙에 의해 지켜질 수 있습니다:
|
||||
> 1. 오브젝트 'A'는 'B'에 대한 레퍼런스를 보유하고 있을 경우에만 메시지를 전송할 수 있다.
|
||||
> 2. 오브젝트 'A'가 'C'에 대한 레퍼런스를 가지고 싶다면 오브젝트 'A'는 'C'에 대한 레퍼런스가 포함된 메시지를 수신해야 한다.
|
||||
>
|
||||
> 이 두 법칙에 따르면 특정 오브젝트는 기존에 존재하는 레퍼런스 체인을 통해서만 다른 오브젝트에 대한 레퍼런스를 받을 수 있는 것입니다. 단순하게 설명하면 "연결성이 연결성을 불러온다"는 것입니다.
|
||||
|
||||
오브젝트 가능성에 대한 소개는 [이 글(영문)](http://habitatchronicles.com/2017/05/what-are-capabilities/)을 참고하세요.
|
||||
|
||||
원칙적으로 말하면, 다음과 같은 문제점 때문에 Golang은 엄격한 오브젝트 가능성을 도입하지 않는다고 볼 수 있습니다:
|
||||
|
||||
- 보편적으로 "unsafe" 또는 "os" 같은 원시적 모듈(primitive module)을 임포트할 수 있음.
|
||||
- 보편적으로 [모듈 vars 오버라이드(https://github.com/golang/go/issues/23161)]가 가능.
|
||||
- 2개 이상의 goroutine이 illegal interface value를 만들 수 있는 data-race 허점.
|
||||
|
||||
문제점 중 첫번째 문제는 임포트 감사(import audit)과 체계적인 디펜던시 버전 컨트롤 시스템(dependency version control system)을 이용하여 문제점을 사전에 찾을 수 있습니다. 다만, 두번째와 세번째 문제는 다서 불편하기는 하지만 노력을 통해서 감사(audit)가 가능합니다.
|
||||
|
||||
현재로써는 [Go2에서 오브젝트 가능성 모델이 도입되는](https://github.com/golang/go/issues/23157)것을 기대하는 상태입니다.
|
||||
|
||||
## 실전에서의 오브젝트 가능성 모델(Ocaps)
|
||||
|
||||
Ocaps의 핵심 아이디어는 특정 일을 수행하는데 필요한 정보만을 공개하는 것입니다.
|
||||
|
||||
예를 들어, 다음의 코드는 오브젝트 가능성 원칙을 위해합니다:
|
||||
|
||||
```go
|
||||
type AppAccount struct {...}
|
||||
var account := &AppAccount{
|
||||
Address: pub.Address(),
|
||||
Coins: sdk.Coins{sdk.NewInt64Coin("ATM", 100)},
|
||||
}
|
||||
var sumValue := externalModule.ComputeSumValue(account)
|
||||
```
|
||||
|
||||
위 코드의 `ComputeSumValue` 메소드는 순수한(pure) 함수를 암시하지만, 포인터 밸류를 받아드리는 것의 암시된 가능성(implied capability)은 해당 밸류를 변경할 수 있는 가능성입니다. 서명 메소드는 그대로 포인터 밸류를 받아들이지 않고 해당 밸류의 사본을 사용하는 것이 바람직합니다.
|
||||
|
||||
```go
|
||||
var sumValue := externalModule.ComputeSumValue(*account)
|
||||
```
|
||||
|
||||
코스모스 SDK에서 이 원칙을 응용한 것을 [gaia 앱](../gaia/app/app.go)에서 확인이 가능합니다.
|
||||
|
||||
```go
|
||||
// register message routes
|
||||
app.Router().
|
||||
AddRoute(bank.RouterKey, bank.NewHandler(app.bankKeeper)).
|
||||
AddRoute(staking.RouterKey, staking.NewHandler(app.stakingKeeper)).
|
||||
AddRoute(distr.RouterKey, distr.NewHandler(app.distrKeeper)).
|
||||
AddRoute(slashing.RouterKey, slashing.NewHandler(app.slashingKeeper)).
|
||||
AddRoute(gov.RouterKey, gov.NewHandler(app.govKeeper))
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
# SDK 애플리케이션 아키텍쳐
|
||||
|
||||
## 스테이트 머신 (상태 기계, State machine)
|
||||
|
||||
블록체인 애플리케이션은 근본적으로 [결정론적 복제 상태 기계(replicated deterministic state machine)](https://ko.wikipedia.org/wiki/%EC%83%81%ED%83%9C_%EA%B8%B0%EA%B3%84_%EB%B3%B5%EC%A0%9C)입니다.
|
||||
|
||||
스테이트 머신은 특정 기계(머신, machine)이 오랜 기간동안 다수의 상태(스테이트, state)를 보유할 수 있지만, 특정 시점에 오직 하나의 상태를 유지하는 있는 컴퓨터 공학 개념입니다. 여기서 '스테이트 머신' 개념에는 시스템의 현 상태를 뜻하는 '스테이트(state)'가 있으며, 스테이트의 변경을 유발하는
|
||||
트랜잭션(transaction)'이 있습니다.
|
||||
|
||||
`S` 라는 스테이트와 `T` 라는 트랜잭션이 있는 경우, 스테이트 머신은 `S'`라는 새로운 스테이트를 리턴합니다.
|
||||
|
||||
```
|
||||
+--------+ +--------+
|
||||
| | | |
|
||||
| S +---------------->+ S' |
|
||||
| | apply(T) | |
|
||||
+--------+ +--------+
|
||||
```
|
||||
|
||||
실전에서는 트랜잭션들이 일종의 '블록' 단위로 묶여 스테이트 변경 과정을 더 효율적일 수 있게 합니다. `S`라는 스테이트와 `B`라는 트랜잭션들이 있는 경우, 스테이트 머신은 `S'`라는 새로운 스테이트를 리턴합니다.
|
||||
|
||||
```
|
||||
+--------+ +--------+
|
||||
| | | |
|
||||
| S +----------------------------> | S' |
|
||||
| | For each T in B: apply(T) | |
|
||||
+--------+ +--------+
|
||||
```
|
||||
|
||||
블록체인이라는 시스템 내의 개념으로 볼때 스테이트 머신은 결정론적(deterministic)입니다. 즉, 특정 스테이트에서 시작한 후 동일한 트랜잭션들을 반복할 경우, 결과 스테이트는 언제나 동일합니다.
|
||||
|
||||
코스모스 SDK는 애플리케이션의 스테이트, 트랜잭션 형태 그리고 스테이트 변경 기능(state-transition function)을 정의하는데 최대한의 유연성을 제공합니다. 코스모스 SDK를 이용해 스테이트 머신을 만드는 과정은 이후 항목에서 다루겠습니다. 우선 이 시스템 내에서 어떻게 **텐더민트**를 사용해 '스테이트'가 복제되는지 알아보겠습니다.
|
||||
|
||||
## 텐더민트
|
||||
|
||||
개발자는 코스모스 SDK를 사용하여 스테이트 머신만을 정의하면 되며, 해당 스테이트를 네트워크에 복제하는 기능은 [*텐더민트*](https://tendermint.com/docs/introduction/introduction.html)가 제공합니다.
|
||||
|
||||
|
||||
```
|
||||
^ +-------------------------------+ ^
|
||||
| | | | 코스모스 SDK로 개발
|
||||
| | 스테이트 머신 = 애플리케이션 | |
|
||||
| | | v
|
||||
| +-------------------------------+
|
||||
| | | ^
|
||||
블록체인 노드 | | 컨센서스 | |
|
||||
| | | |
|
||||
| +-------------------------------+ | 텐더민트 코어
|
||||
| | | |
|
||||
| | 네트워킹 | |
|
||||
| | | |
|
||||
v +-------------------------------+ v
|
||||
```
|
||||
|
||||
텐더민트는 오직 블록체인의 *네트워킹*과 *합의(컨센서스)* 계층을 처리하는 애플리케이션-불가지성(application-agnostic) 엔진입니다. 실전적으로 볼때, 텐더민트는 단순히 트랜잭션의 바이트를 나열하고, 해당 트랜잭션을 네트워크에 전파하는 역할만을 한다는 것입니다. 텐더민트 코어는 텐더민트 비잔틴 결함 감내(BFT, Byzantine-fault tolerant) 알고리즘을 사용하여 트랜잭션 순서에 대한 합의를 합니다. 텐더민트에 대해서 더 알고싶으시다면 [여기](https://tendermint.com/docs/introduction/introduction.html)를 확인하세요.
|
||||
|
||||
텐더민트 합의 알고리즘은 '검증인(Validators)'이라는 특정 노드 세트를 기반으로 작동합니다. 검증인의 주 역할은 트랜잭션을 블록 단위로 블록체인에 추가하는 것입니다. 특정 블록에는 V 검증인 세트 검증인 존재하며, 이 V 검증인 세트 안에 있는 검증인 중 하나의 검증인이 다음 블록 생성자로 알고리즘에 의해 선택됩니다. 만약 블록이 V 검증인 세트 2/3 이상의 [프리보트(prevote)](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)와 [프리커밋(precommit)](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)을 받고 내용 트랜잭션이 유효한 경우 해당 블록은 '유효(valid)'한 것으로 간주됩니다. 검증인 세트는 스테이트 머신에 작성된 규칙에 따라서 바뀔 수 있습니다. 알고리즘에 대해 더 자세한 정보는 [여기](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview)를 참고하세요.
|
||||
|
||||
코스모스 SDK 애플리케이션의 주요 파트는 네트워크에 포함되어있는 노드가 각자 로컬 환경에서 운영하는 블록체인 데몬(daemon)입니다. 만약 *검증인 세트*의 1/3 이하가 악의적(byzantine)인 경우, 각 노드는 동시에 스테이트를 조회할때 동일한 결과를 받게됩니다.
|
||||
|
||||
## ABCI
|
||||
|
||||
텐더민트는 네트워크에서 어플리케이션으로 거래를 넘겨줍니다. 이때, ABCI 라고 불리우는 인터페이스를 사용합니다. 그리고 이는 어플리케이션이 반드시 구현해야하는 부분입니다.
|
||||
|
||||
```
|
||||
+---------------------+
|
||||
| |
|
||||
| Application |
|
||||
| |
|
||||
+--------+---+--------+
|
||||
^ |
|
||||
| | ABCI
|
||||
| v
|
||||
+--------+---+--------+
|
||||
| |
|
||||
| |
|
||||
| Tendermint |
|
||||
| |
|
||||
| |
|
||||
+---------------------+
|
||||
```
|
||||
|
||||
**텐더민트는 오직 거래의 bytes 값들만 취급하지 실제 그 bytes 들이 어떤 의미를 가지고 있는지는 파악하지 않습니다.** 텐더민트가 하는 일은 이 거래 bytes 들을 결정론적으로 나열하는 것 뿐입니다. 텐더민트는 이 bytes 들을 ABCI 를 통해서 어플리케이션에 넘겨주고, 그 메세지에 담겨있는 거래들이 잘 처리되었는지 안되었는지를 확인해주는 return code 를 기다립니다.
|
||||
|
||||
아래에 ABCI 의 메세지들 중 가장 중요한 것들을 나열해놓았습니다:
|
||||
|
||||
- `CheckTx`: 텐더민트 코어로부터 거래를 받게 될 때, 이 거래는 어플리케이션에 넘겨져서 몇가지 기본 요건을 잘 만족했는지를 확인합니다. `CheckTx` 는 풀노드의 mempool을 스팸행위로 부터 보호하는데 사용됩니다. "Ante Handler" 라고 불리우는 특별한 handler 는 일련의 검증 과정을 실행하는데 사용됩니다. 예를 들면, 충분한 수수료가 있는지와 서명이 유효한지를 확인합니다. 만약 검사 결과가 유효한 것으로 나오게 되면, 그 거래는 [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) 에 더해지게 됩니다. 그리고 피어 노드들에게도 전달됩니다. 거래가 블록에 담기기 전까지는 `CheckTx` 과정은 진행되지 않는다. (즉, 상태의 변경이 일어나지 않는다.)
|
||||
|
||||
- `DelieverTx` : [유효한 블록](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation)이 텐더민트 코어에 의해서 전달되었을 때, 해당 블록에 있는 모든 개별 거래들은 `DeliverTx`에 의해서 어플리케이션에게 전달됩니다. 상태 변환이 일어나는 단계가 이 단계이다. "Ante Handler" 는 실제 handler 와 함께 거래 내의 각 메세지에 대한 검증을 위해 다시 실행한다.
|
||||
|
||||
- `BeginBlock`/`EndBlock` : 이 메세지들은 블록이 거래를 담고 있던 아니던 각 블록의 시작과 끝에 실행됩니다. 과정을 자동화 해놓으면 상당히 유용할 것입니다. 하지만, 진행 중 주의해야 할 사안이 하나 있습니다. 과도하게 컴퓨팅 자원이 많이 필요로 하는 루프는 블록체인의 속도 면에서 악영향을 끼칠 수 있고 만약 무한 루프라면 작동을 멈출 수도 있습니다.
|
||||
|
||||
ABCI 메소드와 타입에 대해서 더 자세하게 싶다면, [여기](https://tendermint.com/docs/spec/abci/abci.html#overview)를 클릭하십시오.
|
||||
|
||||
텐더민트 상에서 구현된 모든 어플리케이션은 ABCI 인터페이스를 구현해야만 합니다. 그래야 로컬 텐더민트 엔진과 통신할 수 있습니다. 다행스럽게도, 당신이 스스로 직접 ABCI 인터페이스를 구현할 필요는 없습니다. Cosmos SDK 가 [baseapp](https://cosmos.network/docs/intro/sdk-design.html#baseapp) 의 형태로 boilerplate 를 제공합니다.
|
||||
|
||||
### 자 이제 다음단계로 [SDK 고수준 설계 원칙에 대해서 알아보자.](https://cosmos.network/docs/intro/sdk-design.html#baseapp)
|
||||
@@ -0,0 +1,39 @@
|
||||
# Cosmos SDK Documentation Translation (Korean)
|
||||
|
||||
This document tracks the progress of the Korean translation of the official Cosmos SDK documentation.
|
||||
|
||||
Documentation has been translated for **reference use only** and may contain typos, factual errors and be out-of-date with the latest english documentation.
|
||||
|
||||
Please refer to the official english version of the documentation for the latest and accurate information.
|
||||
|
||||
|
||||
## 코스모스 SDK 도큐멘테이션 번역 (한국어)
|
||||
|
||||
이 문서는 코스모스 공식 문서의 번역 작업 트래킹을 위한 문서입니다.
|
||||
|
||||
번역된 문서는 **참고용**으로 번역되었습니다. 다수의 오타, 오류가 존재할 수 있으며, 영문 업데이트보다 번역이 느리게 진행될 수 있다는 점을 인지하시기 바랍니다.
|
||||
|
||||
코스모스 관련 가장 정확한 정보를 확인하시기 위해서는 영어 원문을 참고하시기 바랍니다.
|
||||
|
||||
|
||||
## Progress by directory
|
||||
|
||||
|
||||
### [`concepts`](../concepts/)
|
||||
- Synced until commit [14ebc65](https://github.com/cosmos/cosmos-sdk/commit/14ebc65daffd63e1adf17995c103aac9380207ef#diff-f874f370376bf359320af0543de53fcf)
|
||||
|
||||
### [`spec`](../spec/)
|
||||
- Redacted from until completion
|
||||
|
||||
### [`gaia`](../gaia/)
|
||||
- Synced until commit [288df6f](https://github.com/cosmos/cosmos-sdk/commit/288df6fe69dcef8fa95aca022039f92ba1e98c11#diff-3302fe357e01f0996ddb0f10adec85f0)
|
||||
|
||||
### [`intro`](../intro/)
|
||||
- Synced until commit [0043912](https://github.com/cosmos/cosmos-sdk/commit/0043912548808b4cfd6ab84ec49ba73bd5f65b5b#diff-e518eaec0d99787e6f75682d54751821)
|
||||
|
||||
### [`modules`](../modules/)
|
||||
- Synced until commit [78a2135](https://github.com/cosmos/cosmos-sdk/commit/78a21353da978d6c2a9b711f29b3874ff9ca14ae#diff-449cc65858e8929d15f4a170950e7758)
|
||||
|
||||
### [`clients`](../clients/)
|
||||
- Synced until Commit [857a65d](https://github.com/cosmos/cosmos-sdk/commit/857a65dc610cd736a47980b5d4778e5123206a3d#diff-93dd988c16d20a1bce170b86ad89425a)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# Bank
|
||||
|
||||
`x/bank` 모듈은 계정 간 코인을 이동할때 사용됩니다.
|
||||
|
||||
[API 문서](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank)를 확인하세요.
|
||||
|
||||
# Stake
|
||||
|
||||
`x/staking` 모듈은 코스모스 위임형 지분증명(Delegated-Proof-of-Stake) 시스템에서 사용됩니다.
|
||||
|
||||
[API 문서](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking)를 확인하세요.
|
||||
|
||||
관련 스펙은 [여기](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking)에서 확인하실 수 있습니다.
|
||||
|
||||
|
||||
# Slashing
|
||||
|
||||
`x/slashing` 모듈은 코스모스 위임형 지분증명(Delegated-Proof-of-Stake) 시스템에서 사용됩니다.
|
||||
|
||||
[API 문서](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing)를 확인하세요.
|
||||
|
||||
관련 스펙은 [여기](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing)에서 확인하실 수 있습니다.
|
||||
|
||||
# Provisions
|
||||
|
||||
`x/provisions` 모듈은 수수료 보상 분배와 스테이킹 인플레이션을 조정할때 사용됩니다.
|
||||
|
||||
[API 문서](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution)를 확인하세요.
|
||||
|
||||
관련 스펙은 [여기](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution)에서 확인하실 수 있습니다.
|
||||
|
||||
# Governance
|
||||
|
||||
`x/gov` 모듈은 본딩한 토큰 보유자들이 프로포절을 만들고 투표를 진행할때 사용됩니다.
|
||||
|
||||
[API 문서](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov)를 확인하세요.
|
||||
|
||||
관렉 스펙은 [여기](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance)에서 확인하실 수 있습니다.
|
||||