테조스 백서(한글) - Tezos — a self-amending crypto-ledger White paper

in #token-lab7 years ago

테조스 백서(한글)

Tezos — a self-amending crypto-ledger White paper
자가 수정형 암호화 원장 백서

L.M. Goodman
2014년 9월2일

번역 @areyoucrazy
기획 @krexchange

“Our argument is not flatly circular, but something like it.”
윌리엄 반 오르먼 퀸

요약

우리는 테조스, 일반적이고 자가 수정을 진행하는 암호화 원장을 대표합니다. 테조스는 어떠한 블록체인 기반 원장이든 대표하는 것이 가능합니다. 정상적인 블록체인 상에서의 작업은 네트워크를 담당하는 shell로 추상화된 순전히 기능적인 모듈로 구현되게 됩니다. 비트코인, 이더리움, 크립토 노트 등은 모두 네트워크 레이어에 대한 적절한 인터페이스를 구현함으로써 Tezos 내에서 표현을 하는 것이 가능합니다. 가장 중요하게, 테조스는 메타 업그레이드를 지원함으로써, 프로토콜은 자신들의 코드를 수정함으로써 진화하게 됩니다. 이를 위해 테조스는 씨드 프로토콜을 시작하여서 스테이크 홀더들이 수정안들에 대해 승인하는 과정을 거치게 되며, 이는 투표 과정 또한 포함하게 됩니다. 이것은 철학자인 피터 서버의 Nomic이라는 게임과는 다르지 않습니다. (완전히 내성적인 규칙 세트를 중심으로 구축된 게임입니다.) 또한, 테조스의 씨드 프로토콜은 순수한 POS 시스템을 기반으로 해서 완벽한 스마트 컨트랙트를 지원하게 됩니다. 테조스는 Ocaml 상에서 구현되어 있습니다. Ocaml은 강력한 함수프로그래밍 언어로써, 속도, 명확한 구문과 의미, 그리고 생태계 생성 기능을 제공합니다. 테조스는 정식증명에 대한 좋은 후보자 입니다. 비트코인 프로토콜과 유사한 점과 암호화 화폐의 기본적인 원리는 이 논문의 나머지 부분에서 다루고 있습니다.

목차

  1. 도입부
  2. 자가 수정형 암호화 원장
    2.1. 수학적인 표현
    2.2. 네트워크 쉘
    2.2.1. 시계
    2.2.2. 체인 선정 알고리즘
    2.2.3. 네트워크 레벨의 방어
    2.3. 기능적인 표현
    2.3.1. 체인의 유효성 검사
    2.3.2. 프로토콜 개정
    2.3.3. RPC
  3. 씨드 프로토콜
    3.1. 경제학
    3.1.1. 코인들
    3.1.2. 채굴과 서명 보상
    3.1.3. 잃어버린 코인들
    3.1.4. 수정 규칙
    3.2. POS 메커니즘
    3.2.1. 전반적인 오버뷰
    3.2.2. 시계
    3.2.3. 랜덤 시드 생성
    3.2.4. 코인을 따라가는 절차
    3.2.5. 블록 채굴
    3.2.6. 서명 블록
    3.2.7. 체인의 무게
    3.2.8. 폐기
    3.3. 스마트 컨트랙트
    3.3.1. 컨트랙트 종류
    3.3.2. 생성
    3.3.3. 트랜잭션들
    3.3.4. 저장비
    3.3.5. 코드
    3.3.6. 사용료
  4. 결론

1. 도입부

이 논문의 첫번째 부분에서는 추상적인 블록체인들의 컨셉과 자가 수정형 암호화 원장의 구현에 대해 다룰 것이며, 두번째 부분에서는 우리들의 제안된 씨드 프로토콜에 대해서 설명할 예정입니다.

2. 자가 수정형 암호화 원장

블록체인 프로토콜은 3가지 종류의 특정적인 부분으로 분해 될 수 있습니다.

  • 블록을 발견하고 트랜잭션을 중계하는 네트워크 프로토콜
  • 트랜잭션을 유효하게 만드는 것을 지정하는 트랜잭션 프로토콜
  • 특정한 체인에서 컨센서스를 형성하는 컨센서스 프로토콜

테조스는 일반적인 네트워크 쉘을 구현합니다. 이 쉘은 트랜잭션 프로토콜 및 합의 프로토콜에 적용됩니다. 우리는 합의 프로토콜과 트랜잭션 프로토콜을 함께 블록체인 프로토콜이라고 부르게 됩니다. 우리는 우선 블록체인 프로토콜을 수학적으로 표현한 다음에 테조스의 여러한 부분들을 구현해냅니다.

2.1. 수학적인 표현

블록체인 프로토콜은 근본적으로 글로벌 상태의 병행 돌연변이의 모나드 구현입니다. 이것은 “블록”을 글로벌한 상태에서 활동하는 연산자로 정의하면서 이루어지게 됩니다. 제네시스 상태에서 작용하는 블록의 자유로운 단조는 나무 구조를 형성합니다. 전역, 표준 상태는 지정된 순서에 대한 최소 잎사귀로 정의됩니다.
이것은 다음과 같은 추상적인 표현을 제안하게 됩니다:

  • (S, ≤)를 가능한 순서대로 나열하고, 셀 수 있는 상태 집합이라 하자.
  • ⊘ ∈ / S는 특수한 무효 상태를 나타낸다.
  • B⊂SSU{⊘}가 블록의 집합이다. 유효한 블록들은 B ∩ SS일 것이다.

S에 대한 전체 순서는 ∀s ∈ S, ⊘ <s가되도록 확장됩니다. 이 순서는 블록 트리에서 어떤 잎사귀(리프)가 표준 잎사귀로 간주되는지 결정합니다. B의 블록은 활동하는 운영자의 상태로 간주됩니다.
모든 블록체인 프로토콜(비트코인. 이더리움, 피어코인등)은 튜플에 의해 완전히 결정될 수 있습니다.

(S, ≤, ⊘, B ⊂ SS∪{⊘})

네트워킹 프로토콜은 기본적으로 이러한 블록체인들과 동일합니다. 하지만, 블록생성으로 인해 인센티브를 받는 채굴 알고리즘은 매우 중요한 부분으로 작용하게 됩니다.
테조스는 이러한 블록들이 스스로 프로토콜 속에서 움직이게 함으로써, 블록체인 프로토콜을 조금 더 내성적으로 만들었습니다. 그러면 우리는 다음과 같이 재귀적으로 일련의 프로토콜을 표현하는 것이 가능해집니다.

