# Coinbase 만기 규칙 (A.K.A 출력 )
Coinbase 산출물 (블록 보상 및 수수료)은 "잠겨"있고 쓰는 것이 가능하기 전에 1,440개의 충분한 확인 (즉, 체인에 추가 된 이후 24 시간정도의 확인, *블록이 추가된 후 24시간 정도의 확인이 필요하다는 뜻 - 역자 주*)이 필요합니다. 이것은 체인 재구성(chain reorganization)이 발생할 경우 나중에 txs가 되돌려질 위험을 줄이기위한 것입니다.
Bitcoin도 비슷한 과정을 거칩니다. Bitcoin은 마이닝 보상을 쓰기 전에 100 회의 확인 (Bitcoin 블록은 매 10 분, Grin 블록은 매 60초)을 수행합니다.
Grin은 트랜잭션 풀과 블록입증(block validation) 파이프라인(Pipeline) 둘다 코인베이스 만기 규칙을 강제합니다. 코인베이스 출력을 사용하는 입력을 포함하는 트랜잭션은 현재 체인 높이와 코인베이스 출력을 생성하는 블록의 높이를 기준으로 충분히 만기가 될 때까지 트랜잭션 풀에 추가 될 수 없습니다. 블록에서도 (트랜잭션 과)비슷하게 입력을 포함하는 블록의 높이와 원래 코인베이스 출력을 생성 한 블록의 높이를 기준으로 충분히 만기가 되기 전에 코인베이스 출력을 소비하는 입력을 포함하면 유효하지 않습니다.
*만기 규칙( Maturity rule)은 코인베이스 출력에만* 적용 됩니다. 일반적인 트랜잭션 출력은 유효한 lock height가 0입니다(Zero confirm 이라는 뜻- 역자 주).
출력값은 아래와 같은 값으로 이뤄집니다.
* 기능 (현재의 코인베이스 VS non-코인베이스)
* `rG+vH` 실행값(commitment)
* rangeproof
기존 트랜잭션 출력을 사용하려면 두 가지 조건이 충족되어야 합니다. 출력이 이전에 쓰지 않았다는것 을 보여주어야하며 출력의 소유권(ownership of output)을 증명해야합니다.
Grin 트랜잭션은 다음과 같이 구성되어 있습니다.
* 입력값의 셋, 각 입력값은 이전 소비된 출력값에 대해서 참조합니다.
* 새로운 출력값들의 셋은 다음과 같은 요소를 포함합니다.
* `v`값과 비밀키이자 Bliding factor인 `r`과 타원곡선 값이 곱해지고 더해진 값인 `rG+vH`(commitment 값이기도 함)
* `v`값이 음수가 아님(non-negative)을 보여줄 range proof
* 명백한 트래잭션 수수료
* 모든 출력값에 수수료를 더하고 입력값을 뺀 초과 Blinding factor 로 계산하고 비밀키로 사용된 서명 값
현재 출력 셋에서 실행값(`rG+vH`, commitment값 - 역자 주)을 찾음으로써 출력이 미사용 상태임을 나타낼 수 있습니다. 만약 출력이 출력셋에 존재하는 경우 아직 사용되지 않았다는 것을 알 수 있기 때문에 출력셋은 신뢰할 수 있습니다. 출력이 출력 셋에 존재하지 않는다면 출력값이 존재하지 않았거나 이전에는 있었고 소비되었음을 알 수 있습니다 (필연적으로 출력셋이 존재하지 않았던 것이든 이전에 있었던 것이든 어떤 것이든 알지 못할 것입니다).
소유권을 증명하기 위해 트랜잭션 서명을 입증할 수 있습니다. 트랜잭션의 합이 0이 되고 *그리고* `v`와 `r`을 모두 알고있는 경우에만 *오직* 트랜잭션에 서명 할 수 있습니다.
`v`와 `r`을 알면 우리는 출력을 실행값(commitment)을 통해 구분 할 수 있습니다. *그리고* 원래 코인베이스 트랜잭션에서 서명의 유효성을 검사하여 출력의 소유권을 증명할 수 있습니다.
Grin은 동시에 출력 셋에 중복된 실행값(commitment)이 존재하는 것을 허용하지 않습니다. 그러나 일단 출력이 소비되면 출력 셋에서 제거되고 중복된 실행값(commitment)이 출력 셋에 다시 추가 될 수 있습니다.
이것은 반드시 권장하지 않지만 Grin은 네트워크를 통해 합의를 깨지 않는 방식으로 이런 상황을 처리해야합니다.
아래와 같은 몇 가지가 이런 상황을 복잡하게 만듭니다.
1. 특히 빈 블록의 경우 두 블록이 동일한 보상을 받을 수 있습니다. 뿐만 아니라 거래 수수료가 있는 비어 있지 않은 블록의 경우에도 가능합니다.
1. 코인베이스 출력이 아닌 출력값이 코인베이스 출력과 동일한 값을 가질 수 있습니다.
1. 권장되진 않지만 마이너가 비밀키(private key)를 재사용 할 수 있습니다.
Grin은 동시에 출력 셋에 중복된 실행값(commitment)이 존재하는 것을 허용하지 않습니다. 그러나 출력 셋은 특정 체인 분리(fork)의 상태에 따라 다릅니다.
같은 순간에 있는 서로 다른 체인에 중복 된 *동일한* 실행값(commitment)가 동시에 *존재할 수 있습니다*. 그리고 이러한 중복된 실행값은 다른 "lock height"를 가질 수 있습니다. 그리고 각각 다른 체인에서 이런 실행값들은 코인베이스 만기가 다 되어서 소비 할 수 있수도 있습니다.
* block B1에서 온 출력값 O1 소비 가능한 높이는 h1 (체인 f1)
* block B2에서 온 출력값 O1' 소비 가능한 높이 h2 (체인 f2)
여기서 복잡한 점은 입력 I1을 포함하는 블록이 있는 포크에 따라 O1 또는 O1'을 사용한다는 것입니다. 그리고 결정적으로 I1은 어떤 체인에서는 특정 블록 높이에서 유효하지만 다른 포크에서는 유효하지 않을 수 있다는 것입니다.
다른 말로 하자면, 실행값은 여러 개의 출력을 의미 할 수 있으며, 모든 출력은 서로 다른 lock height를 가질 수 있습니다.
그리고 우리는 어떤 결과가 실제로 소비되고 있는지, 코인베이스 만기 규칙이 현재의 체인 상태(chain state)를 기반으로 정확하게 시행되고 있는지 정확하게 *반드시 확인해야 합니다.*
특정 lock height에서 coinbase 만기 규칙으로 잠긴 코인베이스 출력은 고유하게 확인될 수 *없습니다*. 그리고 자신의 실행값 만으로는 안전하게 사용할 수 *없습니다.*
코인베이스 출력을 사용하려면 아래와 같이 추가적인 요소 하나를 알아야 합니다.
* 코인베이스 출력값이 어디서 나왔는지 기록되어 있는 블록(The block the coinbase output originated from 라고 원문에 표기되어 있음 -역자 주)
이 경우 블록의 높이를 검증하고 출력물의 "lock height"(+ 1000 블록)를 알아 낼 수 있습니다.
## 풀 아카이브 노드
풀 아카이브 노드가 있으면 출력이 어느 블록에서 시작되었는지 식별하는 것은 간단한 작업입니다. 전체 아카이브 노드는 다음을 저장합니다.
* 체인 내에 있는 전체 블록의 모든 블록 데이터
* 해당 블록들 안에 있는 전체 출력값의 모든 출력값 데이터
체인의 이전의 모든 블록을 볼 수 있으며 특정 출력이 들어있는 블록을 찾을 수 있습니다.
문제는 전체 블록 데이터가 없는 노드(Pruning 노드, 아카이브 노드가 아닌 노드)를 고려해야 할 때입니다.
전체 블록 데이터가 없더라도 코인베이스 만기에 대해서 어떻게 입증 할 수 있을까요??
## 비 - 아카이브 노드(non - achive node)
A node may not have full block data.
A pruned node may only store the following (refer to pruning doc) -
노드에는 전체 블록 데이터가 없을 수 있습니다. pruning 노드는 다음을 저장할 수 있습니다 ([프루닝 문서 참조](pruning_KR.md)).
* 블록 헤더 체인
* All transaction kernels.
* 전체 트랜잭션 커널(kernels)
* 전체 미사용된 출력값(unspent outputs)
* 출력값의 MMR 과 range proof MMR
이 최소한의 데이터 셋을 가지고 어느 블록에서 시작되었는지 어떻게 알 수 있습니까?
주어진 데이터로 여러 출력(여러 포크, 잠재적으로 서로 다른 lock height)이 모두 *같은* 실행값을가질 수 있는지, 사용한 출력을 고유하게 식별하기 위해 입력값에 어떤 추가 정보가 필요한가요?
그리고 한 단계 더 나아가기 간다면 전체 출력 데이터에 액세스하지 않고도 이 모든 작업을 수행 할 수 있을까요? 출력 MMR만 사용할 수 있나요?
### 제안된 해결법
출력 MMR 내에서 위치의 인덱스 매핑 실행값을 유지합니다.
인덱스에 항목이 없거나 주어진 실행값에 대해 출력 MMR내에서 항목이 존재하지 않으면 출력값은 사용할 수 없습니다. (이전에 소비되었거나 아예 존재하지 않았음).
출력 MMR에서 항목을 찾으면 쓸 수 있는 출력이 출력셋에 있음을 알 수 있습니다. *하지만* 이것이 올바른지 여부는 알 수 없습니다. 코인베이스 출력인지 아닌지와 그 블록이 시작된 블록의 높이를 알지 못합니다.
출력 MMR에 저장된 해시가 실행값(commitment)및 출력 기능을 모두 포함하고 실행값과 기능을 모두 제공하기 위해 입력이 필요한 경우 아래와 같은 추가 검증 단계를 수행 할 수 있습니다.
* 실행값 베이스의 출력값 MMR 내에 출력값이 있고
* MMR의 해시는 입력에 포함 된 출력 데이터와 일치합니다.
이 추가 단계를 통해 출력이 코인베이스 출력인지 또는 제공된 기능을 기반으로 하는 일반적인 트랜잭션 출력인지 여부를 알 수 있습니다. 입력값이 원래 출력값과 일치하지 않으면 해시가 일치하지 않습니다.
일반적인 non-coinbase 출력에 대해서 설명은 이미 끝냈습니다. 출력값은 현재 쓸 수 있으므로 lock height를 확인할 필요가 없습니다.
코인베이스 출력의 경우 lock height와 블록 만기를 검증 할 수 있습니다. 이를 위해 출력이 발생한 블록을 식별해야합니다.
블록 자체를 결정할 수는 없지만 블록 해시을 특정하기 위해서 입력을 필요 할 수 있습니다. 그런 다음 전체 블록 데이터 없이 블록 헤더의 머클 루트를 기반으로 증명할 수 있습니다.
[추후에 결정될 것 - 머클 proofs의 개요와 블록헤더 안의 머클 루트 (merkle root)기반으로 어떻게 머클 proofs 를 사용하여 포함된 것을 증명 할 것인가 ]
요약하자면 -
실행값(commitment) 자체만으로는 충분하지 않기 때문에 출력 MMR은 `commitment | features`을 기반으로 출력 해시를 저장합니다 .
출력 해시 생성시 range proof를 포함 할 필요가 없습니다.
출력값을 소비하기 위해 아래와 같은 것이 필요합니다. -
* `r`과 `v`는 실행값(commitment)을 만들고(build) 소유권을 증명합니다.
입력값은 아래와 같은 값을 반드시 포함해야 합니다.
* MMR 내에서 찾은 실행값 ( commitment)
* 출력값 (features|commitment 에 따른 출력값 MMR 의 해시)
* 원래 불록 내에서의 Merkle proof 를 포함하는 출력값
* 원래 블록의 블록 해시
* [추후에 결정될 것 - Merkle proof 기반 인덱스를 유지할 것인가?]
실행값(commitment)과 기능을 통해 올바른 출력이 현재 사용되지 않은지 확인할 수 있습니다.
블록과 출력값로부터 lock height(있는 경우)를 결정할 수 있습니다.