diff --git a/doc/grin4bitcoiners.md b/doc/grin4bitcoiners.md index acdb6f96e0..fbf4a52d9c 100644 --- a/doc/grin4bitcoiners.md +++ b/doc/grin4bitcoiners.md @@ -1,5 +1,7 @@ # Grin/MimbleWimble for Bitcoiners +*Read this in other languages:[Korean](grin4bitcoiners_KR.md) + ## Privacy and Fungibility There are 3 main properties of Grin transactions that make them private: @@ -39,7 +41,7 @@ Bitcoin's 10 minute block time has its initial 50 btc reward cut in half every 4 Nope, no address. All outputs in Grin are unique and have no common data with any previous output. Instead of relying on a known address to send money, transactions have to be built interactively, with two (or more) wallets exchanging data with one another. This interaction **does not require both parties to be online at the same time**. Practically speaking, there are many ways for two programs to interact privately and securely. This interaction could even take place over email or Signal (or carrier pigeons). -### If transaction information gets removed, can't I just cheat and create money? +### If transaction information gets removed, can I just cheat and create money? No, and this is where MimbleWimble and Grin shine. Confidential transactions are a form of [homomorphic encryption](https://en.wikipedia.org/wiki/Homomorphic_encryption). Without revealing any amount, Grin can verify that the sum of all transaction inputs equal the sum of transaction outputs, plus the fee. Going even further, comparing the sum of all money created by mining with the total sum of money that's being held, Grin nodes can check the correctness of the total money supply. diff --git a/doc/grin4bitcoiners_KR.md b/doc/grin4bitcoiners_KR.md new file mode 100644 index 0000000000..214bbb6d15 --- /dev/null +++ b/doc/grin4bitcoiners_KR.md @@ -0,0 +1,58 @@ +# Bitcoiner를 위한 Grin/MimbleWimble + +## 프라이버시와 대체가능성(Fungibility) + +Grin 트랜잭션에는 트랜잭션을 프라이빗하게 만드는 3 가지 주요 속성이 있습니다. + +1. 주소가 없습니다. +2. 금액은 없습니다. +3. 하나는 다른 트랜잭션을 사용하는 2 개의 트랜잭션을 하나의 블록으로 병합하여 모든 중간 정보를 제거 할 수 있습니다. + +처음두 가지 속성은 모든 트랜잭션을 서로 구별 할 수 없음을 의미합니다. 거래에 직접 참여하지 않는 한 모든 입력과 출력은 임의의 데이터 조각처럼 보입니다 (말하자면 출력값과 입력값 모두 랜덤한 곡선 위의 점입니다). + +또한 블록에 트랜잭션이 없습니다. Grin 블록은 마치 하나의 거대한 트랜잭션처럼 보이고 입력과 출력 사이의 모든 연관성이 사라집니다. + +## 확장성(Scalability) + +이전 섹션에서 설명한 것처럼 MimbleWimble 트랜잭션과 블록 포맷 때문에 출력이 다른 트랜잭션의 입력에 의해 직접 소비(spent) 될 때 트랜잭션을 합칠 수 있습니다. (예를 들어 - 문맥의 부드러움을 위해 첨가함, 역자 주 )앨리스가 밥에게 돈을 주고 밥이 캐럴에게 돈을 주면 밥은 결코 연관되지 않은것처럼 보이고 실제로 밥의 트랜잭션은 블록체인에서 보이지 않습니다. + +더 많은 트랜잭션들을 블록에 밀어 넣으면 대부분의 출력이 다른 입력에 의해 조만간 소비됩니다. 따라서 *모든 소비 출력값을(spent outputs) 안전하게 제거 할 수 있습니다*. 그리고 (bitcoin과 유사한 트랜잭션의 수를 가정 한다면)몇 GB 이하로 전체 블록 체인을 저장하고, 다운로드하고, 완벽하게 검증 할 수 있습니다. + +즉, Grin 블록 체인은 트랜잭션 수가 아닌 사용자 수 (사용되지 않은 출력)에 따라 확장됩니다. 그러나 현재 하나 주의하자면 (kernel 이라고 불리는 약 100 바이트의 데이터) 작은 데이터 조각은 각 트랜잭션마다 기다릴 필요가 있습니다. 그러나 이를 최적화하기 위해 노력하고 있습니다. + +## 스크립팅(Scripting) + +아마도 MimbleWimble은 스크립트(Script)를 지원하지 않는다는 말을 들었을 겁니다. 어떤면에서 이 말은 사실입니다. 그러나 암호화 기법 덕분에 Bitcoin에서 스크립트를 필요로 하는 많은 계약은 Elliptic Curve Cryptography의 속성을 사용하여 Grin으로 작성 할 수 있습니다. 지금까지 아래와 같은 구현을 어떻게 하는지 하는지 알고 있습니다. : + +* Multi-signature transactions. +* 아토믹 스왑 (Atomic swap). +* Time-locked transactions and outputs. +* 라이트닝 네트워크 (Lightning Network) + +## 블록 생성주기와 블록 보상비율 + +비트코인(Bitcoin)은 처음에 10분마다 50개의 btc를 제공했고 2100만 비트코인이 유통 될 때까지 4 년마다 블록 보상이 반으로 줄어듭니다. Grin의 블록 보상율은 선형적이며(Linear) 블록 보샹율은 떨어지지 않습니다.( 계속 60GRN/block의 비율을 유지한다는 의미 - 역자 주) Grin의 블록 보상은 현재 60 초마다 블록을 생성하고 블록당 60개의 Grin을 받도록 세팅되어 있습니다. 이는 ​다음과 같은 두가지 이유로 인해 효과가 있습니다. 1) (코인의) 가치저하가 0에 가까우며 2) 매년 무시할 수 없는 양의 동전이 매년 분실되거나 파괴되기 때문입니다 (코인을 계속 사용한다면 코인의 가치저하는 없으며 비트코인처럼 많은 양의 코인이 분실되거나 없어지기 때문에 상기 2가지 이유를 말한것 같음 - 역자 주). + +## FAQ + +### 잠시만요 뭐라구요? 주소가 없다구요? + +네, 주소가 없습니다. Grin의 모든 출력은 유니크 하고 이전 출력과 공통된 데이터가 없습니다. 알려진 주소를 사용하여 돈을 송금하는 대신 두 개 이상의 지갑(주소)이 서로 데이터를 교환하면서 대화식으로 트랜잭션을 만들어야만 합니다. **이 인터렉션에서는 서로 동시에 온라인 상태일 필요는 없습니다**. 실제로 두 프로그램이 프라이빗 하고 안전하게 인터렉션 할 수 있는 방법은 다양합니다. 이 인터렉션은 이메일이나 시그널 (또는 전보 전달 비둘기)을 통해 일어날 수도 있습니다. + +### 트랜잭션 정보가 제거된다면 사기는 치거나 코인을 만들어 낼수 있지 않나요? + +아니요, MimbleWimble과 Grin의 장점이 돋보이는것이 바로 이런 점 입니다. Confidential transaction은 [동형(homomorphic)암호](https://en.wikipedia.org/wiki/Homomophic_encryption)의 한 형태입니다. 금액을 드러내지 않고 Grin은 모든 거래의 입력값의 합계가 거래의 출력값의 합계 + 수수료를 합한 것과 일치하는지 확인이 가능합니다. 더해서 마이닝으로 만들어진 모든 코인의 합계와 보유하고 있는 총 금액과 비교하여, Grin노드는 코인의 모두 얼마나 공급 되었는지 그 정확성을 확인할 수 있습니다. + +### 만약 트랜잭션 릴레이를 받는다면 컷 쓰루 전에는(cut-through) 누구에게 트랜잭션이 속하는지 알 수 없지 않나요? + +어떤 거래에 의해서 어떤 출력값을 소비하고 있는지 알 수 있지만 여기서 데이터의 흔적이 멈춥니다. 모든 입력과 출력은 임의의 데이터 조각처럼 보이므로 돈이 전송되었는지, 여전히 같은 사람에게 속해 있는지, 어떤 출력값이 실제로 전송했는지, 어떤것이 변경되었는지 등은 알 수 없습니다. Grin 트랜잭션들은 *식별 할 수있는 정보가 없습니다*. + +또한, Grin은 [Dandelion relay](dandelion/dandelion_KR.md)를 활용하여 트랜잭션이 발생한 IP 또는 클라이언트에 대한 추가적인 익명성을 제공하고 트랜잭션을 합칠 수 있습니다. + +### 퀀텀 컴퓨타게돈(compute + armageddon) 에 대해서 궁금해요. + +모든 Grin 출력값에는 해싱된 퀀텀 세이프 데이터가 포함되어 있습니다. 양자 컴퓨팅이 현실화되더라도, 기존 동전을 해킹하지 못하게 하는 추가 검증을 안전하게 도입 할 수 있습니다. + +### 어떻게 이 모든일이 가능한거죠? + +이와 관련해서는 [technical introduction](intro_KR.md)문서를 참조하세요. diff --git a/doc/merkle.md b/doc/merkle.md index 9ea4788dee..6077638250 100644 --- a/doc/merkle.md +++ b/doc/merkle.md @@ -1,5 +1,7 @@ # Merkle Structures +*Read this in other languages:[Korean](merkle_KR.md) + MimbleWimble is designed for users to verify the state of the system given only pruned data. To achieve this goal, all transaction data is committed to the blockchain by means of Merkle trees which should support efficient diff --git a/doc/merkle_KR.md b/doc/merkle_KR.md new file mode 100644 index 0000000000..69a9609406 --- /dev/null +++ b/doc/merkle_KR.md @@ -0,0 +1,113 @@ +# 머클의 구조 + +MimbleWimble은 Pruning 데이터만 있는 시스템의 상태를 사용자가 증명하도록 설계되었습니다. 이러한 목표를 달성하기 위해 모든 트랜잭션 데이터는 pruning 된 경우라도 효율적인 업데이트와 serialization을 지원하는 Merkle 트리를 사용하여 블록 체인에 커밋됩니다. + +또한 거의 모든 거래 데이터 (입력, 출력, Excess 및 Excess proof)는 어떤 방식으로 합산 될 수 있으므로 Merkle sum 트리를 기본 옵션으로 처리하고 여기에서 합계를 처리하는 것이 좋습니다. + +Grin의 디자인 목표는 모든 구조를 구현하기 쉽고 가능한 한 간단하게 만드는 것입니다. +MimbleWimble은 많은 새로운 암호화 방식을 내 놓았고 이러한 방식을 가능한 한 쉽게 이해할 수 있도록 만들어야합니다. +새로운 암호화 방식의 입증 규칙은 스크립트가 없이도 구체화 하기 쉽고 Grin은 매우 명확한 의미론을 가진 프로그래밍 언어로 작성되기 때문에 단순함은 잘 알려진 컨센서스 룰을 달성하는 것에도 좋습니다. + +## Merkle Trees + +각 블록마다 4가지의 머클 트리가 커밋됩니다. + +### Total Output Set + +각 오브젝트는 uspent output 을 나타내는 commitment 또는 spent를 나타내는 NULL 마커 두 가지 중 하나입니다. Unspent 출력에 대한 sum-tree 입니다 (Spent 된 것은 합계에 아무런 영향을 미치지 않습니다). output 세트는 현재 블록이 적용된 *후에* 체인 의 상태를 반영해야합니다. + +Root 합계는 제네시스 블록 이후 모든 Excess의 합계와 같아야합니다. + +설계 요구 사항은 아래와 같습니다. + +1. 효율적으로 추가 되어야 하고 및 unspent 에서 spent 로 업데이트가 되어야 합니다. +2. 특정 출력값이 Spent 임을 효율적으로 증명해야 합니다. +3. UTXO root간에 diffs를 효율적으로 저장합니다. +4. 수백만 개의 항목이 있거나 누락된 데이터가 있는 경우에도 트리에 효율적으로 저장되어야 합니다. +5. 노드가 NULL로 커밋되는 경우에는 unspent 하위 항목이 없고 그 데이터를 결과적으로 영구히 삭제할 수 있게 합니다. +6. 부분 아카이브 노드에서 Pruning된 트리의 serializtion 및 효율적인 병합을 지원합니다. + +### Output의 증거 + +이 트리는 전체 출력 set을 반영하지만 commitment 대신 range proof를 가집니다. 이 트리는 절대 업데이트 되지 않고, 단지 추가되고, 어떤 것이든 더이상 더하지 않습니다. 출력을 소비 할 때 Tree를 삭제하는 것보다는 tree 에서 rangeproof를 삭제하는 것으로 충분합니다. + +설계 요구 사항은 아래와 같습니다. + +1. 부분 아카이브 노드에서 Pruning 된 트리의 serializtion 과 효율적인 병합을 지원해야 합니다. + +### 입력과 출력 + +각 객체는 입력 (이전 트랜잭션 출력에 대한 명확한 레퍼런스) 또는 출력 (commitment, rangeproof) 중 하나입니다. 이 sum-tree는 출력에 대한 commitment이고 입력의 commitment에 대한 원본입니다. + +입력 레퍼런스는 이전 commitment의 해시입니다. 모든 unspent 출력은 유니크 해야한다는 것이 컨센서스의 규착입니다. + +Root 합계는 이 블록의 Excess 합계와 같아야 합니다. 이에 대해 다음 섹션을 참고하세요. + +일반적으로 밸리데이터는 이 Merkle 트리의 100 % 또는 0 %를 확인 할 수 있으므로 모든 디자인과 호환됩니다. +설계 요구 사항은 다음과 같습니다 : + +1. Proof of publication을 위해서 증명을 효율적으로 포함해야 합니다. + +### Excesses + +각 객체는 (초과, 서명) 형식입니다. 이러한 객체는 Excess를 합친 sum-tree 입니다. + +일반적으로 밸리데이터는 항상 이 트리의 100 %를 확인 할 것이므로 Merkle 구조일 필요가 전혀 없습니다. 그러나 나중에 부분 아카이브 노드를 지원하기 위해 효율적인 Pruning을 지원하기를 원합니다. + +설계 요구 사항 은 아래와 같습니다. : + +1. 부분 아카이브 노드에서 pruning 된 tree의 serialzatoin 과 효율적인 병합을 지원해야 합니다. + +## 제안된 Merkle 구조 + +**모든 tree에 대해 다음과 같은 설계가 제안됩니다. Sum-MMR은 모든 노드가 합계에 포함될 데이터 와 자식수의 합계입니다. +결과적으로 모든 노드가 모든 하위 노드의 수로 커밋됩니다.** + +[MMRs, or Merkle Mountain Ranges](https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md) + +출력값 세트를 위해서 6개의 디자인 원칙은 다음과 같습니다. + +### 효율적인 insert/updates + +즉시적이여야 합니다. (지금은 proof-of-inclusion입니다.). 이 원칙은 균형 잡힌 Merkle tree 디자인에 합당합니다. + +### 효율적인 proof-of-spentness + +Grin은 proof of spentness가 필요하지 않지만 SPV client 을 위해 앞으로 지원하는 것이 좋습니다. + +자식의 수는 tree의 각 개체에 대한 인덱스를 의미합니다. 삽입은 트리의 맨 오른쪽에서만 발생하므로 변경되지 않습니다. + +이렇게하면 동일한 출력이 나중에 트리에 추가 되더라도 영구적으로 proof-of-spentness를 허용하고 동일한 출력에 대해서도 오류 잘못된 증명에 대해서도 방지 할 수 있습니다. 이러한 속성은 삽입 순서가 지정되지 않은 tree에서는 하기 어렵습니다. + +### 효율적인 diffs의 저장 + +모든 블록을 저장하면 충분합니다. 업데이트는 실행 취소만큼 수월하고, 블록은 항상 순서대로 처리되기 때문에 트리의 오른쪽에서 인접한 출력 세트를 제거하는 것과 만큼 reorg를 하는 동안 블록을 되감는 것이 간단합니다. 삭제를 지원하도록 설계된 트리의 반복 삭제보다 훨씬 빠릅니다. + +### 데이터가 손실되는 상황에서도 효율적인 tree의 저장 + +랜덤한 결과가 소비되었을 때 root 해시를 업데이트하려면 전체 tree를 저장하거나 계산할 필요가 없습니다. 대신 depth 20에 해시 만 저장할 수 있습니다. 쉽세 말하자면 최대 100 만개가 저장됩니다. 그런 다음 각 업데이트는 이 depth보다 위의 해시를 다시 계산하면됩니다 (Bitcoin의 히스토리에는 2 ^ 29 미만의 출력이 있으므로 각 업데이트에 대해 크기가 2 ^ 9 = 512 인 트리를 계산해야 함). 모든 업데이트가 완료되면 root 해시를 다시 계산할 수 있습니다. + +이 깊이는 설정 할 수 있고 출력 set가 증가하거나 사용 가능한 디스크 공간에 따라 변경 될 수 있습니다. + +이런 과정은 어느 Merkle 트리에서 가능하지만 깊이를 어떻게 계산하느냐에 따라 PATRICIA tree 나 다른 prefix tree로 인해 복잡 할 수 있습니다. + +### 사용된 코인 지우기 + +코인은 spent 에서 unspent로 이동하지 않으므로 spent 된 코인에 대한 데이터는 더 이상 업데이트나 검색를 위해 필요하지 않습니다. + +### Pruning 된 tree 의 효율적인 Serialization + +모든 노드는 자식 수를 가지므로 밸리데이터는 모든 해시가 없이도 tree 구조를 결정할 수 있으며 형제 노드를 결정할 수 있습니다. + +출력 세트에서 각 노드는 unspent한 자식의 합계도 커밋하므로 밸리데이터는 pruning 된 노드에서 합계가 0인지 여부를 반드시 확인을 하기에 unspent 된 코인의 데이터가 누락되더라도 알게 됩니다. + +## Algorithms + +구현체로서 함께 표시됩니다. +( 소스코드를 참고하라는 의미 - 역자 주 ) + +## Storage + +합계 tree 데이터 구조를 사용하면 출력 set과 출력 증거를 효율적으로 저장하면서 root 해시 또는 root 합계 (해당되는 경우)를 즉시 검색 할 수 있습니다. 그러나 tree는 시스템에 모든 출력 commitment 와 증거 해시를 포함해야합니다. 이 데이터는 너무 커서 pruning을 고려하더라도 메모리에 영구적으로 저장 될 수 없으며 재시작 할 때마다 처음부터 다시 작성하기에는 비용이 큽니다. (이런 경우에 Bitcoin이 UTXO당 2개의 해시를 가진다고 가정하면 적어도 3.2GB의 용량을 필요로 하는 50M UTXO가 있습니다.). 따라서 이 데이터 구조를 디스크에 저장하는 효율적인 방법이 필요합니다. + +해시 트리의 또 다른 한계는 키 (즉, 출력 commitment)가 주어지면, 그 키와 연관된 tree에서 리프노드를 발견하는 것이 불가능합니다. 그래서 root에서 tree로 찾아 내려 갈 수 없습니다. 따라서 전체 키에 대한 추가 인덱스가 필요합니다. MMR은 append 전용 바이너리 tree이므로 삽입 위치를 기준으로 tree에서 키를 찾을 수 있습니다. 따라서 tree에 삽입 된 키의 전체 인덱스 (즉, 출력 commitment)의 삽입 포지션 또한 필요합니다. \ No newline at end of file diff --git a/doc/mmr.md b/doc/mmr.md index cbd06d03f7..62bd9b4bad 100644 --- a/doc/mmr.md +++ b/doc/mmr.md @@ -1,5 +1,7 @@ # Merkle Mountain Ranges +*Read this in other languages:[Korean](mmr_KR.md) + ## Structure Merkle Mountain Ranges [1] are an alternative to Merkle trees [2]. While the diff --git a/doc/mmr_KR.md b/doc/mmr_KR.md new file mode 100644 index 0000000000..0194a1e774 --- /dev/null +++ b/doc/mmr_KR.md @@ -0,0 +1,117 @@ +# Merkle Mountain Ranges + +## MMR의 구조 + +Merkle Mountain Ranges [1]은 Merkle trees [2]의 대안입니다. 후자는 완벽하게 균형 잡힌 이진 트리를 사용하지만 전자는 완벽하게 균형잡힌 binary tree list 거나 오른쪽 상단에서 잘린 single binary tree로 볼 수 있습니다. Merkle Mountain Range (MMR)는 엄격하게 append 에서만 사용됩니다. 원소는 왼쪽에서 오른쪽으로 추가되고, 두 하위 원소가 있는 즉시 부모를 추가하여 그에 따라 범위를 채웁니다. + +다음 그림은 각 노드를 삽입 순서대로 표시한 것입니다. 11 개의 삽입 된 리프와 총크기 19가 있는 range 를 표시합니다. + +``` +Height + +3 14 + / \ + / \ + / \ + / \ +2 6 13 + / \ / \ +1 2 5 9 12 17 + / \ / \ / \ / \ / \ +0 0 1 3 4 7 8 10 11 15 16 18 +``` + +이 구조는 편평한 리스트로 표시할 수 있습니다. 여기서는 각 노드의 삽입 포지션에서 노드의 높이를 나타냅니다. ( 위의 그림과 아래의 평면 리스트를 비교하면 이해가 쉬움 - 역자 주 ) + +``` +0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 +0 0 1 0 0 1 2 0 0 1 0 0 1 2 3 0 0 1 0 +``` + +이 구조는 크기(19)에서 간단히 설명 할 수 있습니다. 빠른 binary operation을 사용하기 때문에 MMR 내에서 탐색하는 것도 매우 간단합니다. 주어진 노드의 위치`n`이라면 이 MMR의 높이, 부모의 위치, 형제 등을 계산할 수 있습니다. + +## Hashing 과 Bagging + +Merkle tree와 마찬가지로 MMR의 부모 노드는 자신의 두 하위 노드의 해시 값을 가지고있습니다. Grin은 전체적으로 Blake2b 해시 함수를 사용하고 충돌을 피하기 위해 해싱하기 전에 항상 노드의 위치를 ​​MMR에 추가합니다. 따라서 데이터 `D`를 저장하는 인덱스 ​`n` 에 리프노드 `l`이 있는 경우엔 (예를 들자면 출력의 경우 해당 데이터는 Pedersen commitment 입니다), 다음과 같이 표시됩니다. + +``` +Node(l) = Blake2b(n | D) +``` + +인덱스 `m`에서 어떤 부모 `p`라면 다음과 같습니다. + +``` +Node(p) = Blake2b(m | Node(left_child(p)) | Node(right_child(p))) +``` + +Merkle 트리와는 달리 MMR은 일반적으로 하나의 root를 구성하지 않으므로 계산할 방법이 필요합니다. 그렇지 않으면 해시 트리를 사용하는 목적이 무의미 합니다. 이 과정은 [1]에서 설명한 이유 때문에 "bagging the peaks" 라고 합니다. + +먼저 MMR의 최고 높이를 확인합니다. (여기서 확인 할 수 있는 한 가지 방법을 정의 할 것입니다.) 일단 다른 작은 예제 MMR을 보여드리겠습니다. 인덱스는 1부터 시작하고 10 진수가 아닌 2 진수로 작성됩니다. + +``` +Height + +2 111 + / \ +1 11 110 1010 + / \ / \ / \ +0 1 10 100 101 1000 1001 1011 +``` + +이 MMR에는 11 개의 노드가 있으며 그 피크는 111(7), 1010(10) 및 1011(11) 입니다. 먼저 이진법으로 표현 될 때 가장 왼쪽 첫번째 피크가 항상 가장 (위치가) 높고 항상 "모두 1"이 되는 것에 주목하세요. 그럼 이 피크는 `2^n - 1` 형태의 위치를 ​​가질 것이고 항상 MMR 내부에있는 가장 높은 위치 (그 위치는 전체 크기보다 작습니다)입니다. 사이즈 11의 MMR에 대해서도 반복적으로 처리합니다. + +``` +2^0 - 1 = 0, and 0 < 11 +2^1 - 1 = 1, and 1 < 11 +2^2 - 1 = 3, and 3 < 11 +2^3 - 1 = 7, and 7 < 11 +2^4 - 1 = 15, and 15 is not < 11 +``` + +Finally, once all the positions of the peaks are known, "bagging" the peaks +consists of hashing them iteratively from the right, using the total size of +the MMR as prefix. For a MMR of size N with 3 peaks p1, p2 and p3 we get the +final top peak: + +따라서 첫 번째 피크는 7입니다. 다음 피크를 찾으려면 오른쪽 형제에게 "점프" 해야 합니다. 해당 노드가 MMR에 없다면 왼쪽 하위 노드를 가져옵니다. 만약 그 하위노드도 MMR에 없으면, MMR에 있는 노드를 가져올 때까지 왼쪽에 있는 하위 노드를 계속 가져옵니다. 다음 피크를 찾으면 마지막 노드에 도달 할 때까지 프로세스를 반복합니다. + +이 모든 오퍼레이션은 매우 간단합니다. 높이 `h`에 있는 노드의 오른쪽 형제로 점프하는 것은 `2^(h + 1)-1`만큼을 높이 `h`에 추가하는 것입니다. 왼쪽 형제를 가져 가면 `2^h`만큼 값을 뺍니다. + +마지막으로 피크의 모든 위치를 알게되면 피크들을 "bagging"하는 것은 MMR의 전체 크기를 prefix로 사용해서 반복적으로 오른쪽에서부터 해싱하는 것으로 구성됩니다. 3 개의 피크 p1, p2 및 p3을 갖는 크기 N의 MMR에 대해, 다음과 같은 최종 최고 피크를 얻습니다. : + + +``` +P = Blake2b(N | Blake2b(N | Node(p3) | Node(p2)) | Node(p1)) +``` + +## Pruning + +Grin에서는 해시되고 MMR에 저장되는 많은 데이터가 결국 제거 될 수 있습니다. 이런 일이 발생하면 해당 MMR안의 일부 리프 해시가 있는지 여부가 불필요하고 리프의 해시를 제거 될 수 있습니다. 충분한 리프가 제거되면 부모의 존재도 불필요하게 될 수 있습니다. 따라서 우리는 그 리프들의 삭제로 인해 MMR의 상당 부분을 pruning 할 수 있습니다. + +MMR의 pruning은 간단한 반복 프로세스에 의존합니다. `X`는 우선 첫번째 제거할 리프로 초기화됩니다. + +1. `X`를 Pruning 한다. +2. 만약 `x`가 형제 노드가 있다면 여기서 prunging을 중단한다. +3. 만약 `X`가 형제 노드가 없다면 `X`의 부모 노드는 `X`라고 배정된다. + +결과를 시각화하기 위해 첫 번째 MMR 예시에서 시작하여 리프[0, 3, 4, 8, 16]을 제거하면 다음과 같은 pruning MMR이 발생합니다. + + +``` +Height + +3 14 + / \ + / \ + / \ + / \ +2 6 13 + / / \ +1 2 9 12 17 + \ / / \ / +0 1 7 10 11 15 18 +``` + +[1] Peter Todd, [merkle-mountain-range](https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md) + +[2] [Wikipedia, Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree) diff --git a/doc/pow/pow.md b/doc/pow/pow.md index 61bf632f82..a470e0e2eb 100644 --- a/doc/pow/pow.md +++ b/doc/pow/pow.md @@ -1,5 +1,7 @@ # Grin's Proof-of-Work +*Read this document in other languages: [Korean](pow_KR.md).* + This document is meant to outline, at a level suitable for someone without prior knowledge, the algorithms and processes currently involved in Grin's Proof-of-Work system. We'll start with a general overview of cycles in a graph and the Cuckoo Cycle algorithm which forms the @@ -31,7 +33,7 @@ and some of the motivations behind it. ### Cycles in a Graph Cuckoo Cycle is an algorithm meant to detect cycles in a bipartite graph of N nodes -and M edges. In plainer terms, a bipartite graph is one in which edges (i.e. lines connecting nodes) +and M edges. In plain terms, a bipartite graph is one in which edges (i.e. lines connecting nodes) travel only between 2 separate groups of nodes. In the case of the Cuckoo hashtable in Cuckoo Cycle, one side of the graph is an array numbered with odd indices (up to the size of the graph), and the other is numbered with even indices. A node is simply a numbered 'space' on either side of the Cuckoo Table, and an Edge is a diff --git a/doc/pow/pow_KR.md b/doc/pow/pow_KR.md new file mode 100644 index 0000000000..7d6f555a2f --- /dev/null +++ b/doc/pow/pow_KR.md @@ -0,0 +1,156 @@ +# Grin의 작업증명 + +이 문서는 사전지식이 없는 사람의 수준에서 Grin의 작업증명 시스템과 관련된 알고리즘 및 프로세스를 대략적으로 설명합니다. Grin의 작업 증명의 기초를 형성하는 Cuckoo Cycle 알고리즘과 그래프의 사이클에 대한 개요로 시작하겠습니다. 그런 다음 Cuckoo Cycle과 결합하여 Grin에서 마이닝 전체 형태를 형성하는 시스템인 Grin특유의 세부 정보에 대해서 설명합니다. + +Grin은 현재 활발하게 개발 중이며,이 중 일부 및 전부는 릴리즈 전에 변경 될 수 있습니다. + +## Graphs 와 Cuckoo Cycle + +Grin의 기본 Proof-of-Work 알고리즘은 Cuckoo Cycle 이라고 합니다 이 알고리즘은 Bitcoin 스타일의 하드웨어 경쟁에 (ASIC을 뜻함 - 역자 주) 내성을 갖도록 특별히 설계되었습니다 . Cuckoo cycle은 이론 상으로 slution time 이 CPU 프로세서 또는 GPU 속도가 아닌 메모리 대역폭에 의해 제한된다는 메모리 바운드( [memory bound function](https://en.wikipedia.org/wiki/Memory_bound_function)) 알고리즘 입니다. 따라서 마이닝 Cuckoo cycle solution은 대부분의 상용 하드웨어에서 실행 가능해야만 하고 다른 대부분의 GPU, CPU 또는 ASIC 바인딩 된 작업 증명 알고리즘보다 훨씬 적은 에너지를 필요로 합니다. + +Cuckoo cyle pow의 최신 문서들과 구현은 John Tromp 의 [깃헙](https://github.com/tromp/cuckoo)에서 볼 수 있으며 이 알고리즘의 pow는 그의 작업 결과물입니다. 이 [링크](https://github.com/tromp/cuckoo/blob/master/doc/cuckoo.pdf)는 Cuckoo cycle 의 백서이고 좀 더 기술적인 디테일에 대해서 최고의 자료입니다. + +John Tromp가 Cuckoo Cycle 에 대해 한참을 이야기하는 [Monero Monitor의 마이크가 진하는 팟 캐스트 (Podcast)](https://moneromonitor.com/episodes/2017-09-26-Episode-014.html)도 있습니다. Cuckoo cycle 에 대한 기술적인 세부사항 이라던지 알고리즘 개발의 역사 또는 그 안에 숨겨진 개발 동기등 관련 배경 지식을 더 많이 원하는 사람들을 위해 청취해보기를 추천합니다. + +### Graph 의 Cycle + +Cuckoo Cycle은 N 개의 노드와 M 개의 가장자리로 구성된 양분 그래프의 사이클을 감지하기 위한 알고리즘입니다. 간단히 말해서, 양분 그래프는 엣지(즉, 노드를 연결하는 선)가 2개의 노드 그룹 사이에서만 이동하는 그래프입니다. Cuckoo Cycle에서 Cuckoo 해시 테이블의 경우, 그래프의 한면은 인덱스(그래프 크기까지)가 홀수개 인 배열이고 다른 배열은 짝수 인덱스로 번호가 매겨집니다. 노드는 단순히 Cuckoo Table의 한쪽에 번호가 매겨진 '공간'이고, Edge는 반대쪽에있는 두 노드를 연결하는 선입니다. 아래의 간단한 그래프는 '짝수'측면 (상단)에 4 개의 노드, 홀수 측면 (하단)에 4 개의 노드 및 엣지 (즉, 모든 노드를 연결하는 선)가 없는 그래프를 나타냅니다. + +![alt text](images/cuckoo_base_numbered_minimal.png) + +*제로 엣지가 있는 8개 노드의 그래프* + +랜덤하게 몇개의 엣지들을 그래프에 던져 보겠습니다. + +![alt text](images/cuckoo_base_numbered_few_edges.png) + +*솔루션이 없는 8개의 노드와 4개의 엣지* + +이제 8개의 노드 (N)와 4개의 에지 (M) 또는 N = 8과 M = 4 인 NxM 그래프가 있는 랜덤하게 생성된 그래프가 있습니다. 기본적인 Proof-of-Work는 이 랜덤한 그래프 내에서 특정 길이의 '주기'를 찾거나 단순히 같은 노드에서 시작하고 끝나는 일련의 연결된 노드를 찾는 것과 관련이 있습니다. 따라서 길이 4 (동일한 노드에서 시작하고 끝나는 4 개의 노드를 연결하는 경로)의 사이클을 찾는다면 이 그래프에서 하나도 찾을 수 없습니다. + +노드 수 N과 연관된 엣지의 수인 M를 조정하면 사이클 찾기 문제의 난이도와 현재 그래프에서 사이클이 존재할 확률이 바뀝니다. 예를 들어, POW 문제가 그래프에서 길이 4의 주기를 찾는 것과 관련된다면, 현재의 4/8 난이도 (M / N)는 모든 4 개의 엣지가 0-5-4-1-0 인 완벽한 사이클에서 무작위로 생성 된 것을 의미하고 그것이 정답임을 의미합니다. + +랜덤으로 몇개의 엣지를 다시 더해보겠습니다. + +![alt text](images/cuckoo_base_numbered_more_edges.png) + +*7개의 엣지가 있는 8개의 노드* + +사이클은 아래와 같이 찾을 수 있습니다. + +![alt text](images/cuckoo_base_numbered_more_edges_cycle.png) + +*0-5-4-1-0 에서 발견 할 수 있는 사이클* + +노드 수에 비례하여 엣지의 수를 늘리면 솔루션이 있을 확률이 높아집니다. 위의 그래프에 몇 개의 가장자리가 추가되면 0-5-4-1-0에서 길이 4의 사이클이 나타나고 그래프에는 솔루션이 있습니다. + +따라서, 비율 M / N을 변경하면 무작위로 생성된 엣지를 갖는 그래프에 대한 사이클의 예상 발생 횟수가 변경됩니다. + +위와 같은 작은 그래프의 경우 특정 길이의 주기가 존재하는지 여부를 판별하는 것은 간단합니다. 그러나 그래프가 커질수록 이러한 주기를 감지하는 것이 더욱 어려워집니다. 예를 들어 이 그래프는 길이가 8 인 사이클, 즉 동일한 노드에서 시작하고 끝나는 8 개의 연결된 노드라고 할 수 있습니까? + +![alt text](images/cuckoo_base_numbered_many_edges.png) + +*실제 사이클을 확인해봅시다* + +대답은 독자에게 연습으로 남겨 두지만 전반적인 원리는 다음과 같습니다. + +* 그래프의 크기에 비례해서 그래프에서 사이클을 감지하는 것이 더 어려워집니다. + +* M/N이 커짐에 따라 그래프에서 주어진 길이의 주기 확률이 증가합니다. 즉, 그래프의 노드 수에 따라서 엣지를 더 추가합니다. + +### Cuckoo Cycle + +Cuckoo Cycle 알고리즘은 정확히 이 문제를 해결하기 위해 고안된 특수 알고리즘입니다. Cuckoo Cylcle 알고리즘은 노드를 두 개의 개별 배열로 가능한 위치에 매핑하는 해시에 따라 'Cuckoo Hashtable' 라고 불리는 구조에 값을 삽입하여 수행합니다. 이 문서는 기본 알고리즘에 대해서는 자세히 설명하지 않으며 [백서](https://github.com/tromp/cuckoo/blob/master/doc/cuckoo.pdf)에서 충분히 설명되어 있습니다. 또한 알고리즘에서 속도/메모리 트레이드 오프를 만드는 몇몇 변형이 있지만 이 문서의 (설명)범위를 역시 넘어갑니다. +하지만 Grin의 작업증명의 기술적 측면을 계속 설명하기 전에 앞서 알아둬야 할 몇 가지 세부 사항이 있습니다. + +* 위의 그래프에서 '랜덤'에지는 실제로 랜덤하지 않지만 시드배정을 받은 해시함수 인 SIPHASH에 엣지 인덱스(0..N)를 넣어서 생성됩니다. 각 엣지 인덱스는 SIPHASH 함수를 두 번 사용해서 두 개의 엣지 엔드포인를 만들어 냅니다. 첫 번째 엣지 엔드포인트는 2* edge_index이고, 두 번째 엣지 엔드포인트는 2* edge_index+1 입니다. 이 함수의 시드는 블록 헤더의 해시를 기반으로 하고 관 아래에서 자세히 설명합니다. + +* 이 알고리즘에 의해 만들어진 '증명'는 길이가 42 인 사이클을 생성하는 nonce 집합이고 다른 피어들이 쉽게 검증 할 수 있습니다. + +* 위에서 설명한 두 가지 주요 매개 변수는 솔루션의 확률에 영향을 주는 Cuckoo Cycle 알고리즘과 솔루션 검색을 위해 그래프를 검색하는 데 걸리는 시간의 일부가 됩니다. + * 위에서 설명한 M/N 비율은 그래프의 크기에 따른 엣지의 숫자를 제어합니다. + Cuckoo Cycle이 M을 N의 절반 값으로 고정시킨다면 사이클의 숫자를 최대한 몇몇개로 제한합니다. + * 그래프의 사이즈. + +이 파라메터들이 실제로 어떻게 상호작용 하는지는 [이 문서](#mining-loop-difficulty-control-and-timing)를 참고하세요. + +Cuckoo Cycle 알고리즘이 무엇을 하려는지, 파라매터가 솔루션을 찾는데 것이 얼마나 영향을 미치는 지에 대해 기본적으로 이해하고 있으므로, Grin의 POW 시스템의 다른 부분으로 넘어갑니다. + +## Mining in Grin + +위에서 설명한 Cuckoo Cycle은 Grin의 마이닝 프로세스의 윤곽을 설명합니다. 그러나 Grin은 Cuckoo Cycle을 여러 다른 시스템과 함께 사용하여 Proof-of-Work를 만듭니다. + +### 추가적인 난이도 조정에 대해서 + +계속 늘어나는 해시파워의 가용성를 가진 네트워크의 필요성 때문에 추가적인 난이도에 대한 제어권을 제공하기 위해 Hashcash 기반 난이도 확인은 다음과 같이 잠재적인 솔루션 세트에 적용됩니다. + +솔루션 논스의 잠재적인 집합인 Blake2b 해시가 (현재는 42 u32의 배열이 사이클 논스를 나타냅니다.) 계속 늘어나는 난이도인 타겟 T보다 작다면, 그 솔루션은 유효하다고 간주됩니다. +좀더 정확하게는, 증명 난이도는 현재 해시로 나눈 최대 목표 해시 (2 ^ 256)로 계산되고 정수(integer)로 얻기 위해 반올림됩니다. +이 정수가 증가하는 네트워크 난이도보다 큰 경우, POW는 유효한 것으로 간주되며 블록이 유효성 검사를 위해 체인에 제출됩니다. + +즉, 잠재적 증거는 유효한 Cuckoo 사이클을 포함 할뿐만 아니라 또한 목표 난이도보다 높은 값으로 해시해야합니다. 이 난이도는 다음과 같이 유도됩니다. + +### 증가하는 네트워크 난이도 + +난이도는 평균 블록 생성 시간을 특정 범위 내로 유지하기 위한(현재는 60 초이지만 변경 될 수 있음)목표로 사용 가능한 네트워크 해시파워에 따라 증가시킬 예정입니다. + +난이도 계산은 Digishield 및 GravityWave 계열의 난이도 계산을 기반으로 ZCash와 매우 비슷합니다. 참조 난이도는 현재 합의 값인 23 개 블록 난이도의 평균입니다. +해당 시간 간격은 23개 블록의 시작과 끝의 중간 타임 스탬프 간의 차이를 사용하여 계산됩니다. 시간 범위가 특정 범위보다 높거나 낮으면 (표준 편차를 허용하는 dampening 팩터로 조정) 블록 생성시간을 목표로 하는 값으로 난이도를 높이거나 낮 춥니 다. + +### 마이닝 루프(Loop) + +이러한 시스템은 유요한 작업증명이 체인에 최신 증명을 생성하려 하는 마이닝 루프에 모두 통합됩니다. +다음은 메인 마이닝 루프가 단일 반복 중에 수행하는 작업에 대한 개요를 설명합니다. + +* 최신 체인 상태를 얻고 그 위해 블록을 만드는 것은 다음을 포함합니다. + * 새값을 가진 블록헤더는 : + * [이전 섹션](#증가하는-네트워크-난이도) 에서 설명했던 알고리즘으로 선택된 최신 타겟 난이도 + * 트랜잭션 풀에서 입증된 트랜잭션의 세트 + * 코인베이스 트랜잭션 + * 현재 타임 스탬프 + * 헤더의 해시에 랜덤하게 생성된 논스를 더해서 추가적으로 랜덤성을 추가 + * (아직 구현되지 않은) UTXO세트와 fee의 머클루트 + * 그런 다음 Sub-loop는 현재 2초로 설정된 시간동안 작동하며 다음과 같은 상황이 일어납니다. + * 새로운 블록 헤더를 해시해서 새로운 해시 값을 만듭니다. + * 다음과 같은 값을 파라메터로 받아들인 Cuckoo 그래프 제너레이터가 초기화 됩니다. + * 그래프에서 0..n 인 논스세트의 각 요소 위치 쌍을 만들어내는 SIPHASH 함수의 키로 사용 되는 잠재적인 블록 헤더의 해시 + * 그래프의 사이즈 ( 합의 값) + * 합의 값인 Easiness 값은 M/N비율을 나타내며 이 값은 위에서 나타낸것 처럼 그래프에 나타나는 솔루션의 확률입니다. + * Cuckoo 사이클 탐지 알고리즘은 생성된 그래프 내에서 솔루션을 찾으려고 합니다. + * 만약 사이클을 찾았다면 증거 Blake2b 해시가 생성되고 현재 타겟의 난이도와 비교됩니다. 이와 관련해서는 위에 [추가적인 난이도 조정에 대해서](#추가적인-난이도-조정에-대해서)에 설명되어 있습니다. + * 만약 Blake2b 해시의 난이도가 타겟난이도보다 크거나 같다면 블록은 트랜잭션 풀에 보내지고 유효성을 검사하기 위해 피어들에게 전파됩니다. 그리고 다음 블록을 마이닝을 시작합니다. + * 만약 Blake2b 해시의 난이도가 타겟의 난이도 보다 낮다면, 증명된 것 (Blake2b 해시)는 버리고 다시 Sub-loop인 타임 루프가 계속됩니다. + * 만약 솔루션을 찾지 못했다면 헤더에 있는 논스값을 1 증가시킵니다. 그리고 헤더의 타임스탬프를 업데이트 합니다. 그래서 다음 루프의 그래프 생성 과정의 기초가 되는 이터레이션 해시가 다른 값이 됩니다. + * 솔루션을 찾지 못한채 루프의 타임아웃이 되었다면 제일 위해서부터 다시 시작하고 새로운 트랜잭션을 모으고 새로운 블록을 다 같이 만듭니다. + +### 마이닝 루프 난이도 조정과 타이밍 + +마이닝 루프의 난이도를 조정하기 위해서는 위해서 언급한 세 값의 밸런스를 찾아야 합니다. + +* 그래프 크기 (현재 2 ^ n 노드의 크기를 나타내는 비트 시프트 값 n으로 표현, 합의 값은 DEFAULT_SIZESHIFT임). + 더 작은 그래프는 철저히 더 빨리 검색 될 수 있지만 주어진 Easiness value 에 대해 더 적은 솔루션를 가집니다. 아주 작은 그래프는 더 낮은 Easiness value을 가진 더 큰 그래프와 (비교를 할때) 해답을 찾는 동일한 기회를 가지기 위해 더 높은 Easiness value가 필요합니다. +* 'Easiness'합의 값,또는 퍼센티지로 나타나는 그래프의 M / N 비율. + 이 값이 높을수록 생성 된 그래프에 솔루션이 포함될 확률이 높아집니다. 위와 함께 그래프가 커질수록 주어진 Easiness value 에 대해 더 많은 솔루션이 포함될 가능성이 높아집니다. Cuckoo Cycle 구현은 이 M을 N / 2로 고정시켜 비율을 50%로 만듭니다. +* 증가한 네트워크 난이도 해시값. + +마이닝 알고리즘이 Cuckoo 그래프 크기와 증가하는 난이도 사이에서 올바른 균형을 찾을 수 있도록 위의 값들은 신중하게 조정해야 합니다. POW는 대부분 Cuckoo Cycle 기반을 유지할 필요가 있지만 새로운 트랜잭션을 빨리 처리 할 수 ​​있도록 합리적인 수준에서 블록 생성시간을 짧게 해야 합니다. + +예를 들어, 그래프 크기가 ​​너무 작고 easiness (value)가 높다면 주어진 블록에 대해 많은 Cuckoo 사이클 솔루션을 쉽게 찾을 수 있으며 POW는 Cuckoo Cycle이 피하고자 하는 현상 즉, 더 빨리 해싱 할 수 있는 사람들이 선호할 것입니다. +그러나 만약에 그래프가 너무 크고 easiness (vaule)가 너무 낮으면 단일 그래프에서 솔루션을 찾는 데 시간이 오래 걸릴 수 있고 새로운 트랜잭션을 수집하는것을 중단 할 수도 있습니다. + +현재 이 값은 그래프 사이즈로 2^12으로 세팅되어 있고 Cuckoo Cycle로 고정된 easiness value는 50% 로 설정되어 있지만 (이러한) 사이즈 값은 테스트를 위한 임시 설정 값입니다. 현재의 마이너 구현체는 최적화되지 않았으며, 그래프 사이즈는 보다 빠르고 최적화 된 Cuckoo Cycle 알고리즘으로 변경 될 필요가 있습니다. + +### Pooling Capability + +Cuckoo Cycle의 poolability에 대한 현재의 우려와는 달리 위에서 설명한 Grin의 POW 구현은 마이닝 풀에 아주 적합합니다. +별개의 단일 그래프를 풀기 위한 노력을 증명하는 것은 어려운 반면에, Grin의 작업증명 내에서 조합 된 요소들이 결합하여 모든 마이너들의 공정성뿐만 아니라 'poolability'을 가능하게 만드는 'progress-freeness' 라는 개념을 강제합니다. + +#### Progress Freeness + +Progress-freeness 는 직업 증명의 'poolability'의 핵심이며 POW 문제에 대한 해결책이 합리적인 시간 내에 발견 될 수 있다는 단순한 생각에 기반합니다. +예를 들어, 블록체인에서 1분의 POW시간이 있고 (당연히) 마이너가 솔루션을 찾기 위해 평균 1 분을 써야합니다. 이는 POW의 요건을 충족하지만 규모가 큰 마이너에게 이점을 제공합니다. +이러한 환경에서 소규모 광부는 적어도 1분을 매번 잃어 버리는 반면 큰 광부는 해결책을 찾으면 (바로 다음루프로) 이동할 수 있습니다. +따라서 광업을 상대적으로 progress-free 시키기 위해서는 각 시도마다 상대적으로 적은 시간이 걸리며 다수의 솔루션을 찾는 시도가 있는 POW가 바람직합니다. + +Grin의 Progress - freeness는 Grin의 기본 파라매터가있는 Cuckoo의 솔루션이 일반적으로 대부분의 GPU에서 1초 이내에 발견 될 수 있고 Blake2b 난이도 체크의 추가 요구사항이 그 위에 있다는 사실에 기인합니다 . +따라서 Pool의 멤버는 현재의 네트워크 타겟 난이도에 속하는 유효한 Cuckoo 솔루션 (또는 Cuckoo 솔루션의 작은 묶음)을 제출하여 블록의 솔루션에 대해서 작업하고 있음을 증명할 수 있습니다.