P ={(S, ≤, ⊘, B ⊂ S(S×P)∪{⊘})}

2.2. 네트워크 쉘

이 수학적인 설명은 어떻게 블록 트리를 만들 수 있는지 우리에게 설명해주지 않습니다. 이것은 gossip네트워크와 프로토콜 사이의 인터페이스 역할을 하는 네트워크 쉘의 역할입니다.
네트워크 쉘은 최선의 체인이라고 여겨진 클라이언트를 유지시킴으로써 작동됩니다. 이것은 3가지 종류의 객체를 인식합니다. 첫번째와 두번째는 트랜잭션과 블록들로, 유효한 것으로 간주될 경우에만 네트워크를 통해 전송됩니다. 세번째는 프로토콜로, ocaml 모듈은 기존의 프로토콜을 수정하는데 사용되게 됩니다. 이 부분에 대해선 이후에 설명할 예정이며, 지금은 트랜잭션과 블록 부분에 대해서 집중할 예정입니다.
네트워크 쉘에서 가장 중요하자 힘든 부분은 DOS 공격으로부터 노드를 보호하는 것입니다.

2.2.1. 시계(clock)

모든 블록은 네트워크 쉘에 보이는 타임 스탬프를 들고 있습니다. 미래의 블록은 타임스탬프가 시스템 시간의 몇 분 내에 있으면 버퍼링되고 그렇지 않은 경우 거부됩니다. 프로토콜 설계는 클라이언트에서 합리적인 clock 드리프트를 허용해야 하며 타임 스탬프가 위조될 수 있다고 가정해야 합니다.

2.2.2. 체인 선정 알고리즘

쉘은 전체 블록 트리가 아닌 단일 체인을 유지합니다. 이 체인은 클라이언트가 훨씬 더 나은 체인을 인식할 때에만 덮어 쓰게 됩니다.
트리를 유지 관리하는 것은 네트워크 통신 측면에서는 다소 간소화됩니다. 하지만, 공격자들이 낮은 스코어를 가지면서 하는 유효한 포크를 생산하는DOS 공격에는 취약하게 됩니다.
그러나 한 노드가 주어진 체인에 대해서 거짓말을 하는 것은 가능합니다. 이 거짓말은 클라이언트가 많은 수의 블록을 처리해야만 발견하는 것이 가능합니다. 그러나 그런 노드들은 이후에 무시될 수 있습니다.
다행히도, 낮은 점수를 받게 되는 프로토콜은 블록의 생성 시간이 매우 더뎌 집니다. 따라서 클라이언트는 발표된 점수가 거짓말이라고 결론 짓기전에 몇 블록의 “약한” 포크들만 고려해도 되게 됩니다.

2.2.3. 네트워크 레벨의 방어

추가적으로 쉘은 “방어적”입니다. 이것은 다양한 IP 범위에서 많은 피어에 연결을 시도합니다. 또한, 연결이 끊긴 피어를 탐지하고 악성 노드를 차단합니다.
특정 서비스 거부 공격으로부터 보호하기 위해서 이 프로토콜은 쉘에 블록 및 트랜잭션 크기에 대한 종속 범위를 제공하게 됩니다.

2.3. 기능적인 표현

2.3.1. 체인의 유효성 검사

다음과 같은 Ocaml의 유형을 사용해서 추상적인 블록체인 구조의 거의 모든 일반적인 부분들을 효율적으로 캡쳐 할 수 있었습니다. 우선, 블록의 헤더는 다음과 같이 정의합니다.

type raw_block_header = { 
   pred: Block_hash.t; 
   header: Bytes.t; 
   operations: Operation_hash.t list;
   timestamp: float; 
}

우리는 의도적으로 헤더필드를 강력하게 입력하지 않으므로 임의의 내용을 나타냅니다. 그러나 우리는 쉘 조작에 필요한 필드를 입력합니다. 여기에는 이전 블록의 해시, 작업 해시 목록 및 타임 스탬프가 포함됩니다. 실제로 블록에 포함된 작업은 네트워크 수준에서 블록과 함께 전송됩니다. 연산 자체는 여기서 임의의 얼룩으로(arbitrary blobs) 표현이 되게 됩니다.

type raw_operation = Bytes.t

이 상태는 디스크 기반의 불변의 key-value 값 저장소를 캡슐화하는 Context 모듈의 도움으로 표현이 됩니다. Key-value 저장소의 구조는 다목적이며 다양한 상태를 효율적으로 나타낼 수 있습니다.

module Context = sig 
   type t 
   type key = string list 

   val get: t -> key -> Bytes.t option Lwt.t 
   val set: t -> key -> Bytes.t -> t Lwt.t 
   val del: t -> key -> t Lwt.t 
   (*...*) 
End

디스크 작업에서 블로킹을 막기 위해서 함수의 경우 비동기 모나드를 사용하게 됩니다. Context에서 연산은 순전히 기능적입니다:

get은 옵션 모나드를 사용하고 set과 del은 새로운 Contect를 반환합니다. Context 모듈은 메모리 캐싱 및 디스크 스토리지를 사용하여서 불변 저장소(immutable store)의 모양을 효율적으로 제공합니다.

이제 임의의 블록 체인 프로토콜의 모듈 유형을 정의할 수 있습니다:

type score = Bytes.t list
module type PROTOCOL = sig
   type operation
   val parse_block_header : raw_block_header -> block_header option
   val parse_operation : Bytes.t -> operation option

   val apply :
      Context.t ->
      block_header option ->
      (Operation_hash.t * operation) list ->
      Context.t option Lwt.t

   val score : Context.t -> score Lwt.t
   (*...*)
end

우리는 더 이상 수학적 모델 에서처럼 상태를 직접 비교하지 않습니다. 우리는 스코어 함수를 사용하여 Context를 바이트 목록에 투영합니다. 바이트 리스트는 길이에 의해 순서가 정해지며, 그 다음에 어순 순서에 의해 정렬이 되게 됩니다. 이는 소프트웨어 버전 관리에 사용되는 것과 비슷한 상당히 일반적인 구조로 다양한 순서를 나타낼 때에는 매우 유용합니다.

왜 프로토콜 모듈 내에서 비교 기능을 정의하지 않을까요?

첫번째로는 그러한 기능이 총 주문을 나타내는 요구 사항을 시행하는 것은 어렵기 때문입니다. 점수 투영은 이를 항상 확인하게 됩니다(마지막 블록의 해시를 기반으로 연결 고리가 끊어질 수도 있습니다).

둘째로는, 원칙적으로 우리는 별개의 프로토콜을 통해서 상태를 비교할 수 있는 능력이 필요합니다. 특정 프로토콜 수정 규칙은 이 일이 거의 일어나지 않을 것으로 보지만, 네트워크 쉘은 이것을 알지 못합니다.

Parse_block_header및 parse_operation 작업은 쉘에 노출되어 완전히 형식화된 작업 및 블록을 프로토콜로 전달할 수 있게 하지만, 작업을 릴레이하거나 로컬 블록트리 데이터베이스에 블록을 추가하기 전에 이러한 작업 및 블록의 형식이 올바른지 확인해야 합니다.
Apply 함수는 프로토컬의 핵심으로 작용합니다:

  • 블록 헤더와 관련 연산 목록이 전달되면, 컨텍스트에 대한 변경 사항을 계산하고 수정된 복사본을 반환합니다. 내부적으로 차이점은 버전 관리 시스템에서 저장되어서, 블록의 해시를 버전핸들로 사용한다는 것입니다.
  • 작업 목록이 전달되게 된다면, 이것은 가능한 많은 작업을 적용시키려고 합니다. 이 기능은 프로토콜 자체에게는 효율적이지 않지만, 유효 블록을 생성하려 하는 채굴자들에겐 유용합니다.

2.3.2. 프로토콜 개정

테조스의 가장 강력한 특징은 자체 수정이 가능한 프로토콜을 구현할 수 있다는 것입니다. 이것은 두개의 절차 기능을 프로토콜에 노출시킴으로써 이루어집니다.

  • set_test_protocol은 테스트넷에서 사용된 프로토콜을 새로운 프로토콜(일반적으로 스테이크 홀더 투표자들에 의해서 채택된 프로토콜)로 대체합니다.
  • promote _test_protocol은 현재 프토토콜을 시험중인 프로토콜로 교체해줍니다.
    이러한 함수는 관련 프로토콜을 변경하여 컨텍스트를 변환합니다. 새로운 프로토콜은 다음 블록이 체인에 적용될 때 적용됩니다.
module Context = sig 
   type t 
   (*...*)
   val set_test_protocol: t -> Protocol_hash.t 
   Lwt.t val promote_test_protocol: t -> Protocol_hash.t -> t Lwt.t 
End

Protocol_hash는 .ml와 .mli의 타르볼을 sha256으로 해싱한 값입니다. 이 파일들은 즉시 컴파일링 됩니다. 그들은 작은 표준 라이브러리에 액세스할 수 있지만 샌드 박싱되어 있으며, 시스템 호출을 할 수 도 없습니다.

이 함수들은 프로토콜의 적용 함수를 통해서 호출되며, 새 Context를 반환하게 됩니다.
많은 조건이 프로토콜 변경을 유발할 수 있습니다. 가장 간단한 방식으로는 스테이크 홀더들의 투표로 인해서 프로토콜이 변경이 되게 됩니다. 보다 복잡한 규칙들을 점진적으로 투표하는 것도 가능합니다. 예를 들어서 스테이크 홀더들이 원한다면 앞으로 하는 개정안들에 대해서 특정 자산을 존중한다는 컴퓨터로 확인 가능한 증거를 제공하라고 하는 개정안을 만들 수도 있습니다. 이것은 “합헌성”(constitutionality)의 효과적이고 알고리즘 적인 검사입니다.

2.3.3. RPC

GUI의 구축작업을 쉽게 만들기 위해서, 이 프로토콜은 JSON-RPC API를 드러냅니다. API 자체는 다양한 프로 시저 유형을 나타내는 json 스키마로 설명 됩니다. 일반적으로 get-balance와 같은 함수들은 RPC에서 구현이 될 수 있습니다.

type service = {
   name : string list ;
   input : json_schema option ;
   output : json_schema option ;
   implementation : Context.t -> json -> json option Lwt.t
}

The name은 프로 시저에서 네임 스페이스를 허용하는 문자열 목록입니다. 입력과 출력은 선택적으로 json 스키마에 의해서 설명이 되게 됩니다.
이 호출은 일반적으로 가장 높은 득점을 한 leaf의 조상인 주어진 context에서 수행이 되게 됩니다. 예를 들어, 가장 높은 득점을 한 리프보다 6 블록 앞에서 문맥을 쿼리하게 된다면, 여섯 가지 확인 사항이 있는 원장의 상태가 표시됩니다.
UI자체는 특정 버전의 프로토콜에 맞게 조정되거나 일반적으로 JSON 사양에서 파생됩니다.

3. 씨드 프로토콜

대부분의 블록체인은 제네시스 해시로부터 시작이 되게 됩니다. 테조스는 씨드 프로토콜에서 시작합니다. 이 프로토콜은 사실상 모든 블록 체인 알고리즘을 반영하도록 수정될 수 있습니다.

3.1. 경제 부분

3.1.1. 코인

처음에는 100억개의 코인이 존재합니다. (하지만, 토큰 공급은 군중 중에 발급되는 토큰의 수이며, 100억은 단순히 자리 표시일 뿐입니다. ) 그리고, 소수점 두번째 자리까지 사용할 수 있습니다. (이 역시 우리가 실제로 사용할 수 있는 부분은 소수점 8째자리까지 가능합니다.) 하나의 코인은 tez라고 불리며, 가장 작은 단위는 센트입니다. 0.01tez= 1 센트.

3.1.2. 채굴와과 서명 보상

원리 우리는 탈중앙화된 통화의 안전성을 유지하기 위해서는 참여자들이 필요하다는 것을 인식하고 있고, 그들에게 금전적인 보상인 인센티브를 지급합니다. (현재는 보상에 대한 계획을 마무리하는 과정입니다.) 포지션 페이퍼에서 나왔듯이, 트랜잭션피에만 의존하는 것은 위험하며, 테조스는 보상과 채권(bond)에 의존해서 돌아가게 됩니다.

이러한 bond는 채굴자들이 구매한 1년 예금과 같은 개념입니다. (현재 bond는 한주기만 지속됩니다. 기회 비용 및 1주기를 초과할 경우 유대 기간 연장의 보안에 대한 적은 이점이 주된 이유입니다. 보증인(endorser) 또한 이러한 bond를 구매해야 합니다) 이중 서명의 경우 이러한 BOND는 무효화 처리 됩니다.

한 주기 이후, 채굴자들과 보증인들은 그들의 기회 비용을 보상받기 위해서 bond에 대한 인센티브를 받습니다. 보안에 대한 부분은 채권(bond)의 가치로 제공되기 때문에, 보상에 대한 부분은 그 가치의 작은 비율이기만해도 괜찮습니다.

채권 (Bond)의 주요 목적은 필요한 보상액을 줄이는 것이며 네트워크 이점에 loss-adversion effect를 적용하는 것입니다.
자세한 부분들 씨드 프로토콜에서 블록을 채굴함으로써 512개의 테조스를 제공받으며, 1536개의 테조스 채권(bond)를 필요로 합니다. 블록 서명을 통해서 32∆T −1 테조스를 지급 받게 되며, ∆T는 블록이 서명된 시간과 이전 블록과 해당 블록 사이의 시간 간격(분) 입니다. 블록당 최대 16개까지의 서명에 대해서는 bond를 필요로 하지 않습니다. (위 수치는 이전 10억개로 가정했을 때의 수치이므로, 이후 변경이 될 가능성이 큽니다. 추후 업데이트 예정입니다)

이러한 보상 계획은 연간 5.4%의 인플레이션을 기준으로 예정되어 있습니다.
유의하실 점은 1년의 기준은 블록들의 타임스탬프를 기준으로 하며, 블록 개수로 환산하지 않습니다. 이것은 채굴자들이 약속한 길이에 관한 불확실성을 확실히 제거하기 위함이 주요 목적입니다.

이러한 채권(bond)의 보상은 33프로 정도로 예상이 되어 있습니다. (이 부분 역시 검토 중입니다.) 이 수익은 채굴자들과 서명자들이 잠재적으로 불안정한 자산을 1년동안 홀딩 해야 하기 때문에 수익이 초기엔 높을 필요성이 존재합니다. (현재는 1년에서 한 주기로 변경되었습니다)

하지만, 테조스가 성장할수록 이러한 bond의 보상은 현행 이자율 수준까지 줄 것이며, 그럴 이유가 분명 하진 않지만, 1프로 이하의 명목상 인플레이션율이 유지될 예정입니다.

3.1.3. 잃어버린 코인들

통화량에 대한 불확실성을 줄이기위해서 1년간(타임스탬프 기준으로) 활동이 없는 주소들에 한해서 코인과 주소가 모두 삭제될 예정입니다. (이부분은 수정이 되었습니다. 코인에 대한 소각은 이루어지지 않고, 스테이킹 권리만 잃게 됩니다. 이후 주소가 활성화되면 이 권리를 되찾는 것이 가능해집니다.

3.1.4. 수정 규칙

개정안은N=217= 131062 블록 지속되는 선거 주기 동안 채택됩니다. 1분 블록 간격을 감안했을 때 이것은 약 3개월로 추정이 됩니다. 선거주기는 이를 4등분한 215= 32768 블록마다 이루어지게 됩니다. 이 주기는 초기 개선을 장려하는데는 상대적으로 짧지만, 추가 수정을 통해서 주기의 길이가 길어질 것으로 예정됩니다. (프로토콜 개정안은 첫 해에는 훨씬 더 자주 이루어질 예정입니다. 보안 조치의 수단으로써 테조스 재단은 많은 것이 안정화된 12개월 후에 거부권을 행사하게 될 것입니다.)

1분기 프로토콜 수정안은 .ml와 .mli의 타르볼을 해슁해서 제출하는 것으로 제안됩니다. 스테이크 홀더들은 이러한 프로토콜들을 승인할 수 있습니다. 이를 “승인 투표”라고 하며, 특히나 강력한 투표 절차로 여겨집니다.

2분기 1분기에서 가장 많은 승인을 얻은 개정안은 이제 투표 대상이 됩니다. 스테이크 홀더들은 이를 위해서 투표안을 제시하거나 기권을 할 수도 있습니다. 이때 기권은 정족수에 포함이 됩니다.

3분기 정족수가 충족이 되고, 개정안 찬성표가 80% 이상을 받게 된다면, 개정안은 승인되어서 테스트 프로토콜을 대신하게 됩니다. 그렇지 않다면(80프로 미만이라면), 이는 거부 됩니다. 이전의 도달된 정족수가 q하고 가정하면 그 다음 투표의 최소 정족수 Q는 다음과 같이 업데이트 됩니다:

Q ← 0.8Q + 0.2q.

여기서 이 업데이트의 목표는 분실되거나 사용되지 않는 코인들로 인해서 투표가 늦춰지는 것을 막기 위함 입니다. 이렇게 함으로써 최소 정족수는 이전 선거때마다 도달한 정족수 지수 이동의 평균으로 설정이 됩니다.

4분기 개정안이 승인되었다고 가정하게 된다면, 이는 3분기 초에서부터 테스트넷에서 실행됩니다. 스테이크 홀더들은 이때 이 테스트 프로토콜을 메인 프로토콜로 승격시키기를 원하는지에 대해서 두번째 투표를 실행하게 됩니다. 이 역시 정족수를 충족 시켜야 하며, 80%이상의 대다수가 동의해야 합니다.

3.2. POS 메커니즘

3.2.1. 전반적인 오버뷰

우리들의 POS 메커니즘은 slasher, 체인-오프-활동(chain-off-activity), Proof-of-burn등 여러 아이디어들의 섞인 형태로 이루어져 있습니다. 다음 내용은 알고리즘의 오버뷰이며, 알고리즘의 구성 요소들은 아래에서 보다 자세히 설명이 됩니다.

각 블록들은 임의의 스테이크 홀더(채굴자)가 채굴하게 되며, 임의의 스테이크 홀더들이 제공한 이전 블록의 여러 서명들을 포함하게 됩니다. 채굴와과 서명 모두 작은 보상을 받지만, 만드는데 이중 채굴나이나 이중 서명의 경우 몰수 안전 보증금이 몰수되기에 1년의 시간이 소요(UNBONDING은 1년이 아닌 1 주기내로 이루어질 가능성이 더 큽니다) 됩니다.

이 프로토콜은 2048 블록 주기 사이에서 펼쳐지게 됩니다. 각 사이클이 시작될 때, 채굴을 한 사용자가 선택하고 마지막에서 두 번째 주기에 넣은 숫자로부터 무작위의 씨드가 파생되고 마지막에 공개가 됩니다. 이 무작위의 씨드를 이용하는 동시에 코인 전략이 사용되어 채집 권리와 다음 주기를 위한 특정한 주소에 계약할 권리가 주어집니다. 그림1을 참조하십시오.

3.2.2. 시계

프로토콜은 블록 간에 최소 지연을 부과합니다. 원칙적으로 각 블록은 그 어떠한 스테이크 홀더일지라도 채굴이 가능합니다. 하지만, 주어진 블록에 대해서 각 스테이크 홀더들은 임의의 최소 지연이 적용되게 됩니다. 예를 들어서 최고 순위를 받게 되는 스테이크 홀더는 이전 블록을 채굴하게 된 후 1분이면 다음 블록을 채굴 할 수 있을 것입니다. 두번째 순위를 받게 되는 스테이크 홀더는 이전 블록 이후 2분을 기다리게 될 것이고, 세번째 순위를 받게 되면 이전 블록 이후 3분을 기다리게 될 것입니다.

이렇게 함으로써 소수의 스테이크 홀더들이 기여하게 되는 포크는 낮은 블록 생성 비율을 나타내게 됩니다. 이렇지 않을 경우에는 노드를 속여서 그저 길기만 한 체인 높은 점수를 받았다고 속여서 CPU 서비스 거부 공격이 일어날 수도 있습니다.

3.2.3. 랜덤 시드 생성

채굴 된 모든 블록은 채굴자가 선택한 임의의 번호로 해시 커밋을 전달합니다. 이 번호는 안전 bond를 몰수하게 되는 페널티 때문에 다음주기에 공개하게 됩니다. 이 페널티는 씨드의 엔트로피를 공격하는데 사용될 수 있는 번호들의 선택적인 보류를 방해하기 위해서 주어지게 됩니다.

다음 주기의 악의적인 광부들은 이러한 계시들을 검열하려고 시도할 수도 있지만, 하나의 블록에 여러 개의 숫자가 나타날 수 있기 때문에, 성공 가능성은 매우 낮습니다.

한 주기에서 공개된 모든 번호는 해시 목록에 결합되게 되며, 씨드는 암호화 키 유도 함수를 이용하여 루트(root)에서 파생되게 됩니다. 핵심적으로 파생된 것은 씨드를 파생하는 시간이 일반적인 Pc에서 평균적인 승인 시간의 몇퍼센트의 일부분의 시간으로 요청을 받아드릴 수 있도록 조정을 해야 합니다.

스크린샷 2018-04-09 오후 9.03.45.png

그림1: POS 메커니즘의 4가지 단계

3.2.4. 코인을 따라가는 절차 (follow-the-coin procedure)

스테이크 홀더를 랜덤하게 고르기 위해서 우리는 이러한 절차를 따릅니다.

핵심

이 아이디어는 사토시의 비트 코인에서는 사토시를 따르라 라고도 알려져 있습니다. 이 절차는 마치 채굴된 모든 사토시가 고유한 일련 번호가 적혀 있듯이 작용합니다. 사토시들은 암시적으로 생성 시간에 따라 정렬되며, 임의의 사토시가 블록체인을 통해서 그려지고 추적이 되게 됩니다. 여기서 물론 개별 센트는 직접 추적되지 않습니다. 그 대신에 입력이 결합되어 여러 출력에 걸쳐 사용될 때, 어떤 일이 발생하는지 설명하기 위해서 규칙이 적용되게 됩니다.

결국 알고리즘은 각 키와 관련된 사이(간격들(interval))의 집합들을 추적합니다. 여기서 각 간격들은 사토시의 범위를 나타내게 됩니다. 하지만 안타깝게도 시간이 지나면 지날수록 데이터베이스는 점점 단편화 되게 되어서 클라이언트 쪽에서 이것이 부풀어 오르게 됩니다.

코인 롤 (Coin Rolls)

따라서 우리는 10000tez로 이루어진 “코인 롤”을 구성하여 이전의 알고리즘을 최적화합니다. 따라서 100만개의 롤이 존재하며, 데이터 베이스는 모든 롤을 현재 소유자에게 매핑하게 됩니다.

각 주소에는 일정한 롤 세트와 함께 작은 변경 사항들을 느슨하게 적용시킬 수 있는 능력을 가지고 있습니다. 전체 롤에서 일부를 쓰기를 원할 때에는 롤이 끊어지게 되며, 일련변호가 LIFO줄의 롤(일종의 림보)로 보내지게 됩니다. 모든 트랜잭션은 손상된 롤 수를 최소화 시키는 방식으로 처리되며, 주소에 롤을 형성할 코인이 충분하게 있다면 일련번호가 다시 대기열에 놓이고 롤이 다시 형성되게 됩니다.

LIFO의 우선 순위는 비밀 포크에서 작업하고 있는 공격자가 계정간의 변경 사항을 뒤섞어서 코인을 변경할 수 없게 하는 것입니다.

이 방법의 작은 단점은 스테이크가 롤들의 가까운 정수로 정해진다는 것입니다. 하지만, 이는 사토시의 방식에 비해서는 효율성에서 엄청난 향상을 제공하게 됩니다.

롤들에 번호가 매겨지지만, 이 접근법은 Zerocash 와는 다르게 대체가능한 보존형 프로토콜(fungibility preserving protocol)의 사용을 배제하지 않습니다. 그러한 프로토콜은 같은 림보 큐 기술을 사용할 수 있습니다.

Motivation

이 절차는 가중치가 부여된 임의의 주소를 뽑아내는 것과는 기능적으로 다릅니다.
사실 비밀 포크에서는 채굴자들은 임의의 시드 생성을 제어하고 적절한 주소를 미리 작성하여 서명 및 발행 권한을 할당하려고 시도할 수 도 있습니다. 이러한 부분들은 롤들이 무작위로 선택될 때 더욱 어려워질 것입니다. 왜냐하면 비밀 포크는 특정 롤의 소유권을 위조할 수 없고, 서명 및 발행 권한을 할당하기 위해선 시드에 적용된 해시 함수를 이미지화해야 하기 때문입니다.
실제로 한 길이가 N=2048인 주기에서 f만큼의 롤의 부분을 가진 사람은 평균적으로 fN만큼의 채굴 권한을 가지게 될 것이며, 수령한 부분의 구간인 f0의 표준편차는:

스크린샷 2018-04-09 오후 9.06.16.png

공격자가 만약 W개의 다른 씨드를 통해서 공격을 했을 때 그의 예상되는 최대 이득인

스크린샷 2018-04-09 오후 9.06.52.png

블록 수 입니다. 예를 들어서 공격자가 f=10%의 롤들을 조정한다면, 매 주기마다 205개의 블록들을 캐낼 것입니다. 이렇게 된다면, 그가 시도하는 비밀 포크에서 씨드를 제어하기 위해서 1조개가 넘는 해시를 계산했다고 가정하면 약 302개의 블록 또는 블록의 약 14.7%를 할당할 수 있을 것입니다. 다음을 유의 하십시오:

  • 씨드가 파생된 해시는 값비싼 키 파생 함수로 무차별 검색은 비실용적입니다.
  • 채굴된 블록에서 선형 이득을 보기 위해서는 공격받은 사람들은 quadratically exponential effort를 늘려야할 것입니다.

3.2.5. 블록 채굴

랜덤 시드는 반복적으로 롤을 선택하는데 사용됩니다. 선택된 첫번째 롤이 스테이크 홀더가 1분뒤에 채굴할 수 있게 한다면, 그 다음엔 2분후에 가능할 것이며, 같은 맥락으로 흘러갈 것입니다.

스테이크 홀더가 씨드를 관찰하다가 그가 다음 주기에서 우선 순위의 블록을 채굴할 수 없다는 것을 알았을 때, 그는 보안 보증금을 낼 수 있습니다.

잠재적으로 문제가 되는 상황을 피하기 위해 만약 아무 스테이크 홀더가 블록을 캘 때 보안 보증금을 내지 않았더라면, 16분뒤에 그 블록은 보증금 없이 채굴이 가능합니다.

Bond들은 암시적으로 블록을 채굴하지 않는 체인의 구매자에게 즉시 반환되게 됩니다.

3.2.6. 서명 블록

알고 있듯이, 우리는 작동직전의 POS 시스템을 가지고 있습니다. 우리는 체인의 무게로 블록 개수를 정의할 수 있습니다. 하지만, 이것은 이기적인 채굴의 형태로 이어질 것입니다.

따라서 우리는 서명 방식을 소개 합니다. 블록이 발행되는 동안 무작위의 시드는 16개의 롤에 16개의 서명 권한은 무작위로 할당하는데 사용됩니다.

이러한 서명 권한을 받은 스테이크 홀더들은 블록들이 발행되는 것을 관찰한다음에 서명을 승인합니다. 그런 다음에 그 서명은 그 블록체인에 부모(이전 체인)의 포함을 확보하려는 채굴자들에 의해 다음 블록에 포함됩니다.

서명자가 받는 서명 보상은 블록과 그 전 블록 사이의 시간 간격에 반비례 합니다. 따라서 서명자들은 그들이 서명하는 블록이 최선의 블록이라는 것에 대해서 믿고 서명하는 것에 강력한 동기 부여가 되게 됩니다. 그들은 또한 블록이 블록체인에 포함될 경우에만 보상금을 받기 때문에, 어떠한 블록을 서명해야 할지에 대한 구분도 할 수 있습니다.

가장 우선 순위에 있는 블록이 채굴되지 않는 경우(광부가 대기하지 않았을 경우가 큽니다) 기다리는 서명자들에겐 인센티브가 주어집니다. 하지만 다른 서명자들은 그때 우선 순위 블록을 서명하기로 결정할 수 있으며, 그렇게 되면 새로운 블록들이 서명을 받게 되어 이전 대기열이 풀리지 않을 수도 있습니다. 따라서 광부들은 이 전략을 따르지 않을 가능성이 큽니다.

반대로, 예를 들면 서명자가 공황상태에 빠져 첫번째 블록에 서명하기 시작하는 상황을 생각할 수 있습니다. 다른 서명자가 그렇게 하고, 새로운 블록을 즉시 만들 수 있다는 두려움 때문입니다. 그러나 이는 아무 에게도 도움이 되지 않는 말이 되지 않는 상황입니다. 이런 방식으로 행동할 정도로 프로그램 코드를 수정하는 것도 불가능하고, 이러한 균형이 가능할 것이라고 서명자가 생각할 동기마저 없기 때문입니다. 악의적으로 운영을 혼란 시키려는 사람은 다른 이들이 이 전략을 따르지 않을 것이기 때문에, 스스로 피해만 입게 되는 상황이 일어날 것입니다.

3.2.7. 체인의 무게

체인의 무게는 서명의 수와 같습니다.

3.2.8. 폐기

블록의 이중 발행이나 이중 서명을 막기 위해서 광부는 그의 블록에 폐기 통보를 포함시킬 수 있습니다.

이 폐기 처분은 두가지 형태의 서명을 필요로 합니다. 각각의 발행 서명이나 블록 서명은 블록의 높이를 표시해서 불법 행위의 증거를 간결하게 만들어줍니다.

우리가 불법 행위를 비난할 수는 있어도, 블록을 채굴하는 광부를 초월해서 무언가를 하는 것은 불가능합니다.

사실 광부는 불법 행위에 대해서 증거를 복사한 후 자신의 발견으로 보고할 수 있습니다.
또한, 당사자가 이중 승인이나 이중 서명으로 인해서 범죄를 저질렀다는 사실이 발견되면, 안전 bond는 박탈이 되게 됩니다.

3.3. 스마트 컨트랙트

3.3.1. 스마트 컨트랙트 종류

사용하지 않은 출력 대신 테조스는 상태 저장 계정을 사용합니다. 이러한 계정이 실행 코드를 저장하게 되면 우리가 아는 컨트랙트가 됩니다. 계정은 컨트랙트 유형이기에 우리는 이 두가지를 모두 보편적인 계약으로 지정하게 됩니다.

각 컨트랙트는 관리자가 있으며, 계정의 경우 단순히 소유자로 여겨지게 됩니다. 컨트렉트에 쓸모가 있다고 표시가 된 경우, 관리자는 컨트렉트에 관련된 자금을 사용할 수 있게 됩니다. 또한 각 컨트렉트는 POS 프로토콜에서 블록 서명이나 채굴에 사용되는 공개 키의 해시를 지정할 수 있습니다.

개인 키는 관리자가 제어할 수도 있으며, 하지 않을 수도 있습니다.
형식적으로 계약은 다음과 같이 표현이 됩니다.

type contract = {
   counter: int; (* counter to prevent repeat attacks *)
   manager: id; (* hash of the contract 's manager public key *)
   balance: Int64.t; (* balance held *)
   signer: id option; (* id of the signer *)
   code: opcode list; (* contract code as a list of opcodes *)
   storage: data list; (* storage of the contract *)
   spendable: bool; (* may the money be spent by the manager? *)
   delegatable: bool; (* may the manager change the signing key? *)
}

컨트랙트에서의 핸들은 초기 내용의 해시입니다. 해시가 기존 컨트렉트와 충돌되는 컨트렉트를 만들 려고 하면 이는 잘못된 연산으로 판단되어서 올바른 블록에 포함 시킬 수 없습니다.

데이터는 공용체 유형으로 다음과 같이 표시 됩니다:

type data =
   | STRING of string
   | INT of int

여기서 INT는 부호가 있는 64-비트 정수이며, 스트링은 최대 1024 바이트의 배열입니다. 저장 용량은 정수로 8바이트로, 문자열을 길이로 계산했을 때, 16384 바이트로 제한이 됩니다.

3.3.2. 생성

생성 작업은 새로운 계약을 생성하는데 사용될 수 있고, 계약의 코드 및 계약의 저장소의 초기 내용을 특정합니다. 핸들이 이미 존재하는 컨트랙트의 핸들이면 생성은 거부되게 됩니다. (이러한 경우는 실수나 악의가 있는 경우를 제외하고는 발생할 일이 없습니다) 컨트랙트를 유지하려면 최소 잔액이 1이상 이어야하며, 그 숫자보다 낮게 되면 컨트랙트는 파괴됩니다.

3.3.3. 트랜잭션들

트랜잭션은 한 컨트랙트에서 다른 컨트랙트로 전해진 메시지며, 아래와 같이 표현 됩니다.

type transaction = {
   amount: amount; (* amount being sent *)
   parameters: data list; (* parameters passed to the script *)
   (* counter (invoice id) to avoid repeat attacks *)
   counter: int;
   destination: contract hash;
}

위와 같은 트랜잭션은 관리자의 키를 이용해서 서명되었을 경우엔 컨트랙트에서 전송하거나, 컨트랙트 내에서 실행되는 코드를 통해서 프로그래밍 방식으로 전송할 수 있습니다. 트랜잭션이 수신되면, 해당 금액이 도착지의 컨트랙트 잔고에 더해지며, 도착지의 컨트랙트 코드는 삭제 되게 됩니다. 이 코드는 전달된 매개 변수를 사용할 수 있으며, 컨트랙트의 저장소를 읽고 쓸 수 있고, 서명키를 변경하거나 트랜잭션을 다른 컨트랙트로 전송할 수 있습니다.

카운터의 역할은 재생 공격을 막는 것입니다. 트랜잭션은 컨트랙트의 카운터가 트랜잭션의 카운터와 동일한 경우에만 유효합니다. 트랜잭션이 적용되게 된다면, 카운터는 1씩 증가하게 되어서 트랜잭션이 재사용되지 않도록 막게 됩니다.

또한 트랜잭션에는 클라이언트가 유효하게 간주하는 최근 블록의 블록 해시도 포함합니다. 공격자가 포크로 긴 재구성 작업을 강요하게 되는 경우, 그는 이러한 트랜잭션을 포함시키지 못할 것이며, 포크가 거짓이라는 것은 쉽게 들통이 나게 될 것입니다. 이것은 마지막 방어선이며TAPOS라고 불리는 이 시스템은 장기적인 재조직을 방지하지만, 단기적인 이중 지출을 방지하는 시스템은 아닙니다.

이 쌍(account_handle,counter)는 대략적으로 비트 코인에서의 사용되지 않는 출력과 같습니다.

3.3.4. 저장료

저장 장치가 네트워크에 비용을 부과하기 때문에, 저장 장치의 각 바이트 증가에 대해서 최소 1ꜩ의 요금이 부과 됩니다. 예를 들어서 트랜잭션 실행후 정수가 저장 영역에 추가 되고, 저장 장치의 기존 문자열에 10자가 추가되게 된다면 18ꜩ이 계약의 잔고에서 철회되어 폐기되게 됩니다.

3.3.5. 코드

언어는 스택 기반이며, 높은 수준의 데이터 유형과 초기적인 상태 및 엄격한 정적 타입 체크가 존재합니다. 이것의 디자인은 Forth, Scheme, ML and Cat에서 귀감을 얻게 되었습니다. 명령 세트의 구체적인 내용은 https://tezos.com/pages/tech.html, 2014. 에서 확인이 가능합니다. 해당 사이트에서는 완벽한 명령어 세트, 타입 시스템 및 언어의 의미를 제공하고 있습니다. 이 사이트는 간편하고 쉬운 매뉴얼이기 보다는 정확한 참조 매뉴얼을 제공하고 있습니다.

3.3.6. 사용료

지금까지의 이 시스템은 이더리움이 트랜잭션을 처리하는 방식과 매우 유사합니다. 하지만 테조스는 수수료를 처리하는 방식이 조금 다릅니다. 이더리움은 긴 프로그램들에 대해서 제멋대로 시간에 따른 선형적인 수수료 부분을 바꿉니다. 하지만, 이것은 한 광부가 거래를 검증할 보상을 제공하지만, 이 거래를 검증해야 될 다른 광부들에게도 그러한 동기, 즉 인센티브를 제공하진 못합니다. 또한 실제로, 대부분의 관심 가는 프로젝트들이 스마트 컨트랙트를 사용할 수 있는 시간은 매우 짧습니다. 따라서 우리는 프로그램을 실행할 수 있는 단계의 수를 엄격하게 부과함으로써 구조를 단순화시키게 됩니다.

이러한 하드 캡이 일부 프로그램에서 너무 빡빡하게 여겨진다면, 그들은 이것을 여러 단계로 나누어서 여러 트랜잭션을 이용해서 완전히 실행을 시키게 되면 됩니다. 또한 테조스는 수정될 수 있기에 향후에 캡을 바꾸거나 새로운 opcode로 조금 더 나은 선택안을 할 수 있을 것입니다.

계정이 허용하는 경우에는 변경을 요청하는 서명된 메시지를 발행하여 서명 키 또한 변경할 수 있습니다.

4. 결론

우리는 매력적인 시드 프로토콜을 구축했다고 느낍니다. 하지만, 테조스의 진정한 가치는 스테이크 홀더들이 그들이 가치 있다고 느껴지는 프로토콜을 만들어감에 있습니다.


백서 원문
번역 후기 - 테조스 한글 백서 번역을 무사히 끝마쳤습니다.


Steemit Token LAB 백서 번역 #1. 테조스

  • Steemit KR에서 암호화폐 백서를 번역합니다. 첫번째 프로젝트로 테조스 백서를 한글로 번역하였습니다.
  • 테조스에 관심이 많으신 @areyoucrazy 님께 번역을 의뢰하였으며, 빠르게 번역을 해주셨습니다. 앞으로 3번에 걸쳐 업로드할 계획입니다.
  • 앞으로도 지속적으로 관심있는 암호화폐 백서의 번역 작업을 이어갈 계획입니다.
  • 선 지급한 번역료 외에 본 글 저자보상 SBD의 30%는 번역가에게 전달되며, 50%는 다음 백서 번역을 위하여 적립합니다.

번역 저작권

  • 이용시 출처 표시
  • 비상업적 이용만 가능
  • 변형 등 2차적 저작물 작성 가능

번역 후원자

skan
leesunmoo
ioc
arneb271828
bramd
ssm1810
musicholic
corn113
jyp
khaiyoui
jsg
kakaotalk
kwak
stellasjshin
kwonjs77
vingroup
ppomppu
inchonbitcoin
brent1042
segyepark
olorin
floridasnail
ibk
ediya
tabris
oldstone
blockchainnomad
happyberrysboy
aiyren
krexchange
jack8831
cheolwoo-kim
sonki999
sexyboy
chungjh
clarkgold
yoon
ksc
noctisk
get-cheaper
kimsungmin
louispark
changyoon
greenjuice
gotit
sonamoo
verygoodsurgeon
successtrainer
hyokhyok
beoped
yirgacheffe2shot
kingbit
doctorfriend
pitasa
jjangh1717
chunseungho
yangpankil27
woojumbs
uksama
deuksoo84
zet
cornerstone
tradingideas
lattecom
sinner264
coolzero
tigris
jungs
idas4you
sjchoi
tmkor
siritable
cine
loki80
solar-junely
backdm
vega321
sleepcat
banjjakism
steemtruth
smartbear
soon8013
iieeiieeii
jxwonah
sailingtohappy
sun510
koreaculture
ioe3
pyorinho
shinhancard
chipee
mawan1002
mooyeobpark
lonose
watermelon13
mattchoi
coffeenut
eversloth
jaywon
jsquare
d7795
hawoon
efsane
ohnamu
junhan57
arama
goodhello
wooklym
pediatrics
crawfish37
innople
hwantag
lcc3108
tjayhas
acceptkim
imnb
xiian
dmsqlc0303
lostmine27
roona1383
koreaminer
catharina
krgamer
room9
sismaru
thegreatgatsby
dongsuh
mandurah
joeuhw
partykim
hangeul
brianyang0912
sigizzang
rantertx
gilma
gidung
idencosmos
rainbowdash
ksheva1
jjangdol69
youngbinlee
skt1
soosoo
futurecurrency
dodge3507
brunch
thing-2
coldmonkey
heonbros
jjjjabe
dev1by0
dream-o
jisang
scylogo
jisui
aram04
jeongwooyu
gentlebot
danbain
cancerdoctor
lighthil
candyboy
holic7
simin
makefigure
wooyamum77
wabangcute
neojew
mastertri
minifam
bizventurer
happylazar
hukyong74
yeonhage
mrjang
hackerzizon
hygge
leemikyung
esccere
chunwu
seaturtle
yajirang
dhn0411
konan
comaiiii
chrisjeong
senseicat
lhy
yoonwonlim
hutchson
zorba
kopasi
rok-sivante
isi3
pkalra
luakiz
bluebottle
gaeteul
warofcraft
jinibh.house
ioioioioi
minseungchoi
bitcointravel
robrigo
steemarter
innovit
julianpark
actapeta
hyunaria
thewriting
tworld
lorem
creamer7
lsuny
yjc638
designkoi
steembest
naha
crowsaint
radiologist
steamsteem
bulsik
cubo
qkr1066
agar
yuky
blake.heo
capzzang
jsj1215
ojaber
stalk.yoon
kyju
dimon14
nickwalshblog
fordmogul
bue
tryword
hegel
hee4552
traveler.terry
biophil
dylanhobalart
gichan
amartinezque
da-dawn
forhappywomen
daydreams4rock
subijung01
fiat19
teeegs90
bonjovis
jay4u
kimegggg
energizer000
ssin
joopang2
rampant
drac59
judyhopps
nhj12311
gekko
kimminyoung
eth0619
ldsklee
emmaa
jeank
doctoryak
soyou.park
leeki7801
foruni73
toka
skuld2000
snowflake
luna33
freeyourmind
someonewhoisme
herokdj
hyoree
neoguri
joeparys
vandal
ghostcode
neonartist
card1001
foodflaneur
planet-power
illust
adelepazani
jameszenartist
meldesixym
aloha-mylife
randrade
anxin
coffeex
suin
willbeonceagain8
valueup
deanhass
junubia
procyon21
cryptoboii
jacobyu
thehoneybee
coldsiksu
vikaspoonia
elfrances185
steemitlsh
ivet
thomasfarley
tommycoin
learn2earn
nps0132
chic.hyun
dimens
stella12
formysons
eunyx
hkmoon
evesick
soul-factory
yyromkim
jd8578
jang-doctor
sonntag51
rkmrkm99
kimyh
lesto
munhwan
goodcontent4u
zionjohn
injoy
vommie
rahmanovic
limzua
asinayo
lovelyyeon
yong2daddy
piggypet
banguri
omani02
psitorn
cron
yahweh87
drgkim
tip2yo
agood
jonnyla08
go4d
apdls92
dianamun
chocolate1st
enturia
cryptodollar1
dongtube
koreart
mystory03
doctorbme
delphic
madamf
talkit
mysted
maikuraki
yellowrain
tcban
marskyung
qrwerq
millionfist
samuelhull
twohs

Coin Marketplace

STEEM 0.19
TRX 0.18
JST 0.032
BTC 88143.93
ETH 3070.82
USDT 1.00
SBD 2.78