├── ko └── translations │ ├── assets │ ├── dawn_4_ppp.png │ ├── dawn_4_lpscp.png │ ├── customer-table-example.png │ ├── dpos_missing_wp_image1.png │ ├── dpos_missing_wp_image2.png │ ├── dpos_missing_wp_image3.png │ ├── dpos_missing_wp_image4.png │ ├── dpos_missing_wp_image5.png │ ├── dpos_missing_wp_image6.png │ ├── dpos_missing_wp_image7.png │ ├── service-table-example.png │ ├── Single-Host-Testnet-No-keosd.png │ ├── action-apply-context-diagram.png │ ├── Accounts-and-Wallets-Overview.png │ ├── Single-Host-Multi-Node-Testnet.png │ └── Basic-EOSIO-System-Architecture.png │ ├── RELEASE_EOSIO_1_0_5.md │ ├── RELEASE_EOSIO_1_0_6.md │ ├── Glossary.md │ ├── eosio-applesedemo-readme.md │ ├── Accounts-&-Permissions.md │ ├── DPOS_Consensus_Algo_Missing_Whitepaper.md │ ├── Fix_DPoS_Loss_of_Consensus.md │ ├── EOSIO_Dawn_4_2.md │ ├── Dawn_of_EOS.md │ ├── TUTORIAL.md │ ├── EOSIO_Dawn_4_1.md │ ├── EOSIO_Dawn_4_Release.md │ ├── Testnet-Single-Host-Multinode.md │ ├── Dice.md │ ├── Tutorial-Hello-World-Contract.md │ ├── Tutorial-eosio-token-Contract.md │ ├── Dawn_2_Released.md │ ├── Tutorial-Comprehensive-Accounts-and-Wallets.md │ ├── Introducing_EOSIO_Dawn_4.md │ ├── Dawn_3_Now_Available.md │ ├── Smart-Contract.md │ └── Tutorial-Tic-Tac-Toe.md ├── reports ├── eoseoul_tps_benchmark_20180423.pdf ├── eoseoul_presentation_on_bancor_20180529.pptx └── eoseoul_tps_2nd_benchmark_20180430.md └── README.md /ko/translations/assets/dawn_4_ppp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/dawn_4_ppp.png -------------------------------------------------------------------------------- /ko/translations/assets/dawn_4_lpscp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/dawn_4_lpscp.png -------------------------------------------------------------------------------- /reports/eoseoul_tps_benchmark_20180423.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/reports/eoseoul_tps_benchmark_20180423.pdf -------------------------------------------------------------------------------- /ko/translations/assets/customer-table-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/customer-table-example.png -------------------------------------------------------------------------------- /ko/translations/assets/dpos_missing_wp_image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/dpos_missing_wp_image1.png -------------------------------------------------------------------------------- /ko/translations/assets/dpos_missing_wp_image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/dpos_missing_wp_image2.png -------------------------------------------------------------------------------- /ko/translations/assets/dpos_missing_wp_image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/dpos_missing_wp_image3.png -------------------------------------------------------------------------------- /ko/translations/assets/dpos_missing_wp_image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/dpos_missing_wp_image4.png -------------------------------------------------------------------------------- /ko/translations/assets/dpos_missing_wp_image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/dpos_missing_wp_image5.png -------------------------------------------------------------------------------- /ko/translations/assets/dpos_missing_wp_image6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/dpos_missing_wp_image6.png -------------------------------------------------------------------------------- /ko/translations/assets/dpos_missing_wp_image7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/dpos_missing_wp_image7.png -------------------------------------------------------------------------------- /ko/translations/assets/service-table-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/service-table-example.png -------------------------------------------------------------------------------- /reports/eoseoul_presentation_on_bancor_20180529.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/reports/eoseoul_presentation_on_bancor_20180529.pptx -------------------------------------------------------------------------------- /ko/translations/assets/Single-Host-Testnet-No-keosd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/Single-Host-Testnet-No-keosd.png -------------------------------------------------------------------------------- /ko/translations/assets/action-apply-context-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/action-apply-context-diagram.png -------------------------------------------------------------------------------- /ko/translations/assets/Accounts-and-Wallets-Overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/Accounts-and-Wallets-Overview.png -------------------------------------------------------------------------------- /ko/translations/assets/Single-Host-Multi-Node-Testnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/Single-Host-Multi-Node-Testnet.png -------------------------------------------------------------------------------- /ko/translations/assets/Basic-EOSIO-System-Architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eoseoul/docs/HEAD/ko/translations/assets/Basic-EOSIO-System-Architecture.png -------------------------------------------------------------------------------- /ko/translations/RELEASE_EOSIO_1_0_5.md: -------------------------------------------------------------------------------- 1 | # EOSIO 1.0.5 Release Notes 2 | 2018년 6월 16일에 발생한 MainNet 장에를 해결하기 위한 긴급 출시. 3 | 4 | 지연 트랜잭션이나 유보 트랜잭션의 실행에서 기능 정지(hard failure)가 발생하는 경우에도 블록 생성을 계속하게 함. ([#4158](https://github.com/EOSIO/eos/pull/4158)). 5 | 6 | ## Pull Request #4158 7 | 8 | * heifner : transaction_receipt에 메소드를 하나 추가해서 지연/유보 트랜잭션을 결정하게 하고, 다음 버전에서 유닛 테스트를 추가하겠습니다. 9 | * testcode77 : 지연된(delayed) 트랜잭션의 수가 증가하면, 이 경우가 무의미해집니다. 제 생각으로는 지연 트랜잭션을 다루는 방법이 변해야 합니다. 10 | 11 | ## [이슈 #4159](https://github.com/EOSIO/eos/issues/4159) : Throw unexpected fails in apply_block - revisit 12 | 13 | [#4158](https://github.com/EOSIO/eos/pull/4158) 퀵 픽스에 따른 유닛 테스트가 필요함. 또한 체인에 블록을 푸시하는 현재의 유닛 테스트가 이 경우를 잡아내지 못한 이유를 찾아야 함. 14 | 15 | [#4158](https://github.com/EOSIO/eos/pull/4158) 버그 픽스는 우리가 지연/유보 트랜잭션을 결정하는 방식이 미묘하다는 점을 강조하고 있음. transaction_receipt trx variant는 지연/유보 트랜잭션에 대해 transaction_id_type를 가짐. transaction_receipt에 메소드를 추가해서 명확하게 유보/지연 트랜잭션임을 드러내게 함. transaction_receipt의 구조는 그것이 signed_block의 일부이기 때문에 쉽게 변할 수 없다는 점을 주의해야 함. 16 | 17 | ## 번역 정보 18 | 19 | * 원문 : https://github.com/EOSIO/eos/releases/tag/v1.0.5 20 | * 원문 게시일 : 한국표준시 2018년 6월 16일 23시 01분 -------------------------------------------------------------------------------- /ko/translations/RELEASE_EOSIO_1_0_6.md: -------------------------------------------------------------------------------- 1 | # EOSIO 1.0.6 Release Notes 2 | 3 | v1.0.6 버전 출시를 통해서 기존의 EOSIO를 기반으로 하는 블록체인의 관리자들에게 사전에 밝힌 중대한 보안 버그에 대한 업데이트를 제공합니다. 4 | 5 | 블록원(Block.one)은 안드레이 나데즈데(Andrei Nadejde)에게 이 취약점을 발견하고 보고한 점에 대해 감사드리고, EOSIO를 기반으로 하는 블록체인의 블록 프로듀서들에게 그들이 맡고 있는 블록체인을 보호하기 위한 신속한 대응과 노고에 감사드리고 싶습니다. 6 | 7 | ## 이슈 설명 8 | 이번 출시 버전은 다음 두 개의 이슈를 다룹니다. 9 | 10 | * `nodeos` 동작에서: 지연 트랜잭션(deferred transaction)이, 동일한 `sender_id`를 가지는 새로운 지연 트랜잭션에 의해 암시적으로 대체된 경우, 원래의 지연 트랜잭션을 저장하는 데 사용한 RAM이 사용자 자원 풀로 다시 해제되지 않습니다. 11 | * 시스템 컨트랙트 동작에서: `refund` 지연 트랜잭션을 저장하는 데 사용하는 RAM의 요금을 지불한 계정이 `from` (환급 금액을 빚진 당사자) 대신, 적합하지 않게도 `receiver` (지분참여한 자원으로부터 혜택을 받은 당사자)로 설정되었었습니다. 12 | 13 | 이 두 가지 이슈가 복합적으로 작용하여, 악의적인 사용자가 피해자 계정에 약간의 자원을 위임(delegate)하고 이어서 조금씩 반복적으로 지원을 위임해제(undelegate)하면 피해자 계정의 RAM 자원 풀이 고갈되는 상황이 발생합니다. 14 | 15 | ## 완화 방안 - Mitigations 16 | * v1.0.6 버전으로 구동되는 노드는 현재 대기중인 지연 트랜잭션을 암시적으로 덮어쓰게될 지연 트랜잭션을 예약하게 될 트랜잭션을 주관적으로 거절할 것입니다. 17 | * 대기중인 지연 트랜잭션이 존재하지 않는 경우에도, 이와 같은 필터를 피하기 위한 새로운 트랜잭션을 예약하기 전에, 이 기능을 사용하려고 하는 컨트랙트는 내장 함수 `cancel_deferred`를 안전하게 실행할 수 있습니다. 18 | * 시스템 컨트랙트는 위와 같은 명시적인 취소-후-예약 방식을 사용하도록 업데이트되었고, 그래서 `undelegatebw`의 기능은 변하지 않은 상태로 안전해졌습니다. 19 | * 시스템 컨트랙트는 지연된 환불 트랜잭션을 예약하는 데 관련되는 임시 RAM 사용료를 빚진 당사자에게 요금이 제대로 청구되도록 업데이트되었습니다. 20 | 21 | ## 번역 정보 22 | 23 | * 원문 : https://github.com/EOSIO/eos/releases/tag/v1.0.6 24 | * 원문 게시일 : 한국표준시 2018년 6월 23일 3시 45분 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EOSeoul Documentation 2 | 3 | ## EOSeoul 4 | 5 | - [EOSIO Testnet Builder](https://github.com/eoseoul/testnetbuilder) - Full Suites for EOSIO Launching from Booting to Live Production. 6 | - [`eos-ramcost` contracts collection](https://github.com/eoseoul/eos-ramcost) - Adjusting supply of a token and connector balance of bancor during final phase of Boot sequence. 7 | 8 | - EOSIO Benchmark 9 | * [EOSIO Benchmark 1st Report 20180423](https://github.com/eoseoul/docs/blob/master/reports/eoseoul_tps_benchmark_20180423.pdf) 10 | * [EOSIO Benchmark 2nd Report 20180430](https://github.com/eoseoul/docs/blob/master/reports/eoseoul_tps_2nd_benchmark_20180430.md) 11 | * [EOSIO Benchmark scripts](https://github.com/eoseoul/scripts/tree/master/bmt_client) 12 | 13 | - Presentations 14 | * [Bancor Protocol: Liquidity Providing Algorithm for RAM](https://github.com/eoseoul/docs/blob/master/reports/eoseoul_presentation_on_bancor_20180529.pptx) on EOSIO Developer Meetup in Seoul / 2018.05.30 / PowerPoint file 15 | 16 | ## Korean Translations 17 | 18 | - EOSIO Technical White Paper V2 19 | * [EOSIO Technical White Paper v2](https://github.com/eoseoul/docs/blob/master/ko/translations/TechnicalWhitePaperV2.md) 20 | 21 | - EOSIO Release Notes 22 | * [The Dawn of EOS.IO](https://github.com/eoseoul/docs/blob/master/ko/translations/Dawn_of_EOS.md) 23 | * [EOS.IO DAWN 2.0 Released & Development Update](https://github.com/eoseoul/docs/blob/master/ko/translations/Dawn_2_Released.md) 24 | * [EOSIO Dawn 3.0 Now Available](https://github.com/eoseoul/docs/blob/master/ko/translations/Dawn_3_Now_Available.md) 25 | * [Introducing EOSIO Dawn 4.0](https://github.com/eoseoul/docs/blob/master/ko/translations/Introducing_EOSIO_Dawn_4.md) 26 | * [EOSIO Dawn 4.0 Release](https://github.com/eoseoul/docs/blob/master/ko/translations/EOSIO_Dawn_4_Release.md) 27 | * [EOSIO Dawn 4.1 Release](https://github.com/eoseoul/docs/blob/master/ko/translations/EOSIO_Dawn_4_1.md) 28 | * [EOSIO Dawn 4.2 Release](https://github.com/eoseoul/docs/blob/master/ko/translations/EOSIO_Dawn_4_2.md) 29 | * [EOSIO 1.0.5 Release Notes](https://github.com/eoseoul/docs/blob/master/ko/translations/RELEASE_EOSIO_1_0_5.md) 30 | * [EOSIO 1.0.6 Release Notes](https://github.com/eoseoul/docs/blob/master/ko/translations/RELEASE_EOSIO_1_0_6.md) 31 | 32 | - EOSIO Technical Documents 33 | * [Fix DPOS Loss of Consensus due to conflicting Last Irreversible Block](https://github.com/eoseoul/docs/blob/master/ko/translations/Fix_DPoS_Loss_of_Consensus.md) 34 | 35 | - EOSIO Wiki 36 | * [Glossary](https://github.com/eoseoul/docs/blob/master/ko/translations/Glossary.md) 37 | * [Setting Up A Local Environment](https://github.com/eoseoul/docs/blob/master/ko/translations/Local-Environment.md) 38 | * [Accounts & Permissions](https://github.com/eoseoul/docs/blob/master/ko/translations/Accounts-%26-Permissions.md) 39 | * [Getting Started with Smart Contracts](https://github.com/eoseoul/docs/blob/master/ko/translations/TUTORIAL.md) 40 | * [eosio.token, Exchange, and eosio.msig Contracts](https://github.com/eoseoul/docs/blob/master/ko/translations/Tutorial-eosio-token-Contract.md) 41 | * [Hello World Tutorial](https://github.com/eoseoul/docs/blob/master/ko/translations/Tutorial-Hello-World-Contract.md) 42 | * [Comprehensive Accounts & Wallets Tutorial](https://github.com/eoseoul/docs/blob/master/ko/translations/Tutorial-Comprehensive-Accounts-and-Wallets.md) 43 | * [Persistence API](https://github.com/eoseoul/docs/blob/master/ko/translations/Persistence-API.md) 44 | * [Smart Contracts](https://github.com/eoseoul/docs/blob/master/ko/translations/Smart-Contract.md) 45 | * [Tic-Tac-Toe](https://github.com/eoseoul/docs/blob/master/ko/translations/Tutorial-Tic-Tac-Toe.md) 46 | * [Dice](https://github.com/eoseoul/docs/blob/master/ko/translations/Dice.md) 47 | * [Single Host Multi-Node (Private) Testnet](https://github.com/eoseoul/docs/blob/master/ko/translations/Testnet-Single-Host-Multinode.md) 48 | * [eosio-applesedemo README](https://github.com/eoseoul/docs/blob/master/ko/translations/eosio-applesedemo-readme.md) 49 | -------------------------------------------------------------------------------- /ko/translations/Glossary.md: -------------------------------------------------------------------------------- 1 | | 용어 | 한글번역 | 동의어 | Block.one 에서의 정의 | 2 | |-----------------|------------------|----------|--------------------------------| 3 | | Account | 계정 | | 하나 이상의 키나 계정에 할당된 기본/커스텀 권한들로 구성된 체인 상에서의 식별자. | 4 | | Authority | 자격 | | 권한(permission)을 추상화해서 권한이 실제로 개인이나 그룹에 연동돼 적용될 수 있도록 표현한 것. | 5 | | Block | 블록 | Blk | 블록체인의 확정 가능한 단위. 각 블록에는 0개 이상의 트랜잭션이 포함돼 있으며, 이전의 모든 블록들에 대한 암호화된 연결도 포함돼 있음. 블록이 "번복 불가능하게 확정(irreversibly confirmed)" 됐다는 의미는 블록 프로듀서의 절대 다수가 해당 블록 내의 트랜잭션이 정당하다는 데 동의하였다는 것. 일단 블록이 번복 불가능하게 확정됐다면, 이 블록은 재생 가능한 블록체인에 영구적으로 포함됨. | 6 | | DAC | | | 분권화된 자율 집단(Decentralized Autonomous Collective), 혹은 분권화된 자율 회사(Decentralized Autonomous Corporation). https://en.wikipedia.org/wiki/Decentralized_autonomous_organization | 7 | | DAO | | | 분권화된 자율 조직(Decentralized Autonomous Organization). | 8 | | Deferred Transaction | 지연된 트랜잭션 | defTx | 지정한 미래의 특정 시점에 실행되도록 스마트 컨트랙트에서 생성한 트랜잭션. 지연된 트랜잭션 내에서도 자신이 실행되고 난 이후의 미래 특정 시점에 실행되는 트랜잭션(즉, 새로운 지연된 트랜잭션)을 생성할 수 있음. 이를 이용하면 지연된 트랜잭션으로 무한 반복의 문을 열 수 있음. 지연된 트랜잭션의 실행 자격을 가진 사용자는 반드시 미래에 트랜잭션을 실행할 수 있는 대역폭(스케줄링 시점에서 평가됨)과 실행될 때 까지 저장해 둘 수 있는 저장공간을 보유해야 함. | 9 | | DLTs | 분산 원장 기술 | | Distributed Ledger Technologies. 분산된 원장(공유된 원장이라고도 불리거나 분산 원장 기술로 통칭됨)은 지리적으로 떨어진 여러 도시, 국가, 기관 간에서 복제되고, 공유되고, 동조(synchronize)돼 합의를 이룬 디지털 데이터를 의미함. https://en.wikipedia.org/wiki/Distributed_ledger | 10 | | DPoS | 지분 증명 위임 | | Delegated Proof of Stake. 한편으로는 "Democracy as Proof of Stake(지분 증명의 민주화)." DPoS는 일련의 합의 알고리즘 중 하나로, 예를 들면 어떤 블록 프로듀서가 어떤 트랜잭션에 동의(합의에 도달)하게 하고, 블록을 "실체화" 하여 확정시킴으로써 번복 불가능하게 할 수 있는 방법들의 총체. | 11 | | Key pair | 키 쌍 | keys | 공개키와 그에 해당하는 개인키의 조합 | 12 | | larimer | 라리머 | | 1/10000 EOS(토큰), `0.0001 EOS` | 13 | | Master Password | 마스터 패스워드 | | 지갑 파일의 암호를 푸는(해제하는) 데 사용되는 패스워드 | 14 | | Action | 액션 | | 블록체인에 변화를 일으키는 행동. 하나 이상의 액션을 모아 트랜잭션으로 만들 수 있음. | 15 | | Non-Producing Node | 비생산 노드 | | nodeos를 돌리는 풀 노드 중에서 자체로는 블록체인의 전체 복제본만을 보유하고 있으며 블록 자체만을 감시하고 확인하는 풀 노드. "대기 풀"에 있는 비생산 노드들은 투표에서 선정된다면 BP 노드가 됨. 기존의 BP 노드가 표를 잃어 탈락하게 되면 비생산 노드가 됨. 대부분의 비생산 노드는 "대기 풀"에 있지 않음. | 16 | | Oracle | 오라클 | | "블록체인과 스마트 컨트랙트 관련 내용에서 오라클(선지자)이란, 실제로 일어나고 있는 일들을 찾고 검증하며, 이 정보를 블록체인에 전달해 스마트 컨트랙트가 쓸 수 있도록 하는 에이전트를 의미함." *[원문](https://blockchainhub.net/blockchain-oracles/)* | 17 | | peer-to-peer | 피어 투 피어 | p2p | 피어 투 피어 연산이나 네트워킹이란 분산된 애플리케이션 구조를 이용해 태스크나 워크로드를 피어 간에 분배하는 것을 의미함. 피어란 각각 동등한 권한을 가지는 애플리케이션의 참여자를 의미함. 노드 간에 피어 투 피어 네트워크를 구성한다고 표현함. https://en.wikipedia.org/wiki/Peer-to-peer | 18 | | Permission | 권한 | | 서명의 자격(authority)을 평가해 메시지가 적합한 자격을 가지고 있는지 결정하는, 가중치를 이용한 보안 메커니즘. | 19 | | Private Key | 개인 키 | | 트랜잭션에 서명하기 위한 비밀 키 | 20 | | Public Key | 공개 키 | pub key | 트랜잭션과 더불어 전송되는 공개 키 | 21 | | Scope | 영역 | | 컨트랙트 내의 데이터가 차지하는 구역. 컨트랙트는 내부의 구역에만 쓰기 가능하지만 다른 컨트랙트의 구역에서 읽기 가능함. 영역 설정을 적당히 해 주면 같은 구역에 쓰지 않기 때문에 트랜잭션이 같은 컨트랙트 내에서 병렬적으로 수행되게 할 수 있음. 영역은 계정 이름과 일치하지는 않지만, 컨트랙트는 편의상 양쪽에 같은 값을 사용할 수 있음. | 22 | | Smart Contract | 스마트 컨트랙트 | | 컨트랙트의 협상이나 수행을 가능케 하거나 검증하거나 강제하기 위해 사용되는 컴퓨터 프로토콜. | 23 | | Standby Pool | 대기 풀 | | BP로 선출되고자 하며 BP 역할이 주어질 경우 수행할 수 있는 100개의 풀 노드의 집합. 블록체인에서 현재 BP를 갈아치우고자 할 때 새 BP는 대기 풀 내에서 선정됨. | 24 | | Transaction | 트랜잭션 | Tx, Txn | 블록체인에 가해지는 복구 불가능한 변화. 하나 이상의 메시지(옮긴이: 백서 v1과 v2의 큰 차이 중 하나가 '메시지'가 사용되는 부분을 '액션'으로 변경한 것인데, 여기까지는 아마 반영 안된 것으로 보임)로 구성됨. 대개는 스마트 컨트랙트의 실행. | 25 | | Wallet | 지갑 | | 클라이언트가 생성하거나 관리하는 암호화된 파일(예를 들면 `cleos`)로 개인 키를 관리하며 보안 측면에서 트랜잭션에 서명함. 지갑은 잠긴 상태나 잠금 해제된 상태를 가질 수 있음. | 26 | | Block Producer | 블록 프로듀서 | bp | 블록체인에서 자신의 차례를 맞아 "바로 지금" 블록을 생산하고 있는 노드, 혹은 그와같은 역할을 수행하도록 선출된 그룹의 멤버. 'block producer'와 동의어(옮긴이: ???) | 27 | 28 | 29 | ## 번역 정보 30 | 31 | * 원문 : https://github.com/eosio/eos/wiki/Glossary 32 | * 번역 기준 리비전 : 669211e579aa1fef575a0cb1ea0e6d14ced3371f 33 | -------------------------------------------------------------------------------- /ko/translations/eosio-applesedemo-readme.md: -------------------------------------------------------------------------------- 1 | # EOSIO Apple Secure Enclave 데모 2 | 3 | EOSIO는 타원 곡선 전자 서명 알고리즘(ECDSA)에 대해 두 가지 타원 곡선을 4 | 지원합니다. 각각 secp256k1과 (prime256v1으로 불리기도 하는) secp256r1입니다. 5 | r1 곡선의 장점은 아이폰이나 안드로이드 디바이스와 같은 많은 모바일 기기에서 6 | 하드웨어 지원이 가능하다는 점입니다. 이 어플리케이션은 터치바가 장착된 7 | 최근의 맥북 프로 노트북에 있는 Secure Enclave를 통해서 하드웨어 장치 내에서 8 | r1 곡선을 사용하는 데모입니다. r1 비밀키는 secure enclave에 저장되고, 9 | 호스트 시스템에 보이지 않습니다. 이 비밀키는 (EOSIO 트랜잭션의 해시로 10 | 사용될 수 있는) SHA256 다이제스트를 secure enclave를 거쳐서 서명하는데 11 | 사용할 수 있습니다. 적절한 작동인지 검증하기 위해서, 어플리케이션은 12 | EOSIO 코드 베이스에서 공개키 복구의 검증을 가능케 합니다. 13 | 14 | # 빌드하고 사인하기 15 | `applesedemo` 어플리케이션은 EOSIO 소스 트리에서 macOS 빌드로 컴파일됩니다. 16 | 사용하는 API는 macOS 10.12 이상이 필요합니다(iOS 10 이상에서도 역시 작동할 17 | 것입니다). 그러나 Secure Enclave를 사용하기 위해선 어플리케이션은 18 | Mac App Store (MAS) 스타일의 서명으로 사인되어야 합니다 -- 과거의 다윈 19 | 스타일 서명으로는 충분하지 않습니다. 이런 강한 서명 체계로, 20 | 특정 비밀키를 생성한 어플리케이션이 해당 비밀키를 사용할 수 있는 유일한 21 | 어플리케이션임을 보장합니다. 22 | 23 | `applesedemo`를 MAS 스타일 어플리케이션으로 서명하는 작업은 두 가지 면에서 24 | 다루기 힘듭니다. 1) 이 서명은 커맨드 라인 어플리케이션으로 썩 어울리지 25 | 않는 "app bundle" 형식으로 패키징해야 합니다. 2) 모든 빌드 과정을 26 | XCode 사용 없이 유지해야 합니다. 27 | 28 | `sign.sh` 스크립트는 app bundle `applesedemp.app`를 생성하고 서명합니다. 29 | 이 작업은 서명되지 않는 `applesedemo` 가 현재 작업 디렉토리에 있는 상황에서 30 | 진행되어야만 합니다. 세 가지 파라미터가 필요합니다. 31 | 32 | 1. 서명에 사용할 인증서의 SHA1 thumbprint 33 | 2. 서명된 어플리케이션의 완전한 AppID (teamID + bundleID) 34 | 3. 서명에 사용할 프로비저닝 프로파일 경로 35 | 36 | CMakeLists.txt에 주석 처리된 예제가 하나 있는데 이 예제는 빌드 이후에 37 | 자동으로 실행될 수 있는 방법을 보여줍니다. 38 | 39 | 서명한 후, `applesedemo`를 app build 안에서 번들된 형태인 40 | `applesedemo.app/Contents/MacOS/applesedemo`로 실행해야 합니다. 41 | 서명하지 않은 `applesedemo`를 실행할 경우 에러를 출력하는 42 | 대충 만든 체크가 하나 있지만, 유효하지 않게 서명된 어플리케이션의 43 | 경우를 잡아내지 못할지도 모릅니다. 유효하지 않게 서명된 44 | 어플리케이션이 Secure Enclave를 사용하려고 시도하면 45 | 도움이 되지 않는 에러 메시지를 만나게 될 것입니다. 46 | 47 | ## Personal Signing 48 | 49 | Apple Developer Program에 계정이 있다면 개발 포탈에 들어가서 50 | 프로비저닝 프로파일을 다운로드하고/거나 아직 인증서가 없다면 51 | 개발자 인증서를 생성할 수 있습니다. 52 | 53 | 그러나 Developer 계정이 없는 경우라도 아무 Apple ID를 이용해서 54 | 로컬 개발 환경에서 사용할 수 있는 개발용 인증서와 프로비저닝 55 | 프로파일을 생성할 수 있습니다. 불행하게도, 이 과정은 56 | XCode가 자동으로 "관리하는" 서명 메커니즘으로 진행됩니다. 57 | XCode 안에서 Cocoa 앱을 만들고, 적절한 번들ID를 할당하고, 58 | 사용할 Team에 대응하는 "Personal Team"을 선택해야 합니다. 59 | XCode는 애플 서버에 접속해서 아직 없다면 적절한 프로비저닝 60 | 프로파일과 인증서를 생성할 것입니다. 61 | `~/Library/MobileDevice/Provisioning\ Profiles/` 디렉토리를 62 | 들여다보면서 어떤 프로파일이 사용하기에 적절한지 63 | 손으로 찾아보아야 할지도 모릅니다. 64 | 65 | XCode가 Secure Enclave에 접근하기 위해 사용하는 TeamID와 Bundle ID를 66 | 기억해두세요. 둘 중 어느 하나를 값을 변경하면, 변경 전의 값으로 67 | 생성한 키를 볼 수 없게 됩니다. 68 | 69 | # 사용법 70 | ## 비밀키 생성 71 | 먼저, Secure Enclave 내부에서 비밀키를 생성합니다. 이 어플리케이션은 72 | 키를 보호할 보안 레벨을 제어할 수 있는 몇 가지 다른 방법으로 73 | 키를 생성하는 기능을 지원합니다 (`--help` 도움말을 확인하세요). 74 | 이 예제에서는, 다이제스트를 서명할 때(트랜잭션에 서명하는 것과 같이) 75 | 지문 사용이 필요한 방식으로 키를 생성할 것입니다. 76 | ``` 77 | $ applesedemo.app/Contents/MacOS/applesedemo --create-se-touch-only 78 | Successfully created 79 | public_key(PUB_R1_7iKCZrb1JqSjUncCbDGQenzSqyuNmPU8iUA15efNW5KD1iHd9x) 80 | ``` 81 | 비밀키에 대응하는 공개키가 출력됩니다. 이 값을 어딘가 적어두세요. 82 | Secure Enclave를 이용해서 비밀키 여러 개를 생성하고 각각에 이름을 83 | 붙일 수 있습니다만 이 어플리케이션은 오직 한 번에 한 개의 키만 84 | 지원합니다. 85 | ## 다이제스트 생성 및 서명 86 | EOSIO는 SHA256 다이제스트를 이용해서 트랜잭션을 서명하고, 짧은 문자열로부터 87 | 단순한 SHA256 다이제스트를 만듭니다. 88 | 89 | ``` 90 | $ echo 'Hello world!' | shasum -a 256 91 | 0ba904eae8773b70c75333db4de2f3ac45a8ad4ddba1b242f0b3cfc199391dd8 - 92 | ``` 93 | 이제 Secure Enclave만 알고 있는 비밀키를 이용해서 다이제스트를 94 | 서명해봅시다. 유효한 지문을 사용하기 전에는, 서명이 생성되지 않을 것입니다. 95 | ``` 96 | $ applesedemo.app/Contents/MacOS/applesedemo --sign 0ba904eae8773b70c75333db4de2f3ac45a8ad4ddba1b242f0b3cfc199391dd8 97 | signature(SIG_R1_Jx4sBidhFV6PSvS8hWbG5oh77HKud8xpkoHLvWaZVaBeWttRpyEjaGbPRVEKu3JePTyVjANmP4GKFtG2DAuB4MTVqsdC9W) 98 | ``` 99 | ## 키 복구 100 | 서명과 다이제스트가 주어지면, 이 내용을 다이제스트를 서명하는 데 101 | 사용한 공개키와의 연관성을 보여줄 수 있어야 합니다. 102 | ``` 103 | $ applesedemo.app/Contents/MacOS/applesedemo --recover 0ba904eae8773b70c75333db4de2f3ac45a8ad4ddba1b242f0b3cfc199391dd8 \ 104 | SIG_R1_Jx4sBidhFV6PSvS8hWbG5oh77HKud8xpkoHLvWaZVaBeWttRpyEjaGbPRVEKu3JePTyVjANmP4GKFtG2DAuB4MTVqsdC9W 105 | public_key(PUB_R1_7iKCZrb1JqSjUncCbDGQenzSqyuNmPU8iUA15efNW5KD1iHd9x) 106 | ``` 107 | 실제로 이 다이제스트와 서명을 통해 복구한 공개키는 Secure Enclave에 108 | 저장된 공개키와 동일합니다. 109 | 110 | ## 번역 정보 111 | 112 | * 원문 : https://github.com/EOSIO/eos/blob/master/programs/eosio-applesedemo/README.md 113 | * 번역 기준 리비전 : f55f431f8fb4d91e8d872d281ffd3a1cd9de3758 114 | -------------------------------------------------------------------------------- /ko/translations/Accounts-&-Permissions.md: -------------------------------------------------------------------------------- 1 | - [지갑(Wallets)](#지갑Wallets) 2 | - [계정(Accounts)](#계정Accounts) 3 | - [자격과 권한(Authorities and Permissions)](#자격과-권한Authorities-and-Permissions) 4 | - [최종 요약 (Putting it all Together)](#최종-요약-Putting-it-all-Together) 5 | - [기본 계정 구성 (단일 서명, Single-Sig)](#기본-계정-구성-단일-서명-Single-Sig) 6 | - [다중 서명 계정 그리고 사용자 지정 권한](#다중-서명-계정-그리고-사용자-지정-권한) 7 | - [번역 정보](#번역-정보) 8 | 9 | 10 | **계정(account)** 는 블록체인상에 저장된 사람이 읽을 수 있는 형태의 식별자입니다. 모든 트랜잭션 (transaction)의 권한(permission)은 트랜잭션을 일으키는 계정의 자격 구성에 의해 결정됩니다. 각각의 권한은 고유의 이름을 가지고 있습니다. 권한을 결정하는데 있어 임계값 (threshold)이라는 개념이 있습니다. 트랜잭션의 유효하기 위해선 트랜잭션에 필요한 권한값이 (weight) 임계값을 넘었을 때 발생합니다. (역주:원문을 그대로 번역한다면 권한값은 가중치로 번역되겠지만 이해를 돕기위해 이 문서에서는 권한값이라는 표현을 사용하였습니다.) **클라이언트(client)** 프로그램을 통해 지갑(wallet)을 불러오고 잠금을 해제한 뒤 트랜잭션에 서명을 남길 수 있습니다. 지갑은 사용자가 가지고 있는 키를 안전하게 보관하고 사용할 수 있는 소프트웨어입니다. 블록체인 상에서 각 계정에는 여러 키들이 부여될 수 있고 이 키마다 다른 계정에 대한 권한은 해당 계정의 자격 구성에 따라 다를 수 있습니다. 11 | 12 | ## 지갑(Wallets) 13 | 14 | 지갑(wallet)은 클라이언트(client)프로그램으로 키들을 저장합니다. 각 키들은 다른 계정의 권한을 가질 수 있습니다. 이상적인 경우, 지갑은 높은 엔트로피의 비밀번호 (역주: 상당히 복잡한 비밀번호)로 보호되는 잠금 상태 (암호화 상태)와 잠금이 해제된 상태(복호화 상태)를 가집니다. EOSIO/eos 저장소의 `keosd`라는 lite-client와 상호작용하는 `cleos`라는 command line interface client가 이러한 패턴을 보여줍니다. 15 | 16 | ## 계정(Accounts) 17 | 18 | 계정(account) 는 블록체인상에 저장된, 사람이 읽을 수 있는 이름입니다. 계정의 소유자는 권한 구성에 따라 개인이 될수도 있고 개인들의 그룹이 될수도 있습니다. 블록체인에 트랜잭션를 전송하거나 다른 방식을 통해 실행하는 경우에 계정이 사용됩니다. 19 | 20 | ## 자격과 권한(Authorities and Permissions) 21 | 22 | 자격은 통해 어떤 액션의 적합성 여부를 결정할 수 있습니다. 23 | 24 | 모든 계정은 두 가지 _시스템 권한 (native permission)_ 을 갖게 됩니다. 25 | 26 | - 계정의 소유권을 나타내는 권한으로 `owner` 권한이 있습니다. 극히 일부의 트랜잭션에서 이 권한이 요구되며 대표적으로 소유자 권한을 변경할 때 사용됩니다. 일반적으로 이러한 `owner` 권한의 비밀키는 보안상 콜드스토리지(역주: 외부에 노출될 염려가 없는 저장장치, 종이에 기록, 네트워크가 분리된 저장장치 등)에 저장하고 그 누구와도 공유하지 않는 편이 안전합니다. 또한 이 `owner` 권한은 `owner` 권한이 아닌 다른 권한이 탈취되었을 때 복원 기능을 제공합니다. 27 | 28 | - `active` 권한은 `owner` 권한 다음 막강한 권한으로 토큰을 전송, 블록 프로듀서에게 투표를 포함해 비교적 높은 자격이 요구되는 액션에 사용됩니다. 29 | 30 | _시스템 권한_ 은 EOSIO에서 부여하는 권한입니다. 이 _시스템 권한_ 이외에, 계정 관리를 용이하게 하기 위해 각 계정은 사용자 지정 권한을 정의할 수 있습니다. 사용자 지정 권한 정의는 상당히 자유로워서, 대다수의 경우를 구현할 수 있습니다. 앞으로 만들어질 권한들은 개발자 커뮤니티가 사용하는 방식, 채택될 규칙 등에 의해 달라질 것으로 예상됩니다. 31 | 32 | 하나 또는 다수의 유효한 `계정명` 또는 `공개 키`가 각 자격에 대한 권한을 구성하게 됩니다. 33 | 34 | ## 최종 요약 (Putting it all Together) 35 | 36 | 다음 내용에서는 실제 적용가능한 몇가지 예시를 포함해 지금까지 소개한 모든 개념을 다룰 예정입니다. 37 | 38 | 39 | ### 기본 계정 구성 (단일 서명, Single-Sig) 40 | 41 | 계정이 생성되면 기본 권한 구성을 가지게 됩니다. 이 기본 권한 구성 하에서 시스템 권한인 `owner`와 `active` 권한에는 각각 한개의 키가 존재합니다. 이 키들의 권한값은 **1**이며 권한의 임계값 또한 **1**로 동일합니다. 즉 이 구성에서는 `owner`, `active` 자격으로 액션을 실행하기 위해 각각 `owner`, `active` 권한의 단일 서명이 요구됩니다. 42 | 43 | #### __*@bob account authorities*__ 44 | 45 | | Permission | Account | Weight | Threshold | 46 | |------------|-------------------------------------------------------|--------|-----------| 47 | | owner | | | 1 | 48 | | | EOS5EzTZZQQxdrDaJAPD9pDzGJZ5bj34HaAb8yuvjFHGWzqV25Dch | 1 | | 49 | | active | | | 1 | 50 | | | EOS61chK8GbH4ukWcbom8HgK95AeUfP8MBPn7XRq8FeMBYYTgwmcX | 1 | | 51 | 52 | `@bob` 계정의 `owner` 권한에 대해서 `@bob`의 owner key는 1이라는 권한값을 가집니다. `owner` 자격을 얻기위한 임계값은 1로 `@bob`의 owner key 서명만 있다면 `owner` 자격이 필요한 트랜잭션를 일으킬 수 있습니다. 이 owner key는 지갑에 저장될 수 있고 cleos를 통해 사용할 수 있습니다. 53 | 54 | ### 다중 서명 계정 그리고 사용자 지정 권한 55 | 56 | 아래의 예시에서 가상의 `@multisig` 계정의 권한 구성이 소개됩니다. `@multisig`계정에서 `owner` 자격 및 `active` 자격은 `@bob`과 `@stacy`의 권한으로 획득할 수 있습니다. `publish` 자격은 유저3명의 권한을 통해 다양한 방식으로 획득할 수 있습니다. 57 | 58 | #### __*@multisig account authorities*__ 59 | 60 | | Permission | Account | Weight | Threshold | 61 | |------------|-------------------------------------------------------|--------|-----------| 62 | | owner | | | 2 | 63 | | | @bob | 1 | | 64 | | | @stacy | 1 | | 65 | | active | | | 1 | 66 | | | @bob | 1 | | 67 | | | @stacy | 1 | | 68 | | publish | | | 2 | 69 | | | @bob | 2 | | 70 | | | @stacy | 2 | | 71 | | | EOS7Hnv4iBWo1pcEpP8JyFYCJLRUzYcXSqt... | 1 | | 72 | 73 | 이 예시에서, `owner`에 대한 권한은 `@bob`과 `@stacy`가 가지고 있고 각각의 권한값은 **1**입니다. `owner` 자격을 획득하기 위한 임계값은 **2**이기 때문에 `owner` 자격이 필요한 트랜잭션를 일으키기 위해선 `@bob`과 `@stacy` 모두의 서명이 필요하게 됩니다. 74 | 75 | `active` 권한 또한 `@bob`과 `@stacy`가 가지고 있으며 각각의 권한값은 **1**입니다. `active` 자격을 얻기 위한 임계값은 1이기 때문에 `active` 자격이 필요한 트랜잭션에는 `@bob` 또는 `@stacy`의 서명만이 필요하게 됩니다. 76 | 77 | `publish` 권한은 *사용자 지정 권한* 입니다. 이 예시 에서, 가상의 블로그 dApp에서는 `@multisig`의 `publish` 자격이 있다면 `@multisig` 계정의 블로그에 포스팅을 할 수 있습니다. `publish` 자격을 얻기 위한 임계값은 **2**이고 `@bob`과 `@stacy`의 권한값은 각각 **2**, 공개 키의 권한값은 **1**입니다. 즉 `@bob` 과 `@stacy`는 본인의 서명만으로 `publish` 자격을 획득할 수 있으나, 공개 키의 권한 값(**1**) 은 임계치(**2**)보다 작기 때문에 `publish` 자격을 얻기 위해선 `publish` 권한을 가지고 있는 다른 계정의 서명이 필요합니다. 78 | 79 | 따라서 `@bob`과 `@stacy`는 `@multisig`의 소유자로 _편집자 또는 관리자_ 정도의 높은 권한을 갖고 있다고 볼 수 있습니다. 이 예시에서는 EOSIO가 권한 시스템을 자유롭게 구성할 수 있음을 보여줍니다. 다만, 예시의 방식은 확장성이 떨어지고 좋지 못한 디자인 패턴을 가지는 한계가 있어 실제 사용되기에는 어려움이 있습니다. 80 | 81 | 또한, 앞서 기술되었던 바와 같이 권한은 **계정이름**과 **키**로 구성될 수 있습니다. 이 부분은 다소 당연하게 받아들여질 수 있지만, 이로 인해 권한 시스템을 한껏 자유롭게 구성할 수 있습니다. 82 | 83 | **관찰 포인트** 84 | 85 | - `@bob`과 `@stacy`는 `@multisig` 계정의 소유자임을 명백히 밝힐 수 있습니다. 86 | - 공개키의 경우 `@bob`또는 `@stacy`의 서명이 없이는 `publish` 자격으로 액션을 실행할 수 없습니다. 87 | - `@bob`과 `@stacy`는 다른 서명이 없이도 `publish` 자격으로 액션을 실행할 수 있습니다. 88 | 89 | ## 번역 정보 90 | 91 | * 원문 : https://github.com/eosio/eos/wiki/Accounts%20%26%20Permissions 92 | * 번역 기준 리비전 : b81148e028926ce3db16b2ff45d405c0d1a665ed 93 | -------------------------------------------------------------------------------- /ko/translations/DPOS_Consensus_Algo_Missing_Whitepaper.md: -------------------------------------------------------------------------------- 1 | # DPOS 합의 알고리즘 – 누락된 백서 2 | 이 문서는 누락된 백서이며 위임 지분 증명(DPOS)에 대한 분석입니다. 이 문서의 목적은 DPOS가 작동하는 이유와 무엇이 DPOS를 견고하게 만드는지 분석한 내용을 제공하는 것입니다. [DPOS에 대한 초기 설명은 bitshares.org에서 찾을 수 있습니다.](https://bitshares.org/technology/delegated-proof-of-stake-consensus/) 그러나 그 설명에는 실제 합의 과정의 일부가 아닌 많은 측면들이 포함되어 있습니다. 3 | 4 | 모든 블록체인은 근본적으로 트랜잭션에 의해 작동하는 결정론적 스테이트 머신(deterministic state machine)입니다. 합의는 트랜잭션의 결정론적 순서에 동의하고 잘못된 거래를 필터링하는 과정입니다. 동일한 트랜잭션 순서를 생성할 수 있는 여러 가지 합의 알고리즘이 있지만, DPOS는 여러 블럭체인을 수년간 안정적으로 운영해왔다는 사실로 견고하고 안전하며 효율적이라고 입증되었습니다. 5 | 6 | 모든 합의 알고리즘과 마찬가지로, 블록 프로듀서가 초래할 수 있는 가장 큰 해악은 검열입니다. 모든 블록은 결정론적 오픈소스 스테이트 머신 로직에 따라 유효해야 합니다. 7 | 8 | ## DPOS 알고리즘 요약 9 | DPOS 알고리즘은 블록 프로듀서 그룹 선출과 블록 생성 일정을 수립하는 두 부분으로 나뉩니다. 선출 과정은 지분참여자(stakeholders)가 궁극적으로 통제권을 가질 수 있게 만듭니다. 왜냐하면 네트워크가 부드럽게 운영되지 못하면, 지분참여자는 많은 것을 잃게되기 때문입니다. 사람들이 선출되는 방식은 분 단위로 합의가 이루어지는 방법에 거의 영향을 미치지 않습니다. 따라서 이 문서는 블록 프로듀서가 선출된 후 합의가 이루어지는 방법에 초점을 맞출 것입니다. 10 | 11 | 이 알고리즘을 설명하기 위해 A, B, C라는 3명의 블록 프로듀서가 있다고 가정합니다. 모든 경우를 해결하기 위해 합의가 2/3 + 1이 필요하기 때문에, 이 단순화된 모델은 생산자 C가 타이 브레이커(tie breaker)로 간주됩니다. 현실 세계에는 21개 이상의 블록 프로듀서가 있을 것입니다. 작업 증명(Proof of Work)처럼, 가장 긴 체인이 승리한다는 것이 일반적인 규칙입니다. 정직한 피어가 유효하고 엄격하게 긴 체인을 볼 때마다 현재 포크에서 더 긴 체인으로 전환할 것입니다. 12 | 13 | 가장 상상할 수 있음직한 네트워크 상황에서 DPOS가 어떻게 동작하는지를 예제를 통해 보여드리겠습니다. 이 예제를 통해 DPOS가 견고하고 깨지기 어려운 이유를 이해하는 데 도움이 될 것입니다. 14 | 15 | ## 정상 작동 16 | 정상적인 작동 상태에서 블록 프로듀서는 3초마다 블록을 생성합니다. 아무도 자신의 차례를 놓치지 않는다고 가정하면 가장 긴 사슬이 만들어질 것입니다. 블록 프로듀서가 예정된 시간 슬롯이 아닌 다른 시간 슬롯에서 블록을 생성한다면 이는 유효하지 않습니다. 17 | 18 | ![정상 작동](assets/dpos_missing_wp_image1.png) 19 | 20 | ## 소수 포크 21 | 노드 중 최대 1/3이 악의적이거나 오작동할 수 있으며, 이로 인해 소수 포크를 만들 수 있습니다. 이 경우 소수 포크는 매 9초마다 한 블록만을 생성하고, 다수의 포크는 매 9초마다 두 블록을 생성할 것입니다. 다시 한번, 정직한 2/3를 구성하는 다수는 항상 소수 체인보다 길 것입니다. 22 | 23 | ![소수 포크](assets/dpos_missing_wp_image2.png) 24 | 25 | ## 단절된 소수의 블록 이중 생성 26 | 소수은 포크를 무제한으로 만들려고 시도할 수 있지만, 이들의 포크는 모두 대다수 체인보다 짧을 것입니다. 소수의 체인은 다수의 체인보다 느리게 커지기 때문입니다. 27 | 28 | ![단절된 소수의 이중 생산](assets/dpos_missing_wp_image3.png) 29 | 30 | ## 네트워크 파편화 31 | 네트워크가 파편화될 가능성이 전적으로 존재합니다. 이 경우 어떤 포크에도 블록 프로듀서의 다수가 포함되지 못합니다. 이 경우 가장 긴 체인은 가장 큰 소수의 몫이 됩니다. 네트워크 연결이 복원되면, 더 작은 수로 구성된 소수 포크는 자연적으로 가장 긴 체인으로 전환되고, 모호하지 않은 합의가 복원됩니다. 32 | 33 | ![네트워크 파편화](assets/dpos_missing_wp_image4.png) 34 | 35 | 두 개의 가장 긴 포크가 길이가 같을 경우, 포크가 3개일 수 있습니다. 이 경우 3번째 프로듀서(작은 포크)는 네트워크에 다시 연결될 때 타이(tie)를 이룬 상태를 깹니다. 홀수의 프로듀서가 있기 때문에, 타이 상태를 오랫동안 유지하기가 불가능합니다. 나중에 우리는 프로듀서 생산 순서 셔플링을 설명할 것인데, 이 방법은 생산 순서를 랜덤하게 만들어서 두 개의 포크가 동일한 수의 생산자를 가지고 있더라도 각각의 포크가 다른 길이로 확 성장하게 만들어서 포크 하나가 다른 포크보다 커지도록 만듭니다. 36 | 37 | ## 연결된 소수의 이중 생산 38 | 이 시나리오에서, 소수 집단 B는 자신의 생산 시간대에 두 개 이상의 대체 블록을 생성했습니다. 다음 예정 프로듀서 (C)는 B가 생산한 대체 블록 중 하나를 선택해서 생산을 시작할 수 있습니다. 이렇게 되면 이 체인이 가장 긴 체인이 되고 B1을 선택한 모든 노드가 포크를 전환합니다. 악의를 가진 프로듀서들의 소수 집단 얼마나 많은 대체 블록을 전파하려고 시도하는 지는 중요하지 않습니다. 아무리 해도 라운드 하나 이상으로 가장 긴 체인의 일부가 절대로 될 수 없기 때문입니다. 39 | 40 | ![연결된 소수의 이중 생산](assets/dpos_missing_wp_image5.png) 41 | 42 | ## 마지막 비가역 블록 (Last Irreversible Block) 43 | 네트워크 파편화가 발생할 경우 여러 포크가 오랜 시간 동안 계속해서 성장할 수 있습니다. 장기적으로 가장 긴 사슬이 이길 것이지만, 관찰자는 블록이 가장 빠르게 성장하는 체인의 확실한 일부인지 확실하게 알 수 있는 수단이 필요합니다. 이것은 블록 프로듀서의 2/3 + 1에 의한 확인을 보고 결정할 수 있습니다. 44 | 45 | 아래 그림에서 블록 B는 2/3 + 1 확인을 나타내는 C와 A에 의해 확인되었고, 그렇기 때문에 생산자의 2/3이 정직한 경우 다른 어떤 체인도 더욱 길어질 가능성이 없다고 추론할 수 있습니다. 46 | 47 | ![마지막 비가역 블록](assets/dpos_missing_wp_image6.png) 48 | 49 | 이 "규칙"은 Bitcoin의 6블록 확인 "규칙"과 유사합니다. 일부 스마트한 개인들은 두 개의 노드가 각각 다른 마지막 비가역 블록으로 끝날 수 있는 사건 발생 순서를 생각해낼 수 있습니다. 이 엣지 케이스(edge case)는 공격자가 통신 지연 상황을 완전히 통제할 수 있고 이와 같은 통제를 한 번이 아닌 두 번을 분 간격으로 통제할 수 있어야 합니다. 이런 상황이 일어날 경우, 가장 긴 사슬의 장기적인 규칙(옮긴이 주: 장기적으로 정직하게 만든 가장 긴 사슬이 살아남는다)이 여전히 적용됩니다. 우리는 그러한 공격의 확률이 0에 가까울 것으로 예상하고 경제적 결과가 아주 사소해서 걱정할 가치가 없다고 추정합니다. 50 | 51 | ## 프로듀서 정족수 부족 52 | 정족수를 채우지 못한 프로듀서 집단이 있는 예상 밖의 상황이라면, 소수 집단이 계속해서 블록을 생산하는 상황이 가능합니다. 이런 상황에서 생성된 블록에서 지분참여자들은 자신의 투표를 변경하는 트랜잭션을 보낼 수 있습니다. 이와 같은 투표는 블록을 만들 새로운 프로듀서군을 선출할 수 있고 블록 생산 참여율을 100%로 복원할 수 있습니다. 이런 일이 발생하면 소수의 체인은 결국 100% 미만의 참여율로 운영되는 다른 모든 체인을 추월하게 됩니다. 53 | 54 | 이 과정에서 모든 관찰자는 67%의 참여율을 가진 체인이 나타날 때까지 네트워크 상태가 유동적이라는 것을 알게 됩니다. 이러한 조건 하에서 트랜잭션을 보내는 액션을 선택하는 사람들은 6가지 미만의 확인을 받아들이는 사람들과 비슷한 위험을 감수합니다. 그들은 합의에 의해 궁극적으로 다른 포크에 정착할 수 있는 작은 확률이 있다는 인지한 상태로 행동하는 것입니다. 실제로 이 상황은 Bitcoin 확인이 3개 미만인 블록을 허용하는 것보다 훨씬 안전합니다. 55 | 56 | ## 프로듀서 다수의 부패 57 | 대다수의 생산자가 부패하면 무제한의 포크를 생산할 수 있으며 각 포크는 2/3의 다수결로 생산되는 것처럼 보일 것입니다. 이 경우 마지막 비가역 블록 알고리즘은 가장 긴 체인 알고리즘으로 되돌아갑니다. 가장 긴 체인은, 남은 정직한 노드의 소수에 의해 결정될 최대 다수에 의해 승인된 체인이 될 것입니다. 이러한 형태의 양상은 오래 가지 않을 것입니다. 왜냐하면 지분참여자들이 이런 프로듀서들을 교체하기 위해 결국 투표를 할 것이기 때문입니다. 58 | 59 | ![프로듀서 다수의 부패](assets/dpos_missing_wp_image7.png) 60 | 61 | ## 지분 증명으로서의 트랜잭션 (TaPoS) 62 | 사용자가 트랜잭션에 서명할 때, 블록체인의 상태에 대한 특정 가정 하에서 트랜잭션에 서명합니다. 이 가정은 최근 생성된 블록들에 대한 인식에 기반합니다. 가장 긴 체인에 대한 합의가 바뀌면, 서명자가 트랜잭션에 동의했을 때 서명자가 가졌던 가정을 잠재적으로 무효화할 수 있습니다. 63 | 64 | TaPoS를 사용하면 모든 트랜잭션에 최근 블록의 해시가 포함되며 해당 블록이 체인 기록에 존재하지 않으면 유효하지 않은 것으로 간주됩니다. 분리된 포크에서 트랜잭션에 서명하는 사용자는, 해당 트랜잭션이 유효하지 않게 되고 메인 포크로 전환할 수 없음을 알게될 것입니다. 65 | 66 | 이 프로세스의 부수적인 효과(side effect)는 대체 체인을 생성하려는 장기 공격에 대한 보안입니다. 개별 지분참여자는 트랜잭션을 만들 때마다 블록체인을 직접 확인합니다. 시간이 지남에 따라 모든 블록은 모든 지분참여자에 의해 확인되며 이것은 위조한 체인에서 복제할 수 없는 중요한 특징입니다. 67 | 68 | ## 결정론적 프로듀서 순서 셔플링 69 | 모든 예에서 우리는 블록 프로듀서의 라운드-로빈(round-robin) 스케쥴링을 보여주었습니다. 실제로 블록 프로듀서 집합은 N블록마다 셔플되고, 여기서의 N은 프로듀서의 수입니다. 이 무작위화는 블록 프로듀서 B가 블록 프로듀서 A를 항상 무시하지 않으며, 동일한 프로듀서 수를 가지는 여러 포크가 있을 때마다 동수 상황(tie)이 결국 깨질 것을 보장합니다. 70 | 71 | ## 결론 72 | 위임 지분 증명은 생각할 수 있는 모든 자연적 네트워크 혼란 상황에 견고하고 큰 소수를 구성하는 프로듀서의 부패가 발생해도 안전합니다. 일부 경쟁 알고리즘과 달리, DPOS는 프로듀서 다수가 서비스를 못하는(fail) 상황에서도 계속 작동할 수 있습니다. 이 과정에서 커뮤니티는 100% 참여율로 재개될 때까지 서비스 불능 프로듀서들을 교체하기 위해서 투표할 수 있습니다. 저는 이러한 어렵고 다양한 실패 조건 하에서도 튼튼한 다른 합의 알고리즘을 알고있지 않습니다. 73 | 74 | 궁극적으로 DPOS는 블록 프로듀서를 선출하기 위해 선택된 알고리즘으로부터 중요한 보안성을 획득하고, 프로듀서들의 노드가 높은 품질인지 개별적인 주체인지 검증합니다. 승인 투표 프로세스를 사용하면 50%의 실질적인 의결권을 행사하는 사람도 단신으로 하나의 프로듀서를 선택할 수 없습니다. DPOS는 견고한 네트워크 연결로 연동된 정직한 노드의 100% 참여라는 명목 조건의 성능을 최적화하도록 설계되었습니다. 이런 방법으로 DPOS는 평균 1.5 초 이내에 99.9%의 확실성으로 트랜잭션을 확인할 수 있는 능력을 부여받는 한편, 성능이 저하되는 상황이 오더라도 복구가 용이한 우아하고 탐지 가능한 방식으로 성능이 저하됩니다. 75 | 76 | 다른 컨센서스 알고리즘은 네트워크 상태가 좋지 않은 상황과 부정직한 노드가 있다는 명목 조건 기반으로 디자인되어 있습니다. 대안적인 설계들의 최종 결과는, 느린 성능, 높은 지연시간(latency), 높은 통신 오버헤드를 보이고 33%의 노드가 망가지는 경우 완전히 중단되는 네트워크입니다. 77 | 78 | BitShares 3년 동안 Steem 1년 동안의 성공적인 운영을 통해서 우리는 모든 형태의 네트워크 상황과 소프트웨어 버그를 경험했습니다. DPOS는 이와 같은 환경을 성공적으로 탐색해왔고, 다른 블록체인보다 더 많은 트랜잭션을 처리하면서 컨센서스를 유지하는 능력을 입증했습니다. 79 | 80 | ## 번역 정보 81 | 82 | * 원문 : https://steemit.com/dpos/@dantheman/dpos-consensus-algorithm-this-missing-white-paper 83 | * 원문 최초 포스팅 시점 : 한국표준시 2017년 5월 29일 -------------------------------------------------------------------------------- /ko/translations/Fix_DPoS_Loss_of_Consensus.md: -------------------------------------------------------------------------------- 1 | # 마지막 비가역 블록 처리 충돌로 인한 DPOS 합의 유실 수정 2 | 3 | 이 문서는 DPOS (위임 지분 증명) 알고리즘의 개선 사항을 설명합니다. 개선된 4 | DPOS는 DPOS 3.0 프로토콜을 따르는 노드의 네트웍이 합의에서 벗어나지 않도록 5 | 더욱 강하게 보장합니다. 합의에서 벗어난다(falling out of consensus)는 상황은 6 | 두 개의 노드가 서로 다른 블록을 비가역(변경불가확정) 상태에 도달했다고 7 | 결론을 내릴 때라고 정의합니다. 8 | 9 | ## 배경 10 | 11 | 비트코인과 같이 작업 증명(proof of work)으로 동작하는 블록체인은 합의를 12 | "가장 긴 체인" 규칙에 따라 정의합니다. 이 규칙을 사용하면 그 어떤 블록도 13 | 비가역 상태에 도달했다고 확인할 수 없습니다. 어떤 시점에서도 누구나 14 | 오래된 블록을 기반으로 더 긴 체인을 만들 수 있고 노드 역시 전환할 수 있습니다. 15 | 이런 관점에서 보면 우리는 비트코인이 포크를 변경하려는 시도의 경제적인 비용에 16 | 기반한 높은 확률의 비가역성만 제공한다는 결론을 내릴 수 있습니다. 17 | 18 | BitShares는 위임 지분 증명을 도입했습니다. 이 알고리즘을 이용하면 19 | 지분참여자들은 블록 프로듀서를 선거로 선출합니다. 블록 프로듀서는 20 | 의사 무작위 방식으로(pseudo-randomly) 섞이고, 블록을 생산할 수도 있고 21 | 아닐 수도 있는 절대 시간 슬롯을 할당받습니다. 22 | 대부분의 프로듀서가 작성해가는 블록체인은 프로듀서가 거의 23 | 없는 블록체인보다 길이의 측면에서 훨씬 빨리 길어질 것입니다. 다른 속도로 24 | 길어지는 두 개의 체인이 있다고 가정하면, 더 빨리 길어지는 체인이 종국에 가서 25 | 가장 긴 체인이 될 것입니다. 그렇기 때문에, 원래의 위임 지분 증명 알고리즘은 26 | 비트코인과 유사한 보장을 제공했었습니다. 말하자면, 체인에 블록이 추가됨에 따라 27 | 블록 하나를 뒤집을 만한 다른 체인이 존재할 확률이 점점 더 낮아지기 때문입니다. 28 | 29 | DPOS 스케줄링 알고리즘의 본질은 지켜보는 참관자들에게 많은 정보를 전달해주는 30 | 데 있습니다. 예를 들어, 놓친 블록의 빈도를 근거로 참관자가 31 | 속한 체인이 소수 체인(옮긴이 주: 짧은 체인)이 될 가능성을 탐지할 수 있습니다. 32 | 21개의 프로듀서가 있는 상황에서 노드는 딱 2번 연속으로 놓친 블록(6초)이 33 | 발생한 직후 자신이 소스 포크에 속해있을지도 모른다는 사실을 34 | 정확히 감지할 수 있습니다. 이렇게 하면 네트워크가 불안정한 경우 사용자에게 35 | 상황을 알리고 사용자는 확정이 완료될 때까지 조금 더 기다릴 수 있습니다. 36 | 마찬가지로 모든 프로듀서가 트랜잭션을 받아들이는 21개의 블록에서 놓친 블록이 37 | 없다면, 생성된 블록이 되돌려지지 않을 것이라고 확신할 수 있습니다. 38 | 39 | (옮긴이 주: 기술백서 v1 기준에서 블록 생성은 3초마다 이루어집니다. 그래서 40 | 이 문서는 EOSIO 기술백서 v1을 기준으로 작성된 것으로 추정됩니다. 41 | 기술백서 v2 기준으로 본다면, 블록 생성은 0.5초마다 이루어집니다. 42 | 그러므로 '딱 2번 연속으로 놓친 블록'은 1초입니다. 이에 대해 깃헙 43 | 이슈 2718번의 덧글로 RalfWeinand는 위의 내용을 지적했습니다.) 44 | 45 | ## 거의 발생하지 않는 합의 유실 (DPOS 2.0) 46 | 47 | DPOS 2.0에 들어서서 우리는 마지막-비가역-블록 개념을 도입했습니다. 이 블록은 48 | 블록 프로듀서 수의 2/3에서 1을 더한 프로듀서가 생성한 가장 최근에 만든 49 | 블록입니다. 이론적으로 보자면, 블록 하나를 승인한 체인 하나를 전체 프로듀서 50 | 수의 2/3에서 1을 더한 만큼의 프로듀서가 작성하고 있다면, 다른 포크가 51 | 존재하기는 불가능하다는 이야기입니다. 52 | 53 | 그렇긴 하지만, 진취적인 사람들은 네트워크가 나눠져서 두 개의 체인을 만드는 54 | 네트워크가 생기는 가상의 시나리오를 생각해왔습니다. 이런 경우 보통 하나 혹은 55 | 양쪽의 체인이 양쪽 어느 네트워크 하나가 프로듀서 수 2/3에서 1을 더한 수만큼의 56 | 프로듀서에 재연결되기 전까지는 마지막-비가역-블록을 그 다음 블록으로 57 | 확정하는 작업을 중단합니다. 이와 같이 정상적인 동작이 이루어지면, 58 | 모든 작업이 순조롭게 진행되며 연결이 정상화될 때 모든 노드는 59 | 하나의 진짜 체인으로 수렴할 것입니다. 60 | 그렇긴 하지만, 두 개의 부분집합이 동시에 포크를 전환해서, 61 | 양쪽의 포크가 서로 다른 블록 하나에 프로듀서 수 2/3에서 1을 더한 62 | 만큼의 투표에 도달한 상황에 처하는, 레이스 컨디션(race condition)이 존재합니다. 63 | 이런 상황이 발생하면 포크의 양쪽에 있는 노드들은 양쪽 모두 마지막-비가역-블록이 64 | 정해진 시점 이전으로 되돌리지 않을 것이므로, 양쪽의 노드들은 동기화할 수 65 | 없습니다. 이제 수동으로 조정해주어야 합니다. 66 | 67 | 이런 상황에서 하나 또는 양쪽 포크는, 포크의 어느 한 쪽에 프로듀서 수 2/3에 68 | 1을 더한 수를 만족했느냐에 따라서 비가역 지점을 확정해나가는 동작을 멈출 69 | 것입니다. 소수 체인은 절반의 속도로 작성될 지도 모릅니다만, 비가역 상태를 70 | 기다리는 노드들은 소수 체인에 수용되는 어떤 트랜잭션도 최종적인 상태라고 더이상 71 | 인정하지 않을 것입니다. 72 | 73 | 이런 장애 유형은, 역전되는 단일 블록을 초래하고, 몇몇 서비스는 손해를 74 | 입을지도 모릅니다. 우리의 추산으로는, 이런 일이 벌어질 확률은 6개의 승인을 75 | 얻은 비트코인 블록 하나가 역전되는 확률보다 훨씬 낮습니다. 이런 추정은 76 | 이와 같은 상황이 목격되지 않은 상태로 3년 동안 운영해온 77 | BitShares와 Steem 양쪽의 실환경 테스트를 밑받침합니다. 78 | 79 | ## DPOS 3.0 + BFT 80 | 81 | EOSIO를 통해서 우리는 하나의 체인에서 일어난 트랜잭션이 최종적임(final)을 82 | 다른 체인에 효율적으로 증명할 수 있는 방법을 제공하는 블록체인간 83 | 통신(Inter-Blockchain Communicaion, 줄여서 IBC)을 도입했습니다. 84 | 하나의 블록체인이 다른 블록체인으로부터 메시지를 받아들이면, 85 | 실수를 바로잡기 위해서 양쪽 체인을 역전시키는 것이 쉽지도 않고 86 | 바람직하지도 않기 때문에, IBC에서는 최종성(finality)이 대단히 중요합니다. 87 | 88 | 블록체인 하나가 비트코인 예치금을 자신의 체인 안에 받아들이는 시도를 하는 89 | 순간을 상상해보세요. 사용자는 모든 비트코인 블록 헤더와 자신이 참조하는 90 | 블록 위에 이어서 만들어진 6개의 블록 헤더를 제출합니다. 이 증거에 따라서 91 | 블록체인은 비가역적인 액션을 실행합니다. 이제 비트코인이 포크되고, 92 | 증거에 포함된 블록 6개가 undo되었다고 상상해볼까요? 이 블록체인은 이전에 93 | 승인된 비트코인 트랜잭션을 불합격 처리할 수도 없고 비트코인 트랜잭션이 포함된 94 | 자신의 블록을 역전시킬 수도 없습니다. 그러한 사고가 발생하면 수동으로 95 | 조정하고/조정하거나 하드 포크(hard fork)가 필요합니다. 그러한 96 | 하드 포크/수동 조정은 연결된 모든 체인을 통해서 파문을 일으킬 것입니다. 97 | 이것은 실행 가능한 옵션이 아닙니다. 98 | 99 | 모든 비(非)-비잔틴 상황에서 안전하고 믿을 수 있는 IBC를 가능하게끔, 100 | DPOS 3.0 + BFT 방식은 마지막-비가역-블록(Last Irreversible Block, 줄여서 LIB) 101 | 계산 방식을 약간 변경합니다. 이 변경을 통해서 우리는 블록 프로듀서 노드의 102 | 최소 1/3이 의도적으로 악한 마음을 품지 않는다면 두 노드가 LIB와 관련하여 103 | 서로 다른 결론을 내리는 게 불가능하다는 점을 증명할 수 있습니다. 104 | 뿐만 아니라, 심지어 노드 하나의 악의적인 행동도 증명할 수 있습니다. 105 | 106 | DPOS의 핵심 아이디어는 생성된 블록 각각이 모든 이전 블록에 대한 투표라는 107 | 점입니다. 이 모델을 사용하면, 프로듀서 2/3 이상이 특정 블록 하나를 기반으로 108 | 블록을 만들어왔다면 해당 블록이 2/3 이상의 투표를 얻은 것입니다. 109 | 이 상황은, 비(非)-비잔틴 블록 프로듀서들이 다른 시점에 다른 포크에서 110 | 블록을 작성할 가능성이 있다는 점을 제외한다면, 이론상 적절하게 들립니다. 111 | 만약 비(非)-비잔틴 블록 프로듀서들이 다른 포크에서 블록을 생산한다면, 112 | 포크된 각 체인에 나타나는 동일한 블록 넘버에 대해 결국 간접적으로 113 | 상충하는 표를 던지게 되는 상황에 처하게 됩니다. 114 | 115 | 블록 프로듀서 A, B, C가 참여하는 네트워크 하나를 생각해봅시다. 이 네트워크에 116 | 문제가 하나 발생한 탓에 두 개의 블록 프로듀서가 짧은 시간 동안 통신이 117 | 두절되었고, 시각 T에 블록 프로듀서 A는 블록 N을 생성하고 시각 T+1에 118 | 블록 프로듀서 B는 블록 N을 생성했다고 해봅시다. 이제 블록 프로듀서 C는 119 | 블록 프로듀서 B가 시각 T+1에 생성한 블록 N에 이어서 시각 T+2에 블록 N+1을 120 | 생성하면서 동점(tie)를 깼다고 해봅시다. 이런 상황이 발생하고 프로듀서 A가 121 | 프로듀서 C의 블록 N+1의 존재를 알게되면, 프로듀서 A는 더 긴 포크를 따라 122 | 전환할 것입니다. 프로듀서 A가 블록을 생성할 차례가 오면, 프로듀서 A는 123 | 자신이 이전에 생성한 블록 N과 상충하는 프로듀서 B의 블록 N을 간접적으로 124 | 승인할 것입니다. 125 | 126 | DPOS 2.0 규칙에 따르면, 프로듀서 A가 만든 블록 N은 프로듀서 A, B, C로부터 127 | 투표를 받았을 것이며 그러므로 (2/3 + 1) 승인으로 인해 비가역 상태가 128 | 되었을 것입니다. DPOS 3.0에서 우리는 프로듀서 A가 자신이 다른(alternative) 129 | 블록 N을 승인했다고 공개하도록 요구합니다. 이와 같은 정보 공개 때문에 130 | 네트워크는 프로듀서 B가 만든 블록 N이 받은 투표수에서 프로듀서 A의 블록 131 | 하나를 뺄 것입니다. 그러면 프로듀서 B의 블록은 단 2개의 투표만 받은 셈이 되고, 132 | 이건 비가역 상태에 도달하기엔 충분하지 않습니다. 133 | 134 | DPOS 3.0 규칙에 따르면, 프로듀서 B가 만든 블록 N은 직접적인 비가역 상태에 135 | 절대로 도달할 수 없습니다. 왜냐하면 비가역 상태에 도달하기 위해서는 136 | 프로듀서 A, B, C로부터 2/3 + 1 만큼의 투표를 얻어야 하고 프로듀서 A는 137 | 다른(alternative) 블록 N에 투표하기 때문입니다. 대신 프로듀서 A가 블록 N+2를 138 | 작성하고 프로듀서 B가 블록 N+2를 작성하면, 블록 N+1은 비가역 상태가 됩니다. 139 | 이렇게 해서 블록 N+1은 2/3 + 1에 도달하는 데 필요한 투표 3개를 확보합니다. 140 | 프로듀서 C가 만든 블록 N+1이 비가역 상태에 도달하면, 프로듀서 B가 만든 141 | 블록 N도 비가역 상태로 간주됩니다. 142 | 143 | 이 알고리즘을 구현하기 위해 각 블록 프로듀서는 임의의 포크에서 이전에 승인한 144 | 가장 높은 블록 번호 (H)를 블록 헤더에 집어넣습니다. 블록 N이 적용될 때, 145 | [H+1, N] 범위에 있는 블록에 대해서만 비가역성에 대한 투표를 받게 됩니다. 146 | 147 | 겹치는 범위에 있는 블록에 서명하는 모든 프로듀서는 비잔틴(배반자)으로 간주되며 148 | 잘못된 행동을 드러내는 암호 증명을 생성하게 됩니다. 149 | 150 | 이 정보를 이용하면, 임의의 블록 높이의 동일한 블록 높이를 가진 151 | 두 개의 서로 다른 블록이 2/3 + 1 만큼의 투표를 얻기 위해서는 최소 1/3의 152 | 블록 프로듀서가 상충하는 범위의 블록에 서명했다는 게 틀림없음을 증명하는 153 | 간단한 증거를 생성할 수 있습니다. 이런 상황은, 각각 1/3 크기의 선량한 프로듀서 154 | 두 그룹이 두 개의 다른(alternative) 블록을 생성하게 되는 어쩔 수 없는(honest) 155 | 네트워크 분할이 발생했고 나쁜 1/3으로 구성된 그룹이 양쪽 포크 모두에 156 | 서명하는 경우입니다. 실제로 접속이 잘 살아있는 네트워크 환경에서 157 | 비가역 상태로 간주되는 두 개의 다른 블록을 만들기 위해선 2/3 +1 만큼의 158 | 악의적인 프로듀서가 있어야 합니다. 159 | 160 | 이런 규칙 아래에서 프로듀서가 비잔틴(배반 행위)를 드러내는 서명을 하는 161 | 경우는 이제 두 가지 경우가 존재합니다. 162 | 163 | 1. 직접 또는 간접적으로, 동일한 블록 번호를 가진 두 개의 블록에 서명하는 경우 164 | 2. 동일한 블록 시간에 생성된 두 개의 블록에 서명하는 경우 165 | 166 | 기본 소프트웨어를 실행하는 정직한 노드는 이러한 일을 절대로 하지 않을 것입니다. 167 | 그러므로 나쁜 관계자 모두를 실패한 시도까지 처벌하기가 쉽습니다. 168 | 169 | ## Credits 170 | 171 | 이 문제의 해결책은 블록원 팀의 몇몇 다른 멤버들과 Bart, Arhag과 제(댄 라리머)가 172 | 협업을 통해서 찾아냈습니다. 173 | 174 | ## 번역 정보 175 | 176 | * 원문 : https://github.com/EOSIO/eos/issues/2718 177 | * 원문 작성자 : Daniel Larimer (bytemaster) 178 | * 원문 작성 시점 : 한국표준시 2018년 5월 3일 12시 35분 179 | -------------------------------------------------------------------------------- /ko/translations/EOSIO_Dawn_4_2.md: -------------------------------------------------------------------------------- 1 | # EOSIO Dawn 4.2 출시 2 | 3 | EOSIO 버전 1.0이 바로 코 앞에 있는 상황에서, 오늘 우리는 EOSIO 소프트웨어의 Dawn 4.2 릴리즈를 태그했습니다. 몇몇 작은 기능이 코드에 추가되었지만, 아래에서 볼 수 있는 내용과 같이, 우리는 버그 픽스와 안정성 개선에 집중해오고 있습니다. 4 | 5 | ## 중요한 변경 사항 6 | 7 | **EOSIO.SYSTEM 자금 분리** 8 | 9 | 시스템 자금 할당이 확실한지 확인하기 위해서, 시스템 자금을 다음과 같이 분리하기로 결정했습니다. 10 | 11 | * 모든 램 구매와 판매에 1%의 수수료를 구현함 12 | * 사용자가 지불하는 모든 램 거래 수수료는 `eosio.ramfee`로 지불됨 13 | * 램 판매의 모든 수익은 `eosio.ram`으로부터 보냄 14 | * 지분참여한(staked) 토큰 전부는 `eosio.stake`로 보냄 15 | * 지분참여가 해제된(unstaked) 토큰 전부는 `eosio.stake`로부터 보냄 16 | * 계정 이름 경매 수익의 전부는 `eosio.names`로 보냄 17 | * 할당되지 않은 인플레이션(통화 증가량)은 `eosio.saving`로 보냄 18 | * 프로듀서 블록 생성 보상(producer block pay)은 `eosio.bpay`로 보냄 19 | * 프로듀서 투표 획득 보상(producer vote pay)은 `eosio.vpay`로 보냄 20 | 21 | 자세한 사항은 `contracts/eosio.system/producer_pay.cpp`를 확인하세요. 22 | 23 | **Chain Plugin** 24 | 25 | 디스크에 저장되는 데이터의 몇몇에 대해 그리고 노드를 동작시키는데 사용하는 사용자에게 노출된 옵션 몇몇에 대해 약간의 혼란이 커뮤니티에 있다는 것을 지켜봤습니다. 그래서 다음 업데이트를 통해서 보다 분명하게 설명하려고 합니다. 26 | 27 | 우리는 "shared_mem" 디렉토리를 "state"라고 이름을 바꾸었고, 플러그인 옵션 몇 개를 변경했습니다. 28 | 29 | * "--block-log-dir" 옵션을 "--blocks-dir"로 바꿈 30 | * "--checkpoint" 의 단축 옵션이었던 "-c" 를 제거함 31 | * "--shared-memory-size-mb" 옵션을 "--chain-state-db-size-mb"로 바꿈 32 | * "--reversible-blocks-db-size-mb" 옵션을 추가해서 가역(reversible) 블록 DB의 초기값을 변경할 수 있도록 함 33 | * "--resync-blockchain" 옵션을 "--delete-all-blocks"로 바꾸고, 이 옵션의 사용을 지양하도록 함 34 | * "--contracts-console" 옵션은 컨트랙트 출력을 콘솔에 나오도록 하고 config.ini에서 설정 가능함 35 | * "--hard-replay-blockchain" 옵션을 추가해서 블록 로그와 데이터를 백업 디렉토리에 옮길 수 있게 하고, 새로운 "blocks.log"를 만들어서 마치 "--replay-blockchain" 옵션이 사용된 것처럼 이어서 진행하게 함 36 | * "--force-all-checks" 옵션을 추가해서 수신한 트랜잭션, 인라인 액션, 컨트랙트 내부에서 생성된 트랜잭션에 대해 강제로 권한 승인 여부를 검증하게 함 37 | * "--fix-reversible-blocks" 옵션을 추가해서 nodeos로 하여금 "가역적인" 블록 데이터베이스로부터 복구를 시도하고 이어서 바로 종료(exit)하게 함 38 | * "--hard-replay-blockchain" 옵션의 동작을 업데이트해서, "가역적인" 블록 데이터베이스로부터, 이 데이터베이스가 지저분한 상태(dirty state)로 남아있다고 해도, 최대한 많은 가역 블록을 복구하고 replay하도록 시도함 39 | * "--genesis-json" 옵션을 추가해서 genesis state를 읽어올 파일을 명시함 40 | * "--genesis-timestamp" 옵션을 추가해서 Genesis State 파일의 초기 타임스탬프를 덮어씀 41 | * "--print-genesis-json" 옵션을 추가해서 blocks.log로부터 genesis state 정보를 JSON 형태로 추출해서 콘솔에 출력함 42 | * "--extract-genesis-json" 옵션을 추가해서 blocks.log로부터 genesis state 정보를 JSON 형태로 추출한 후 명시한 파일에 저장함 43 | 44 | **Producer Plugin** 45 | 46 | 우리는 커맨드 라인 옵션 하나 (--max-irreversible-block-age)를 추가했고, 이 옵션은 마지막 비가역 블록(last irreversible block) 시간이 N초보다 오래되면 노드로 하여금 자동적으로 블록 생산을 중단하게 만듭니다. LIB 시간이 N초보다 오래되는 상황은 체인이 계속 생성되기에는 블록을 승인하는 프로듀서가 충분하지 않다는 점을 암시합니다. 이 옵션은, 충분한 수의 프로듀서가 네트워크에 다시 합류하게 되었을 때 블록 생성을 재개하기 위해 합리화가 필요한 과도한 수의 블럭을 생성하지 못하게 막습니다. 47 | 48 | 우리는 필요에 따라 노드가 블록 생성을 잠깐 멈출 수 있는 기능을 추가했습니다. 이 기능의 목적은, 나쁜 상황이 발생하는 동안 체인 replay/resync 등의 시간 소모가 생기는 가변성 없이 프로듀서가 체인 생산을 잠시멈춤/재개하는 조정이 가능하도록 하기 위해서입니다. 49 | 50 | 참고로 다음과 같은 RPC API가 있습니다. 51 | * POST /v1/producer/pause - 블록 생산 일시 정지 52 | * POST /v1/producer/resume - 일시 정지된 블록 생산을 재개 53 | * POST /v1/producer/paused - 현재 노드가 일시 정지된 상태인지 아닌지에 따라 true/false를 돌려줌 54 | 55 | **Genesis JSON 파일은 더이상 기본으로 생성되지 않음** 56 | 57 | `genesis.json`은 더이상 config 디렉토리에 있을 것이라고 예상되지 않고, 자동으로 생성되지 않을 것입니다. 아래는 앞으로 실행해야 할 명령어입니다. 58 | 59 | `nodeos --extract-genesis-json ` 60 | 61 | 파일 내용을 변경하고, 타임스탬프를 바꾸고, 초기 프로듀서 키와 보통 변경하는 다른 파라미터를 바꾸세요. 과거에 실행했던 것처럼 파일을 공유해서 사용하세요. 62 | 63 | `nodeos --delete-all-blocks --genesis-json ` 명령으로 (모든 노드에서) 새로운 블록체인을 초기화합니다. 64 | 65 | 이어지는 론칭 과정에서, `--genesis-json` 파일을 명시하지 마십시오. 그러면 nodeos는 블록 로그로부터 genesis state를 가져올 것입니다. 그리고 물론 `--delete-all-block` 옵션도 사용하지 마세요. 66 | 67 | nodeos가 깨끗하게 재시작하지 못하면, `--replay-blockchain`를 사용하시고, 만약 그래도 제대로 동작하지 않는다면 `--hard-replay-blockchain`를 사용하세요. 68 | 69 | resync 옵션은 실제로 동작하는 내용을 반영하기 위해서 `--delete-all-blocks`로 변경되었습니다. 70 | 71 | **BIOS Boot Process 튜토리얼 업데이트** 72 | 73 | 우리는 프로듀서가 보상을 청구하는 부분, 위임(프록시) 투표, `eosio` 계정 만료(resign), 프로듀서가 `eosio.msig` 컨트랙트를 이용해서 `eosio.system` 컨트랙트를 교체하는 과정과 몇몇 버그 수정 등을 포함해서 BIOS Boot 튜토리얼 내용을 개선했습니다. 튜토리얼에서 설명하는 파일들을 "programs" 디렉토리에서 새로운 "tutorials" 디렉토리로 옮겼다는 점을 참고해주세요. 74 | 75 | **다른 수정 사항** 76 | 77 | 지난주 "Quality Name Distribution & Namespaces" ([#3189](https://github.com/eoseoul/docs/blob/master/ko/translations/EOSIO_Dawn_4_1.md#%EA%B9%83%ED%97%99-%EC%9D%B4%EC%8A%88-3189)) 제안에서 언급한 내용과 같이, 계정 이름 경매가 구현되었고, 네트워크가 언락된 (15%의 투표) 이후 2주 동안 활성화되지 않을 것입니다. 78 | 79 | 프로듀서는 앞으로 RAM 크기를 증가시킬 수만 있고 절대로 줄일 수 없습니다. 블록 프로듀서에 의한 램 시장의 잠재적인 조작을 방지하기 위해서 그렇게 구현했습니다. 80 | 81 | Boost 라이브러리 버전을 1.66에서 1.67로 업데이트했습니다. 82 | 83 | "data/shared_mem" 디렉토리가 "data/state"로 변경되었습니다. 84 | 85 | config.ini의 옵션 중 "block-log-dir"는 "blocks-dir"로 변경되었습니다. 86 | 87 | 새로운 활성 프로듀서 스케줄을 제청한다(propose)는 함수의 의도를 보다 정확히 반영하기 위해서, "set_active_producers" 기본 메소드를 "set_proposed_producers"로 변경했습니다. 88 | 89 | 지난주에 토큰 심볼 변경에 따라서, Dockerfile에 코어 토큰 심볼을 명시할 수 있는 기능을 추가했습니다. 우리는 또한 Docker 빌더 이미지로 Ubuntu 18.04 LTS로 바꿨습니다. 90 | 91 | 체인을 초기화할 때 설정한 genesis state의 SHA256 다이제스트가 이제 체인 ID입니다. `--genesis-json`을 사용해서 덮어쓰지 않으면, nodeos는 소프트웨어의 genesis state 기본값을 사용할 것입니다. genesis state 기본값의 초기 root key는 EOSIO_ROOT_KEY CMake 옵션을 이용해서 변경할 수 있습니다. 92 | 93 | 블록을 생성하는 프로듀서가 다음 프로듀서로 생성 순서를 넘길 때(handoff), 특히 프로듀서 사이의 네트워크 레이턴시가 높은 경우, 작은 포크(mini fork)가 예상치 않게 높은 빈도로 발생한다는 사실을 발견했고, 수정했습니다. 94 | 95 | 블록 프로듀서는 시스템 컨트랙트에 새로 추가된 "setparams" 액션을 이용해서 블록체인 파라미터를 이제 변경할 수 있게 되었습니다. 96 | 97 | 몇몇 테스트넷에서 프로듀서 투표로 비활성화되는 유예 시간이 너무 빡빡하다는 점에 주목했습니다. 유예 시간이 대략 4분에서 7시간으로 변경되었습니다. 비활성화와 관련된 몇몇 코너 케이스 역시 수정되었습니다. 98 | 99 | 우리는 명시된 필터 규칙에 맞는 액션만 추적하도록 history 플러그인을 수정해서 history 플러그인의 메모리 사용량을 크게 줄였습니다. 모든 액션을 추적하면 shared_mem을 채우기 쉽기 때문에, 이제 모든 액션을 추적하는 방법은 없습니다. 100 | 101 | 우리는 비정상적이고 다양한 ABI 정의를 이용한 무한 재귀 버그를 발견했고, 고쳤습니다. 102 | 103 | 우리는 블록 프로듀서가 블록 생성 스케줄에서 적절하지 않게 제외되지 않도록 프로듀서 비활성화 로직을 변경했습니다. 우리는 이제 각각의 프로듀서 정보인 "time_became_active" 값을, 처음으로 블록 프로듀서로 선출되는 시점에서만 업데이트하지 않고, 프로듀서로 선출될 때마다 업데이트합니다. 만약 처음으로 선출되었거나 마지막으로 선출된지 하루 이상이 지났다면, 우리는 "last_produced_block_time"을 체크하지 않으며 비활성화시키지 않습니다. 그렇게 하지 않으면 로직은 옛날과 같이 동작할 것입니다. 이런 방법으로, 투표에서 밀려난 탓에 블록을 생산하지 못한 프로듀서를 불리하게 만들지 않습니다. 104 | 105 | ## 패트로니오스 - Patroneos 106 | 107 | 우리는 지난주에 패트로니오스를 소개했고, 이제 EOSIO 깃헙 저장소 https://github.com/EOSIO/patroneos 를 통해서 커뮤니티에 제공합니다. 108 | 109 | 상기시키는 차원에서 다시 말씀드리자면, 패트로니오스는 기초적인 서비스 거부 공격(Denial of Service) 경로를 방어하기 위해 설계된 보호 계층을 EOSIO 노드에 제공합니다. 110 | 111 | ## 깃헙에 올라온 Dawn 4.2 112 | 113 | EOSIO Dawn 4.2가 깃헙에 올라와 있습니다.(https://github.com/EOSIO/eos/releases/tag/dawn-v4.2.0) 이를 이용해서 개발자들과 블록 프로듀서 출마자들은 애플리케이션과 네트워크를 계속 테스트할 수 있습니다.. 114 | 115 | ## 커뮤니티 지원 116 | 117 | 상기하는 차원에서 다시 말씀드리지만, 우리는 커뮤니티로부터 피드백을 듣는 게 참 좋고, EOSIO를 성공적으로 동작시키도록 커뮤니티를 돕는 데 헌신하고 있습니다. 우리의 EOSIO 스택 익스체인지 (https://eosio.stackexchange.com/) Beta는 잘 성장하고 있고, 이 소프트웨어를 사용하는 방법에 대한 질문을 스택 익스체인지에 올려주시길 장려합니다. 아래 정보를 포함시켜서 깃헙에서 발견할 지도 모르는 잠재적인 버그를 계속 리포트해주시길 바랍니다. 118 | 119 | * Testnet: (옮긴이 주: 이슈를 발견한 테스트넷이 어디인지) 120 | * EOSIO git version: `nodeos -v output` 결과 문자열 121 | * config.ini: 사용하고 있는 `config.ini` 파일을 첨부해주세요 122 | * genesis.json: 사용하고 있는 `genesis.json` 파일을 첨부해주세요 123 | * Command line: 사용한 `nodeos` 전체 커맨드 명령어 124 | * Console output: 확인하고 있는 에러와 관련된 콘솔 디버그 출력값 (짧으면 아예 이슈 설명에 붙여넣어도 좋습니다) 125 | 126 | ## 추후 릴리즈 127 | 128 | 우리는 6월 1일에 EOSIO 1.0을 예정하고 있습니다. 깃헙의 버전 1.0 마일스톤(https://github.com/EOSIO/eos/milestone/10) 을 지켜보시면 다음 몇 주간 우리가 집중해서 작업하고 있는 이슈들을 따라잡으실 수 있습니다. 129 | 130 | 131 | ## 번역 정보 132 | 133 | * 원문 : https://github.com/EOSIO/eos/releases/tag/dawn-v4.2.0 134 | * 원문 첫 게시 시점 : 2018년 5월 26일 9시 44분 KST 135 | -------------------------------------------------------------------------------- /ko/translations/Dawn_of_EOS.md: -------------------------------------------------------------------------------- 1 | # The Dawn of EOS.IO 2 | 3 | [EOS.IO 기술 백서](https://github.com/eoseoul/docs/blob/master/ko/translations/TechnicalWhitePaperV2.md)에서 우리는 블록체인 컴퓨팅의 새로운 시대의 도래로서 EOS.IO 소프트웨어를 제안했습니다. EOS.IO 개발팀은 여름을 열심히 일하면서 보냈습니다. 여름이 끝나고 EOS.IO 소프트웨어의 개발이 일정보다 앞서있습니다. 이제 분산 네트워크 구성과 함께 사용할 수 있습니다. 흥미진진한 EOS.IO 소프트웨어 개발에 대한 리포트가 많습니다. 끝까지 읽으십시오! 4 | 5 | ## 성과의 증거 6 | 이제 EOS.IO 소프트웨어를 분산 네트워크 구성에서 사용할 수 있으므로 성능을 벤치마크할 수 있습니다. 우리의 내부 테스트에 따르면 이 소프트웨어는 현재 다중 노드 네트워크에서 초당 10,000 개의 단일-스레드 트랜잭션을 유지할 수 있습니다. 이를 통해 100 개 이상의 CPU 코어가 있는 시스템에서 1 백만 TPS 이상을 지원할 수 있습니다. 7 | 8 | ### 디자인 개선 9 | 개발자들은 최근의 소프트웨어 아키텍처 개선으로 인해 서로 통신하는 병렬 애플리케이션들 보다 쉽게 ​​만들 수 있어서 기쁠 것 입니다. 10 | 11 | #### 공유 데이터베이스 액세스 12 | 이제 하나의 애플리케이션이 복잡한 비동기 통신 없이 다른 애플리케이션들의 데이터베이스 상태를 읽을 수 있게 되었습니다. 각 트랜잭션이 읽기 또는 쓰기 액세스 권한이 필요한 범위 (데이터 범위, scope)를 선언할 수 있도록 함으로써, 병렬 실행 기능을 유지하면서도 이 작업(비동기 통신 없이 다른 애플리케이션의 데이터베이스 상태를 읽음)을 수행할 수 있습니다. 블록 프로듀서는 데이터 충돌이 발생하지 않도록 트랜잭션을 스케줄링해야 합니다. 13 | 14 | #### 애플리케이션 데이터의 사용자 로컬 저장소 15 | 애플리케이션들은 계정에서 읽기 액세스를 지원할 뿐만 아니라 이제 다른 계정에 데이터를 저장할 수 있습니다. 이는 currency contact가 자체 scope가 아닌 개별 사용자 계정에 잔액을 저장할 수 있음을 의미합니다. Alice에서 Bob으로의 transfer는 Alice와 Bob의 데이터 scope에 대한 읽기/쓰기 액세스만 필요하며 currency contract의 scope에는 영향을 미치지 않습니다. 이로 인해 많은 종류의 애플리케이션들이 쉽게 병렬 처리되고 단일 스레드 처리량 한도를 초과하는 currency transfer를 처리할 수 ​​있습니다. 우리가 알고 있는 한, 다른 어떤 블록체인 디자인도 병렬 소프트웨어 아키텍처를 개발하기 위한 확장 가능하고 쉬운 방법을 지원하지 않습니다. 16 | 17 | #### 인라인 메시지 전달 (Inline Message Passing) 18 | 이제는 다른 애플리케이션에 메시지를 훨씬 쉽게 보내고 확실히 수신되고 유효성이 검증된다는 점을 이전보다 훨씬 쉽게 알 수 있습니다. 애플리케이션은 현재 트랜잭션의 끝에 덧붙일 수 있는 추가 메시지를 여러 개 생성할 수 있습니다. 이렇게 생성된 메시지가 동일한 읽기/쓰기 scope를 공유하고 할당된 시간 내에 실행할 수 있는 한, 메시지가 전달되거나 전체 트랜잭션을 되돌릴 수 있음을 보증합니다. 19 | 20 | 이 접근 방식은 다른 플랫폼에서 사용되는 동기식 접근 방식과 다릅니다. 스레드가 return할 때까지 실행을 차단하는 동기적 메시지 전달은 예상치 못한 재진입(reentrancy)가 발생할 가능성이 있습니다. 이런 Reentrancy는 개발자가 동기식 호출을 하기 전에 컨트랙트가 일관된 상태에 있음을 보장하기 어렵기 때문에 수많은 버그와 공격의 원인이 됩니다. 인라인 메시지 전달을 사용하면 현재 트랜잭션 핸들러가 끝날 때까지 실행이 지연되므로, 개발자는 메시지를 전달해놓고, 성공한 것처럼 진행할 수 있습니다. 실패할 경우 유해한 부작용 없이 전체 트랜잭션이 되돌려집니다. 즉, 메시지 핸들러가 불일치(incinsistent) 상태로 호출되지 않습니다. 21 | 22 | #### 지연된 메시지 전달 (Deferred Message Passing) 23 | 가끔 메시지가 유효한지 또는 현재 트랜잭션과 함께 인라인 메시지를 실행할 충분한 시간이 시간상 남아 있는지 여부를 알 수 없는 경우가 있습니다. 다른 경우에는 현재 트랜잭션의 scope를 벗어나는 데이터에 액세스하는 메시지를 보내야 합니다. 이 상황에서 애플리케이션은 블록 프로듀서에게 다음 주기(cycle) 또는 이후 블록에서 전달할 메시지를 예약하도록 요청할 수 있습니다. 유효하다면 애플리케이션은 예약 신청에 대해 알림을 받을 수 있고, 그렇지 않은 경우 일정이 잡히지 않으며 애플리케이션은 시간 초과(timeout) 후 정리할 수 있습니다. 24 | 25 | #### 무제한 수평 확장 26 | EOS.IO 소프트웨어의 최신 디자인 개선 사항은 개발자들에게 높은 단일-기계 성능을 제공합니다. 비즈니스 로직은 더 복잡한 비동기식 아키텍처를 필요로 하기 전에 초당 백만 건의 트랜잭션까지 확장할 수 있습니다. 27 | 28 | 그렇긴 하지만, EOS.IO 소프트웨어는 상태를 공유할 필요가 없는 애플리케이션 그룹간에 비동기 메시지 전달을 계속 지원할 것입니다. 비동기 메시지 전달에는 많은 이점이 있습니다 (예 : 쉽게는 클러스터 지원). 하지만 이러한 이점은 개발 복잡성이 커지는 단점을 발생시키며 EOS.IO 소프트웨어는 수백만 TPS를 필요로 하는 기업을 위해 이 기능을 지원하지만 그렇지 않은 기업을 위해 간소화된 접근 방식을 제공합니다. 29 | 30 | ## 차세대 네트워크 토폴로지 31 | **EOS.IO 소프트웨어는 블록 프로듀서가 고성능 분산 인프라를 서비스로 제공할 수 있도록 설계되었습니다.** 애플리케이션 개발자들은 트랜잭션을 모아서 처리하는 일군의 블록 프로듀서가 필요할 뿐만 아니라 API 노드, Seed 노드, 데이터베이스 색인, 저장소 및 호스팅이 필요합니다. 32 | 33 | 고성능 블록체인은 기존 블록체인과 매우 다른 요구 사항을 가진 고성능 네트워크 아키텍처를 요구합니다. 백만 TPS에서 각 노드는 커넥션당 초당 수백 메가바이트를 처리해야 합니다. 이는 대용량 데이터센터에서는 사소하지만, 개인 사용자에게는 상상할 수 없습니다. 34 | 35 | 또한 고성능 블록체인은 블록체인의 다른 하위 집합을 실행하는 이기종 노드(heterogeneous nodes)로 구성되며 트랜잭션 기록을 정리할(prune) 수 있습니다. 이것은 모든 노드가 동일하고 전체 이력을 보유한 이전 블록체인 시스템과 크게 달라진 점입니다. 36 | 37 | *전통적인 블록체인은* 메쉬 네트워크의 형태로 *랜덤하게 연결된 노드의* 동적 집합으로 구성됩니다. 이 블록체인은 제한된 대역폭을 가진 가정 사용자를 대상으로 하며 홈 라우터 (NAT)를 가로지르고 네트워크에 노드를 동적으로 추가하도록 설계되었습니다. 우리가 관찰한 바에 따르면 이런 아키텍처는 고성능 블록체인 인프라에 적합하지 않다고 생각합니다. 38 | 39 | *EOS.IO 소프트웨어는* *모든 노드가 의도적으로 서로 연결하고 있다고* 가정합니다. 노드 운영자는 네트워크 토폴로지가 안전하고, 잘 계획되며, 효율적으로 동작하도록 협력합니다. 이를 통해 블록 프로듀서는 서로 직접 (그리고 secure한) 연결을 구축하고, 공격자가 셧다운시킬 노드를 찾기 위해 전체 네트워크 토폴로지를 스캐닝하지 못하도록 합니다. 40 | 41 | 블록 프로듀서는 누구나 원하는 트랜잭션 데이터의 하위 집합에 연결하고 구독할 수 있도록 public endpoint를 호스팅합니다. 이는 블록 프로듀서가 아닌 주체가 운영하는 full node에 대한 대역폭 요구 사항을 최소화합니다. 어느 블록 프로듀서 하나를 신뢰하지 않는 노드는 여러 소스에 가입할 수도 있고 블록 프로듀서 전체 2/3의 승인(confirmation)을 기다릴 수도 있습니다 (약 45 초). 42 | 43 | 이 아키텍처의 이점은 새로운 노드가 블록 프로듀서가 제공하는 높은 대역폭 인프라를 통해 매우 빠른 속도로 연결하고 동기화 할 수 있다는 것입니다. 또한 이 아키텍처는 효율성이 낮은 양방향 프로토콜보다는 효율적인 단방향 스트리밍이 용이하게끔 설계되었습니다. 44 | 45 | *큰 그림으로 보면, 블록 프로듀서는 EOS.IO 소프트웨어로 구동되는 새로운 인터넷 백본을 운영 할 것입니다.* 블록 프로듀서는 대륙간 전용회선을 사용하는 Tier-1 인터넷 서비스 제공자와 같을 것입니다. 블록 프로듀서는 Tier-2 가입자가 연결할 수 있는 데이터센터를 운영할 것입니다. Tier-2에는 full node 또는 partial 노드 또는 대규모 애플리케이션을 실행하려는 사용자들이 있을 것입니다. 예를 들어 블록탐색기(block explorer), 웹 지갑 및 암호화폐 거래소와 같은 서비스는 블록 프로듀서의 Tier-2 가입자가 될 것입니다. 46 | 47 | 우리는 의도적인 협력 네트워크를 구축하는 이와 같은 아키텍처가 블록 프로듀서들에게 암호화폐 산업에서 고유한 서비스 품질을 제공할 수 있다고 생각합니다. 48 | 49 | ## 앞으로의 갈 길 50 | 올해 9월에 block.one은 EOS.IO Dawn 1.0을 출시할 예정입니다. 이 제품은 충분히 안정적이어야 하며 누구나 자신의 애플리케이션을 구축하고 배포할 수 있는 자체 테스트 네트워크를 시작할 수 있을 만큼 충분히 문서화되어야 합니다. EOS.IO Dawn 1.0은 EOS.IO SDK (소프트웨어 개발 킷)의 첫 번째 프리릴리즈입니다. 51 | 52 | [EOS.IO 로드맵](https://github.com/EOSIO/Documentation/blob/master/Roadmap.md)을 지켜본 사람들은 *우리가 일정보다 앞섰다는 것을* 기쁘게 생각할 것입니다. 1단계 : 독립 실행형 노드, native contracts, 가상 머신 API, RPC 인터페이스, 명령 줄 도구 (eosc) 및 기본 개발자 설명서 등이 포함된 최소 실행 가능 테스트 환경이 완성되었습니다. 우리는 "EOS.IO Dawn 1.0"로 태그된 릴리즈를 만들 것입니다. 이 단계는 9월 22일로 끝나는 2017년 여름에 완료될 예정이었습니다. 53 | 54 | 우리는 이미 **최소한의 실행 가능한 테스트 네트워크인 2단계의** 절반을 완료했습니다. 이 단계는 2017년 가을에 완료 될 예정이며 작동하는 네트워킹 코드, 가상 머신 샌드박싱, 리소스 사용 및 속도 제한, genesis 가져오기 및 블록체인 간 통신을 포함합니다. 현재 우리는 작동하는 분산 네트워크와 가상 머신 샌드박싱을 이미 갖추고 있습니다. 우리는 2단계를 일정대로 완료할 것으로 확신합니다. 55 | 56 | EOS.IO Dawn 2.0은 차기 주요 프리릴리스로서, 올해 말에 출시될 예정입니다. EOS.IO Dawn 1.0에 없는 몇 가지 중요한 기능이 포함됩니다. 57 | 58 | * 리소스 속도 제한 (스팸/악용 차단) 59 | * 머클 트리 생성 (블록체인간 통신용) 60 | * 업그레이드 관리 및 거버넌스 61 | * 더욱 견고한 SDK 62 | * 기본 인프라 개선 63 | * ERC20 토큰의 스냅샷 예제 64 | 65 | EOS.IO Dawn 2.0의 목표는 라이브 블록체인을 런치할 수 있을 정도로 기능적이어야 한다는 것입니다. 66 | 67 | ## 하나 더... 68 | ## EOS.IO 스토리지! 69 | 사상 최초로, 개발자들은 대역폭과 스토리지 비용을 걱정하거나 서버 자체를 호스팅하지 않고도 분산 애플리케이션 및 웹 인터페이스를 만들고 배포할 수 있습니다. 분산된 YouTube, Soundcloud 및 기타 저장 공간이 많이 필요한 프로젝트와 같은 새롭고 혁신적인 분산된 비즈니스 모델을 구현할 수 있습니다. 70 | 71 | 또한 계산 대역폭 외에도, **native EOS.IO의 소프트웨어 기반 블록체인 토큰 보유자는 이제 IPFS / HTTPS를 통해 무료 클라우드 스토리지,** 호스팅 및 다운로드 대역폭을 사용할 수 있으며, 이렇게 사용해도 토큰을 소모하거나 이체하지 않고 사용할 수 있습니다. 72 | 73 | 이를 위해 블록 프로듀서들은 사용자를 위해 IPFS / HTTPS를 통해 파일을 호스팅하고 다른 사용자가 해당 파일을 다운로드 할 수 있게 할 것입니다. 저장 공간은 블록체인 배출(emissions)을 통해 지불되며(옮긴이 주: '블록체인 배출'이라는 용어로 무엇을 의미하는지 명확하지 않습니다), 소유량에게 비례하여 토큰 보유자에게 제한공급됩니다. EOS.IO 대역폭 모델과 마찬가지로 스토리지는 EOS.IO 소프트웨어 기반 블록체인 토큰 및 토큰 저장 용량을 소비하지 않습니다. 블록 프로듀서의 하드웨어 업그레이드로 시간이 지남에 따라 증가할 것입니다. 74 | 75 | EOS.IO 소프트웨어 스토리지 솔루션은 토큰 없는 사람들을 위한 공용 호스팅도 지원할 수 있습니다. 자세한 내용은 상해와 런던에서 개최되는 블록체인 산업 행사에서 곧 공개될 예정입니다 76 | 77 | ## 면책조항 78 | 79 | 블록원(block.one)은 소프트웨어 기업이며 EOS.IO 소프트웨어를 무료이자 오픈소스 소프트웨어로 작성합니다. 이 소프트웨어는 이 소프트웨어를 도입하는 사용자가 블록체인 또는 위에서 설명한 기능을 갖춘 분산 어플리케이션을 시작할 수 있도록 합니다. 블록원은 EOS.IO 소프트웨어를 기반으로 하는 퍼블륵 블록체인을 론칭하지 않습니다. 제 3자나 커뮤니티나 자신들이 적합하다고 보는 위에서 설명한 기능과/또는 서비스를 제공하여 블록 프로듀서가 되길 원하는 주체들의 단독 책임일 것입니다. 블록원은 임의의 주체가 그러한 기능을 구현하거나 그러한 서비스를 제공하거나 EOS.IO 소프트웨어가 어떤 방식으로든 채택되고 구현된다는 것을 보증하지 않습니다. 80 | 81 | 역사적 사실에 대한 진술 이외에, 블록원의 비즈니스 전략, 계획, 전망, 개발 및 목표에 관한 이 문서의 모든 진술은 미래 예측 진술입니다. 이 진술은 예측일 뿐이며 미래의 사건에 대한 블록원의 현재의 믿음과 기대치를 반영하고 가정에 근거하며 언제든지 위험, 불확실성 및 변경의 영향을 받습니다. 우리는 급변하는 환경에서 사업을 운영합니다. 새로운 위험이 수시로 발생합니다. 이러한 위험과 불확실성을 감안할 때 이러한 미래 예측 진술에 의존하지 않도록 주의해야 합니다. 실제 결과, 실적 또는 이벤트는 미래 예측 진술에 포함된 내용과 실질적으로 다를 수 있습니다. 실제 결과, 실적 또는 이벤트가 미래 예측 진술과 실질적으로 다른 원인이 될 수 있는 요인에는 시장 변동성, 자본, 재원 및 인력의 지속적인 가용성; 제품 수용; 어떤 새로운 제품이나 기술의 상업적 성공; 경쟁; 정부 규제 및 법률; 그리고 일반적인 경제, 시장 또는 사업 조건이 포함되며 이에 제한되지 않습니다. 블록원이 작성한 모든 미래 예측 진술은 진술이 이뤄진 날짜에 대해서만 말하고 블록원은 새로운 정보, 후속 사건 또는 기타 사건의 결과이건 간에 미래 예측 진술을 업데이트하거나 변경할 의무가 없으며 분명히 부인할 의무가 없습니다. 82 | 83 | ## 번역정보 84 | 85 | * 원문 : https://steemit.com/eos/@eosio/the-dawn-of-eos-io 86 | * 원문 작성 시점 : 한국표준시 2017년 9월 3일 -------------------------------------------------------------------------------- /ko/translations/TUTORIAL.md: -------------------------------------------------------------------------------- 1 | ## 컨트랙트 시작하기 2 | 3 | 이 튜토리얼은 로컬 블록체인을 구성하고 스마트 컨트랙트를 테스트하는 방법을 4 | 다룹니다. 이 튜토리얼의 첫 번째 파트는 다음과 같이 구성되어 있습니다. 5 | 6 | - 프라이빗 블록체인 시작하기 7 | - 지갑 만들기 8 | - BIOS 컨트랙트 로딩하기 9 | - 계정 만들기 10 | 11 | 두 번째 파트는 스마트 컨트랙트를 만들고 블록체인에 배포하는 방법을 설명합니다. 12 | 13 | - `eosio.token` 컨트랙트 14 | - 거래소 컨트랙트 15 | - Hello World 컨트랙트 16 | 17 | 이 튜토리얼을 진행하기 위해서는 EOSIO 소프트웨어가 설치되어 있어야 하고 18 | `nodeos`와 `cleos`가 PATH 환경변수에 등록된 디렉토리에 설치되어 있어야 합니다. 19 | 20 | (역자 주: `eosio`를 빌드하면 build/programs 디렉토리 아래에 21 | `nodeos`와 `cleos` 디렉토리 아래 실행 바이너리가 있습니다. 22 | 상대 경로를 사용해도 무방합니다.) 23 | 24 | 25 | ## 프라이빗 블록체인 시작하기 26 | 27 | 다음 한 줄의 명령어로 하나의 node로만 실행되는 프라이빗 블록체인을 28 | 만들 수 있습니다. 29 | 30 | ``` 31 | $ nodeos -e -p eosio --plugin eosio::chain_api_plugin --plugin eosio::history_api_plugin 32 | ... 33 | eosio generated block 046b9984... #101527 @ 2018-04-01T14:24:58.000 with 0 trxs 34 | eosio generated block 5e527ee2... #101528 @ 2018-04-01T14:24:58.500 with 0 trxs 35 | 36 | ``` 37 | 38 | 명령어 가장 앞쪽의 `nodeos`는 node를 실행합니다. 이 명령어는 튜토리얼 진행에 39 | 필요한 두 가지 플래그를 사용하고, 세 가지 플러그인을 로딩합니다. 40 | 위 명령어가 문제없이 실행이 되었다면 0.5초마다 블록이 생성되는 로그 메시지를 41 | 확인할 수 있습니다. 42 | 43 | ``` 44 | ... 45 | 3165501ms thread-0 producer_plugin.cpp:944 produce_block ] Produced block 00000a4c898956e0... #2636 @ 2018-05-25T16:52:45.500 signed by eosio [trxs: 0, lib: 2635, confirmed: 0] 46 | 3166004ms thread-0 producer_plugin.cpp:944 produce_block ] Produced block 00000a4d2d4a5893... #2637 @ 2018-05-25T16:52:46.000 signed by eosio [trxs: 0, lib: 2636, confirmed: 0] 47 | ``` 48 | 49 | 이 로그는 다음 세 가지 정보를 알려줍니다. 1. 방금 만든 블록체인이 라이브 50 | 상태이다. 2. 블록이 잘 생성되고 있다. 3. 블록체인을 사용할 수 있는 상태이다. 51 | 52 | `nodeos` 명령어의 더 많은 정보를 얻으려면 다음 명령어를 사용하세요. 53 | 54 | ``` 55 | nodeos --help 56 | ``` 57 | 58 | ## 지갑 만들기 59 | 60 | 지갑은 블록체인에서 액션을 승인할 때 필요한 비밀키들의 저장소입니다. 61 | 이 키들은 사용자를 위해 생성된 비밀번호를 이용해 암호화된 상태로 디스크에 62 | 저장됩니다. 이 비밀키는 반드시 안전한 패스워드 관리 도구에 저장되어 있어야 63 | 합니다. 64 | 65 | ``` 66 | $ cleos wallet create 67 | Creating wallet: default 68 | Save password to use in the future to unlock this wallet. 69 | Without password imported keys will not be retrievable. 70 | "PW5JuBXoXJ8JHiCTXfXcYuJabjF9f9UNNqHJjqDVY7igVffe3pXub" 71 | ``` 72 | 73 | 간단한 개발 환경의 용도로, 여러분의 지갑은 `nodeos`를 시작할 때 활성화했던 74 | `eosio::wallet_api_plugin`을 통해 로컬 노드에 의해 관리되고 있습니다. 75 | `nodeos`을 실행할 때마다, 지갑 안의 키들을 사용하기 위해선 "잠금 해제" 76 | 과정을 거쳐야 합니다. 77 | 78 | ``` 79 | $ cleos wallet unlock --password PW5JuBXoXJ8JHiCTXfXcYuJabjF9f9UNNqHJjqDVY7igVffe3pXub 80 | Unlocked: default 81 | ``` 82 | 83 | 이렇게 지갑을 잠금 해제했습니다. 다만 비밀번호가 화면에 노출되죠? 실제로 84 | 명령어에 바로 비밀번호를 사용하면 bash 쉘 로그에 남기 때문에 보안상 권장되는 85 | 방식은 아닙니다. 따라서 보통 다음과 같은 방식을 사용합니다. 86 | 87 | ``` 88 | $ cleos wallet unlock 89 | password: 90 | ``` 91 | 92 | 지갑을 사용하지 않을 때는 지갑을 다시 잠그는 것이 보안에 좋습니다. `nodeos`를 종료하지 않으면서 지갑을 잠그려면 다음 명령어를 실행하면 됩니다. 93 | 94 | ``` 95 | $ cleos wallet lock 96 | Locked: default 97 | ``` 98 | 99 | 남은 튜토리얼을 진행하려면 지갑을 잠금 해제한 상태로 두면 됩니다. 100 | 101 | ## BIOS 컨트랙트 불러오기 102 | 103 | 이제 지갑에 `eosio` 계정의 비밀키를 담았기 때문에 초기 시스템 컨트랙트를 104 | 설정할 수 있습니다. 개발 용도로 디폴트 `eosio.bios` 컨트랙트를 사용할 수 105 | 있습니다. 이 `eosio.bios` 컨트랙트를 이용하여 다른 계정의 자원 할당을 직접 106 | 제어하고 다른 권한 관련 api를 호출할 수 있습니다. 퍼블릭 블록체인에서는 107 | `eosio.bios` 컨트랙트를 통해 일반 컨트랙트의 메모리, 네트워크 및 CPU 활동을 108 | 위한 대역폭을 예약할 수 있는 토큰의 staking과 unstaking을 관리할 수 있습니다. 109 | 110 | `eosio.bios` 컨트랙트는 EOSIO 소스 코드의 `contracts/eosio.bios` 디렉토리에 111 | 있습니다. `eosio` 소스의 루트 경로에서 `eosio.bios`를 실행시킬 때 아래의 112 | 명령어를 사용할 수 있습니다. 만약 다른 위치에서 `eosio.bios`를 실행하고 113 | 싶다면 `eosio.bios`의 절대 경로를 입력하면 됩니다. 114 | 115 | ``` 116 | $ cleos set contract eosio build/contracts/eosio.bios -p eosio 117 | Reading WAST... 118 | Assembling WASM... 119 | Publishing contract... 120 | executed transaction: 414cf0dc7740d22474992779b2416b0eabdbc91522c16521307dd682051af083 4068 bytes 10000 cycles 121 | # eosio <= eosio::setcode {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d0100000001ab011960037f7e7f0060057f7e7e7e... 122 | # eosio <= eosio::setabi {"account":"eosio","abi":{"types":[],"structs":[{"name":"set_account_limits","base":"","fields":[{"n... 123 | ``` 124 | 125 | `cleos`는 두 가지 액션(`eosio::setcode`, `eosio::setabi`)을 실행하는 트랜잭션 126 | 하나를 만듭니다. 127 | 128 | 코드는 컨트랙트 실행 로직을 정의하고, ABI는 인수를 JSON과 바이너리 사이의 129 | 변환 방식을 정의합니다. 기술적으로 보자면 ABI 정의는 꼭 해야 하는 작업은 130 | 아니지만, EOSIO 유틸리티는 사용 편의를 위해서 ABI 정의가 필요합니다. 131 | 132 | 트랜잭션을 실행할 때마다 다음과 같은 형태의 출력을 볼 수 있습니다. 133 | 134 | ``` 135 | executed transaction: 414cf0dc7740d22474992779b2416b0eabdbc91522c16521307dd682051af083 4068 bytes 10000 cycles 136 | # eosio <= eosio::setcode {"account":"eosio","vmtype":0,"vmversion":0,"code":"0061736d0100000001ab011960037f7e7f0060057f7e7e7e... 137 | # eosio <= eosio::setabi {"account":"eosio","abi":{"types":[],"structs":[{"name":"set_account_limits","base":"","fields":[{"n... 138 | ``` 139 | 140 | 풀이하면 이렇습니다. 컨트랙트 계정 `eosio`가 인수 `{args...}`로 `eosio`에 141 | 정의된 액션 `setcode`를 실행함. 142 | 143 | ``` 144 | # ${executor} <= ${contract}:${action} ${args...} 145 | > console output from this execution, if any 146 | ``` 147 | 148 | 아래에 보게 됩니다만, 액션은 다수의 컨트랙트로 실행될 수 있습니다. 149 | 150 | 커맨드 마지막 부분에 사용한 `-p eosio`는 `cleos`에게 `eosio` 계정의 권한을 151 | 사용하여 액션을 실행하라고 알려줍니다. 그러면 `cleos`는 앞서 지갑에 담았던 152 | `eosio` 계정의 비밀키를 사용합니다. 153 | 154 | ## 계정 생성 155 | 156 | 이제 베이직 시스템 컨트랙트를 셋업했기 때문에 계정을 만들 수 있습니다. 157 | `user`, `tester`라는 계정 두 개를 만들 계획이고, 각 계정마다 비밀키/공개키가 158 | 필요합니다. 튜토리얼에서는 이 두 개의 계정에 동일한 비밀키/공개키를 159 | 사용하겠습니다. 160 | 161 | ``` 162 | $ cleos create key 163 | Private key: 5Jmsawgsp1tQ3GD6JyGCwy1dcvqKZgX6ugMVMdjirx85iv5VyPR 164 | Public key: EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 165 | ``` 166 | 167 | 이어서 생성한 키를 지갑에 담습니다. 168 | ``` 169 | $ cleos wallet import 5Jmsawgsp1tQ3GD6JyGCwy1dcvqKZgX6ugMVMdjirx85iv5VyPR 170 | imported private key for: EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 171 | ``` 172 | 173 | **주의** 위의 예시에 나온 키를 사용하지 말고, 실제로 `cleos`를 실행했을 때 174 | 나오는 키를 사용해야 합니다! 175 | 176 | 키는 자동으로 지갑에 추가되지 않습니다. 이 단계를 건너뛰면 계정에 대한 177 | 컨트롤을 잃게 됩니다. 178 | 179 | ## 유저 계정 2개 생성 180 | 181 | 이제 위에서 생성한 키를 이용하여 `user`와 `tester`, 이렇게 2개의 계정을 생성하겠습니다. 182 | 183 | ``` 184 | $ cleos create account eosio user EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 185 | executed transaction: 8aedb926cc1ca31642ada8daf4350833c95cbe98b869230f44da76d70f6d6242 364 bytes 1000 cycles 186 | # eosio <= eosio::newaccount {"creator":"eosio","name":"user","owner":{"threshold":1,"keys":[{"key":"EOS7ijWCBmoXBi3CgtK7DJxentZZ... 187 | 188 | $ cleos create account eosio tester EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 189 | executed transaction: 414cf0dc7740d22474992779b2416b0eabdbc91522c16521307dd682051af083 366 bytes 1000 cycles 190 | # eosio <= eosio::newaccount {"creator":"eosio","name":"tester","owner":{"threshold":1,"keys":[{"key":"EOS7ijWCBmoXBi3CgtK7DJxentZZ... 191 | ``` 192 | **주의** `create account` 커맨드의 인수로 키 두 개가 필요합니다. 193 | 앞엣것은 (프러덕션 환경에서 매우 엄중한 보안 아래에 보관해야 할) OwnerKey이고, 194 | 뒤엣것은 ActiveKey입니다. 튜토리얼에서는 편의상 구분 없이 사용합니다. 195 | 196 | 우리가 `eosio::account_history_api_plugin`를 사용하고 있기 때문에 생성한 197 | 공개키로 제어할 수 있는 모든 계정을 확인할 수 있습니다. 198 | 199 | ``` 200 | $ cleos get accounts EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 201 | { 202 | "account_names": [ 203 | "tester", 204 | "user" 205 | ] 206 | } 207 | ``` 208 | 209 | ## 이어서 - `eosio.token`, 거래소, `eosio.msig` 컨트랙트 210 | 211 | 이어서 다음 튜토리얼을 진행할 준비가 되었습니다. [eosio.token, 거래소, eosio.msig 컨트랙트](https://github.com/eoseoul/docs/blob/master/ko/translations/Tutorial-eosio-token-Contract.md) 212 | 213 | # 번역 정보 214 | 215 | * 원문 : https://github.com/eosio/eos/wiki/Tutorial-Getting-Started-With-Contracts 216 | * 번역 기준 리비전 : 0c18223ea118597c7b2476118091c4094be6af99 217 | -------------------------------------------------------------------------------- /ko/translations/EOSIO_Dawn_4_1.md: -------------------------------------------------------------------------------- 1 | 2 | # EOSIO Dawn 4.1 출시 3 | 4 | 우리는 1.0 출시를 향해 계속 행진하고 있고, 오늘 EOSIO 소프트웨어의 4.1 출시 5 | 태그를 달았습니다. 6 | 7 | ## 중요한 변경 사항 8 | 9 | 우리는 계속해서 버그를 잡고 안정성을 개선하고 있습니다. 일반적인 네트워크 10 | 안정성 문제, 네트워크에 스팸이 되는 중복 트랜잭션 문제, 어떤 경우에 트랜잭션을 11 | 전파하지 못하는 노드 문제를 비롯한 여러 문제를 고쳤습니다. 12 | 13 | ### 장애가 발생한 노드를 다시 서비스 상태(online)으로 되돌리기 14 | 15 | 우리는 nodeos를 개선해서 허용되고 가역적인 블록을 계속 수용할 수 있도록 했습니다([#3140](https://github.com/EOSIO/eos/issues/3140)). 이로써 노드가 다시 온라인 상태가 되고 리싱크(resync)하는 스타트업 시간을 크게 개선했습니다. 16 | 17 | #### [깃헙 이슈 3140](https://github.com/EOSIO/eos/issues/3140) 18 | 19 | 노드가 셧다운하면 가장 최근 240개(혹은 그 이상)의 블록이 유실됩니다. 이런 경우는 대개 문제가 아닙니다. 왜냐하면 노드는 리부팅할 때 다른 피어 노드로부터 블록을 싱크할 것이기 때문입니다. 그러나 블록 생성 로직에 있는 버그 하나로 인해서, 동시에 모든 노드가 결정론적으로 크래시하는, 크래시 유형이 하나 존재합니다. 이런 크래시 유형은 네트워크를 지켜보고 있는 모든 노드(speculative validators)를 다운시킬지도 모르고 그렇지 않을지도 모릅니다. 20 | 21 | 이와 같은 이벤트에서 프로듀서들은 "비잔틴 증거"를 생성하지 않고는 체인을 재시작할 수 없을 것입니다. 22 | 23 | 이 문제를 해결하기 위해서, 적용되었지만 되돌릴 수 있는(applied but reversible) 블록을 저장할 새로운 공유 메모리 파일(chainbase)을 만들기로 했습니다. 24 | 25 | 셧다운 모드에서는 이렇습니다: 26 | 1. Graceful - 포크 데이터베이스는 디스크에 로깅되고, 로딩할 때 복원됨. 27 | 2. Ungraceful - 포크 데이터베이스는 디스크에 로깅되지 않아서, forkdb와 공유 메모리 상태가 불일치하도록 그대로 놓아두고 "replay"를 강제하게 함. 이론적으로 모든 내용이 일치 상태에 도달되기 전까지는 모든 undo 이력이 삭제(pop)될 수 있음. 28 | 29 | 스타트업(시작) 모드에서는 이렇습니다: 30 | 1. Replay - 포크 데이터베이스를 모두 삭제하고, 네트워크로부터 가장 최근 240개 블록을 재동기화해야 함. 31 | 2. Resync - forkdb와 공유 메모리의 내용이 사라지고, 모든 것을 처음부터 다운로드 받음. 32 | 3. Inconsistent - forkdb는 공유 메모리 파일의 내용과 불일치하는 상태임. 33 | 34 | 버그 처리하기 35 | 36 | 때때로 "나쁜 블록" 하나가 버그를 일으키고, 노드는 해당 블록 없이 스타트업을 하려고 할 것입니다. 이 블록은 포크 데이터베이스에 있거나 계류 중인 블록 캐시에 존재할 수 있습니다. 몇몇 극단적인 경우(비잔틴 오류가 있는 등)에 블록은 비가역 블록 로그에 존재할지도 모릅니다. 37 | 38 | 구동을 시작하는 시점에, 노드는 자신이 시작하기 위하는 블록이 "어느 블록"인지 명시할 수 있어야 합니다. 39 | 40 | ### 커맨드 라인 툴 개선 41 | 42 | 커맨드 라인 툴인 `cleos`는 이제 프로듀서 전체 목록을 출력할 수 있게 되었습니다([#2933](https://github.com/EOSIO/eos/issues/2933)). 한 페이지씩 출력할 수 있고 받은 투표수로 정렬됩니다. 43 | 44 | #### [깃헙 이슈 2933](https://github.com/EOSIO/eos/issues/2933) 45 | 46 | `slim` 브랜치에서 오직 10개의 프로듀서만 알파벳 순서대로 보여줌. 사용하는 커맨드는 다음과 같음(동일한 출력을 돌려줌) 47 | 48 | ``` 49 | cleos system listproducers 50 | 51 | cleos get table eosio eosio producers 52 | ``` 53 | 만약 (예를 들어서 모두 "k"로 시작하는 이름을 가지고 있다고 가정하고) 10개의 프로듀서가 등록되어 있고 "m"으로 시작하는 프로듀서를 하나 추가하려고 한다면, 목록에 보이지 않을 것임. 그런데 첫 글자가 "a"로 시작하는 프로듀서를 추가하면, (목록) 제일 처음에 등록되고 기존에 있던 제일 마지막 프로듀서가 제거될 것임. (제거된 프로듀서는 블록을 생성하지만, 아마 목록 출력에만 영향을 줌) 54 | 55 | 업데이트. `cleos system listproducers` 명령은 이름으로만 정렬하고 첫 10개만 보여줌. 56 | 57 | 업데이트. 10개 이상의 목록을 보여주는 방법을 찾음. 58 | 59 | ``` 60 | сleos get table eosio eosio producers -l 100 61 | ``` 62 | 그러나 `cleos system listproducers`의 목록 개수 제한을 늘릴 수 있는 키값은 없으며, 확인한 바로는 프로듀서 순서가 알파벳 순서이고 지분참여된(staked) 토큰량에 따르지 않음. 63 | 64 | ### Quality Name Distribution & Namespaces 65 | 66 | 이번 릴리즈에서 특히 주목할만한 점은 계정 이름을 "."이 없는 정확히 12글자로 제한한 점입니다. 이 변경은 계정 이름 알박기를 좌절시키기 위한 시도입니다. 댄은 깃헙 이슈([#3189](https://github.com/EOSIO/eos/issues/3189))를 통해서 이름 정책에 관한 자신의 제안에 대해 커뮤니티의 피드백을 요청하고 있습니다. 67 | 68 | #### [깃헙 이슈 3189](https://github.com/EOSIO/eos/issues/3189) 69 | 70 | 현재 EOSIO는 12글자보다 짧고 "."를 포함하는 새로운 계정 이름의 생성을 금지하고 있습니다. 이 제한의 목적은 계정 이름 알박기를 좌절시키기 위해서입니다. 그렇긴 합니다만, 사용성의 측면에서 보자면 짧은 계정 이름이 바람직합니다. 왜냐하면 짧은 계정 이름은 시장성있는 상품이기 때문입니다. 71 | 72 | 게다가 조직(사업체)의 입장에서는 ".edu"나 ".com"과 같이 누구나 신뢰할 수 있는 계정 접미어(suffix)를 사용할 수 있는 "신뢰할 만한" 이름 체계(namespace)를 만들 수 있다면 바람직할 것입니다. 짧은 접미어를 이용하면 긴 계정 이름을 접두-접미어로 구성할 수 있고, 그렇게 되면 좀더 큰 이럼 체계가 가능해지고 더 가치있게 됩니다. 73 | 74 | 짧은 계정 이름과/또는 이름 체계를 할당하는 가장 경제적으로 효율적이고 공정한 방법은, 이름을 시장가로 판매하는 것입니다. 프리미엄 계정 이름에 대해 최대의 가치를 얻기 위해서는, 한번에 판매되면 안 되고 시간을 두고 판매되어야 합니다. 75 | 76 | ##### 제안 77 | 1. "com" 계정 이름만 유일하게 새로운 계정 "xyz.com"을 등록할 수 있음 78 | 2. 많아도 하루에 단 하나의 ("."을 포함하지 않는) "프리미엄 계정 이름"만 판매될 수 있고 가장 높은 경매가를 받은 계정 이름일 것임. 79 | 80 | ###### 계정 이름 경매 81 | 82 | ``` 83 | bidname( account_name bidder, account_name desired, asset bid ) 84 | ``` 85 | 만약 '호가'가 가장 높은 경매자보다 큰 경우, 경매자는 해당 계정 이름의 예정된 낙찰자가 됩니다. 각각의 호가는 기존 호가보다 10% 이상 커야만 합니다. 기존의 입찰자는 환불받게 됩니다. 이런 방법으로 참여자가 충분히 높은 가격으로 입찰하고, 입찰했을 때 바로 빠지지 않게 하며 같은 이름을 두고 왔다갔다 입찰하지 못하게 합니다. 게다가 이런 방법을 사용하면 자신보다 높은 낙찰가를 다른이가 부르지 않기를 바라는 계정 이름 알박기를 좌절시킵니다. 86 | 87 | 24시간마다 가장 높은 입찰가를 받은 이름 하나가 낙찰됩니다. 한번 낙찰되면 낙찰자는 해당 계정을 등록하는 `newaccount` 액션을 사용할 수 있습니다. 이 시점에 이르면 경매에 할당된 메모리는 응찰자(bidder)에게 되돌려집니다. 88 | 89 | ###### 대중을 위한 쉬운 옵션 90 | 91 | 대다수의 사용자는 매일 진행되는 계정 이름 경매에 참여하길 원치 않을 것입니다. 왜냐하면 이 과정은 느리고 매우 경쟁이 치열한 과정이기 때문입니다. 대신 이름-등록소(name-registrars)는 좋은 이름에 입찰할 것이고, "하위 계정 이름"으로 사용자들의 계정을 만들 것입니다. 대형 DAPP은 아마 자체 브랜드 이름 체계를 따로 잡고 프리미엄 계정 이름에 대한 자체 정책을 가져가고 싶어할 것입니다. 92 | 93 | ###### 무효화 불가(Non-Revokable) 94 | 95 | '.com'이 계정 'xyz.com'을 한번 만들면, 이 계정은 삭제될 수 없고, 'xyz.com'의 소유자는 잠재적으로 이 계정을 다른 누군가에게 양도할 수 있습니다. 만약 접미어 ".com"으로 끝나는 모든 계정에 대한 제어권을 행사하고 싶은 회사가 있다면, "owner" 퍼미션을 그에 맞추어 설정할 필요가 있을 것입니다. 96 | 97 | ###### 경매 수입 98 | 99 | 경매로 얻은 수입은, 할당되지 않은 다른 인플레이션과 램 거래 수수료와 같이 시스템 잔고 계정(system savings account)에 귀속됩니다. 100 | 101 | ##### FAQ on Quality Name Distribution & Namespaces 102 | 103 | 1. 모든 계정 이름은 언제나 경매에 부쳐질 수 있지만, 매일 가장 높은 입찰가를 받은 계정 이름 하나만 낙찰됩니다. 판매되는 이름의 순서는 "가장 비싼 것 먼저"입니다. 104 | 2. 미래에 있을 worker proposal은 이름 경매로부터 얻은 수입을 할당할 수 있을 것입니다. 105 | 3. 12자 제한은 "접미어"를 포함한 이름 전체에 적용됩니다. 106 | 107 | ##### 덧붙임 by @bytemaster 108 | 109 | * 유저 사용성의 관점에서 본다면 "이름 시작"에서 신원을 확인할 것이라서, 접미어가 더 적절해 보입니다. 경매가 끝나는 관점에서 본다면, 마지막 응찰 이후 최소한 24시간이 지나야 한다는 점에 동의합니다. 110 | * 남은 작업들 111 | * `eosio_global_state`, `bidname`, `namebids` 테이블에 대해 ABI 업데이트하기 112 | * 승인되지 않은 계정이 생성되지 않음을 검증하는 유닛 테스트 작성 113 | * 미래애 SYMBOL 이름은 거래소(exchange)와/또는 토큰 컨트랙트를 통해서 할당되어야만 합니다. 이번 제안에는 SYMBOL 이름을 현재 지원하고 있지 않습니다. 114 | * 사이드 체인은 메인 체인으로부터 계정을 가져올(import) 것 같습니다. 115 | 116 | 117 | ### 코어 토큰 이름 변경 118 | 119 | 토큰 심볼의 이름을 "EOS"에서 "SYS"로 변경했다는 점을 알고 계셔야 합니다. 혹시 다른 이름으로 바꾸고 싶다면, `CMakeLists.txt` 파일에 있는 `CORE_SYMBOL_NAME`을 체크하세요. 120 | 121 | ### BIOS 부트 프로세스 튜토리얼 122 | 123 | EOSIO 네트워크를 부트하는 데 필요한 과정을 설명하는 스크립트와 자세한 튜토리얼(https://github.com/EOSIO/eos/tree/master/programs/bios-boot-tutorial) 을 준비했습니다. 멀티시그(multi-sig)를 이용해서 프로듀서를 통해 `eosio.system` 컨트랙트와 `eosio.token` 컨트랙트를 업그레이드하는 내용을 담은 추가적인 과정을 설명하는 내용을 다음주에 스크립트와 튜토리얼에 추가할 것입니다. 124 | 125 | ## 테스트넷 126 | 127 | 우리가 운영하고 있는 내부적인 테스트넷은 강건하게 동작하고 있습니다. 다수의 커뮤니티 테스트넷을 기쁜 마음으로 지켜보고 있고 우리가 거기서 목격하고 있는 작업들에 대해서 자랑스럽습니다. 특기할 만한 테스트넷은 최근 빌드(DAWN-2018-05-16)로 동작하고 있고 70개 이상의 노드가 연동된 EOS Jungle 테스트넷(http://dev.cryptolions.io) 입니다. EOSIO 커뮤니티 테스트넷 텔레그램(https://t.me/CommunityTestnet) 을 통해서 최근 소식에 귀기울여주세요. 128 | 129 | ## 패트로니오스 - Patroneos 130 | 131 | 남용으로부터 RPC-API 엔드포인트를 보호할 새로운 툴을 준비하고 있습니다. 우리는 이 툴을 패트로니오스라고 부르는데, 왜냐하면 영혼을 빨아먹는 스패머인 디멘터를 궁지로 몰아넣기 때문입니다. 우리가 현재 계속 지켜보고 있는 행동 패턴은 반복되고 유효하지 않은 JSON payload, 서명 스팸, 블랙리스트 처리된 컨트랙트, 지나치게 큰 트랜잭션 payload와 같은 것들입니다. 132 | 133 | 우리는 이 툴을 내부적으로 개발해왔고 곧 자세한 내용과 함께 커뮤니티에 출시할 것입니다. 어떻게 나올지 지켜봐주세요. 134 | 135 | ## 깃헙에 올라온 Dawn 4.1 136 | 137 | EOSIO Dawn 4.1은 깃헙에 올라와있습니다. (https://github.com/EOSIO/eos/releases/tag/dawn-v4.1.0) 이를 이용해서 개발자들과 블록 프로듀서 출마자들은 애플리케이션과 네트워크를 계속 테스트할 수 있습니다. 138 | 139 | ## 커뮤니티 지원 140 | 우리는 커뮤니티로부터 피드백을 듣는 게 참 좋고, EOSIO를 성공적으로 동작시키도록 커뮤니티를 돕는 데 헌신하고 있습니다. 우리의 EOSIO 스택 익스체인지 (https://eosio.stackexchange.com/) Beta는 잘 성장하고 있고, 이 소프트웨어를 사용하는 방법에 대한 질문을 스택 익스체인지에 올려주시길 장려합니다. 141 | 142 | 깃헙에 아래 정보를 포함시켜서 잠재적으로 보일 지도 모르는 버그를 계속 리포트해주시길 바랍니다. 143 | 144 | * Testnet: 이슈를 발견한 테스트넷이 어디인지 145 | * EOSIO git version: `nodeos -v output` 결과 문자열 146 | * config.ini: 사용하고 있는 `config.ini` 파일을 첨부해주세요 147 | * genesis.json: 사용하고 있는 `genesis.json` 파일을 첨부해주세요 148 | * Command line: 사용한 `nodeos` 전체 커맨드 명령어 149 | * Console output: 확인하고 있는 에러와 관련된 콘솔 디버그 출력값 (짧으면 아예 이슈 설명에 붙여넣어도 좋습니다) 150 | 151 | ## 추후 릴리즈 152 | 153 | 우리는 다음주 금요일, 그러니까 5월 25일 경 프리릴리즈(Dawn 4.2)를 한 번 더 계획하고 있고 6월 1일에 EOSIO 1.0을 예정하고 있습니다. 깃헙의 버전 1.0 마일스톤(https://github.com/EOSIO/eos/milestone/10) 을 지켜보시면 다음 몇 주간 우리가 집중해서 작업하고 있는 이슈들을 따라잡으실 수 있습니다. 154 | 155 | ## 번역 정보 156 | 157 | * 원문 158 | * https://github.com/EOSIO/eos/releases/tag/dawn-v4.1.0 159 | * https://github.com/EOSIO/eos/issues/3140 160 | * https://github.com/EOSIO/eos/issues/2933 161 | * https://github.com/EOSIO/eos/issues/3189 162 | * 출시 노트 원문 포스팅 시점 : 한국표준시 2018년 5월 19일 오전 8시 10분 163 | * 각 깃헙 이슈의 포스팅 시점은 출시 노트 포스팅 시점과 다릅니다. 164 | -------------------------------------------------------------------------------- /ko/translations/EOSIO_Dawn_4_Release.md: -------------------------------------------------------------------------------- 1 | # EOSIO Dawn 4.0 Release 2 | 3 | 지난 주 우리는 EOSIO Dawn 4.0을 소개해드렸습니다. 오늘 우리는 EOSIO의 4 | 이어지는 주요 프리릴리즈를 여러분께 내놓게 되어서 자랑스럽습니다. 5 | 지난 일주일 동안 많은 일이 일어났습니다! 6 | 7 | ## Dawn 4.0 램 할당 방식에 대한 피드백 8 | 9 | 몇몇 커뮤니티 구성원들은 사람들이 체인을 사용하면서 RAM을 확보하기도 전에 10 | 일부 사람들이 RAM의 가격이 저렴할 때 RAM을 사재기하여 정당하지 11 | 않은 이익을 얻을 것이라는 점에 대해 우려를 표했습니다. 이와 같은 문제를 12 | 완화하기 위해서, 우리는 체인을 런칭하는 주체들이 매우 제한된 양의 13 | RAM 공급으로 체인을 시작하고, 처음 몇 달에 걸쳐서 서서히 RAM 용량을 14 | 확장하기를 권합니다. RAM을 32GB부터 공급하기 시작하고 몇 개월에 걸친 기간 동안 15 | 1TB로 증설한다면, RAM 가격은 시간이 지남에 따라 초기 가격의 3%로 급격히 16 | 떨어질 지도 모릅니다. 입찰을 할 때 정말 RAM이 필요한 사람들만, 향후 램 공급량을 17 | 감안할 사정이 있는 사람들만 초기 RAM을 구매할 것입니다. 어느 쪽이든, 18 | 아무도 "값싼" RAM 또는 "무료 이익"을 얻지 않을 것입니다. 19 | 20 | ## 테스트넷 현황 21 | 22 | 유럽, 아시아, 미국에 설치된 노드로 구성한 우리의 내부 테스트넷은 큰 문제 없이 23 | 제대로 작동되고 있습니다. 24 | 25 | ## 주관적 CPU 자원 사용량 계산이 돌아왔습니다. 26 | 27 | 지난 몇 개월 동안 우리는 객관적 CPU 사용량 계산을 실험해왔습니다. 객관적 28 | 사용량 계산은 트랜잭션 처리 과정에서 사용되는 CPU 인스트럭션 개수를 29 | 결정론적 방식으로 계산하려고 시도합니다. 이런 방식의 계산은 트랜잭션이 30 | 소모한 자원이 무엇인지에 대해 완전하고 모호하지 않은 합의를 보장하는 31 | 좋은 특성이 있습니다. 이 방식은 다른 스마트 컨트랙트 플랫폼에서도 사용되는 32 | 방식이기도 합니다. 33 | 34 | 일 년 전 우리가 EOSIO를 소개할 때 우리는 [주관적인 최선의 스케줄링](https://github.com/eoseoul/docs/blob/master/ko/translations/TechnicalWhitePaperV2.md#%EC%A3%BC%EA%B4%80%EC%A0%81%EC%9D%B8-%EC%B5%9C%EC%84%A0%EC%9D%98-%EC%8A%A4%EC%BC%80%EC%A4%84%EB%A7%81) 방식을 제시했습니다. 이 모델에서 각 블록 프로듀서는 트랜잭션 실행에 35 | 소요되는 시간을 측정하고 그에 따라 사용자에게 요금을 청구합니다. 사용량에 대한 36 | 합의를 유지하기 위해서, 프로듀서는 트랜잭션 처리에 대해 부과한 37 | 마이크로 초(microsecond) 수를 고지할 것입니다. 38 | 39 | 객관적 사용량 계산은 사용량 청구 분쟁을 없애고 합의 과정을 단순화할 수 있다는 40 | 점에서 훌륭합니다만, 다음과 같은 몇 가지 단점으로 인해 우리는 결국 주관적 41 | 사용량 계산 방식을 사용하기로 결정했습니다. 42 | 43 | 1. 객관적 CPU 사용량 측정을 위해서는 사용량 기록을 추가로 남겨야 하고 이로 인해 성능을 저하시킵니다. 44 | 2. 객관적 CPU 사용량 측정의 과정에서 액션의 실제 자원 소모량과 객관적인 측정 방식을 통한 근사치 사이에 불일치가 발생할 수 있는데, 이런 경우가 생길 때마다 이를 악용한 공격 경로와 서비스 거부 공격(denial of service) 경로가 생길 수 있습니다. 45 | 3. 객관적인 CPU 사용량 측정 방법은 유지하고 업그레이드하고 최적화해가기가 어렵습니다. 46 | 47 | 주관적 CPU 사용량 계산은 나름의 문제점이 있고, 특히 합의 시스템의 측면에서 48 | 그렇습니다. 다행히도 우리는 주관적 CPU 사용량 계산을 타당하게 만들어주는 49 | 혁신적인 해결책을 찾았습니다. 해결이 필요한 문제들 몇 개는 아래와 같습니다. 50 | 51 | 1. 블록 프로듀서가 사용량을 정확히 고지할 것이라고 신뢰해야 함 52 | 2. 프로듀서 저마다의 계산 방식 차이를 해결해야 함 (각 프로듀서마다 하드웨어/소프트웨어/로드가 다름) 53 | 3. 나쁜 마음을 먹은 프로듀서를 상대해야 함 54 | 55 | 위임 지분 증명을 사용하는 환경에서, 블록 프로듀서는 계약상의 의무를 지고 56 | 악의적인 행위시 오랫동안 법률적으로 안 좋은 영향을 받는 공공단체일 것으로 57 | 여겨집니다. 뿐만 아니라 모든 21개의 활성화된 프로듀서는 이들을 선출한 58 | 커뮤니티로부터 높은 평가를 받을 것이라고 예상됩니다. 59 | 60 | 이와 같은 예상에 근거할 때 우리는 프로듀서 모두가 CPU 처리 시간(runtime) 61 | 오라클(옮긴이 주: 정확한 정보를 주는 주체)의 역할을 하고 트랜잭션 1건 62 | 처리시 소요되는 시간에 대해 거짓된 정보를 전달하지 않을 것이라는 63 | 신뢰의 기본 원리 하나를 세울 수 있습니다. 이로써 정상적인 작동 조건에서 64 | 고지된 처리 시간(runtime)은 전체 프로듀서에 걸친 평균 소요 시간의 타당한 65 | 오차 범위 내에 있을 것이라고 믿을 수 있습니다. 66 | 67 | 이런 접근을 비판하는 사람이 있다면 악의적인 프로듀서 하나가 무한 루프가 있는 68 | 블록 하나를 만들고 이 블럭은 처리 시간이 전혀 들지 않는다고 고지할 수도 있다고 69 | 지적할지도 모릅니다. 이런 시나리오를 방지하기 위해 모든 노드는 모든 블록에 대해 70 | 몇 초 정도의 처리 시간 한도를 걸어둡니다. 그러나 이런 한도가 있다고 해도 71 | 이런 시나리오는 네트워크에 상당한 혼란을 일으킬 수 있습니다. 요령 있고 삐뚤어진 72 | 프로듀서는 50%의 노드가 수용하고 50%는 거절할 그런 블록을 만들어내서 73 | 네트워크를 두 동강으로 분열시킬지도 모릅니다. 74 | 75 | 우리 팀은 이와 같은 공격 경로를 분석해왔고, 매우 긴 시간의 처리가 필요한 블록의 76 | 발생은 매우 긴 네트워크 지연이나 장애와 전혀 다를 바가 없다는 점을 깨닫게 77 | 되었습니다. 네트워크가 분할되는 상황에도 견고한 어떠한 합의 알고리즘도 78 | 이론적으로 발생할 수 있는 다른 상황에 직면하는 경우에도 역시 견고해야만 합니다. 79 | 비잔틴 장애 내성이 있는 DPOS는 (미국과 중국이 전체 인터넷에서 일시적으로 80 | 연결이 끊겼을 경우와 같은) 네트워크 분할을 견뎌낼 수 있기 때문에, 81 | 위와 같은 상태를 만들어내는 악의적인 프로듀서보다 더 오래 존속할 수 있습니다. 82 | 83 | 블록 프로듀서는, 네트워크 분할 발생 가능성을 완화할 수 있는 몇 가지 방법이 84 | 있습니다. 이런 방법은 그 원인이 대서양 아래에 설치된 광섬유케이블이 절단된 85 | 경우이거나 악의적인 프로듀서이거나 상관없이 동일합니다. 86 | 87 | ### 여러 개의 연결을 유지하기 88 | 89 | 이 접근 방법을 사용하는 경우, 대서양을 가로지르는 연결이 끊어졌을 때 90 | 프로듀서는 태평양을 통해 패킷을 라우팅시킬 수 있습니다. 블록 유효성을 검증할 91 | 단계에서 프로듀서는 두 개의 노드가 동일한 블록을 검증하지 않는 92 | (옮긴이 주: 블록 하나는 단 하나의 노드가 검증하는) 93 | 다수의 유효성 검증 노드를 운영해야 합니다. 가장 극단적인 경우, 각 프로듀서는 94 | 자신과 연결된 다른 프로듀서 노드 하나하나가 보내는 블록을 처리하는 95 | 각각의 전용 노드를 둘 수도 있을 것입니다. 만약 프로듀서 하나가 무한 루프 블록을 96 | 보내서 이 프로듀서에 연결된 검증 채널(노드)이 막혀버려도, 다른 프로듀서들은 97 | 자신에게 할당된 독립되고 중복된 채널을 통해서 계속해서 통신할 수 있습니다. 98 | 비가역 블록 넘버가 나쁜 블록(무한 루프가 담긴 블록)의 블록 넘버를 지나가게 되면, 99 | 노드는 블록 처리를 강제로 중단하고 종료할 수 있습니다. 합의를 중단시켜 100 | 블록 넘버가 커지지 못하게 막으려면, 프로듀서의 2/3 이상이 비잔틴(배반자)이 101 | 되는 경우에나 가능할 것입니다. 102 | 103 | ### 수리하거나 손상 구역을 우회 104 | 105 | 광섬유케이블 하나가 끊어지는 순간, 대신 통신을 맡길 여러 개의 광섬유케이블 106 | 연결을 준비하기가 항상 가능하지는 않습니다. 이런 장애의 경우 팀 하나가 출동해서 107 | 손상된 케이블을 교체하고 연결을 복구합니다. 이 작업이 오래 걸릴지도 모르지만, 108 | 종국에는 연결이 다시 돌아오고 네트워크는 약간의 다운 타임에 불과한 시간을 109 | 소모한 후 합의를 이어갑니다. 삐뚤어진 프로듀서 하나가 피해를 초래하는 사태가 110 | 발생하면, 다른 프로듀서들은 살짝 설정을 변경해서 삐뚤어진 프로듀서를 블랙리스트 111 | 처리할 수 있고 이어서 네트워크는 평상시의 운용을 이어갈 것입니다. 112 | 비정상적인 처리 시간이 소요되는 블록이 발견될 때마다 악의적인 프로듀서를 113 | 블랙리스트에 올리는 작업을 자동화까지 해놓을 수도 있습니다. 114 | 최악의 시나리오로, 나쁜 프로듀서 하나가 금지 수준 근처에 있는 블록을 만들어서 115 | 딱 절반에 해당하는 프로듀서의 블랙리스트에 올라갈 수 있습니다. 116 | 이 경우 프로듀서들이 계류된 포크(pending fork) 중 어느 포크를 따라갈 지 117 | 결정할 때까지, 마지막 비가역 블록은 다음 블록으로 넘어가지(advance) 않을 118 | 것입니다. 119 | 120 | 위에 언급된 모든 경우에 있어서, 마지막 비가역 블록을 근거로 최종성을 결정하는 121 | 사용자들은 이중 지불 공격에서 안전합니다. 그리고 네트워크가 겪을 "다운 타임"은 122 | 사람들이 전력회사나 인터넷 서비스 제공자(ISP)로 인해 겪는 전형적인 123 | "다운 타임"에 비해 짧을 가능성이 있습니다. 124 | 125 | 우리는 DPOS의 거버넌스 프로세스와 인센티브가, 악의적인 행위가 초래할 단기간의 126 | 다운 타임의 발생 확률을 인터넷 연결 문제로 발생할 수 있는 모든 블록체인 플랫폼의 127 | 다운 타임의 발생 확률보다 낮게 만들 것이라고 판단하고 있습니다. 적어도 128 | DPOS 환경에서는, 사용자는 재연결 이후 제대로 블록을 다시 쌓지 않은 129 | 소수 체인을 자신도 모르게 사용하게 되는 문제로부터 안전합니다. 130 | 작업 증명으로 동작하는 체인 환경에서는, 네트워크 분할이 발생하면 고정된 숫자의 131 | 승인에만 의존하는 사용자를 노린 이중 지출 공격을 불러일으키게 할 수도 있습니다. 132 | 133 | ## 시스템 컨트랙트 수정 사항 134 | 135 | 'eosio.system' 컨트랙트는 프로듀서 등록, 투표, 지분참여, 자원 할당 등의 136 | 기능을 구현하여 제공됩니다. 우리 팀은 커뮤니티가 체인을 만들 때 사용하기로 137 | 선정할지도 모르는 레퍼런스 구현을 제공하기 위해 작업해오고 있습니다. 138 | 이번 출시를 통해 시스템 컨트랙트는 아래 사항을 포함하여 수정되었습니다. 139 | 140 | 1. 150,000,000.0000 개의 토큰이 최소 하나의 프로듀서 또는 하나의 대리인(proxy)에 투표를 진행한 상태에 도달하기까지, 어느 누구도 지분회수(unstake)를 할 수 없음. 141 | 2. 만약 어느 체인 하나가 10%의 토큰을 블록원에 할당하기를 원한다면, 일년에 1%씩만 지분회수(unstake)하도록 제한(rate limit)될 것임. 142 | 143 | (옮긴이 주: 사용자가 대리인(proxy)을 설정하면, 사용자 자신이 지분참여한 토큰만큼을 대리인이 대신 투표할 수 있습니다. 대리인을 설정하지 않은 경우, 지분참여한 토큰이 있는 자신의 계정을 대리인(proxy)으로 등록할 수 있습니다.) 144 | 145 | ## 해킹당한 계정 복구 & 잃어버린 패스워드 복구 146 | 147 | 우리 팀은 해킹당한 계정을 복구하고 잃어버린 패스워드를 복구하는 새로운 방법을 148 | 만들어냈고, 이 방법을 이용하면 웹어셈블리로 거의 모든 기능을 구현할 수 있습니다. 149 | 우리는 해당 계정이 권한 레벨을 승인한 가장 마지막 시각 정보를 돌려주는 150 | 새로운 내장 API를 추가했습니다. 이 정보를 이용해서 스마트 컨트랙트는 151 | 잃어버린 패스워드를 리셋하기 전 7일 동안의 고지 이후 152 | 30일 동안의 비활동 기간을 강제하기 위해 필요한 로직을 153 | 전부 웹어셈블리로 구현할 수 있습니다. 154 | 155 | 우리는 하드-코딩한 액션 핸들러 3개를 지웠고, 이로써 잠재적인 버그를 제거하고 156 | 나중에 소프트-업데이트로 쉽게 개선할 수 있게 만들어 놨습니다. 1.0 출시 이후 157 | 잃어버린 패스워드 복구를 구현한 하나 이상의 구현체가 별도의 스마트 컨트랙트로 158 | 제공될 지도 모릅니다. 159 | 160 | (옮긴이 주: `eosio_contract.cpp`, `eosio_contract_api.cpp` 등의 파일과 다음 이슈를 통해서 기존의 구현과 변경 사항을 확인할 수 있습니다. https://github.com/EOSIO/eos/issues/2854 , https://github.com/EOSIO/eos/pull/285 ) 161 | 162 | ## 깃헙에서 내려받을 수 있습니다. 163 | 164 | EOSIO Dawn 4.0은 이제 깃헙에서 내려받을 수 있습니다. 개발자들은 어플리케이션 165 | 테스트를 시작할 수 있습니다. 166 | 167 | ## EOSIO 1.0이 곧 출시됩니다. 168 | 169 | 우리 팀은 안정적인 EOSIO 1.0을 6월 첫 번째 주에 시장에 출시하기 위해 24시간 내내 170 | 일하고 있습니다. 이 첫 번째 출시에는 누구나 EOSIO 기반의 자체 블록체인을 만들 수 171 | 있도록 필요한 모든 기능이 담길 것입니다. 우리는 "기능 동결"한 스펙을 구현해왔고 172 | 남은 몇 주 동안 내부 테스트넷을 운영하며 테스트하고 발견된 버그를 수정하는 데 173 | 전념할 예정입니다. 우리의 목표는 대단히 중요한 기능들이 바위처럼 극도로 174 | 안정적인지 보장하는 것입니다. EOSIO 1.0 출시 이후 우리는 많은 사용성 개선과 175 | 기반 개선을 가져올, 포크 없는 수정을 통해서 EOSIO 소프트웨어를 지속적으로 176 | 개선할 것입니다. 177 | 178 | ## 면책조항 - Disclaimer 179 | 180 | 면책조항: 블록원(block.one)은 소프트웨어 기업이며 EOSIO 소프트웨어를 무료 오픈소스 소프트웨어로 제작합니다. 이 소프트웨어는, 특기할 만한 점으로, 이 소프트웨어를 도입하는 사용자가 다양한 기능을 갖춘 분산 어플리케이션 또는 블록체인을 시작할 수 있도록 합니다. 자세한 내용은 다음 사이트를 방문하십시오. https://github.com/eosio 블록원은 채택하거나 구현할 수 있는 EOSIO 플랫폼의 모든 버전을 이용해서 블록 프로듀서가 되려는 사람에게 경제적 지원을 제공하지 않습니다. 181 | 182 | 블록원은 EOSIO 소프트웨어를 기반으로 하는 퍼블릭 블록체인을 론칭하지 않습니다. 자신들이 선택한 기능 및/또는 자신들이 선택한 서비스를 제공하도록, 자신들이 선택한 형태로 EOSIO를 채택하며 구현하려는 제 3자, 커뮤니티 및/또는 블록 프로듀서가 되길 원하는 주체들의 단독 책임일 것입니다. 블록원은 임의의 주체가 그러한 기능을 채택하여 구현하거나 그런 서비스를 제공하거나 EOSIO가 어떤 방식으로든 채택되고 구현된다는 것을 보증하지 않습니다. 183 | 184 | 블록원은 이 문서에 언급된 경우에도 제 3자 또는 제 3자의 제품 또는 제 3자의 185 | 서비스를 보증하지 않습니다. 블록원은 링크된 어떠한 내용에 대해서도 책임지지 186 | 않습니다. 187 | 188 | 이 문서는 블록원의 비전을 보여 주며 어떠한 보증도 아닙니다. 우리가 그 비전을 실현하도록 노력할 것이지만, 모든 측면이 모든 면에서 블록원의 단독 재량 하에 변경될 수 있습니다. 우리는 블록원의 비즈니스 전략, 계획, 전망, 개발 및 목표에 관한 진술과 같은 역사적 사실에 대한 진술 이외에 이 문서의 모든 진술을 포함하는 이 문서를 "미래 예측 진술"이라고 부릅니다. 이 진술은 예측일 뿐이며 미래의 사건에 대한 블록원의 현재의 믿음과 기대치를 반영하고 가정에 근거하며 언제든지 위험, 불확실성 및 변경의 영향을 받습니다. 우리는 급변하는 환경에서 사업을 운영합니다. 새로운 위험이 수시로 발생합니다. 이러한 위험과 불확실성을 감안할 때 이러한 미래 예측 진술에 의존하지 않도록 주의해야합니다. 실제 결과, 실적 또는 이벤트는 미래 예측 진술에 포함된 내용과 실질적으로 다를 수 있습니다. 실제 결과, 실적 또는 이벤트가 미래 예측 진술과 실질적으로 다른 원인이 될 수 있는 요인에는 시장 변동성, 자본, 재원 및 인력의 지속적인 가용성; 제품 수용; 어떤 새로운 제품이나 기술의 상업적 성공; 경쟁; 정부 규제 및 법률; 그리고 일반적인 경제, 시장 또는 사업 조건이 포함되며 이에 제한되지 않습니다. 189 | 190 | 모든 진술은 포스팅된 첫 날짜에 대해서만 말하고 블록원은 새로운 정보, 후속 사건 또는 기타의 사건이건 간에 미래 예측 진술을 업데이트하거나 변경할 의무가 없으며 분명히 부인할 의무가 없습니다. 이 문서에 나온 그 어떠한 내용도 일반적인 경우에서나 또는 특정 상황 또는 191 | 구현에 있어서나 기술적 재무적, 투자적, 법률적 또는 다른 종류의 조언이 되지 않습니다. 192 | 이 문서에 포함된 내용을 구현하거나 활용하기 전에 해당 분야의 전문가에게 문의하십시오. 193 | 194 | 여기에서 표현된 아이디어와 정보는 전적으로 저자 개인의 것이며 블록원 또는 블록원 직원의 입장과 견해와 조언을 필연적으로 반영한 것은 아닙니다. 195 | 196 | ## 번역 정보 197 | 198 | * 원문 : https://medium.com/eosio/eosio-dawn-4-0-release-b25661a49ac2 (2018년 5월 12일) 199 | -------------------------------------------------------------------------------- /ko/translations/Testnet-Single-Host-Multinode.md: -------------------------------------------------------------------------------- 1 | 이번 튜토리얼에서는 단일 호스트상에서 멀티 노드 블록체인을 구동(_**single host, multi-node testnet**_)할 수 있도록 설정하는 방법을 설명하겠습니다. 로컬 PC에서 두 노드를 설정하고, 서로간에 통신해보도록 할 것입니다. 이 섹션에서 설명하는 예제는 세 커맨드 라인 애플리케이션을 사용합니다: `nodeos`, `keosd`, `cleos`. 구성된 테스트넷을 그림으로 그리면 아래의 다이어그램과 같게 됩니다. 2 | ![Single Host, Multi-Node Testnet](assets/Single-Host-Multi-Node-Testnet.png) 3 | 4 | `keosd`, `cleos`, `nodeos`를 설치하고 경로설정까지 완료돼 있거나, 파일시스템 상에서 저 세 애플리케이션의 실행환경을 알고 있어야 합니다. ([로컬 환경 설정하기](https://github.com/eoseoul/docs/blob/master/ko/translations/Local-Environment.md)를 참고하세요) 5 | 6 | 그럼 이제 터미널 윈도우를 열고, 다음 순서대로 수행해 봅시다. 7 | 8 | ### 지갑 관리자(월렛 매니저) 시작 9 | 먼저, 지갑 관리 애플리케이션인 `keosd`를 실행합니다. 10 | ``` 11 | keosd --http-server-address 127.0.0.1:8899 12 | ``` 13 | 14 | 잘 실행됐다면 결과로 다음과 같은 정보들이 표시됩니다: 15 | ``` 16 | 2493323ms thread-0 wallet_plugin.cpp:39 plugin_initialize ] initializing wallet plugin 17 | 2493323ms thread-0 http_plugin.cpp:141 plugin_initialize ] host: 127.0.0.1 port: 8899 18 | 2493323ms thread-0 http_plugin.cpp:144 plugin_initialize ] configured http to listen on 127.0.0.1:8899 19 | 2493323ms thread-0 http_plugin.cpp:213 plugin_startup ] start listening for http requests 20 | 2493324ms thread-0 wallet_api_plugin.cpp:70 plugin_startup ] starting wallet_api_plugin 21 | ``` 22 | 23 | 표시 정보 중 지갑(wallet)이 127.0.0.1:8899를 리스닝하고 있다는 데 주목하세요. `keosd`가 제대로 수행되어 정상적으로 포트를 리스닝하고 있다는 뜻입니다. 저 라인이 표시되지 않는다면, 혹은 "starting wallet_api_plugin" 라인 앞에 오류 보고가 떠 있다면, 이슈를 진단하고 해결해야 합니다. 24 | 25 | `keosd`룰 제대로 실행시켰다면, 지갑 애플리케이션이 계속 실행되도록 현재 윈도우는 놔 두고, 새 터미널 윈도우를 엽니다. 26 | 27 | ### 기본 지갑 생성 28 | 다음 터미널 윈도우에서 커맨트 라인 유틸리티인 `cleos`를 실행시켜서 기본 지갑을 생성합니다. 29 | ``` 30 | cleos --wallet-port 8899 wallet create 31 | ``` 32 | 33 | `cleos`는 "기본" 지갑을 생성했는지 표시해 줄 것이며, 이후에 지갑에 액세스하기 위한 패스워드를 알려줄 것입니다. 메시지에서도 안내해 주고 있듯이, 이후에 사용할 수 있도록 패스워드를 잘 보관해 둡시다. 예제에서 실행한 결과는 다음과 같습니다: 34 | ``` 35 | Creating wallet: default 36 | Save password to use in the future to unlock this wallet. 37 | Without password imported keys will not be retrievable. 38 | "PW5JsmfYz2wrdUEotTzBamUCAunAA8TeRZGT57Ce6PkvM12tre8Sm" 39 | ``` 40 | 41 | `keosd` 쪽 윈도우에도 현재 상태 변화가 출력될 겁니다. 우리는 계속해서 두 번째 터미널의 `cleos` 명령어 이후 작업을 진행합니다. 42 | 43 | ### 첫번째 프로듀서 노드 시작 44 | 첫번째 프로듀서 노드를 시작하겠습니다. 세 번째 터미널 윈도우에서 다음과 같이 실행합니다: 45 | ``` 46 | nodeos --enable-stale-production --producer-name eosio --plugin eosio::chain_api_plugin --plugin eosio::net_api_plugin 47 | ``` 48 | 49 | 이 명령어는 "bios" 프로듀서로 알려져 있는 특별한 프로듀서를 생성하게 됩니다. 지금까지 모두 정상적으로 진행됐다면, `nodeos` 프로세스의 실행 결과로 블록이 생산되었다고 출력됩니다. 50 | 51 | ### 두 번째 프로듀서 노드 시작 52 | 다음 명령어는 이 튜토리얼을 `${EOSIO_SOURCE}` 디렉토리에서 실행하고 있다고 가정한 상태에서 실행됩니다. 이 디렉토리는 빌드를 위해 `./eosio_build.sh`를 돌렸던 디렉토리입니다. 궁금한 점이 있다면 [코드 받기](https://github.com/eoseoul/docs/blob/master/ko/translations/Local-Environment.md#%EC%BD%94%EB%93%9C-%EB%B0%9B%EA%B8%B0)를 찾아보시면 자세한 정보를 확인하실 수 있습니다. 53 | 54 | 노드를 추가하기 위해서는 우선 `eosio.bios` 컨트랙트를 로드해야 합니다. 이 컨트랙트는 여러분에게 다른 계정에 대한 자원 할당과 다른 권한이 필요한 API 호출에 대한 제어권을 부여합니다. 두 번째 터미널 윈도우에서 다음 명령어를 실행해 컨트랙트를 로드하세요: 55 | ``` 56 | cleos --wallet-port 8899 set contract eosio build/contracts/eosio.bios 57 | ``` 58 | 59 | `inita` 란 계정명을 사용해 프로듀서가 될 계정을 생성할 것입니다. 계정 생성을 위해서는 계정과 연결된 키를 생성해야만 하고, 이 키를 지갑에 임포트해야 합니다. 60 | 61 | 다음과 같이 키 생성 명령어를 실행합니다: 62 | ``` 63 | cleos create key 64 | ``` 65 | 새로 생성된 공개키와 개인키 쌍이 출력됩니다. 다음과 유사한 형식일 것입니다. 66 | 67 | **중요: 이후의 커맨드 라인 명령어는 여기서 출력되는 키를 사용합니다. 이 튜토리얼에서 커맨드를 복붙하려면, 여러분이 방금 생성한 키를 사용해서는 안됩니다. 만약, 여러분이 새로 생성한 키를 사용하고 싶다면, 커맨드라인에서 키값을 여러분이 생성한 키로 변경하셔야 합니다.** 68 | 69 | ``` 70 | Private key: 5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr 71 | Public key: EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg 72 | ``` 73 | 74 | 개인 키 부분을 지갑에 임포트하세요. 성공했다면, 쌍으로 맺어진 공개 키가 표시될 것입니다. 위에서 생성했던 공개 키와 일치해야만 합니다: 75 | 76 | ``` 77 | cleos --wallet-port 8899 wallet import 5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr 78 | imported private key for: EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg 79 | ``` 80 | 81 | 이제 `inita` 계정을 생성해서 프로듀서로 만들 겁니다. `create account` 명령어에는 공개 키 두 개를 인자로 줘야 합니다. 하나는 계정의 소유자(owner) 권한용 키고, 또 하나는 계정의 활동(active) 권한용 키입니다. 이 예제에서는, 새로 생성한 공개 키를 두 번 썼습니다. 소유자랑 활동 권한을 같은 키로 설정한 것이죠. create 명령어의 실행 예제는 아래와 같습니다: 82 | 83 | ``` 84 | cleos --wallet-port 8899 create account eosio inita EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg 85 | executed transaction: d1ea511977803d2d88f46deb554f5b6cce355b9cc3174bec0da45fc16fe9d5f3 352 bytes 102400 cycles 86 | # eosio <= eosio::newaccount {"creator":"eosio","name":"inita","owner":{"threshold":1,"keys":[{"key":"EOS6hMjoWRF2L8x9YpeqtUEcsDK... 87 | ``` 88 | 이제 컨트랙트를 할당받을 수 있게 된 계정을 손에 넣었습니다. 이것으로 여러가지를 할 수 있다는 뜻입니다. 다른 튜토리얼에서는 간단한 컨트랙트 설정을 위해 계정을 사용했습니다. 이번에는 계정을 블록 프로듀서로 사용해 보죠. 89 | 90 | 네 번째 터미널 윈도우를 열고, 두 번째 `nodeos` 인스턴스를 실행합니다. 첫 번째 블록 프로듀서를 생성할 때 사용했던 것 보다 명령어가 좀 더 긴 것에 주목하세요. 이건 첫 번째 `nodeos` 인스턴스와 충돌을 방지하기 위해 불가피한 일입니다. 다행히도, 아래의 명령어를 복붙하시면 됩니다(필요하다면 키 부분을 바꾸세요): 91 | 92 | ``` 93 | nodeos --producer-name inita --plugin eosio::chain_api_plugin --plugin eosio::net_api_plugin --http-server-address 127.0.0.1:8889 --p2p-listen-endpoint 127.0.0.1:9877 --p2p-peer-address 127.0.0.1:9876 --config-dir node2 --data-dir node2 --private-key [\"EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg\",\"5JgbL2ZnoEAhTudReWH1RnMuQS6DBeLZt4ucV6t8aymVEuYg7sr\"] 94 | 95 | ``` 96 | 97 | 새 노드 생성 결과로 약간의 활동 정보가 출력됩니다만, 이 튜토리얼의 마지막 단계에서 `inita` 계정을 프로듀서 계정으로 만들고 활성화하기 전까지는 더이상 아무 정보도 출력되지 않을 것입니다. 새로 시작된 노드에서 출력하는 결과의 예제가 아래 표시돼 있습니다. 여러분이 실제 해 보시면 아마 약간 다를 것인데요, 이는 이 명령어를 실행하는 동안 얼마나 시간이 지났느냐에 따릅니다. 사족을 좀 더 달면, 예제로 보여드리는 것은 출력의 마지막 일부입니다: 98 | 99 | ``` 100 | 2393147ms thread-0 producer_plugin.cpp:176 plugin_startup ] producer plugin: plugin_startup() end 101 | 2393157ms thread-0 net_plugin.cpp:1271 start_sync ] Catching up with chain, our last req is 0, theirs is 8249 peer dhcp15.ociweb.com:9876 - 295f5fd 102 | 2393158ms thread-0 chain_controller.cpp:1402 validate_block_heade ] head_block_time 2018-03-01T12:00:00.000, next_block 2018-04-05T22:31:08.500, block_interval 500 103 | 2393158ms thread-0 chain_controller.cpp:1404 validate_block_heade ] Did not produce block within block_interval 500ms, took 3061868500ms) 104 | 2393512ms thread-0 producer_plugin.cpp:241 block_production_loo ] Not producing block because production is disabled until we receive a recent block (see: --enable-stale-production) 105 | 2395680ms thread-0 net_plugin.cpp:1385 recv_notice ] sync_manager got last irreversible block notice 106 | 2395680ms thread-0 net_plugin.cpp:1271 start_sync ] Catching up with chain, our last req is 8248, theirs is 8255 peer dhcp15.ociweb.com:9876 - 295f5fd 107 | 2396002ms thread-0 producer_plugin.cpp:226 block_production_loo ] Previous result occurred 5 times 108 | 2396002ms thread-0 producer_plugin.cpp:244 block_production_loo ] Not producing block because it isn't my turn, its eosio 109 | 110 | ``` 111 | 112 | 이 시점에서 두 번째 `nodeos`는 놀고 있는 프로듀서입니다. 활동하는(블록을 생산하는) 프로듀서로 바꾸려면 `inita`를 bios 노드에 프로듀서로 등록해야만 합니다. 아울러 bios 노드에서는 프로듀서 스케줄을 업데이트할 액션을 실행해야 합니다. 113 | 114 | ``` 115 | cleos --wallet-port 8899 push action eosio setprods "{ \"version\": 1, \"producers\": [{\"producer_name\": \"inita\",\"block_signing_key\": \"EOS6hMjoWRF2L8x9YpeqtUEcsDKAyxSuM1APicxgRU1E3oyV5sDEg\"}]}" -p eosio@active 116 | executed transaction: 2cff4d96814752aefaf9908a7650e867dab74af02253ae7d34672abb9c58235a 272 bytes 105472 cycles 117 | # eosio <= eosio::setprods {"version":1,"producers":[{"producer_name":"inita","block_signing_key":"EOS6hMjoWRF2L8x9YpeqtUEcsDKA... 118 | ``` 119 | 120 | 축하합니다, 방금 두 노드로 이루어진 테스트넷을 설정하는 데 성공했습니다! 원래 노드(bios 노드)는 이제 블록을 생산하지는 않고 수신만 하는 것을 확인해 보실 수 있습니다. `get info` 명령어를 각 노드에 때려보시면 확인 가능합니다. 121 | 122 | 첫 번째 노드에 대한 `get info` 결과: 123 | ``` 124 | cleos get info 125 | ``` 126 | 127 | 결과는 반드시 다음과 유사해야 합니다: 128 | ``` 129 | { 130 | "server_version": "223565e8", 131 | "head_block_num": 11412, 132 | "last_irreversible_block_num": 11411, 133 | "head_block_id": "00002c94daf7dff456cd940bd585c4d9b38e520e356d295d3531144329c8b6c3", 134 | "head_block_time": "2018-04-06T00:06:14", 135 | "head_block_producer": "inita" 136 | } 137 | ``` 138 | 139 | 이번엔 두 번째 노드: 140 | ``` 141 | cleos --port 8889 get info 142 | ``` 143 | 144 | 결과는 반드시 다음과 유사해야 합니다: 145 | ``` 146 | { 147 | "server_version": "223565e8", 148 | "head_block_num": 11438, 149 | "last_irreversible_block_num": 11437, 150 | "head_block_id": "00002cae32697444fa9a2964e4db85b5e8fd4c8b51529a0c13e38587c1bf3c6f", 151 | "head_block_time": "2018-04-06T00:06:27", 152 | "head_block_producer": "inita" 153 | } 154 | ``` 155 | 156 | 이후 튜토리얼에서는 멀티 호스트, 멀티 노드 테스트넷을 구성하기 위한 보다 발전된 도구들을 어떻게 사용하는지 알아보도록 하겠습니다. 157 | 158 | ## 번역 정보 159 | 160 | * 위키 원문 : https://github.com/eosio/eos/wiki/Testnet-Single-Host-Multinode 161 | * 번역 기준 리비전 : 0c18223ea118597c7b2476118091c4094be6af99 162 | -------------------------------------------------------------------------------- /ko/translations/Dice.md: -------------------------------------------------------------------------------- 1 | 주사위 2 | ----------------- 3 | 4 | 이 컨트랙트는 두 명의 플레이어가 50 대 50의 승률을 가진 간단한 주사위 게임이다. 5 | 6 | 플레이하기 전 모든 플레이어는 `@exchange` 컨트랙트와 마찬가지로 `@dice` 컨트랙트 계정에 자금을 입금한다. 7 | 8 | 1. 플레이어 1은 1 EOS를 걸고 SHA256(secret1) 으로 나온 해시값을 제출한다. 9 | 2. 플레이어 2는 1 EOS를 걸고 SHA256(secret2) 으로 나온 해시값을 제출한다. 10 | 11 | 플레이어 1과 2는 같은 금액을 걸었기 때문에, 주문 내역이 일치하고 이제 게임이 시작된다. 12 | 13 | 3. 플레이어 둘 중 어느 하나가 패를 오픈한다. 14 | 4. 5분 마감 시간이 시작되고, 다른 플레이어가 자신의 패를 오픈하지 않으면 먼저 오픈한 플레이어가 승리한다. 15 | 5. 다른 플레이어가 패를 오픈하면 SHA256( cat(secret1,secret2) ) 의 결과에 따라 승자가 결정되고 승리보수가 지급된다. 16 | 6. 마감시간이 지나면 둘 다 청구하여 보상을 수령할 수 있다. 17 | 18 | 19 | 인터페이스 제작자를 위한 인센티브 20 | ----------------- 21 | 22 | 이 게임을 변형해서 플레이어가 승리했을 때 제작자가 커미션을 받게 하도록 정보를 추가할 수도 있다. 이렇게 커미션이 있다면 서비스 제공 업체가 오래도록 적시에 23 | 게임을 계속 서비스할 재정적 인센티브가 주어질 뿐더러, 게임 퀄리티를 향상시키고 24 | 재미있는 인터페이스를 붙이게도 할 것이다. 25 | 26 | 27 | 다른 게임 28 | ----------- 29 | 이와 동일한 기초 모델로 더 탄탄한 게임을 만들 수 있다. 30 | 31 | 32 | 잠재적 취약성 33 | ------- 34 | 1. 블록 프로듀서가 패-오픈 트랜잭션을 거부할 수 있다. 35 | 2. 패자가 승자를 5분 동안 기다리게 만들 수 있다. 36 | 3. 서비스 제공자가 구현한 자동 패-오픈 시스템이 실행되지 않을 가능성이 있다. 37 | 4. 게임 도중에 인터넷이 끊길 수 있다. 38 | 5. 블록체인 재구성이 일어날 때, 패가 너무 빨리 오픈되는 등의 혼란이 발생할 수 있다. 39 | - `@dice`는 게임 생성이 비가역확정 상태에 도달하기까지(최대 45초) 패-오픈을 거절하여 사용자를 보호할 수 있다. 40 | - 사용자는 필요한 승인 횟수를 결정하여 리스크를 감수할 수 있다. 41 | - 작은 금액의 경우 아마 문제되지 않을 것이다. 42 | - DPOS 체인이 정상적으로 작동하는 경우 체인 재구성이 거의 없을 것이다. 43 | 44 | 45 | `cleos`를 이용한 게임 세션 예제 46 | ------- 47 | #### 사전 준비 48 | * 지갑은 unlock 상태로 만들고 아래 비밀키를 사용한다. 49 | 50 | **5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3** 51 | **5Jmsawgsp1tQ3GD6JyGCwy1dcvqKZgX6ugMVMdjirx85iv5VyPR** 52 | 53 | ##### BIOS 컨트랙트 로딩 54 | ````bash 55 | cleos set contract eosio build/contracts/eosio.bios -p eosio 56 | ```` 57 | 58 | ##### `eosio.token` 계정 생성 59 | ````bash 60 | cleos create account eosio eosio.token EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 61 | ```` 62 | 63 | ##### `eosio.token` 계정에 `eosio.token` 컨트랙트 코드를 배포 64 | ````bash 65 | cleos set contract eosio.token build/contracts/eosio.token -p eosio.token 66 | ```` 67 | 68 | ##### 주사위 컨트랙트 배포용 계정 생성 69 | ````bash 70 | cleos create account eosio dice EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 71 | ```` 72 | 73 | ##### `dice` 계정에 `dice` 컨트랙트 코드를 배포 74 | ````bash 75 | cleos set contract dice build/contracts/dice -p dice 76 | ```` 77 | 78 | ##### 기본 `EOS` 토큰 생성 79 | ````bash 80 | cleos push action eosio.token create '[ "eosio", "1000000000.0000 EOS", 0, 0, 0]' -p eosio.token 81 | ```` 82 | 83 | ##### `alice` 계정 생성 84 | ````bash 85 | cleos create account eosio alice EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 86 | ```` 87 | 88 | ##### `bob` 계정 생성 89 | ````bash 90 | cleos create account eosio bob EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 91 | ```` 92 | 93 | ##### 1000 EOS 를 `alice` 계정에 발행 94 | ````bash 95 | cleos push action eosio.token issue '[ "alice", "1000.0000 EOS", "" ]' -p eosio 96 | ```` 97 | 98 | ##### 1000 EOS 를 `bob` 계정에 발행 99 | ````bash 100 | cleos push action eosio.token issue '[ "bob", "1000.0000 EOS", "" ]' -p eosio 101 | ```` 102 | 103 | ##### `dice` 컨트랙트 실행시 `alice` 계정 대신 입금과 이체를 할 수 있도록 권한 허가 104 | ````bash 105 | cleos set account permission alice active '{"threshold": 1,"keys": [{"key": "EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4","weight": 1}],"accounts": [{"permission":{"actor":"dice","permission":"active"},"weight":1}]}' owner -p alice 106 | ```` 107 | 108 | ##### `dice` 컨트랙트 실행시 `bob` 계정 대신 입금과 이체를 할 수 있도록 권한 허가 109 | ````bash 110 | cleos set account permission bob active '{"threshold": 1,"keys": [{"key": "EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4","weight": 1}],"accounts": [{"permission":{"actor":"dice","permission":"active"},"weight":1}]}' owner -p bob 111 | ```` 112 | 113 | ##### `alice` 계정에서 100 EOS 만큼 `dice` 컨트랙트로 이체 - 베팅용 자금 114 | ````bash 115 | cleos push action dice deposit '[ "alice", "100.0000 EOS" ]' -p alice 116 | ```` 117 | 118 | ##### `bob` 계정에서 100 EOS 만큼 `dice` 컨트랙트로 이체 - 베팅용 자금 119 | ````bash 120 | cleos push action dice deposit '[ "bob", "100.0000 EOS" ]' -p bob 121 | ```` 122 | 123 | ##### `alice` 계정이 사용할 랜덤 문자열 생성 124 | ````bash 125 | openssl rand 32 -hex 126 | 28349b1d4bcdc9905e4ef9719019e55743c84efa0c5e9a0b077f0b54fcd84905 127 | ```` 128 | 129 | ##### `alice` 계정이 사용할 랜덤 문자열의 해시 생성 - sha256(secret) 130 | ````bash 131 | echo -n '28349b1d4bcdc9905e4ef9719019e55743c84efa0c5e9a0b077f0b54fcd84905' | xxd -r -p | sha256sum -b | awk '{print $1}' 132 | d533f24d6f28ddcef3f066474f7b8355383e485681ba8e793e037f5cf36e4883 133 | ```` 134 | 135 | ##### `alice` 계정에서 3 EOS 베팅 136 | ````bash 137 | cleos push action dice offerbet '[ "3.0000 EOS", "alice", "d533f24d6f28ddcef3f066474f7b8355383e485681ba8e793e037f5cf36e4883" ]' -p alice 138 | ```` 139 | 140 | ##### `bob` 계정이 사용할 랜덤 문자열 생성 141 | ````bash 142 | openssl rand 32 -hex 143 | 15fe76d25e124b08feb835f12e00a879bd15666a33786e64b655891fba7d6c12 144 | ```` 145 | 146 | ##### `bob` 계정이 사용할 랜덤 문자열의 해시 생성 - sha256(secret) 147 | ````bash 148 | echo -n '15fe76d25e124b08feb835f12e00a879bd15666a33786e64b655891fba7d6c12' | xxd -r -p | sha256sum -b | awk '{print $1}' 149 | 50ed53fcdaf27f88d51ea4e835b1055efe779bb87e6cfdff47d28c88ffb27129 150 | ```` 151 | 152 | ##### `bob` 계정에서도 3 EOS 베팅 (이제 게임 시작) 153 | ````bash 154 | cleos push action dice offerbet '[ "3.0000 EOS", "bob", "50ed53fcdaf27f88d51ea4e835b1055efe779bb87e6cfdff47d28c88ffb27129" ]' -p bob 155 | ```` 156 | 157 | ##### 게임이 시작된 직후의 `dice` 컨트랙트 테이블 상태 확인 158 | ````bash 159 | cleos get table dice dice account 160 | ```` 161 | ````json 162 | { 163 | "rows": [{ 164 | "owner": "alice", 165 | "eos_balance": "97.0000 EOS", 166 | "open_offers": 0, 167 | "open_games": 1 168 | },{ 169 | "owner": "bob", 170 | "eos_balance": "97.0000 EOS", 171 | "open_offers": 0, 172 | "open_games": 1 173 | } 174 | ], 175 | "more": false 176 | } 177 | ```` 178 | 179 | ````bash 180 | cleos get table dice dice game 181 | ```` 182 | ````json 183 | { 184 | "rows": [{ 185 | "id": 1, 186 | "bet": "3.0000 EOS", 187 | "deadline": "1970-01-01T00:00:00", 188 | "player1": { 189 | "commitment": "d533f24d6f28ddcef3f066474f7b8355383e485681ba8e793e037f5cf36e4883", 190 | "reveal": "0000000000000000000000000000000000000000000000000000000000000000" 191 | }, 192 | "player2": { 193 | "commitment": "50ed53fcdaf27f88d51ea4e835b1055efe779bb87e6cfdff47d28c88ffb27129", 194 | "reveal": "0000000000000000000000000000000000000000000000000000000000000000" 195 | } 196 | } 197 | ], 198 | "more": false 199 | } 200 | ```` 201 | 202 | ##### `bob` 계정이 자신의 패를 오픈(reveal) 203 | ````bash 204 | cleos push action dice reveal '[ "50ed53fcdaf27f88d51ea4e835b1055efe779bb87e6cfdff47d28c88ffb27129", "15fe76d25e124b08feb835f12e00a879bd15666a33786e64b655891fba7d6c12" ]' -p bob 205 | ```` 206 | 207 | ##### `bob` 계정이 패를 오픈한 직후의 게임 테이블(이제 `alice` 계정이 패를 오픈할 수 있는 deadline이 생김) 208 | ````bash 209 | cleos get table dice dice game 210 | ```` 211 | ````json 212 | { 213 | "rows": [{ 214 | "id": 1, 215 | "bet": "3.0000 EOS", 216 | "deadline": "2018-04-17T07:45:49", 217 | "player1": { 218 | "commitment": "d533f24d6f28ddcef3f066474f7b8355383e485681ba8e793e037f5cf36e4883", 219 | "reveal": "0000000000000000000000000000000000000000000000000000000000000000" 220 | }, 221 | "player2": { 222 | "commitment": "50ed53fcdaf27f88d51ea4e835b1055efe779bb87e6cfdff47d28c88ffb27129", 223 | "reveal": "15fe76d25e124b08feb835f12e00a879bd15666a33786e64b655891fba7d6c12" 224 | } 225 | } 226 | ], 227 | "more": false 228 | } 229 | ```` 230 | 231 | ##### `alice` 계정이 패를 오픈 (승자가 결정되고, 게임이 종료됨) 232 | ````bash 233 | cleos push action dice reveal '[ "d533f24d6f28ddcef3f066474f7b8355383e485681ba8e793e037f5cf36e4883", "28349b1d4bcdc9905e4ef9719019e55743c84efa0c5e9a0b077f0b54fcd84905" ]' -p alice 234 | ```` 235 | 236 | ##### 게임이 종료된 후 각 계정의 잔고 237 | ````bash 238 | cleos get table dice dice account 239 | ```` 240 | ````json 241 | { 242 | "rows": [{ 243 | "owner": "alice", 244 | "eos_balance": "103.0000 EOS", 245 | "open_offers": 0, 246 | "open_games": 0 247 | },{ 248 | "owner": "bob", 249 | "eos_balance": "97.0000 EOS", 250 | "open_offers": 0, 251 | "open_games": 0 252 | } 253 | ], 254 | "more": false 255 | } 256 | ```` 257 | 258 | ##### `alice` 계정이 `dice` 컨트랙트에 묶인 103 EOS를 인출 259 | ````bash 260 | cleos push action dice withdraw '[ "alice", "103.0000 EOS" ]' -p alice 261 | ```` 262 | 263 | ##### 인출 이후 `alice`의 잔고 264 | ````bash 265 | cleos get currency balance eosio.token alice eos 266 | 1003.0000 EOS 267 | ```` 268 | 269 | ## 번역 정보 270 | 271 | * 원문 : https://github.com/EOSIO/eos/blob/master/contracts/dice/README.md 272 | * 번역 기준 리비전 : 93d5f9718ed68fe7fc139529459aa307a9d8c406 273 | * 관련 코드 274 | * https://github.com/EOSIO/eos/blob/master/contracts/dice/dice.abi 275 | * https://github.com/EOSIO/eos/blob/master/contracts/dice/dice.cpp 276 | -------------------------------------------------------------------------------- /ko/translations/Tutorial-Hello-World-Contract.md: -------------------------------------------------------------------------------- 1 | ## Hello World 컨트랙트 2 | **이 튜토리얼은 튜토리얼 [컨트랙트 처음 시작하기](https://github.com/eoseoul/docs/blob/master/ko/translations/TUTORIAL.md)와 [eosio.token, 거래소, eosio.msig 컨트랙트](https://github.com/eoseoul/docs/blob/master/ko/translations/Tutorial-eosio-token-Contract.md)를 완료했다고 가정합니다.** 3 | 4 | 다음 단계로 우리의 첫 "hello world" 컨트랙트를 만들어 봅시다. "hello"라는 5 | 디렉토리를 만들고 `cd`로 디렉토리로 들어간 후 "hello.cpp" 파일을 만들어 6 | 아래 내용을 추가합니다. 7 | 8 | ### hello/hello.cpp 9 | ``` 10 | #include 11 | #include 12 | using namespace eosio; 13 | 14 | class hello : public eosio::contract { 15 | public: 16 | using contract::contract; 17 | 18 | /// @abi action 19 | void hi( account_name user ) { 20 | print( "Hello, ", name{user} ); 21 | } 22 | }; 23 | 24 | EOSIO_ABI( hello, (hi) ) 25 | ``` 26 | 27 | 이제 컴파일해서 web assembly(.wast)를 만듭니다. 28 | ``` 29 | $ eosiocpp -o hello.wast hello.cpp 30 | ``` 31 | **주의** 컴파일러에서 에러 메시지가 나올 것입니다. 무시해도 됩니다. 32 | 33 | 이어서 abi를 만듭니다. 34 | 35 | ``` 36 | $ eosiocpp -g hello.abi hello.cpp 37 | Generated hello.abi 38 | ``` 39 | 40 | 이제 계정을 만들고 컨트랙트를 업로드합니다. 41 | 42 | ``` 43 | $ cleos create account eosio hello.code EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 44 | ... 45 | $ cleos set contract hello.code ../hello -p hello.code 46 | ... 47 | ``` 48 | 49 | 이제 컨트랙트를 실행할 수 있습니다. 50 | 51 | ``` 52 | $ cleos push action hello.code hi '["user"]' -p user 53 | executed transaction: 4c10c1426c16b1656e802f3302677594731b380b18a44851d38e8b5275072857 244 bytes 1000 cycles 54 | # hello.code <= hello.code::hi {"user":"user"} 55 | >> Hello, user 56 | ``` 57 | 58 | 위의 `hello/hello.cpp`로 구현한 컨트랙트는 누구나 사용할 수 있습니다. 59 | 다른 권한을 사용해보겠습니다. 60 | 61 | ``` 62 | $ cleos push action hello.code hi '["user"]' -p tester 63 | executed transaction: 28d92256c8ffd8b0255be324e4596b7c745f50f85722d0c4400471bc184b9a16 244 bytes 1000 cycles 64 | # hello.code <= hello.code::hi {"user":"user"} 65 | >> Hello, user 66 | ``` 67 | 68 | 위 커맨드의 `-p tester`에 사용한 `tester`는 권한 계정이고, `user`는 단순히 69 | 인자 하나입니다. 컨트랙트 실행시 자신이 가진 권한 계정으로 인증하려면, 70 | 컨트랙트를 이렇게 바꿔야 합니다. 71 | 72 | "hello.cpp" 파일의 hi() 함수를 이렇게 바꿉니다. 73 | 74 | ``` 75 | void hi( account_name user ) { 76 | require_auth( user ); 77 | print( "Hello, ", name{user} ); 78 | } 79 | ``` 80 | wast 파일을 컴파일하고 ABI를 만드는 과정을 다시 진행하고, `set contract`를 81 | 다시 실행하면 변경된 내용이 배포됩니다. 82 | 83 | 일부러 현재의 권한과 사용하는 권한을 다르게 설정하여 컨트랙트 액션을 84 | 실행하면 에러가 발생합니다. 85 | ``` 86 | $ cleos push action hello.code hi '["tester"]' -p user 87 | Error 3030001: missing required authority 88 | Ensure that you have the related authority inside your transaction!; 89 | If you are currently using 'cleos push action' command, try to add the relevant authority using -p option. 90 | Error Details: 91 | missing authority of tester 92 | ``` 93 | 94 | 다음과 같이 `tester` 권한을 주면 정상적으로 동작합니다. 95 | 96 | ``` 97 | $ cleos push action hello.code hi '["tester"]' -p tester 98 | executed transaction: 235bd766c2097f4a698cfb948eb2e709532df8d18458b92c9c6aae74ed8e4518 244 bytes 1000 cycles 99 | # hello.code <= hello.code::hi {"user":"tester"} 100 | >> Hello, tester 101 | ``` 102 | 103 | ## Hello World 리카도 컨트랙트 104 | 105 | 모든 스마트 컨트랙트는 스마트 컨트랙트가 준수하는 리카도 컨트랙트와 연결되어야 106 | 합니다. 리카도 컨트랙트는 스마트 컨트랙트의 각 액션과 관련된 법적 구속력있는 107 | 행동을 명시합니다. Hello World 컨트랙트에 대한 리카도 컨트랙트의 예시는 108 | 아래와 같습니다. 109 | 110 | ```markdown 111 | ## CONTRACT FOR HELLO WORLD 112 | 113 | ### Parameters 114 | Input paramters: NONE 115 | 116 | Implied parameters: 117 | 118 | * _**account_name**_ (name of the party invoking and signing the contract) 119 | 120 | ### Intent 121 | INTENT. The intention of the author and the invoker of this contract is to print output. It shall have no other effect. 122 | 123 | ### Term 124 | TERM. This Contract expires at the conclusion of code execution. 125 | 126 | ### Warranty 127 | WARRANTY. {{ account_name }} shall uphold its Obligations under this Contract in a timely and workmanlike manner, using knowledge and recommendations for performing the services which meet generally acceptable standards set forth by EOS.IO Blockchain Block Producers. 128 | 129 | ### Default 130 | DEFAULT. The occurrence of any of the following shall constitute a material default under this Contract: 131 | 132 | ### Remedies 133 | REMEDIES. In addition to any and all other rights a party may have available according to law, if a party defaults by failing to substantially perform any provision, term or condition of this Contract, the other party may terminate the Contract by providing written notice to the defaulting party. This notice shall describe with sufficient detail the nature of the default. The party receiving such notice shall promptly be removed from being a Block Producer and this Contract shall be automatically terminated. 134 | 135 | ### Force Majeure 136 | FORCE MAJEURE. If performance of this Contract or any obligation under this Contract is prevented, restricted, or interfered with by causes beyond either party's reasonable control ("Force Majeure"), and if the party unable to carry out its obligations gives the other party prompt written notice of such event, then the obligations of the party invoking this provision shall be suspended to the extent necessary by such event. The term Force Majeure shall include, without limitation, acts of God, fire, explosion, vandalism, storm or other similar occurrence, orders or acts of military or civil authority, or by national emergencies, insurrections, riots, or wars, or strikes, lock-outs, work stoppages, or supplier failures. The excused party shall use reasonable efforts under the circumstances to avoid or remove such causes of non-performance and shall proceed to perform with reasonable dispatch whenever such causes are removed or ceased. An act or omission shall be deemed within the reasonable control of a party if committed, omitted, or caused by such party, or its employees, officers, agents, or affiliates. 137 | 138 | ### Dispute Resolution 139 | DISPUTE RESOLUTION. Any controversies or disputes arising out of or relating to this Contract will be resolved by binding arbitration under the default rules set forth by the EOS.IO Blockchain. The arbitrator's award will be final, and judgment may be entered upon it by any court having proper jurisdiction. 140 | 141 | ### Entire Agreement 142 | ENTIRE AGREEMENT. This Contract contains the entire agreement of the parties, and there are no other promises or conditions in any other agreement whether oral or written concerning the subject matter of this Contract. This Contract supersedes any prior written or oral agreements between the parties. 143 | 144 | ### Severability 145 | SEVERABILITY. If any provision of this Contract will be held to be invalid or unenforceable for any reason, the remaining provisions will continue to be valid and enforceable. If a court finds that any provision of this Contract is invalid or unenforceable, but that by limiting such provision it would become valid and enforceable, then such provision will be deemed to be written, construed, and enforced as so limited. 146 | 147 | ### Amendment 148 | AMENDMENT. This Contract may be modified or amended in writing by mutual agreement between the parties, if the writing is signed by the party obligated under the amendment. 149 | 150 | ### Governing Law 151 | GOVERNING LAW. This Contract shall be construed in accordance with the Maxims of Equity. 152 | 153 | ### Notice 154 | NOTICE. Any notice or communication required or permitted under this Contract shall be sufficiently given if delivered to a verifiable email address or to such other email address as one party may have publicly furnished in writing, or published on a broadcast contract provided by this blockchain for purposes of providing notices of this type. 155 | 156 | ### Waiver of Contractual Right 157 | WAIVER OF CONTRACTUAL RIGHT. The failure of either party to enforce any provision of this Contract shall not be construed as a waiver or limitation of that party's right to subsequently enforce and compel strict compliance with every provision of this Contract. 158 | 159 | ### Arbitrator's Fees to Prevailing Party 160 | ARBITRATOR’S FEES TO PREVAILING PARTY. In any action arising hereunder or any separate action pertaining to the validity of this Agreement, both sides shall pay half the initial cost of arbitration, and the prevailing party shall be awarded reasonable arbitrator's fees and costs. 161 | 162 | ### Construction and Interpretation 163 | CONSTRUCTION AND INTERPRETATION. The rule requiring construction or interpretation against the drafter is waived. The document shall be deemed as if it were drafted by both parties in a mutual effort. 164 | 165 | ### In Witness Whereof 166 | IN WITNESS WHEREOF, the parties hereto have caused this Agreement to be executed by themselves or their duly authorized representatives as of the date of execution, and authorized as proven by the cryptographic signature on the transaction that invokes this contract. 167 | 168 | ``` 169 | 170 | # 번역 정보 171 | 172 | * 원문 : https://github.com/eosio/eos/wiki/Tutorial-Hello-World-Contract 173 | * 번역 기준 리비전 : 0c18223ea118597c7b2476118091c4094be6af99 174 | -------------------------------------------------------------------------------- /ko/translations/Tutorial-eosio-token-Contract.md: -------------------------------------------------------------------------------- 1 | ## `eosio.token`, 거래소, `eosio.msig` 컨트랙트 2 | 3 | **이 튜토리얼은 튜토리얼 [컨트랙트 처음 시작하기](https://github.com/eoseoul/docs/blob/master/ko/translations/TUTORIAL.md)를 완료했다고 가정합니다.** 4 | 5 | 이 단계에서는 블록체인만으로는 할 수 있는 게 별로 없기 때문에, 6 | `eosio.token`이라는 컨트랙트를 배포합시다. 이 컨트랙트 하나만 배포해놓으면, 7 | 여러 사용자들이 이 컨트랙트 하나만 이용해서 서로 다른 토큰을 만들 수 있습니다. 8 | 9 | 토큰 컨트랙트를 배포하려면, 컨트랙트를 배포할 계정을 만들어야 합니다. 10 | 11 | ``` 12 | $ cleos create account eosio eosio.token EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 13 | ... 14 | ``` 15 | 16 | 이제 `${EOSIO_SOURCE}/build/contracts/eosio.token`에 있는 컨트랙트를 배포합니다. 17 | 18 | ``` 19 | $ cleos set contract eosio.token build/contracts/eosio.token -p eosio.token 20 | Reading WAST... 21 | Assembling WASM... 22 | Publishing contract... 23 | executed transaction: 528bdbce1181dc5fd72a24e4181e6587dace8ab43b2d7ac9b22b2017992a07ad 8708 bytes 10000 cycles 24 | # eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001ce011d60067f7e7f7f7f7f00... 25 | # eosio <= eosio::setabi {"account":"eosio.token","abi":{"types":[],"structs":[{"name":"transfer","base":"","fields":[{"name"... 26 | ``` 27 | 28 | ### EOS 토큰 생성 29 | 30 | `contracts/eosio.token/eosio.token.hpp`에 정의된 `eosio.token` 인터페이스를 31 | 살펴봅시다. 32 | ``` 33 | void create( account_name issuer, 34 | asset maximum_supply, 35 | uint8_t can_freeze, 36 | uint8_t can_recall, 37 | uint8_t can_whitelist ); 38 | 39 | 40 | void issue( account_name to, asset quantity, string memo ); 41 | 42 | void transfer( account_name from, 43 | account_name to, 44 | asset quantity, 45 | string memo ); 46 | ``` 47 | 48 | 새로운 토큰을 생성하려면 올바른 인자로 `create(...)` 액션을 호출해야 합니다. 49 | 이 커맨드는 다른 토큰과 구별하기 위해 토큰의 최대 공급량 수치에 토큰 심볼을 50 | 덧붙입니다. 발행자는 발행을 실행하고, 토큰 소유자를 동결, 회수, 허용하는 51 | 액션을 실행하는 권한을 가진 사용자가 됩니다. 52 | 53 | 위치 매개변수(positional argument)를 사용하여 간결하게 커맨드를 실행해봅니다. 54 | 55 | ``` 56 | $ cleos push action eosio.token create '[ "eosio", "1000000000.0000 EOS", 0, 0, 0]' -p eosio.token 57 | executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 260 bytes 1000 cycles 58 | # eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 EOS","can_freeze":0,"can_recall":0,"can_whitelis... 59 | ``` 60 | 61 | 또는, named argument로 자세하게 호출하는 방법도 있습니다. 62 | 63 | ``` 64 | $ cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 EOS", "can_freeze":0, "can_recall":0, "can_whitelist":0}' -p eosio.token 65 | executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 260 bytes 1000 cycles 66 | # eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 EOS","can_freeze":0,"can_recall":0,"can_whitelis... 67 | ``` 68 | 69 | 이 커맨드는 `EOS`라는 심볼을 갖는 새로운 토큰을 생성합니다. 이 토큰은 소수점 70 | 4자리까지 지원하고 최대 공급량은 1000000000.0000 EOS입니다. 71 | 72 | 이 토큰을 생성하기 위하여 `eosio.token` 컨트랙트의 권한이 필요합니다. 73 | `eosio.token` 컨트랙트가 `EOS`와 같은 토큰 심볼 네임스페이스를 "소유"하기 74 | 때문입니다. 여러 주체들이 자동으로 토큰 심볼 구매가 가능하도록, 앞으로 75 | eosio.token 컨트랙트가 변경될 수 있습니다. 그래서 위의 액션을 실행하려면 76 | 커맨드에 `-p eosio.token`를 붙여야 합니다. 77 | 78 | ### `user` 계정에 토큰 발행 79 | 80 | 이제 토큰을 만들었으니, 발행자는 새로운 토큰들을 앞서 만든 `user` 계정으로 발행할 수 있습니다. 81 | 82 | 우리는 (named argument 방식 대신) 위치 매개변수 방식을 사용하겠습니다. 83 | 84 | ``` 85 | $ cleos push action eosio.token issue '[ "user", "100.0000 EOS", "memo" ]' -p eosio 86 | executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles 87 | # eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 EOS","memo":"memo"} 88 | >> issue 89 | # eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 EOS","memo":"memo"} 90 | >> transfer 91 | # eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 EOS","memo":"memo"} 92 | # user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 EOS","memo":"memo"} 93 | ``` 94 | 95 | 출력 내용을 살펴보면 다양한 액션이 눈에 띕니다. 발행(issue) 1건과 96 | 이체(transfer) 3건이 확인됩니다. 우리가 적당한 권한으로 실행한 유일한 액션은 97 | 발행(issue) 하나입니다만, `issue` 액션은 "inline transfer"를 수행했고, 98 | "inline transfer"는 송신자 계정과 수신자 계정에 각각 이체 정보를 전달했습니다. 99 | 출력 내용은, 호출된 액션 핸들러 전체 목록과 호출된 순서와 액션으로 생성된 100 | 출력이 있는지 없는지를 보여줍니다. 101 | 102 | 사실 `eosio.token` 컨트랙트는 `inline transfer`를 건너뛰고 밸런스를 직접적으로 103 | 조절할 수 있었지만, 이 경우에는 `eosio.token` 컨트랙트가 모든 계정 잔액이 104 | 이체 액션의 합으로 계산이 되어야 한다는 토큰 규칙을 따랐습니다. 또, 입금과 105 | 출금을 자동적으로 처리할 수 있도록 송신자와 수신자 모두에게 정보를 이체 정보를 106 | 전달해야 하는 토큰 규칙도 지켰습니다. 107 | 108 | 네트워크에 브로드캐스트된 실제 트랜잭션 내용을 보고 싶다면, `-d -j` 옵션을 109 | 사용하세요. 이 옵션을 사용하면 브로드캐스트 하지 않고 트랜잭션 내용을 110 | JSON 포맷으로 출력합니다. 111 | 112 | ``` 113 | $ cleos push action eosio.token issue '["user", "100.0000 EOS", "memo"]' -p eosio -d -j 114 | { 115 | "expiration": "2018-04-01T15:20:44", 116 | "region": 0, 117 | "ref_block_num": 42580, 118 | "ref_block_prefix": 3987474256, 119 | "net_usage_words": 21, 120 | "kcpu_usage": 1000, 121 | "delay_sec": 0, 122 | "context_free_actions": [], 123 | "actions": [{ 124 | "account": "eosio.token", 125 | "name": "issue", 126 | "authorization": [{ 127 | "actor": "eosio", 128 | "permission": "active" 129 | } 130 | ], 131 | "data": "00000000007015d640420f000000000004454f5300000000046d656d6f" 132 | } 133 | ], 134 | "signatures": [ 135 | "EOSJzPywCKsgBitRh9kxFNeMJc8BeD6QZLagtXzmdS2ib5gKTeELiVxXvcnrdRUiY3ExP9saVkdkzvUNyRZSXj2CLJnj7U42H" 136 | ], 137 | "context_free_data": [] 138 | } 139 | ``` 140 | 141 | ### `tester`계정으로 토큰 이체 142 | 143 | 이제 계정 `user`의 잔고에 토큰이 들어가 있으니, `tester` 계정으로 144 | 이체하겠습니다. `user`가 이 액션을 허가한다 의미로 권한 인자 `-p user`를 145 | 사용합니다. 146 | 147 | ``` 148 | $ cleos push action eosio.token transfer '[ "user", "tester", "25.0000 EOS", "m" ]' -p user 149 | executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles 150 | # eosio.token <= eosio.token::transfer {"from":"user","to":"tester","quantity":"25.0000 EOS","memo":"m"} 151 | >> transfer 152 | # user <= eosio.token::transfer {"from":"user","to":"tester","quantity":"25.0000 EOS","memo":"m"} 153 | # tester <= eosio.token::transfer {"from":"user","to":"tester","quantity":"25.0000 EOS","memo":"m"} 154 | ``` 155 | 156 | ## 거래소 컨트랙트 배포하기 157 | 158 | 위의 예제와 비슷하게 `exchange` 컨트랙트를 배포하겠습니다. `exchange` 컨트랙트는 159 | 통화를 만들고 거래할 수 있는 기능을 제공합니다. 아래 명령어는 EOSIO 소스 코드의 160 | 루트에서 실행할 수 있습니다. 161 | 162 | ``` 163 | $ cleos create account eosio exchange EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 164 | executed transaction: 4d38de16631a2dc698f1d433f7eb30982d855219e7c7314a888efbbba04e571c 364 bytes 1000 cycles 165 | # eosio <= eosio::newaccount {"creator":"eosio","name":"exchange","owner":{"threshold":1,"keys":[{"key":"EOS7ijWCBmoXBi3CgtK7DJxe... 166 | 167 | $ cleos set contract exchange build/contracts/exchange -p exchange 168 | Reading WAST... 169 | Assembling WASM... 170 | Publishing contract... 171 | executed transaction: 5a63b4de8a1da415590778f163c5ed26dc164c960185b20fd834c297cf7fa8f4 35172 bytes 10000 cycles 172 | # eosio <= eosio::setcode {"account":"exchange","vmtype":0,"vmversion":0,"code":"0061736d0100000001f0023460067f7e7f7f7f7f00600... 173 | # eosio <= eosio::setabi {"account":"exchange","abi":{"types":[{"new_type_name":"account_name","type":"name"}],"structs":[{"n... 174 | ``` 175 | 176 | ## `eosio.msig` 컨트랙트 배포하기 177 | `eosio.msig` 컨트랙트는 다수의 관계자가 단일 트랜잭션을 비동기적으로 서명할 수 178 | 있는 기능을 제공합니다. EOSIO는 기본적인 수준에서 다중 서명(멀티시그) 기능을 179 | 제공하지만, 데이터가 오고가고 서명되는 동기적 사이드 채널이 필요합니다. 180 | `eosio.msig`는 비동기적인 제안과 승인, 다수 관계자의 동의를 얻은 트랜잭션을 181 | 네트워크에 퍼뜨리는 보다 사용자 친화적인 방법을 제공합니다. 182 | 183 | 아래와 같은 명령어로 `eosio.msig` 컨트랙트를 배포합니다. 184 | ``` 185 | $ cleos create account eosio eosio.msig EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 EOS7ijWCBmoXBi3CgtK7DJxentZZeTkeUnaSDvyro9dq7Sd1C3dC4 186 | # eosio <= eosio::newaccount {"creator":"eosio","name":"eosio.msig","owner":{"threshold":1,"keys":[{"key":"EOS7ijWCBmoXBi3CgtK7DJ... 187 | 188 | $ cleos set contract eosio.msig build/contracts/eosio.msig -p eosio.msig 189 | Reading WAST... 190 | Assembling WASM... 191 | Publishing contract... 192 | executed transaction: a113a7db8c878dfd894671792770b59a04efb3aa8295f5b3d585daf89c314ec9 8964 bytes 10000 cycles 193 | # eosio <= eosio::setcode {"account":"eosio.msig","vmtype":0,"vmversion":0,"code":"0061736d0100000001bd011b60047f7e7e7f0060047... 194 | # eosio <= eosio::setabi {"account":"eosio.msig","abi":{"types":[{"new_type_name":"account_name","type":"name"},{"new_type_na... 195 | ``` 196 | 197 | ## 이어서 - Hello World 튜토리얼 198 | 199 | 이제 다음 튜토리얼 [Hello World 튜토리얼](https://github.com/eoseoul/docs/blob/master/ko/translations/Tutorial-Hello-World-Contract.md) 로 넘어갑시다. 200 | 201 | # 번역 정보 202 | 203 | * 원문 : https://github.com/eosio/eos/wiki/Tutorial-eosio-token-Contract 204 | * 번역 기준 리비전 : 0c18223ea118597c7b2476118091c4094be6af99 205 | -------------------------------------------------------------------------------- /reports/eoseoul_tps_2nd_benchmark_20180430.md: -------------------------------------------------------------------------------- 1 | ## EOSeoul Report TPS(24th April) and BlockOne Lab Test(26th April) 2 | 3 | On 24th April, EOSeoul sent our BMT TPS results and related questions to BlockOne. 4 | 5 | * https://steemit.com/en/@eoseoul/bmt-eosio-tps-results-by-eoseoul 6 | 7 | BlockOne replied by email / Steemit /Telegram and shared the test methodology on how they obtained TPS data. 8 | 9 | * Instructions : https://gist.github.com/spoonincode/fca5658326837b76fd744d39b2a25b4e 10 | * github issue : https://github.com/EOSIO/eos/issues/2078 11 | * Video demo : https://vimeo.com/266585781 12 | 13 | BlockOne’s methodology involves using the binaryen interpreter between 1 block producing node and 1 full node. In other words, it is a lab test that tests only the engine performance of EOS. It excludes various factors that could affect TPS in a real world environment as it only calculates the core functionality of transactions via P2P. It is very much like an official mpg (miles per gallon) stamp for automobiles. 14 | 15 | EOSeoul’s TPS methodology was slightly different from BlockOne’s lab test. We adopted the cloud environment EOS settings used by most BP candidates at the moment. Most BP nodes have active HTTP plugin that receive transactions. We performed a stress test by sending enough queries to see how much performance degradation occurs – this is the stress benchmark. Our test is based on early Mainnet environment and thus our results are lower than that of BlockOne’s. It is like an observed mpg (miles per gallon) for automobiles. 16 | 17 | 18 | ## BlockOne test verification and replication 19 | 20 | EOSeoul performed BlockOne’s lab test method and recorded 1200+ TPS with a intel i7-6700 3.4GHz CPU. Similarly, we recorded 2000+TPS with JIT active. Below is the performance result when we perform the test in a cloud environment. 21 | 22 | ### BlockOne Test method in a cloud environment 23 | #### Test Environment 24 | * Build : DAWN-v3.0.0 (d9ad8eec) 25 | * AWS EC2 m5.2xlarge 26 | * CPU : Intel Xeon Platinum 8175M 2.5Ghz * 8 Core 27 | * Mem : 32G 28 | * Disk : EBS 120GB SSD (3000 IOPS Fix) 29 | * AWS EC2 C5.2xlarge 30 | * CPU : Intel Xeon Platinum 8124M 3.0Ghz * 8 Core 31 | * Mem : 16G 32 | * Disk : EBS 120GB SSD (3000 IOPS Fix) 33 | #### Test explanation 34 | * txn_test_gen Settings 35 | * generation cycle(ms) x Transaction Count(count per interval) 36 | * 20x20 : 20 transactions per 20ms 37 | * 50x60 : 60 transactions per 50ms 38 | #### Benchmark1. M5.2xlarge - EC2 1 : FN 1 + BPN 1 39 | * 20x20 (1000TPS) : Recorded 1000 TPS. However, it feels like transactions start queuing up after a while. Feels unstable. BP node CPU : 42%, Full node CPU : 82% 40 | * 22x20 (Approx 900TPS) : Fairly stable. BP node : 35%, Full node : approx 78% 41 | * 50x60 (1200TPS) : Halts after CPU reaches 100%. Cannot be processed. 42 | * 60X58 (966TPS) : Unstable after a while. Recorded 966 TPS. BP node : 40%, Full node : 79% 43 | 44 | #### Benchmark 2. C5.2xlarge - EC2 1 : FN 1 + BPN 1 45 | * 20x20 : 1000 TPS processed. Very stable. BP node CPU 30% , Full node 65% 46 | * 20x22 : 1100 TPS processed. Very stable. BP node CPU 34-35%, Full node 75% 47 | * 20x24 : 1200 TPS processed. Fairly stable. BP node CPU 38%, Full node 80% 48 | * 20x26 : 1300 TPS cannt be achieved. Approx 1000 TPS. BP Ndoe CPU : 43%, Full node : 83% 49 | * 50x60 : 1200 TPS. Same as above. 50 | * 50x66 : 1320 TPS should be achievable but failed. 51 | 52 | #### Benchmark 3. C5 EC2 2 machines : FN1 + BPN1 53 | * 20x20 : 1000 TPS processed. Very stable. BP node CPU 30% , Full node 60% 54 | * 20x22 : 1100 TPS processed. Very stable. BP node CPU 36%, Full node 70% 55 | * 20x24 : 1200 TPS processed. Fairly stable but feels like there is a little bit of queuing up. BP node CPU 38%, Full node 78-80% 56 | * 20x26 : 1300 TPS processed. Fairly stable. Actually feels better than 1200 TPS. BP node 42%, Full node 82-84% 57 | * 20x28 : 1400 TPS should be possible but in reality records 1000 TPS. CPU usage is volatile. 58 | 59 | #### Benchmark 4. C5 EC2 3 machines: FN2 + BPN1 60 | * 20x20 : 1000 TPS. Very stable. BP node 33-38% , Full node1 58-64%, Full node2 52-56% 61 | * 20x22 : 1100TPS. Very stable. BP node 38-40%, Full node1 68-72%, Full node2 58-64% 62 | * 20x24 : 1200TPS. Very stable. BP node 40-42%, Full node1 74-80%, Full node2 60-70% 63 | * 20x26 : 1300TPS. Not stable. Approx 1000-1100 TPS, BP, Full node shows volatile CPU usage. At certain points of time TPS records 966 but then drops down to 99. Obviously CPU usage is low when TPS is low. 64 | * 20x28 : 1400 TPS Unable to be processed. BMT stopped due to error. 65 | * 20x12x2 : 600+600 TPS. Stable. Slight queuing maybe due to broadcast time or network delivery time from using 2 nodes recording 600TPS each. BP node : 40-44%, Full node1 : 68-74%, Full node2 : 76-80%, Full node2 records slightly higher CPU usage. 66 | * 20x14x2 : 700+700TPS. Records 1400 TPS at a certain moment but error occurs on one of the 2 nodes. Error occurs as CPU allocation is not possible. BP node 58-64%, Full node : max 98%+, test terminated due to error so CPU usage doesn’t mean much 67 | * 20x20+20x6 : 1000 + 300 TPS. Unstable and TEST Job (300TPS) terminated. CPU results same as no. 7 68 | 69 | ### Activate JIT in cloud environment and verify BlockOne’s test methodology 70 | 71 | #### Benchmark 5. C5 EC2 2 machines : FN1 + BPN1 (Using WAVM ~ JIT) 72 | * 20x20(1000 TPS) : Reach 1000TPS very comfortably. CPU usage BP node 30-34%, Full node approx 33-37% 73 | * 20x30(1500 TPS) : Reach 1500 TPS very comfortably. BP node 50%, Full node approx. 55% 74 | * 20x36(1800 TPS) : Stable 1800 TPS. BP node 56-60%, Full node approx. 66-70% 75 | * 20x38(1900 TPS) : Stable 1900 TPS. BP node 58-62%, Full node approx. 68-72% 76 | * 20x40(2000 TPS) : Fails immediately. Looks like overload. Need testing on a servicer with a higher CPU Clock or need further adjustments. 77 | 78 | ### Comment on Test results 79 | 80 | * 1000 TPS(Worst case) mentioned in Dawn 3.0 by Dan Larimer could be achieved. However, this result was an engine performance test and would be different in a real environment 81 | * In early days of mainnet, it seems optimal to use servers with high performance CPU’s. (seen through Benchmark 1 and Benchmark 2) 82 | * We could see that there is a slight performance gap after separating full node and BP node. It seems that it is correct to separate the two. However, we do not expect there to be massive differences. 83 | * It is rational to run the Mainnet stress test with BP node and Full node set up separately. The current architecture of the TESTNET where BP node takes on the role of Full node isn’t the most optimal structure from a performance perspective. 84 | * There is a decline in performance as Full nodes are added. One Full node and one BP node gave a stable 1300 TPS whereas two Full nodes and One BP node showed unstable performance. 85 | * We expect declining performance as BP nodes are added because communication between the BP nodes will use up resources. 86 | * We believe performance decline is due to transaction broadcasts between nodes. Thus, the more nodes there are, the poorer the performance will become. 87 | * JIT activation can result in better performance. As in Dawn 3.0, optimal performance can be achieved by using binaryen in early contracts together with JIT 88 | 89 | ## Thank you 90 | 91 | EOSeoul has received many feedbacks since releasing the EOSIO benchmark test results. We very much appreciate your feedbacks. 92 | 93 | First of all, we thank Daniel Larimer and developers at BlockOne. We apologize if the benchmark report on 24th April made you unpleasant. Our intention was to test EOSIO’s performance in an average environment. We thought that txn_test_gen plugin was rather simple from a stress text perspective and assumed that BlockOne obtained results with a more complex benchmark scenario in its Dawn 3.0 document released on 6th April. 94 | 95 | We do see EOSIO’s technological development through the logs on github. We thank you for your kind reply. 96 | 97 | We also thank the various feedbacks from EOS BP’s. The discussions and feedbacks will allow us to perform reliable tests in the future. In particular we thank EOS Cannon for sharing their lab test results (BlockOne) with us. We will continue to share test results in order to launch a stable Mainnet. 98 | 99 | 100 | ## We suggest sharing the stress benchmark script and the results 101 | 102 | EOS community wishes for same methodology to be used to test the performance of BP’s nodes. EOSeoul has released the stress benchmark script on github. 103 | 104 | * https://github.com/eoseoul/scripts/tree/master/bmt_client 105 | 106 | Every block producer can test their performance using this script. We recommend BP’s to suggest scripts and share performance results with the community. EOSeoul will contribute to the community by offering a standardized performance test. 107 | 108 | We welcome feedback. Please contact us(EOSeoul) at any time. You can receive EOSeoul’s latest news and engage in technical discussions in our telegram group. 109 | 110 | ## Channels 111 | 112 | * Telegram (English) : http://t.me/eoseoul_en 113 | * Telegram (简体中文) : http://t.me/eoseoul_cn 114 | * Telegram (日本語) : http://t.me/eoseoul_jp 115 | * Telegram (General Talk, 한국어) : https://t.me/eoseoul 116 | * Telegram (Developer Talk, 한국어) : https://t.me/eoseoul_testnet 117 | * Steemit : https://steemit.com/@eoseoul 118 | * Github : https://github.com/eoseoul 119 | * Twitter : https://twitter.com/eoseoul_kor 120 | * Facebook : https://www.facebook.com/EOSeoul.kr 121 | -------------------------------------------------------------------------------- /ko/translations/Dawn_2_Released.md: -------------------------------------------------------------------------------- 1 | # EOS.IO DAWN 2.0 출시 및 개발 진행 상황 업데이트 2 | 3 | EOS.IO Dawn 2.0은, 블록원 팀이 운영할 퍼블릭 테스트 네트워크와 함께 4 | 출시되었습니다. 이번 출시는 2017년 가을 로드맵에 설명되고 원래 2017년 5 | 12월 21일을 완료일로 정했던 남은 기능들 대부분을 구현한 알파 버전입니다. 6 | 로드맵에 게시한 내용과 같이 "2단계 - 최소 실행 가능 테스트 네트워크"는 7 | 2017년 가을까지 아래 기능을 보여줄 예정이었습니다. 8 | 9 | * P2P 네트워크 코드 10 | * 웹어셈블리 정리 & CPU 샌드박싱 11 | * 자원 사용량 추적 / 사용 속도 제한 12 | * 제네시스 임포트 테스트 13 | * 블록체인간 통신 14 | 15 | 현재 시점에서 본다면 우리는 기능 대부분의 초기 구현에 도달했습니다. 16 | 그런데 병렬적으로 개발을 진행하다보니 블록체인간 통신의 구현체는 17 | 초기 테스트 네트워크에서 사용하지 않을 별도 브랜치에서 개발되었습니다. 18 | 19 | EOS.IO Dawn 2.0의 성능 테스트에 관심있는 분들은 프라이빗 네트워크를 20 | 론치하고 운영할 수 있는 모든 블록체인 코드와 네트워크 코드를 21 | [깃헙 저장소](https://github.com/eosio/eos)에서 찾을 수 있습니다. 22 | 평균적인 하드웨어에서 단일-쓰레드 23 | 구현을 이용해서 자체적으로 테스트해보니 1초마다 블럭을 생성할 때 초당 24 | 수천 건의 이체 트랜잭션 처리를 유지할 수 있습니다. 그렇긴 하지만, 25 | 우리가 아직 해결책을 구현해놓지 않은 알려진 공격 경로가 존재합니다. 26 | 예를 들면, 새로운 컨트랙트가 처음으로 컴파일될 때 34 밀리초(ms)가 27 | 소요될 수 있고, 30 TPS로 이런 트랜잭션을 보내는 방식으로 악용하면 28 | 네트워크가 부서지는 결과를 초래할 수 있습니다. 29 | 30 | 이 문제에 대한 우리의 해결책은 컨트랙트 코드가 업데이트될 수 있는 31 | 빈도와, 코드가 업데이트되는 시점과 새로운 코드를 사용하는 트랜잭션이 32 | 처리될 수 있는 시점 사이의 지연 시간에 제한을 설정하는 것입니다. 33 | 모든 블록 프로듀서가 웹어셈블리 코드로부터 최적화된 x86 인스트럭션을 34 | 컴파일하고 캐시하기까지의 시간을 허용하기 위해서, 이런 지연 시간은 약 60초가 35 | 될 것입니다. 36 | 37 | 이와 같은 아직 해결되지 않은 공격 경로가 존재하기 때문에, 성능 테스트는 38 | 프라이빗 테스트 네트워크에서 진행할 작업으로 남겨둡니다. 가동 시간과 39 | 접근성을 보장하기 위해서 우리가 인위적으로 30 TPS로 제한한 퍼블릭 테스트 40 | 네트워크를 통해서 기능 테스트를 이제 진행할 수 있습니다. 41 | 42 | 다음 6개월에 걸쳐서, 우리는 지속적으로 네트워크를 테스트하고 디버깅해서 43 | 안정성과 성능을 개선할 것입니다. 44 | 45 | ## Dawn 2.0에 도입된 새로운 기능 46 | ### 제네시스 임포트(Genesis Import) 테스트 47 | 우리는 이더리움 네트워크에서 구동되는 EOS ERC-20 토큰 배포 결과에 기반한 48 | 초기 상태를 가져올 수 있는 스냅샷 툴을 구현해왔습니다. 우리의 테스트 49 | 네트워크에는 유효한 EOS 공개키로 등록된 잔고만 포함시킬 것입니다. ERC-20 50 | 토큰의 약 20%는 EOS 공개키로 적절하게 등록되어 있습니다. 서명된 이더리움 51 | 트랜잭션 정보를 이용해서 이더리움 계정의 공개키를 복원할 수 있기 때문에, 52 | 우리는 등록되지 않은 ERC-20 토큰을 소유한 모든 이더리움 계정을 위한 53 | 대비용 툴을 스냅샷 툴에 구현했습니다. 이 툴을 이용하면 전체 EOS ERC-20 토큰의 54 | 99%에 대응할 수 있지만, EOS.IO 지갑에 이더리움 비밀키를 임포트해야만 합니다. 55 | 56 | 보안상의 이유로, 우리의 테스트 네트워크는 대비용 프로세스를 통해서 57 | 사용자의 이더리움 비밀키를 임포트하도록 요청하지 않을 것입니다. 58 | 만약 당신의 EOS 비밀키가 테스트 도중에 노출된다면, 이더리움 네트워크를 통해서 59 | 언제나 새로운 키를 등록할 수 있습니다. 60 | 61 | ### 토큰을 나눠주는 수도꼭지 - Token Faucets 62 | 우리는 가진 토큰이 없거나 유효한 EOS 공개키를 등록하지 않은 사용자들이 63 | 네트워크를 테스트할 수 있도록 토큰을 나눠주는 수도꼭지 기능도 구현해왔습니다. 64 | 65 | ### 자원 사용량 계산 & 사용 속도 제한 66 | 우리는 기본적인 사용 속도 제한 기능과 자원 사용량 추적 기능을 구현해왔습니다. 67 | 이 기능은 대역폭, 데이터베이스 스토리지 사용량, 연산 사용량을 추적합니다. 68 | 현재 시점에서 우리가 구현한 사용 속도 제한 알고리즘에 알려진 버그가 69 | 있습니다만, 어플리케이션을 테스트하고 진행하는 데 있어서 방해가 될 수 있는 70 | 것은 아무것도 없습니다. 71 | 72 | 우리는 많은 사람들이 사용 속도 제한 방식이 어떻게 동작하는지, 누구에게 73 | 사용량이 청구되는지, 수익을 얻기 위해서 지분참여한(staked) 토큰을 74 | 임대할 수 있는 방법에 대해 좀더 많은 정보를 요청하고 있다는 점을 75 | 알고 있습니다. 76 | 77 | #### 대역폭 78 | 모든 트랜잭션은 블록 프로듀서들이 설정한 최대 네트워크 대역폭의 일부를 79 | 소모합니다. 트랜잭션 진행에 필요한 자격(authority)을 가진 모든 계정은 80 | 트랜잭션의 크기에 근거해서 증가되는 3일 평균 대역폭 사용량이 계산될 것입니다. 81 | 대역폭을 사용하기 위해서는, 소유 토큰 중 지분참여한 토큰이 있거나 82 | 어플리케이션 제공자가 지분참여한 토큰을 위임 받은 (컨트랙트가 아닌) 83 | 승인 자격을 가진 계정(authorizing account)을 이용해야 합니다. 84 | 85 | #### 연산 대역폭 86 | 모든 트랜잭션을 진행하려면 약간의 연산이 소모됩니다. 연산은 병렬로 실행될 수 87 | 있고, 그래서 서로 다른 모습으로 정체 구간이 생기는 다차선 고속도로로 88 | 비유할 수 있습니다. 각 scope(차선)은 저마다의 별도의 사용 속도 제한이 있고, 89 | 동시에 사용하는 scope(차선)의 수와 가장 정체가 많은 scope에 기반한 90 | 사용 속도 제한 정보를 이용해서 O(S^2) 만큼 사용량이 사용자에게 청구될 것입니다. 91 | 92 | #### 데이터베이스 스토리지 93 | EOS.IO 컨트랙트는 어플리케이션 상태 정보를 저장할 수 있는 94 | 인-메모리(in-memory) 데이터베이스에 접근할 수 있습니다. 95 | 저장된 전체 데이터량과 각각의 데이터베이스 정보에 대한 고정된 오버헤드 96 | 지수를 더한 양으로 컨트랙트의 사용량을 청구할 것입니다. 97 | 앞에서 말한 인-메모리 데이터베이스는 대용량 분산 호스팅/저장소로 98 | 사용될 EOS.IO 스토리지 프로토콜과 독립된 별개의 데이터베이스입니다. 99 | 100 | ### P2P 네트워크 코드 101 | 우리는 퍼블릭 테스트 네트워크에서 시연되고 있는 기본적인 메쉬(mesh) 네트워크 102 | 코드를 구현했습니다. 블록원은 21개의 독립된 서버를 운영하면서 각각의 서버에 103 | 프로듀서를 하나씩 초기설정해놓았습니다. 104 | 105 | ## EOS Dawn 3.0 106 | EOS Dawn 3.0은 단일 체인들을 이용한 수평 확장 기능과 안전한 블록체인간 통신을 107 | 이용한 무한 확장 기능을 다시 도입할 것입니다. 이 두 가지 기능을 이용하면 108 | 블록체인 기술을 이용해서 만들 수 있는 결과물과 블록체인을 이용한 109 | 분산된 네트워크가 변할 수 있는 모습에 아무런 제한이 없어질 것입니다. 110 | 111 | ### 무한 확장과 무한 분산화 112 | 블록체인 기술의 성배는 두 개의 독립된 블록체인이 어느 한 쪽의 블록체인에 113 | 담긴 정보 전체를 검증하지 않고도 서로 안전한 통신을 가능케하는 기능입니다. 114 | 이렇게 구현하려면 블록체인 하나는 다른 블록체인의 경량 115 | 클라이언트(light-client)로 구현할 수 있으면 됩니다. 116 | 117 | 경량 클라이언트는 블록 헤더와 머클 증명만 이용해서 트랜잭션을 인증합니다. 118 | EOS.IO는 경량 클라이언트 검증 기능을 지원하는 첫 번째 위임 증명 프로토콜이 119 | 될 것입니다. 더 중요한 점은, 완전성 증명(proof-of-completeness)을 120 | 생성할 수 있는 유일한 프토코톨이 될 것이라는 점입니다. 대기 기간이나 121 | 이의 기간 없이 다른 체인으로부터 관련된 과거의 모든 메시지를 순서대로 122 | 받아왔다는 점을 증명할 수 있게 될 것이라는 의미입니다. 123 | 124 | 전통적으로 경량 클라이언트는 블록 헤더 전부를 처리해야 하지만, 125 | EOS.IO를 사용하면 경량 클라이언트는 프로듀서가 변경되는 경우 또는 126 | 가장 최근의 블록에서 요구하는 새로운 메시지 처리가 필요할 때만 블록 헤더를 127 | 처리하면 됩니다. 이런 방식으로 빈번한 자체 통신이 발생하는 체인들 사이에서 128 | 일어나는 빈번하지 않은 통신을 효율적으로 처리할 수 있습니다. 129 | 최악의 경우, 500 밀리초(ms)마다 서로 통신하는 두 블록체인의 오버헤드는 130 | 전달한 메시지의 총 개수와 무관하게 초당 약 2건 정도일 것입니다. 131 | 132 | 이 모델을 이용하면, 최소 1/3의 프로듀서가 정직하기만 하면 통신 내용은 133 | 보장될 것입니다. 게다가, 프로듀서 하나가 배신하는 경우에도 배신자는 134 | (다른 블록체인일) 경량 클라이언트를 잠재적으로 속이는 임의의 메시지에 135 | 서명할 것이므로 자동적으로 처벌할 수 있습니다. 136 | 137 | 마지막으로, 다른 블록체인과 통신에 소요되는 왕복 시간은 각 체인이 138 | 비가역 상태에 도달하는 데 필요한 소요 시간(latency)에 좌우됩니다. 139 | EOS.IO 기반의 체인은 3초 이하의 시간 내에 다른 EOS.IO 체인에 메시지를 140 | 보내서 암호화 방법으로 검증된 응답을 받을 수 있을 것입니다. 141 | 142 | 이런 수준의 블록체인간 통신과 보안성은 매우 낮은 소요 시간을 만족하면서 143 | 체인 사이의 양방향 연결을 만들 수 있습니다. 양방향 연결이 가장 눈에 보이는 144 | 예제이겠지만, 이와 동일한 방법을 이용하면 어떠한 비즈니스-비즈니스 사이의 145 | 통신을 수행할 수 있습니다. 146 | 147 | #### 퍼블릭 / 프라이빗 통신 148 | 블록체인간 통신을 이용하면 프라이빗 블록체인이 퍼블릭 블록체인과 안전한 149 | 양방향 통신을 맺는 모델이 가능합니다. 이를 이용하면, 데이터를 공개하는 150 | 성질을 가지는 일반적인 블록체인에 다소 적합하지 않았던 모든 종류의 151 | 블록체인 어플리케이션이 가능해집니다. 예를 들면, 은행 소유자와 152 | 은행 이용자를 제외한 다른 모든 사람들에게 엄청나게 비밀이 보장되는 153 | 스위스 은행 같은 블록체인을 만들 수도 있습니다. 154 | 155 | #### 개발 진척 상황 156 | 퍼블릭 테스트 네트워크를 제공하기 위해서, 우리는 개발 경로를 두 개의 157 | 병렬적인 작업으로 나누었고 그래서 가독성, 성능, 블록체인간 통신을 158 | 구현하기 위한 코드의 많은 부분을 리팩토링할 수 있었습니다. 159 | 리팩토링 작업은 eos-noon 브랜치에서 진행되고 있습니다. 160 | 161 | 지난 번 업데이트를 통해서 다른 컨트랙트가 작동하는 도중에도 개발자들이 162 | 동기적인 읽기-접근과 원자성 트랜잭션(atomic transaction)을 쉽게 163 | 수행할 수 있도록 공유 메모리 아키텍처에 집중할 것이라는 의도를 내비친 바 164 | 있습니다. 이런 접근을 취하다 보니 하이엔드 머신 한 대를 165 | 넘어설 수 있는 수평 확장 기능 구현을 결과적으로 놓쳤습니다. 166 | 167 | EOS Dawn 3.0을 통해서 최대 65,000개의 별도 리전(region)을 이용해서 168 | 머신 여러 대를 이용한 수평 확장 기능을 복원할 것입니다. 모든 리전은 169 | 동일한 계정과 동일한 컨트랙트 코드를 공유할 것이지만, 메모리 데이터베이스 170 | 사용의 측면에서는 모두 독립되어 있습니다. 리전 하나의 컨트랙트는 이에 171 | 대응하는 다른 리전의 컨트랙트(counterpart)와 비동기 트랜잭션을 이용해서 172 | 통신해야만 합니다. 이런 아키텍처를 사용하면 블록 프로듀서 하나는 173 | 클러스터로 구성할 수도 있습니다. 174 | 175 | #### 애플 Secure Enclave를 이용하는, 작동하는 코드 176 | 가장 최근 업데이트에서 우리는 애플, 안드로이드를 비롯한 많은 스마트카드 177 | 플랫폼에서 사용하는 것과 동일한 타원 곡선 알고리즘을 지원하겠다는 의도를 178 | 발표했습니다. 우리의 eos-noon 브랜치에는 최신 맥북 프로 노트북에 장착된 179 | 터치ID(또한 페이스ID)를 이용해서 메시지를 서명하고 검증할 수 있는, 180 | 제대로 동작하는 개념증명용 구현체가 이제 포함되어 있습니다. 181 | 비슷한 코드로 아이폰 네이티브 어플리케이션으로 역시 구현할 수 있습니다. 182 | 이로써 EOS.IO 기반의 모바일 어플리케이션은 지금까지 알려진 가장 183 | 안전한 블록체인 지갑에 포함될 것입니다. 184 | 185 | 게다가, eos-noon 브랜치는 다수의 서명 타입을 지원하는 기능이 추가되었기 때문에 186 | 애플 Secure Enclave를 이용해서 트랜잭션을 서명하는 것이 가능함을 의미하고 187 | eos-noon 브랜치에서 이를 검증할 것입니다. 188 | 189 | (옮긴이 주: 애플 Secure Enclave를 이용한 데모 코드가 깃헙에 올라와 있습니다. 190 | [EOSIO Apple Secure Enclave 데모](https://github.com/eoseoul/docs/blob/master/ko/translations/eosio-applesedemo-readme.md)를 참조하세요.) 191 | 192 | #### 500 밀리초(ms) 블록 승인 193 | eos-noon 브랜치에서 우리는 기반이 되는 DPOS 프레임워크가 500 밀리초 블록 194 | (1초 마다 블록 2개씩 생성) 기능을 지원하게끔 많은 수정을 가했습니다. 195 | 이 변화를 통해서 분산 어플리케이션의 응답성을 극적으로 높힐 것입니다. 196 | 이런 모습을 달성하기 위해서 블록 스케줄링이 일어나는 방법에 중요한 변화가 197 | 있었습니다. 198 | 199 | 프로듀서 하나는 다음 프로듀서에게 순서를 넘기기 전 블록 12개를 연속으로 200 | 생성할 것입니다. 이런 방법으로 블록 생산의 측면에서 가장 큰 병목인 201 | 프로듀서-프로듀서 순서 넘김 문제를 해결했습니다. 새로운 구조를 이용하면 202 | 순서 넘김이 일어나는 순간 예상치 못한 지연이 발생해도 몇 개의 블록 정도만 203 | 놓칠 것입니다. 그러나 순서가 넘어가는 사이에 매우 빠른 승인이 이루어져야 204 | 합니다. 우리는 다양한 순서 넘김 시간 설정을 이용해서 실험할 것입니다. 205 | 순서 넘김 시간이 길어지면 정상적인 작동 환경에서는 누락되는 블록이 206 | 더 적어질 것입니다. 그러나 순서 넘김 시간이 길어진 상황애서 노드 하나가 207 | 다운되면 장애가 일어날 것입니다. 500 밀리초마다 블록을 만들고 블록을 12개 208 | 만든 후 순서를 넘기는 경우라면, Steem과 BitShares에서 프로듀서 하나가 209 | 블록 하나를 누락하는 "다운 타임"보다 심하진 않습니다. 이런 상황이 발생하면 210 | 첫 번째 승인을 얻는 데 6초가 소요될 수 있습니다. 211 | 212 | #### 대기 프로듀서 목록 제거 213 | 블록체인간 통신을 가능하게 하려면 활성 블록 프로듀서의 집합이 변화하는 214 | 모든 블록을 경량 클라이언트가 추적해야 합니다. 215 | "대기 프로듀서 목록(runner up producer list)"가 있어서 새로운 프로듀서가 216 | 매분마다 추가되거나 삭제되고, 그래서 경량 클라이언트는 더 많이는 217 | 아니더라도 매분마다 최소한 하나의 블럭 헤더를 처리해야만 합니다. 218 | 프로듀서 집합 변화의 빈도를 줄이기 위해서 우리는 블록 스케줄링 정보에 219 | 오직 상위 21개의 프로듀서 목록만 담는 것으로 변경했습니다. 우리는 220 | 대기 프로듀서에 대해서 일종의 대기 보상을 주는 방식을 고려하고 있습니다만, 221 | 대기 프로듀서들은 실제로 블럭 생성 작업을 수행하지 않을 것입니다. 222 | 223 | #### 1초 비가역성 224 | 모든 블록 프로듀서는 모든 블럭에 서명할 것이고, 블럭 하나는 2/3 이상의 225 | 프로듀서가 서명하는 대로 비가역 상태로 표시될 것입니다. 프로듀서는 226 | 블록 높이당 하나의 블록 헤더에만 서명할 수 있습니다. 이 말은, 포크가 227 | 발생하는 경우 프로듀서는 동일한 높이에 도달한 포크 양쪽 모두의 블록에 228 | 서명할 수 없다는 뜻입니다. 만약 그런 서명이 있다면 이것은 어느 프로듀서가 229 | 부정 행위를 했다는 암호적 증거이며, 프로듀서의 지위를 자동으로 잃게 만든다거나 230 | 잠재적으로 계약 상실에 이르게 한다거나 잠재적으로 중재에 따른 손해에 대한 231 | 잭임을 지도록 하는 등 여러 가지 방법으로 처리할 수 있습니다. 232 | 233 | 다음 블록을 만들기 전에 2/3 이상의 서명을 모으는 다른 프로토콜과 달리, 234 | EOS DPOS는 서명을 모으는 동안 낙관적 파이프라이닝(optimistic pipelining) 235 | 방식으로 작동하기 때문에, 블록체인을 "계류 상태(pending state)"로 236 | 계속 진행시킬 수 있도록 합니다. 블록체인 바깥에서 이와 같은 추가적인 237 | 서명이 일어나면, Steem과 BitShares와 같은 기존의 DPOS 규칙 아래에서는 238 | 블록이 비가역 상태에 도달한 뒤에야 검증이 완료된 블록을 239 | 정리(prune)할 수 있습니다. 240 | 241 | 이 모델을 이용하면, 비잔틴(배반자) 노드가 배반했다는 암호화 증거를 242 | 남기지 않고서는 어떤 블록도 2/3 이상의 서명을 받을 수 없기 때문에, 243 | 비잔틴 장애 내성을 얻을 수 있습니다. 244 | 245 | #### 프로듀서 스케줄 셔플링 제거 246 | 프로듀서 순서가 넘어갈 때 누락되는 블록의 수를 최소화하기 위해서, 247 | 이어지는 프로듀서 사이의 지연 시간을 최소화하는 것이 바람직합니다. 248 | 뉴욕에 있는 프로듀서가 중국에 있는 프로듀서의 다음 순서라고 가정하면, 249 | 정상적인 경우 (블록 생성 간격의 50%인) 250 밀리초가 걸릴 지도 모르고 250 | 네트워크 정체가 있으면 잠재적으로 훨씬 더 긴 시간이 걸리지도 모릅니다. 251 | 반면에 뉴욕과 텍사스에 프로듀서가 있다면 (블록 생성 간격의 10%인) 50 밀리초 252 | 정도의 지연 시간만 걸릴 수도 있습니다. 즉, 뉴욕에서 중국으로 순서가 넘어가는 253 | 경우에 비해서 뉴욕에서 텍사스로 순서가 넘어가는 경우에 누락 블록이 발생할 254 | 수 있는 확률이 훨씬 더 줄어들 수 있습니다. 255 | 256 | 뉴욕에서 텍사스로, 캘리포니아로, 하와이로, 일본으로, 중국으로, 인도로, 257 | 이스라엘로, 이탈리아로, 영국으로, 아이슬란드로, 그리고 다시 뉴욕으로 오는 258 | 식으로 블록 생성 스케줄을 조정한다면, 50 밀리초에서 100 밀리초 이상의 259 | 지연 시간이 있는 순서 넘김은 절대로 발생하지 않습니다. 그러나 만약 260 | 랜덤하게 순서를 정한다면, 평균적인 순서 넘김 지연 시간은 훨씬 커질 것입니다. 261 | 262 | 프로듀서 셔플링은 프로듀서 하나가 후속 프로듀서를 부당하게 괴롭힐 수 있는 263 | 잠재적인 시나리오를 최소화하기 위해서 도입했습니다. 264 | 프로듀서가 잠재적으로 악의적일 수 있다고 추정되는 세계에는 이런 리스크가 265 | 존재했었습니다. 266 | 그러나 면밀히 심사받고 대중에게 알려지고 고품질의 데이터센터를 267 | 완비한 프로듀서들이 존재하는 세계에서는 이런 리스크가 타당하지 않습니다. 268 | 헌법이 존재하고, 프로듀서 하나가 의도적으로 이웃 프로듀서에 피해를 입히는 경우 분쟁을 해결하는 절차를 준수하는 행동 기대 수준이 있습니다. 269 | 270 | 평균 지연 시간을 최소화하고 인터넷 네트워크 정체로 인한 총 누락 블록 수를 271 | 최소화할 수 있도록, EOS에서 프로듀서는 블록 생성 교대 순서를 투표로 272 | 정할 것입니다. 273 | 274 | ## 알려진 문제들 275 | EOS Dawn 2.0에는 알려진 몇 가지 문제점들이 있고 출시 초기 단계에서는 276 | 불안정성이 클 것으로 예상됩니다. 이번 출시의 목적은 기본적 능력을 시연하는 데 277 | 있고, 우리 팀은 다음 6개월간 버그를 없애고 안정성과 성능을 개선해나갈 것입니다. 278 | 279 | 테스트 네트워크의 안정성을 뒷받침하기 위해서, 우리는 프로듀서 투표 기능을 280 | 꺼두었습니다. 281 | 282 | ## 결론 283 | 우리는 앞으로 시장에 나온 가장 강건하고 가장 높은 성능을 보이고 가장 분산화된 284 | 플랫폼이 될 소프트웨어의 알파 버전인 EOS Dawn 2.0을 작성하고 285 | 출시하기 위해 전세계에 걸쳐 24시간 내내 286 | 일하는 개발팀에게 감사의 말씀을 전하고 싶습니다. 우리는 우리가 발표한 로드맵에 287 | 따라서 작업을 실행하고 있고 원래 계획했던 이상의 기능과 능력을 제공하고 288 | 있습니다. 우리는 2018년을 고대하며 EOS 토큰 배포가 완결되는 시점까지 289 | 모든 기능 구현을 완료하고 버그를 해결할 것이라고 확신합니다. 290 | 291 | ## 면책조항 292 | 블록원(block.one)은 소프트웨어 기업이며 EOS.IO 소프트웨어를 무료 오픈소스 소프트웨어로 제작합니다. 이 소프트웨어는 이 소프트웨어를 도입하는 사용자가 293 | 블록체인 또는 위에서 설명한 기능을 갖춘 분산 어플리케이션을 시작할 수 있도록 합니다. 블록원은 EOS.IO 소프트웨어를 기반으로 하는 퍼블륵 블록체인을 론칭하지 않습니다. 제 3자나 커뮤니티나 자신들이 적합하다고 보는 위에서 설명한 기능과/또는 서비스를 제공하여 블록 프로듀서가 되길 원하는 주체들의 단독 책임일 것입니다. 294 | 블록원은 임의의 주체가 그러한 기능을 구현하거나 그러한 서비스를 제공하거나 EOS.IO 소프트웨어가 어떤 방식으로든 채택되고 구현된다는 것을 보증하지 않습니다. 295 | 296 | 역사적 사실에 대한 진술 이외에, 블록원의 비즈니스 전략, 계획, 전망, 개발 및 목표에 관한 이 문서의 모든 진술은 미래 예측 진술입니다. 이 진술은 예측일 뿐이며 미래의 사건에 대한 블록원의 현재의 믿음과 기대치를 반영하고 가정에 근거하며 언제든지 위험, 불확실성 및 변경의 영향을 받습니다. 우리는 급변하는 환경에서 사업을 운영합니다. 새로운 위험이 수시로 발생합니다. 이러한 위험과 불확실성을 감안할 때 이러한 미래 예측 진술에 의존하지 않도록 주의해야 합니다. 실제 결과, 실적 또는 이벤트는 미래 예측 진술에 포함된 내용과 실질적으로 다를 수 있습니다. 실제 결과, 실적 또는 이벤트가 미래 예측 진술과 실질적으로 다른 원인이 될 수 있는 요인에는 시장 변동성, 자본, 재원 및 인력의 지속적인 가용성; 제품 수용; 어떤 새로운 제품이나 기술의 상업적 성공; 경쟁; 정부 규제 및 법률; 그리고 일반적인 경제, 시장 또는 사업 조건이 포함되며 이에 제한되지 않습니다. 블록원이 작성한 모든 미래 예측 진술은 진술이 이뤄진 날짜에 대해서만 말하고 블록원은 새로운 정보, 후속 사건 또는 기타 사건의 결과이건 간에 미래 예측 진술을 업데이트하거나 변경할 의무가 없으며 분명히 부인할 의무가 없습니다. 297 | 298 | ## 번역 정보 299 | 300 | * 원문 : https://steemit.com/eos/@eosio/eos-io-dawn-2-0-released-and-development-update 301 | * 원문 작성 시점 : 한국표준시 2017년 12월 5일 302 | -------------------------------------------------------------------------------- /ko/translations/Tutorial-Comprehensive-Accounts-and-Wallets.md: -------------------------------------------------------------------------------- 1 | ## 계정 및 지갑에 대한 전반적인 튜토리얼 2 | 3 | **주의** _이 튜토리얼은 **사설 단일 노드 테스트넷**에서 사용하도록 작성됐습니다만, 약간의 수정을 거치면 공용 테스트넷에서도 동작합니다._ 4 | 5 | #### 튜토리얼 대상 6 | 이 튜토리얼에서는 지갑과 계정 관리에 대해 공부하고 싶은 사용자들을 위해 `cleos`를 사용해 지갑과 계정을 관리하는 방법을 포함해, 지갑과 계정을 관리하는 EOSIO 컴포넌트가 서로 어떻게 통신하는지에 대해 다룹니다. 자세한 정보는 **[명령어 레퍼런스](https://github.com/EOSIO/eos/wiki/Command-Reference)** 를 참조하세요. 7 | 8 | #### 다룰 내용 9 | 지갑과 지갑의 키를 어떻게 생성하고 관리하는지 다룰 것이며, `cloes`를 이용해 지갑과 블록체인을 연동하는 방법을 살펴 보겠습니다. 이후에 `cleos`를 이용해 계정을 생성하는 법을 다뤄 보겠습니다. 이 튜토리얼에서는 `cleos`, `keosd`, `nodeos`간 상호작용 중 일부를 통해 블록체인에 올라가는 컨텐츠에 서명하는 과정까지 소개할 것입니다. 10 | 11 | #### 사전 준비 12 | - 시스템에 `cleos`와 `keosd`를 빌드해서 실행중이어야 합니다. 13 | - 시스템에 `nodeos`를 빌드해서 _실행할 수 있게 준비_ 돼 있어야 합니다. 14 | - 커맨드 라인 인터페이스에 대한 기본 지식이 필요합니다. 15 | 16 | **주의:** 도커 설치에 적용할 경우 명령어를 약간 수정해야 합니다. 17 | 18 | ### EOSIO 계정과 지갑의 개념적 개요 19 | 아래의 다이어그램은 EOSIO에서 계정과 지갑의 간단한 개념도입니다. 이 밖에도 지원되는 다른 배포 구성이 있지만, 이 그림은 이 튜토리얼에서 사용할 내용에만 해당합니다. 20 | 21 | ![계정과 지갑의 개념적 개요](assets/Accounts-and-Wallets-Overview.png) 22 | 23 | 지갑은 공개 키-개인 키 쌍의 저장소로 생각할 수 있습니다. 이들은 블록체인에서 수행되는 작업에 대한 서명을 위해 필요합니다. 지갑과 그 내용물은 `keosd`에서 관리되며, 지갑은 `cleos`를 이용해 접근할 수 있습니다. 24 | 25 | 계정은 접근 권한(즉, 보안의 기본)을 가진, 체인 상에서의 식별자라고 생각할 수 있습니다. `nodeos`는 계정 및 계정에 관련된 블록체인 상 액션의 생성을 관리합니다. `nodeos`의 계정 관리 기능은 `cleos`를 이용해서 사용할 수 있습니다. 26 | 27 | 계정과 지갑 간에는 종속관계가 없습니다. 계정은 지갑에 대한 정보를 알지 못하며, 그 역도 마찬가지입니다. 따라서 `nodeos`와 `keosd` 간에도 종속관계가 없습니다. 이 둘의 기본적 기능은 근본적으로 다릅니다. (_물론, 구별을 모호하게 하는 배포 구성이 있습니다만, 그 주제는 이 튜토리얼의 범위를 벗어납니다._) 28 | 29 | 트랜잭션에 서명할 때처럼 서명이 필요한 시점에서 접점이 생깁니다. 지갑은 잠글 수 있는 자체 내의 암호화된 저장소에 키를 저장해서 안전한 방식으로 서명을 가져오기 쉽게 합니다. `cleos`는 `keosd`의 키 검색 연산과, 이 키들을 사용해서 생성된 서명이 필요한 `nodeos`의 계정(및 기타) 블록체인 액션 간의 중개자 역할을 효과적으로 수행합니다. 30 | 31 | ### 지갑을 생성하고 관리하기 32 | 터미널을 열고 EOSID를 빌드한 디렉토리로 이동하세요. 여기서 실행하면 `nodeos`, `keosd`와 커맨드 라인 인터페이스로 통신하는 `cleos`를 보다 쉽게 사용할 수 있습니다. 33 | 34 | ```bash 35 | $ cd /path_to_eos/build/programs/cleos 36 | ``` 37 | 38 | 우선 해야 할 일은 지갑을 생성하는 것입니다; `wallet create` 명령어를 `cleos`에서 실행하세요. 39 | 40 | ```bash 41 | $ cleos wallet create 42 | Creating wallet: default 43 | Save password to use in the future to unlock this wallet. 44 | Without password imported keys will not be retrievable. 45 | "A MASTER PASSWORD" 46 | ``` 47 | 48 | _default_ 란 이름의 지갑이 `keosd` 상에 생기게 되며, 이 지갑의 **마스터 패스워드**가 표시됩니다. 이 패스워드를 어딘가 안전한 곳에 보관해 두시길 바랍니다. 이 패스워드는 지갑 파일의 잠금을 해제(복호화)하는 데 쓰입니다. 49 | 50 | 이 지갑의 파일명은 `default.wallet`입니다. 기본적으로 `keosd`는 지갑을 `~/eosio-wallet` 폴더에 저장합니다만, 지갑 데이터 폴더 위치는 명령어를 실행할 때 `--data-dir` 실행인자를 이용해서 지정할 수 있습니다. 51 | 52 | #### 여러 지갑과 지갑 이름을 관리하기 53 | `cleos`를 이용해 여러 지갑을 관리할 수 있습니다. 지갑은 각각 다른 마스터 패스워드로 보호됩니다. 아래의 예제는 다른 지갑을 생성하고 `-n` 실행인자를 이용해 이름을 정해주는 방법을 보여줍니다. 54 | 55 | ```bash 56 | $ cleos wallet create -n periwinkle 57 | Creating wallet: periwinkle 58 | Save password to use in the future to unlock this wallet. 59 | Without password imported keys will not be retrievable. 60 | "A MASTER PASSWORD" 61 | ``` 62 | 63 | 이제 지갑이 정해준 이름(옮긴이: 예제에서는 periwinkle)으로 생성됐는지 확인합시다. 64 | 65 | ```bash 66 | $ cleos wallet list 67 | Wallets: 68 | [ 69 | "default *", 70 | "periwinkle *" 71 | ] 72 | ``` 73 | 74 | 표시된 두 지갑에 각각 아스테리스크(*) 표시가 돼 있는 것을 잘 봐 두세요, 각각 잠금 해제돼 있다는 의미입니다. `create wallet` 명령어를 사용해서 만든 지갑은 기본적으로 여러분이 사용하기 쉽게 잠금이 해제돼 있습니다. 75 | 76 | 두 번째 지갑을 `wallet lock` 명령어로 잠궈보겠습니다. 77 | 78 | ```bash 79 | $ cleos wallet lock -n periwinkle 80 | Locked: 'periwinkle' 81 | ``` 82 | 83 | 다시 `wallet list` 명령어를 실행시켜 보면, 두 번째 지갑의 아스테리스크가 사라졌음을 보실 수 있을 겁니다. 즉, 그 지갑이 현재 잠겨 있다는 뜻입니다. 84 | 85 | ```bash 86 | $ cleos wallet list 87 | Wallets: 88 | [ 89 | "default *", 90 | "periwinkle" 91 | ] 92 | ``` 93 | 94 | 원하는 대로 이름을 정해준 지갑의 잠금을 해제할 때는 `wallet unlock` 명령어에 `-n` 인자를 준 다음에 지갑의 이름을 써 줍니다. 이어 나오는 패스워드 입력 요청에 지갑의 마스터 패스워드를 입력해 줍니다(물론 패스워드를 복붙해 줄 수 있습니다). 위로 올라가서 생성한 두 번째 지갑의 마스터 패스워드를 복사한 다음, 명령어를 실행시키고 _password_ 입력란에 붙여넣은 뒤 _엔터_ 키를 누르면 확인이 완료됩니다. 95 | 96 | ```bash 97 | $ cleos wallet unlock -n periwinkle 98 | ``` 99 | 100 | `cleos`는 이제 지갑이 잠금 해제됐다고 알려줄 것입니다. 101 | 102 | ```bash 103 | Unlocked: 'periwinkle' 104 | ``` 105 | 106 | _**주의:** `--password` 실행인자를 주고 다음에 마스터 패스워드를 붙여넣으면 패스워드 입력과정이 불필요합니다만, 콘솔 실행내역 보기로 여러분의 마스터 패스워드가 노출될 수 있습니다._ 107 | 108 | 이제 지금까지 진행상황을 확인해 봅시다: 109 | 110 | ```bash 111 | $ cleos wallet list 112 | Wallets: 113 | [ 114 | "default *", 115 | "periwinkle *" 116 | ] 117 | ``` 118 | 119 | _periwinkle_ 지갑도 아스테리스크가 붙어있습니다. 즉 지금은 잠금해제됐다는 뜻입니다. 120 | 121 | _**주의:** `default` 지갑을 지갑 관리 명령어로 관리할 때는 `-n` 인자를 사용하지 않아도 됩니다._ 122 | 123 | 이제 `keosd`를 재시작킵시다. `cleos`를 디시 실행해서 다음 명령어를 입력해 봅니다. 124 | 125 | ```bash 126 | $ cleos wallet list 127 | Wallets: 128 | [] 129 | ``` 130 | 131 | 보시는 것처럼 지갑은 조작하기 전에 우선 열어야(open) 합니다(옮긴이: 잠금해제(unlock)와는 다릅니다). 열리지 않은 지갑은 심지어 표시조차 안됩니다. `keosd`를 종료하면 지갑은 잠기며, `keosd`를 재시작했을 때는 열린 상태가 아닙니다. 다음 명령어로 기본 지갑을 열어서 표시해 봅시다. 132 | 133 | ```bash 134 | $ cleos wallet open 135 | $ cleos wallet list 136 | Wallets: 137 | [ 138 | "default" 139 | ] 140 | ``` 141 | 142 | _**주의:** 이름을 따로 지어준 지갑을 열고 싶다면 `$ cleos wallet open -n periwinkle` 식으로 `-n` 실행인자를 주어 실행해야 합니다._ 143 | 144 | 방금 전 응답에서 기본 지갑이 초기에는 잠겨 있다는 것을 보실 수 있습니다. 이제 잠금을 해제해 봅시다; 다음 단계를 거치게 될 것입니다: 145 | 146 | `wallet unlock` 명령어를 실행하고 _기본_ 지갑의 마스터 패스워드를 패스워드 입력란에 입력합니다. 147 | 148 | ```bash 149 | $ cleos wallet unlock 150 | Unlocked: 'default' 151 | ``` 152 | 153 | 지갑이 잠금해제됐는지 확인합니다. 154 | 155 | ```bash 156 | $ cleos wallet list 157 | Wallets: 158 | [ 159 | "default *" 160 | ] 161 | ``` 162 | 163 | 지갑(기본 지갑) 이름 뒤에 아스테리스크가 표시되고 있습니다. 즉 잠금 해제됐다는 뜻입니다. 164 | 165 | 위에서 `cleos`를 이용해 여러 지갑을 만드는 방법과 다루는 방법을 이미 살펴봤습니다만, 빈 지갑은 아무짝에도 쓸모가 없습니다. 이제 지갑에 키를 임포트해 보겠습니다. 166 | 167 | ### EOSIO 키를 생성하고 임포트하기 168 | 169 | EOSIO 키 쌍을 생성하는 방법에는 몇 가지가 있습니다만, 이 튜토리얼에서는 `cleos`의 `create key` 명령어에 집중하겠습니다. 170 | 171 | 두 쌍의 공개/개인 키를 생성합니다. 키의 일반적인 포맷에 주목하세요. 172 | 173 | ```bash 174 | $ cleos create key 175 | Private key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 176 | Public key: EOSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 177 | $ cleos create key 178 | Private key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 179 | Public key: EOSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 180 | ``` 181 | 182 | 이제 EOSIO 키 쌍 두 개가 생겼습니다. 이 시점에서는 단지 키 쌍만 존재할 뿐 어떠한 자격도 부여되지 않았습니다. 183 | 184 | 이전 단계를 모두 다 따라하셨다면, _default_ 지갑은 열려 있고 잠금 해제돼 있을 것입니다. 185 | 186 | 다음 단계로, 개인 키를 지갑에 임포트해 보겠습니다. `wallet import` 명령어를 두 번 실행하여 위에서 만든 *개인 키* 를 각각 임포트합니다. 187 | 188 | ```bash 189 | $ cleos wallet import ${private_key_1} 190 | ``` 191 | 192 | 두 번째 개인 키도 같은 과정을 거칩니다. 193 | 194 | ```bash 195 | $ cleos wallet import ${private_key_2} 196 | ``` 197 | 198 | 성공했다면 `wallet import` 명령어를 실행할 때 마다 그에 맞는 공개 키가 표시됩니다, 콘솔창에 반드시 다음과 유사한 결과가 나오는지 확인하세요. 199 | (옮긴이: 결과로 나오는 공개키는 위에서 생성한 공개 키와 일치해야 합니다) 200 | 201 | ```bash 202 | $ cleos wallet import 5Hvgh37WMCWAc4GuyRBiFrk4SArCnSQVMhNtEQVoszhBh6RgdWr 203 | imported private key for: EOS84jJqXj5XBz3RqLreXZCMxXRKspUadXg3AVy8eb5J2axj8cywc 204 | ``` 205 | 206 | `wallet keys` 명령어를 이용해 어떤 키가 로드됐는지 확인할 수 있습니다. 207 | 208 | ```bash 209 | $ cleos wallet keys 210 | [[ 211 | "EOS6....", 212 | "5KQwr..." 213 | ], 214 | [ 215 | "EOS3....", 216 | "5Ks0e..." 217 | ] 218 | ] 219 | ``` 220 | 221 | 지갑 파일 자체는 암호화돼 있기 때문에 잠긴 상태에서 지갑은 이 키를 보호하게 됩니다. 잠긴 지갑의 키에 접근하기 위해서는 지갑을 생성할 때 설정한 마스터 패스워드가 핋요합니다. 222 | 223 | ### 지갑을 백업하기 224 | 지갑에 키를 담아두었기 때문에, 지갑 파일의 손실에 대처하기 위해 지갑을 백업하는 습관을 들이는 것이 좋습니다. 음... 플래시 메모리나 다른 미디어가 좋겠네요. 지갑 파일은 높은 복잡도로 암호화돼 있기 때문에 지갑 안의 키는(사용할 수 있는 어떤 방법을 동원해도) 패스워드 없이는 접근할 수 없습니다. 225 | 226 | `data-dir` 폴더에 지갑 파일이 저장돼 있습니다. eos를 실행시킬 때 `--data-dir` 실행인자로 따로 이 폴더를 변경하지 않았다면, 지갑 파일들은 `~/eosio-wallet` 폴더 내에 저장돼 있을 것입니다. 227 | 228 | ```bash 229 | $ cd ~/eosio-wallet && ls 230 | blockchain blocks config.ini default.wallet periwinkle.wallet 231 | ``` 232 | 233 | 튜토리얼의 앞 단계를 충실히 거쳐왔다면, 두 파일이 존재할 것입니다. `default.wallet` 파일과 `periwinkle.wallet` 파일이죠. 이 파일을 안전한 위치에 저장해 둡시다. 234 | 235 | ### 계정 생성하기 236 | 블록체인에서 액션을 실행하려면 계정을 사용해야만 합니다. `cleos`를 이용해 `nodeos`에 계정을 생성하고 블록체인에 등록하는 방법을 살펴보겠습니다. 이 시점에서는 `nodeos`를 실행시켜야만 합니다. 다음 명령어는 단일 노드 테스트넷을 실행시켜줍니다. 로컬에서 단일 노드 테스트넷을 실행하는 자세한 방법은 [단일 노드 테스트넷을 생성하고 실행하기](https://github.com/eoseoul/docs/blob/master/ko/translations/Local-Environment.md#%EB%8B%A8%EC%9D%BC-%EB%85%B8%EB%93%9C-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%84%B7-%EC%83%9D%EC%84%B1%ED%95%98%EA%B3%A0-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0)를 참조하세요. 237 | 238 | > 이 단계에서는 keosd와 nodeos를 동시에 실행시켜야 합니다. 현재 `keosd`와 `nodeos`는 같은 포트(8888)를 사용하고 있습니다. 239 | > nodeos를 실행하는 작업을 간편하게 하기 위해, 이 튜토리얼에서는 `keosd`를 8899 포트에서 실행되도록 바꿔보겠습니다. 두 가지 방법이 있습니다: 240 | > 241 | > 1. `keosd`의 설정 파일(`~/eosio-wallet/config.ini`)을 편집해서 http-server-address 속성을 다음과 같이 변경합니다: 242 | > http-server-address = 127.0.0.1:8899 243 | > 244 | > 2. 다음 실행인자를 줘서 keosd를 실행시킵니다: --http-server-address=localhost:8899 245 | > 246 | > 다음과 같이 실행해서 keosd를 재시작시키세요: 247 | > 248 | > $ pkill keosd 249 | > $ keosd --http-server-address=localhost:8899 250 | > 251 | > 기본 지갑의 잠금을 해제(keosd가 재시작되면 지갑은 잠깁니다)합니다. keosd가 8899 포트를 리스닝하도록 시작됐기 때문에 252 | > --wallet-port 실행인자를 cleos에 주어야 합니다. 253 | > 254 | > cleos --wallet-port=8899 wallet unlock 255 | > 256 | > 패스워드 입력이 필요합니다. 앞 단계에서 지갑을 생성할 때 생성된 패스워드를 입력하세요. 257 | 258 | `nodeos`를 시작하기 위해 새 터미널 창을 엽니다. `nodeos` 실행파일이 있는 폴더로 이동한 뒤 다음과 같이 실행합니다: 259 | 260 | ```bash 261 | $ cd eos/build/programs/nodeos 262 | $ nodeos -e -p eosio --plugin eosio::chain_api_plugin --plugin eosio::account_history_api_plugin 263 | ``` 264 | 265 | 이제 계정을 생성할 수 있습니다. `cleos create account` 명령어의 구조는 다음과 같습니다. 266 | 267 | ```bash 268 | $ cleos create account ${authorizing_account} ${new_account} ${owner_key} ${active_key} 269 | ``` 270 | 271 | - `authorizing_account`는 계정 생성과 새 계정을 위한 비용을 지불할 계정의 이름입니다. 272 | - `new_account`는 생성할 계정의 이름입니다. 273 | - `owner_key`는 계정의 **소유자** 자격에 할당되는 공개 키입니다. ([계정과 권한](https://github.com/eoseoul/docs/blob/master/ko/translations/Accounts-%26-Permissions.md)을 참조하세요) 274 | - `active_key`는 계정의 **활동** 자격에 할당되는 공개 키입니다. 이 키를 가진 두 번째 사용자에게는 여러분 계정의 활동 자격에 대한 권한이 부여됩니다. 275 | 276 | 이 튜토리얼에서는 `eosio`가 자격을 부여하는 계정입니다. 블록체인 상에서 수행되는 액션들은 `eosio` 계정과 연관된 키를 이용해 서명돼야 합니다. `eosio` 계정은 EOSIO 노드를 부팅하기 위해 사용되는 특별한 계정입니다. 이 계정에 대한 키는 `nodeos` 설정파일에서 찾을 수 있습니다. Linux 플랫폼의 경우 `~/.local/shared/eosio/config/config.ini`내에 존재하며, MacOS의 경우 `~/Libraries/Application Support/eosio/nodeos/config/config.ini` 내에 존재합니다. 277 | 278 | 새로 생성한 계정에 이름이 필요합니다. 계정 이름은 다음 가이드라인을 따라야 합니다: 279 | 280 | - 13 글자 미만일 것 281 | - 다음 문자만을 포함하고 있을 것: .12345abcdefghijklmnopqrstuvwxyz 282 | 283 | "myaccount"라는 이름을 새 계정 이름으로 사용하도록 하겠습니다. 284 | 285 | 위에서 생성해 지갑에 임포트한 공개 키(공개 키가 `EOS`로 시작하는 문자열이라는 것을 기억하세요)를 사용할 것입니다. 키는 자격을 부여하기 전까지는 무용지물입니다. 하지만, 자격이 부여되면, 부여된 자격을 꼭 기억해야만 합니다. 소유자 키는 계정의 모든 제어권을 가지고 있습니다. 한편, 활동 키는 계정이 보유한 자금에 대한 모든 접근권한을 가지고 있습니다. 286 | 287 | `cleos create account` 명령어로 계정을 생성해 보겠습니다: 288 | 289 | ```bash 290 | $ cleos --wallet-port=8899 create account eosio myaccount ${public_key_1} ${public_key_2} 291 | ``` 292 | 293 | 성공했다면 다음과 비슷한 결과가 출력됩니다. 294 | 295 | ```bash 296 | executed transaction: 7f1c6b87cd6573365a7bb3c6aa12f8162c3373d57d148f63f2a2d3373ad2fd54 352 bytes 102400 cycles 297 | # eosio <= eosio::newaccount {"creator":"eosio","name":"myaccount","owner":{"threshold":1,"keys":[{"key":"EOS5kkAs8HZ88m2N7iZWy4J... 298 | ``` 299 | 300 | #### 계정과 관련된 조작 301 | 계정에 대한 많은 `cleos` 명령어가 있습니다. 302 | 303 | `cleos` 명령어 | 설명 304 | ----- | ----- 305 | `create account` | 블록체인에 새 계정을 생성합니다 306 | `get account` | 블록체인에서 계정을 검색합니다 307 | `get code` | 계정에 대한 코드와 ABI를 검색합니다 308 | `get accounts` | 공개 키에 묶인 계정(들)을 검색합니다 309 | `get servants` | 주어진 계정이 만든 하위 계정들을 검색합니다 310 | `get transactions` | 범위 내에서 주어진 계정명에 해당하는 모든 트랜잭션을 검색합니다 311 | `set contract` | 계정의 컨트랙트를 생성하거나 업데이트합니다 312 | `set account` | 블록체인 계정의 상태를 설정하거나 업데이트합니다 313 | `transfer` | EOS를 계정에서 다른 계정으로 전달합니다 314 | 315 | ## 번역 정보 316 | * 원문 : https://github.com/EOSIO/eos/wiki/Tutorial-Comprehensive-Accounts-and-Wallets 317 | * 번역 기준 리비전 : 0c18223ea118597c7b2476118091c4094be6af99 318 | -------------------------------------------------------------------------------- /ko/translations/Introducing_EOSIO_Dawn_4.md: -------------------------------------------------------------------------------- 1 | # EOSIO Dawn 4.0을 소개합니다. 2 | 3 | 블록원이 EOSIO Dawn 3.0을 출시한지 1개월 정도 지났습니다. 지난 달 우리 팀은 4 | EOSIO 소프트웨어을 정리하고 안정화하는 데 초점을 맞춰왔습니다. 이 작업의 5 | 큰 부분은 블록체인간 통신의 개념 증명(Proof of concept)을 만드는 데 있었습니다. 6 | 7 | merge를 제외하면, 개발자 43명은 깃헙에 커밋 818개를 푸시해왔습니다. 이로써 8 | EOSIO는 지난달 깃헙의 C++ 프로젝트 중 가장 활발한 8개 프로젝트 안에 들었습니다. 9 | 보시다시피 많은 일이 일어나고 있습니다. 10 | 11 | 1. `now()`는 이제 현재 시각을 돌려줍니다. 12 | 2. 시장 기반의 새로운 RAM 할당 모델 13 | 3. 블록체인간 통신의 등장 14 | 4. DPOS 마지막 비가역 블록 알고리즘 업그레이드 15 | 5. 계정 이름 알박기 16 | 6. 헤더만 검증 17 | 7. 경량 프로듀서 스케줄 변경 증명 18 | 8. 검토된 프로듀서 보상 모델 19 | 9. 프로듀서 투표수 감소 20 | 10. 거래소 통합 지원 21 | 22 | ## `now()`는 이제 현재 시각을 돌려줍니다. 23 | 24 | EOSIO Dawn 4.0의 가장 큰 변화 중 하나는 현재 시각의 정의를 "헤드(head) 블록의 25 | 시각"에서 "현재(current) 블록의 시각"으로 변경한 데 있습니다. 26 | 이렇게 변경한 덕분에 누락 블록이 존재하는 상황에서 27 | 시간과 관련된 작업이 정상작동할 때도 있었고 오류가 발생하기도 했던 코너 28 | 케이스를 해결하고 스마트 컨트랙트 내에서 소요 시간을 훨씬 정확하게 29 | 측정할 수 있게 되었습니다. 30 | 31 | (옮긴이 주: 헤드 블록(head block)은 가장 최근에 만들어진 블록입니다. 헤드 블록은 32 | 마지막 비가역(변경불가확정) 블록(Last Irreversible Block, LIB)보다 블록 높이가 33 | 큽니다. 하지만 헤드 블록은 블록 프로듀서가 만들고 있는 34 | 블록(current block)보다 블록 높이가 작습니다. 변경에 대한 자세한 내용은 다음 커밋 메시지를 35 | 참조하세요. https://github.com/EOSIO/eos/commit/5a72a4b7c37c430a479ecefe4c43811b1bfab08e ) 36 | 37 | ## 램 할당 모델 38 | 39 | 테스트 과정에서 우리는 EOSIO 시스템 컨트랙트가 토큰으로 지분참여(stake)한 40 | 사용자들에게 RAM (데이터베이스 공간)을 할당하는 방법으로는 장래에 부족을 41 | 초래할 것이라는 사실을 알아냈습니다. Bancor 알고리즘을 이용한 시장 기반의 42 | 할당 방식으로 전환했습니다. 43 | 44 | 계산을 해보니 이렇습니다. 1TB의 RAM이 토큰 홀더에게 토큰량 비례로 할당되면 45 | 바이트당 비용은 0.018 달러입니다(토큰당 20달러라고 가정합니다). 46 | 실제로 대부분의 토큰 홀더는 할당받을 RAM을 적극적으로 사용할 필요가 47 | 사실 없습니다. 그래서, 우리는 초기 RAM 비용을 바이트당 0.000018 달러로 48 | 정했습니다(토큰당 20달러라고 가정합니다). 새로운 계정은 대략 4KB의 RAM이 49 | 필요하고 대략 0.10 달러의 비용이 듭니다. RAM이 예약되는 양에 따라 시스템의 RAM이 50 | 부족해지기 전에 가격이 무한대에 근접하도록 가격이 자동으로 증가합니다. 51 | 52 | Dawn 3.0 시스템 컨트랙트는 RAM을 구입한 금액에 따라서만 RAM을 팔 수 있었습니다. 53 | 그렇게 한 목적은 사재기와 투기를 억제하기 위해서였습니다. 이런 접근의 단점은 54 | RAM 사용 수요가 많아져서 정체될 때 과거에 RAM을 싸게 구입했던 사람들이 55 | 다른 사용자를 위해 RAM에 대한 자신의 지분참여량을 줄이는(free) 재정적인 56 | 동기가 없다는 점입니다. Dawn 4.0의 시스템 컨트랙트는 이제 현행 시장 가격으로 57 | RAM 할당량을 매입하고 판매합니다. 이런 접근으로 미래의 잠재적인 부족을 예상하여 58 | 트레이더들이 RAM을 오늘 구입하는 결과를 만들지도 모릅니다. 전반적으로 시장은 59 | 시간이 지남에 따라 RAM에 대한 수요와 공급의 균형을 맞출 것입니다. 60 | 61 | 시간이 지남에 따라 무어의 법칙은 블록 프로듀서들이 RAM을 4TB나 심지어 16TB로 62 | 업그레이드하게 할 것이고, 이런 RAM 공급량의 증가는 EOSIO RAM 시장에 흘러들어와서 63 | 가격을 낮출 것입니다. 64 | 65 | ## 스마트 컨트랙트 개발자에게 주는 영향 66 | 67 | 스마트 컨트랙트 개발자의 입장에서는 RAM은 데이터베이스 레코드를 저장하면 68 | 소모되는 귀한 자원입니다. RAM의 비용을 고려하면, in-memory 69 | 데이터베이스에 저장하는 데이터의 양을 최소화하고 사용자가 70 | 어플리케이션 사용을 마친 후에 RAM을 비울 수 있도록 어플리케이션을 설계하는 71 | 것이 중요합니다. 예를 들어 Steem은 1주일 분량의 컨텐츠만 RAM에 저장하기 때문에 72 | 시간이 지나도 RAM의 전체 크기가 크게 늘어나지 않습니다. 73 | 74 | ## 투기 최소화 75 | 76 | 이제 RAM 시장이 생겼기 때문에, 투기꾼들은 이익을 위해 RAM 가격 변동성을 77 | 거래하려고 할 수 있습니다. EOSIO 시스템 컨트랙트는 RAM을 양도할 수 없게 만들고 78 | 거래에 대해 1%의 수수료를 부과합니다. 이와 같은 수수료로 토큰을 시장에서 꺼내어 79 | 토큰의 자연적인 가격 상승률을 상쇄하는 효과를 보일 것입니다. RAM의 연간 80 | 거래량이 연간 토큰 공급량과 같으면 블록 생산자에게 주어지는 모든 보상의 100%가 81 | RAM 시장 수수료로 충당될 것입니다. 82 | 83 | ## 블록체인간 통신의 등장 84 | 85 | 고성능 블록체인은 모든 데이터를 RAM에 저장할 필요가 있습니다. 디스크 접근에 86 | 소요되는 시간으로 인해 트랜잭션 처리량을 겨우 초당 수백 건으로 금새 떨어뜨리기 87 | 때문입니다. RAM 사용량을 확장시키기 위해 별개의 하드웨어에서 동작하는 88 | 별도의 메모리 리전(region)으로 구성되는 다수의 체인이 필요합니다. 89 | 90 | EOSIO 블록 프로듀서는 RAM을 구입하고 지분참여로 대역폭을 확보하는 데 사용하는 91 | 동일한 토큰을 이용하는 서로 다른 많은 체인을 운영할 수 있습니다. 프로듀서 92 | 선출은 메인 체인에서 일어날 것이며 관련된 모든 사이드체인은 동일한 프로듀서군에 93 | 의해서 운영될 것입니다. 각 체인은 각각 1TB 이상의 RAM을 가질 수 있고 DAPP은 94 | 몇 초의 지연시간 안에서 체인 사이의 메시지를 전송할 수 있습니다. 95 | 96 | RAM의 가격은 체인별로 다를 수 있고, 각 체인은 DAPP 개발자에게 어느 체인이 97 | 가장 저렴한지 알려줄 것입니다. 98 | 99 | ## 병렬 처리 로드맵 100 | 101 | 블록체인간 통신(Inter Blockchain Communication, 줄여서 IBC)은 크기가 1KB 102 | 이상이고 수십 개의 암호화 해시 함수 및/또는 15개 이상의 서명 검증을 포함하는 103 | 머클(merkle) 증명의 유효성을 검사하는 두 개의 체인 사이에서 일어납니다. 104 | 즉, 다른 체인의 메시지를 확인하는 데 드는 비용은 보통의 트랜잭션을 확인하는 105 | 비용보다 약 15배에서 30배 정도 높습니다. 106 | 107 | 다행히 이러한 증명을 검증하는 작업은 블록체인 상태에 의존하지 않으므로 108 | 병렬화하는 것이 쉽습니다. 다른 체인의 메시지만 처리한 블록체인은 109 | 초당 몇 천 개의 트랜잭션만 유지하면서 쉽게 30개의 CPU 코어를 점유할 수도 110 | 있을 것입니다. 111 | 112 | 블록체인간 통신을 통한 확장은 거의 무한한 확장 가능성을 제공할 것이라고 113 | 우리는 믿고 있습니다. 이 접근을 통해서 동시에 RAM, 네트워크 및 CPU 처리 114 | 용량까지 확장합니다. 서명 검증, 컨텍스트-프리 액션 검증 및 IBC 증명이 115 | 이미 단일-쓰레드 처리량이 높은 대부분의 CPU를 포화 상태로 만들 것이라는 116 | 점을 감안할 때, 멀티-쓰레드 WASM 실행 최적화는 다른 자원의 제약으로 인해 117 | 병목 현상을 일으킬 수 있습니다. 118 | 119 | EOSIO Dawn 3.0은 미래에 멀티-쓰레드 WASM 실행을 구현할 가능성을 염두에 120 | 두고 많은 디자인 결정을 내린 결과물입니다. 불행하게도, 실제로 완전한 121 | 멀티-쓰레드 구현체를 완성하기 전까지는 정상작동할 때도 있고 오류를 발생시킬 122 | 때도 있는 코너 케이스 모두를 고쳤는지 확인하기가 불가능합니다. 즉, 123 | EOSIO Dawn 3.0에는 당장의 이점을 주지 않는 아키텍처의 복잡성이 많았습니다. 124 | 125 | 이제 우리는 단일-쓰레드 실행에서 멀티-쓰레드 실행으로 업그레이드하는 과정이 126 | 동일한 블록 프로듀서가 멀티-쓰레드를 지원하고 동일한 네이티브 토큰으로 127 | 지분참여할 수 있는 새로운 체인을 런칭하는 작업이라고 믿습니다. 이와 같은 과정을 128 | 통해서 라이브 체인에 대해 덮어쓰기(in-place) 업그레이드를 진행하는 위험을 129 | 감수하지 않고 새로운 체인을 이용해서 멀티-쓰레드 기능 지원에 필요한 설계 수정을 130 | 반영할 수 있는 완전한 자유를 얻게 됩니다. 131 | 132 | 이와 같은 병렬 처리 로드맵으로 우리는 EOSIO 1.0을 단순화하고 단일-쓰레드 최대 133 | 성능과 개발 편의성을 최적화할 수 있습니다. 우리는 EOSIO 단일-쓰레드 버전이 134 | 언젠가 5,000-10,000 TPS에 도달할 것이라고 예상합니다. 또한 다중-체인 방식이 135 | 전체 비용을 낮추고 빨리 확장할 수 있기 때문에 많은 어플리케이션이 다중-체인 136 | 방식을 선호할 것이라고 예상합니다. 137 | 138 | ## DPOS 마지막-비가역-블록 알고리즘 업그레이드 139 | 140 | 합의 알고리즘 논쟁을 지켜본 사람들은 아마 (Steem과 BitShares에 구현된) 마지막 141 | 비가역 블록 (last irreversible block, LIB) 알고리즘을 사용하는 DPOS가 특정한 142 | 극단적 네트워크 연결 끊김이 발생하는 상황에서 합의가 깨질 가능성이 있다는 143 | 의견을 들었을 것입니다. 과거에 저는 이와 같은 상황이 순전히 이론적인 성격을 144 | 가지고 있고 상대적으로 최소의 비용과 장애시간이 소모될 것이라는 생각으로 이와 145 | 같은 잠재적인 장애 유형을 일축했습니다. LIB 알고리즘은 비트코인의 6-블록 146 | 규칙과 같이, 단지 하나의 기준입니다. 순수한 DPOS는 항상 최종적인 합의에 147 | 도달하는 가장-긴-체인 규칙을 늘 신뢰합니다. LIB 알고리즘은 undo 이력을 148 | 최적화하고 거래에 신뢰 기준을 제공하기 위해 디자인된 지름길입니다. 149 | 150 | EOSIO의 IBC 알고리즘은 최종성을 확실히 하기 위해 DPOS LIB에 의존합니다. 151 | 일단 IBC를 도입하면 LIB 실패와 관련된 비용과 해당 문제를 수정하는 난이도는 152 | 훨씬 높아집니다. 우리 팀, 특히 Bart와 Arhag은 전체 노드의 1/3 이상이 153 | 비잔틴(배반자)가 되지 않고는 두 개의 노드가 서로 다른 LIB에 도달하기가 154 | 불가능함을 보장하는 우아한 개선 방안을 LIB 알고리즘에 반영해왔습니다. 155 | 게다가, 단일 피어의 비잔틴(배반) 행위를 탐지할 수도 있습니다. 156 | 자세한 내용은 [여기](https://github.com/eoseoul/docs/blob/master/ko/translations/Fix_DPoS_Loss_of_Consensus.md)를 참조하세요. 157 | 158 | 레거시 체인들과 블록체인간 통신을 어렵고 매우 높은 지연시간이 걸리게 만드는 159 | 이유는 바로 비트코인과 이더리움의 최종성이 결여되었기 때문입니다. DPOS에 160 | 추가된 새로운 수정 사항으로 새로운 수준의 비잔틴 장애 내성 최종성과 161 | 모든 네트워크 환경에서 견고함을 가져왔습니다. 162 | 163 | ## 계정 이름 알박기 - Name Squatting 164 | 165 | 일부 사용자는 EOSIO 계정 이름에 사용할 수 있는 글자를 12글자로 제한한 점을 166 | 우려해왔습니다. 이 12글자 이름은 64비트 정수형의 base-32 인코딩에서 167 | 비롯됩니다. 64비트 정수형은 기본 머신 워드 사이즈라서 매우 효율적입니다. 168 | 트랜잭션 안에서 계정 이름을 여러 번 참조하고 (코드, scope, 권한 등) 169 | 데이터베이스 인덱스도 64비트 정수형을 기반으로 합니다. 계정 이름의 길이를 170 | 늘리면 성능과 아키텍처에 큰 영향을 미쳤을 것입니다. 171 | 172 | 다시 말하면, 블록체인에 대한 우리의 비전은 계정의 개념을 신원(identity, ID)과 173 | 분리하고 계정 이름과 더 읽기 쉬운 표시 이름 사이의 동적인 체인 내 매핑을 174 | 설정하는 것입니다. 175 | 176 | 계정 이름은 기억하기 쉽게 사용자가 고르는 자동차 장식 번호판과 같은 177 | 자동차 번호판으로 보는 것이 가장 좋습니다. 즉, 대대수의 사람들이 12 글자 178 | (혹은 그 이하)의 매력적인 계정 이름을 찾을 수 있어야 합니다. 179 | 180 | 어떤 이름은 잠재적인 가치가 높을 수 있어서, EOSIO 시스템은 계정 이름에 181 | 대해 동적인 가격 모델을 제공해야 한다고 생각합니다. 또한 *.com 과 같은 182 | 네임스페이스 계정 기능은 사용자와 그룹에 대한 추가적인 보안 계층을 183 | 제공할 수 있습니다. 184 | 185 | EOSIO의 현재 버전과 1.0 버전 사이에 개발할 시간이 제한되어 있기 때문에, 186 | 모든 계정 이름은 12 글자로 제한하고 '.' 문자를 포함하지 않을 것을 권합니다. 187 | 실행가능한 가격 정책과 계정 이름 알박기 방지 정책이 확인되면, 그때 188 | 커뮤니티는 시스템 컨트랙트를 (하드 포크 없이) 업그레이드할 수 있습니다. 189 | 계정 이름이 길이와 글자가 나타내는 내용에 따라 가격이 책정되는 BitShares와 190 | 비슷한 모델을 제공할 가능성이 높습니다. 191 | 192 | ## 헤더만 검증 193 | 194 | Steem, BitShare와 EOS Dawn 3.0과 과거 버전들은 전체 블록을 훓지 않고는 195 | 블록 해더를 검증할 수 없었습니다. EOS Dawn 4.0에서 헤더만 검증하는 기능을 196 | 지원합니다. 이 기능은 라이트 클라이언트와 IBC의 기반이며 또한 다양한 침입 197 | 경로를 막으면서 각각 노드의 전체 검증 진행을 기다리지 않고 네트워크에 198 | 블록을 전파할 수 있게 합니다. 199 | 200 | 잦은 통신을 위한 IBC의 가장 단순한 형태는 모든 헤더를 처리하는 라이트 201 | 클라이언트와 알려진 블록에 대한 액션들의 단순한 머클 증명을 제공하는 202 | 사용자로 구성됩니다. 203 | 204 | ## 블록 생성과 적용 아키텍처를 리팩토링함 205 | 206 | 우리는 블록을 만들고 적용하는 과정을 정리하는 데 많은 시간을 보냈습니다. 207 | 새로운 모델에서는 블록을 적용하는 데 사용되는 동일한 API 호출 순서로 블록을 208 | 만듭니다. 이렇게 해서 동일한 코드 경로를 따르게 되고, 프로듀서가 유효하다고 209 | 생각하는 지점과 검증자가 유효하다고 생각하는 지점 사이의 불일치가 발생할 210 | 가능성을 최소화합니다. 이 정리 작업을 통해서 블록을 적용하는 과정을, 211 | 블록 프로듀서가 한 작업을 리플레이하는 스크립트와 비슷하게 만들었습니다. 212 | 213 | ## 경량 프로듀서 스케줄 변경 증명 214 | 215 | IBC를 개념적으로 증명하는 간단한 코드를 구현하면서 우리는 Dawn 3.0에 단순한 216 | 서명 증명이 불가능한 몇 가지 경계 오류(edge case)가 있다는 점을 알게 217 | 되었습니다. 우리는 경량 최소 헤더 검증을 최대한 단순하게 만들고 싶었고 그래서 218 | 블록이 서명되는 방식을 리팩토링해야했습니다. 219 | 220 | ![경량 프로듀서 스케줄 변경 증명](assets/dawn_4_lpscp.png) 221 | 222 | EOSIO Dawn 4.0에서는 블록 헤더의 유효성을 검증하지 않고도 프로듀서 스케줄 223 | 변경 사항을 검증할 수 있게 되었습니다. 프로듀서가 블록에 서명할 때 새로운 224 | 스케줄에 대해서도 서명합니다. 이로써 2/3 이상의 프로듀서가 공모하거나 225 | 매우 나쁜 네트워크 분할로 1/3 이상의 프로듀서 결탁이 있지 않고서는, 226 | 서명이 유효한 두 개의 충돌하는 프로듀서 스케줄은 존재할 수 없습니다. 227 | 228 | ## 새로운 프로듀서 보상 패러다임 229 | 230 | 프로듀서 블록 생성 보상과 최대 5%의 토큰 인플레이션을 할당하는 방법에 대한 231 | 커뮤니티 토론이 많이 있었습니다. 블록원이 EOSIO 1.0과 함께 제공할 레퍼런스 232 | 시스템 컨트랙트는 인플레이션을 다음과 같이 할당합니다. 233 | 234 | ![새로운 프로듀서 보상 패러다임](assets/dawn_4_ppp.png) 235 | 236 | 21개의 활성 블록 프로듀서와 일부 대기 프로듀서가 있습니다. 상위 21개의 237 | 블록 프로듀서는 각각의 프로듀서가 생산한 블록의 수에 비례해서 블록당 238 | 0.25%의 보상을 나눕니다. 상위 21개를 포함한 모든 블록 프로듀서 출마자는 239 | 자신들이 받는 투표수에 비례해서 0.75%의 투표 보상 예산을 나눕니다. 240 | 각 프로듀서는 투표 보상을 최대 하루에 한 번 청구할 수 있습니다. 241 | 투표 보상을 청구하기 위해서는 하루에 최소 100개의 토큰을 획득해야 합니다. 242 | 하루에 투표 보상 기준 최소 100개의 토큰을 획득하지 못한 프로듀서 출마자들은 243 | 아무것도 받지 않을 것입니다. 244 | 245 | 이 알고리즘의 배경에 있는 아이디어는 모든 프로듀서 출마자가 커뮤니티에 246 | 제공하는 풀노드 서비스에 대한 충분한 보상을 받고록 하고 운영 비용을 충당하는 247 | 데 불충분한 돈을 받는 프로듀서가 없도록 하기 위해서입니다. 상위 200개의 248 | 프로듀서 출마자 모두가 같은 수의 투표를 받았다고 가정하면, 이 방식은 21개의 249 | 활성 프로듀서와 179개의 대기 프로듀서를 지원합니다. 실제로 일부 프로듀서가 250 | 다른 프로듀서보다 훨씬 많은 투표를 받아서, 보상을 받는 대기 프로듀서의 숫자를 251 | 줄일 지도 모릅니다. 252 | 253 | 블록을 생산할 의도가 없는 부유한 개인이 자신의 프로듀서 후보에게 투표함으로써 254 | 자신의 프로듀서 후보가 이익을 얻지 못하도록, 최소한의 하루 보상을 가지는 것이 255 | 중요합니다. 256 | 257 | ## 프로듀서 투표수 감소 258 | 259 | Dawn 3.0 출시 이후 우리가 진행하는 작업의 대부분은 시스템 컨트랙트를 조정하는 260 | 작업입니다. 조정 작업 중 하나는 투표수 감소의 구현입니다. 투표 영향력을 최대한 261 | 유지하기 위해서 각각의 투표자는 매주 투표를 다시 진행해야 할 것입니다. 투표 262 | 영향력은 투표를 최신 상태로 유지하지 않는 사람의 경우 1년의 반감기를 가집니다. 263 | 264 | 우리는 헌법에 자동 투표 봇의 사용을 금지하는 조항을 포함하기를 권고합니다. 265 | 왜냐하면 투표수 감소 기능의 목적은 투표자가 "정해놓고 잊기" 대신 자신의 결정을 266 | 확실히 재고하게끔 하는 데 있습니다. 봇의 사용을 증명할 방법은 없지만, 267 | 사람들이 자동-투표하도록 스마트 컨트랙트를 사용하지 않는다는 점을 증명할 수 268 | 있습니다. 269 | 270 | ## 거래소 통합 지원 271 | 272 | EOSIO 1.0 출시가 가까워짐에 따라, 많은 사람들이 암호화폐 거래소가 273 | 거래소 계좌로의 입금 확인을 위해 EOSIO 블록체인을 모니터링하고 거래소 274 | 바깥으로 나가는 출금이 네트워크에 전달되어 비가역적으로 승인되었는지 검증하는 275 | 방법에 대한 정보를 우리에게 문의하고 있습니다. 우리는 체인의 입금을 276 | 모니터링하는 (EOSIO 인터페이스 커맨드 라인 명령어인) `cleos`를 이용한 277 | 튜토리얼을 작성해왔습니다. 또 입금과 출금을 모니터링하는 데모용 파이썬 278 | 스크립트를 작성해왔습니다. 이 튜토리얼과 예제 스크립트를 이용해서, 암호화폐 279 | 거래소는 EOSIO 기반의 블록체인과 통합을 시작하기 위한 작업에 필요한 모든 280 | 정보를 가지고 있다고 말할 수 있습니다. 281 | 282 | ## EOSIO Dawn 4.0 입수 방법 283 | 284 | EOSIO Dawn 4.0 코드 개발은 깃헙의 'slim' 브랜치에서 계속 진행되고 있습니다. 285 | 우리는 계속 코드를 다듬어서 2018년 5월 11일에 공식 출시할 예정입니다. 286 | 그 시점에 slim 브랜치를 master 브랜치로 옮기고 출시 태그를 달 것입니다. 287 | 최근의 개발 진도를 따라가고 싶은 개발자는 slim 브랜치를 통해서 우리의 288 | 작업 진도를 따라올 수 있습니다. 289 | 290 | ## 결론 291 | 292 | EOSIO 소프트웨어는 이번 6월의 강건한 1.0 출시를 향해서 성큼성큼 걸어가고 293 | 있습니다. Dawn 4.0에서 코드는 매우 깔끔하게 정리되고 왔고 294 | 우리는 그 어떤 때보다 더욱 확신에 가득 차 있습니다. 295 | 296 | ## 면책조항 - Disclaimer 297 | 298 | 면책조항: 블록원(block.one)은 소프트웨어 기업이며 EOS.IO 소프트웨어를 무료 299 | 오픈소스 소프트웨어로 제작합니다. 이 소프트웨어는, 특기할 만한 점으로, 이 소프트웨어를 도입하는 사용자가 다양한 기능을 갖춘 분산 어플리케이션 또는 블록체인을 시작할 수 있도록 합니다. 자세한 내용은 다음 사이트를 방문하십시오. https://github.com/eosio 블록원은 채택하거나 구현할 수있는 EOS.IO 플랫폼의 모든 버전에서 블록 프로듀서가 되려는 사람에게 경제적 지원을 제공하지 않습니다. 300 | 301 | 블록원은 EOS.IO 소프트웨어를 기반으로 하는 퍼블륵 블록체인을 론칭하지 않습니다. 자신들이 선택한 기능 및/또는 자신들이 선택한 서비스를 제공하도록, 자신들이 선택한 형태로 EOS.IO를 채택하며 구현하려는 제 3자, 커뮤니티 및/또는 블록 프로듀서가 되길 원하는 주체들의 단독 책임일 것입니다. 블록원은 임의의 주체가 그러한 기능을 채택하여 구현하거나 그런 서비스를 제공하거나 EOS.IO가 어떤 방식으로든 채택되고 구현된다는 것을 보증하지 않습니다. 302 | 303 | 이 문서는 블록원의 비전을 보여 주며 어떠한 보증도 아닙니다. 우리가 그 비전을 실현하도록 노력할 것이지만, 모든 측면이 모든 면에서 블록원의 단독 재량 하에 변경될 수 있습니다. 우리는 블록원의 비즈니스 전략, 계획, 전망, 개발 및 목표에 관한 진술과 같은 역사적 사실에 대한 진술 이외에 이 문서의 모든 진술을 포함하는 이 문서를 "미래 예측 진술"이라고 부릅니다. 이 진술은 예측일 뿐이며 미래의 사건에 대한 블록원의 현재의 믿음과 기대치를 반영하고 가정에 근거하며 언제든지 위험, 불확실성 및 변경의 영향을 받습니다. 우리는 급변하는 환경에서 사업을 운영합니다. 새로운 위험이 수시로 발생합니다. 이러한 위험과 불확실성을 감안할 때 이러한 미래 예측 진술에 의존하지 않도록 주의해야합니다. 실제 결과, 실적 또는 이벤트는 미래 예측 진술에 포함된 내용과 실질적으로 다를 수 있습니다. 실제 결과, 실적 또는 이벤트가 미래 예측 진술과 실질적으로 다른 원인이 될 수 있는 요인에는 시장 변동성, 자본, 재원 및 인력의 지속적인 가용성; 제품 수용; 어떤 새로운 제품이나 기술의 상업적 성공; 경쟁; 정부 규제 및 법률; 그리고 일반적인 경제, 시장 또는 사업 조건이 포함되며 이에 제한되지 않습니다. 블록원이 만든 모든 미래 예측 진술은 그것이 작성된 날짜에 대해서만 말하고 블록원은 새로운 정보, 후속 사건 또는 기타의 사건의 결과로서건 간에 미래 예측 진술을 업데이트하거나 변경할 의무가 없으며 분명히 부인할 의무가 없습니다. 304 | 305 | 여기에 있는 진술은 기술, 재무, 투자, 법률 또는 기타 조언을 구성하지 않으며 특정 상황이나 구현에 적용되지 않습니다. 이 문서에 포함된 내용을 구현하거나 활용하기 전에 해당 분야의 전문가에게 문의하십시오. 306 | 307 | 여기에서 표현된 아이디어와 정보는 전적으로 저자 개인의 것이며 블록원 또는 블록원 직원의 입장과 견해와 조언을 필연적으로 반영한 것은 아닙니다. 308 | 309 | 토마스 콕스(Thomas Cox)와 그렉 리(Greg Lee)에게 감사의 말씀을 전합니다. 310 | 311 | ## 번역정보 312 | 313 | * 원문 : https://medium.com/@bytemaster/introducing-eosio-dawn-4-0-f738c552879 (2018.05.05 KST) 314 | -------------------------------------------------------------------------------- /ko/translations/Dawn_3_Now_Available.md: -------------------------------------------------------------------------------- 1 | # EOSIO Dawn 3.0 출시 2 | 3 | 블록원은 EOSIO의 첫 번째 [기능 완료 프리-릴리즈인 Dawn 3.0 출시](https://github.com/EOSIO/eos/releases/tag/dawn-v3.0.0)를 알려드리게 되어 기쁩니다. 이번 프리-릴리즈는 2018년 6월 출시 예정된 EOSIO 1.0을 향한 주요 마일스톤입니다. 전 세계 곳곳에서 일하고 있는 우리 팀 개발자들은 EOSIO를 블록체인 어플리케이션을 구현하는 가장 강력한 플랫폼으로 만들기 위해 24시간 내내 일해오고 있습니다. EOSIO Dawn 2.0을 출시한 지 4개월이 지났고 우리는 보여드릴 게 많습니다. 4 | 5 | 최고의 블록체인 아키텍처를 구현하는 작업은 우리가 배우는 만큼 디자인이 변경되는 과정입니다. Dawn 3.0에 구현한 많은 기능들은 EOSIO 백서 첫 버전에 고려조차 하지 않았지만, 플랫폼을 기대한 성능으로 끌어올리고 유연하고 개발하기 쉽게 만드는 과정을 거치면서 이런 기능들을 발견했습니다. 6 | 7 | ## 확장 기능 - Scalability Features 8 | 9 | 확장성은 시장 요구에 맞도록 확장할 수 있는 능력입니다. 개발의 모든 단계에서 우리 팀은 앞으로 필요할 확장성을 염두에 두고 설계에 녹여왔습니다. 그렇기는 하지만, Dawn 3.0은 EOSIO의 확장성을 확보할 잠재적인 최적화의 일부만 구현했습니다. 향후 구현 과정에서 하드 포킹 없이 처리량을 높일 수 있는 병렬 처리(parallel computation)를 이용할 수 있도록 EOSIO를 설계해왔습니다. 10 | 11 | ### 블록체인간 통신 - Inter-blockchain Communication 12 | 블록체인간 통신은 업계에서 side-chain, plasma, sharding 등의 제안을 통해 모색해온 성배와도 같은 결정적인 확장 기능입니다. 이를 이용해 어느 블록체인이 입증된 안전한 방법으로 다른 블록체인에서 일어난 이벤트의 진위 여부를 검증할 수 있습니다. 목표는 단일 블록체인 범위에서 일어나는 스마트 컨트랙트 사이의 내부 통신만큼 블록체인간 통신을 안전하게 구현하는 것인데, 우리가 보기엔 그 목표에 도달했습니다. 13 | 14 | 우리의 관점에서 블록체인간 통신은 스마트 컨트랙트로 라이트 클라이언트를 구현할 수 있느냐 하는 문제에 지나지 않습니다. 라이트 클라이언트는 블록체인 전체를 검증하지 않고 블록체인의 트랜잭션을 검증할 수 있습니다. 즉, 지분 증명 블록체인을 효율적이고 안전한 라이트 클라이언트 검증으로 구현하면 됩니다. 이런 고려 없이 구현해놓은 뒤에 라이트 클라이언트 검증을 구현하기는 불가능하기 때문에, 라이트 클라이언트 검증을 프로토콜 디자인에 녹여야 합니다. 15 | 16 | ### 꼭 필요한 헤더만 검증 - Sparse Header Verification 17 | 종래의 라이트 클라이언트는 모든 블록 헤더를 처리하고 각 블록 헤더에 대응하는 증거를 검증해야 합니다. EOSIO는 1초에 블록을 2개씩 만들기 때문에, 블록체인은 블록 헤더를 처리하기 위해 최소한 초당 처리량 2건을 만족해야 합니다. 이런 경우라면 블록체인간 통신이 상대적으로 자주 일어나지 않는 시나리오에서는 확장성이 떨어집니다. 이 문제를 풀기 위해 비잔틴 장애에 내성이 있고 꼭 필요한 헤더만 검증(sparse-header validation)하는 최초의 블록체인을 구현했습니다. 구체적으로 살펴보면, 라이트 클라이언트를 속이기 위해서 2/3 (21개 중 15개) 이상의 블록 프로듀서가 배반해야 합니다. 거기에, 활동하는 블록 프로듀서 목록에 변경이 있고 관련된 블록체인간 메시지를 포함하는 블록 헤더만 처리합니다. 이렇게 해서 비잔틴 장애 허용 라이트 클라이언트를 유지하는 오버헤드를 크게 낮추고 블록체인간 통신 효율을 크게 높힐 수 있습니다. 18 | 19 | ### 컨텍스트-프리 액션 - Context Free Actions 20 | 컨텍스트-프리 액션은 효율적인 블록체인간 통신을 가능하게 하는 핵심 기능입니다. 블록체인 상태에 의존하지 않지만 트랜잭션에 포함되는 특별한 액션인데, 왜냐하면 "컨텍스트에서 자유”롭기 때문입니다. 컨텍스트-프리 액션의 예를 들면 서명의 머클 증명을 검증하는 작업이 있습니다. 이런 종류의 연산은 상태를 확인하지 않아도 되기 때문에, 병렬 처리로 쉽게 검증할 수 있고 리플레이 과정에서 제외할 수 있습니다. 21 | 22 | 모든 컨텍스트-프리 액션은 트랜잭션 내용 중 특별한 생략 가능 데이터 섹션을 참조할 수 있습니다. 즉, 커다란 머클 증명을 생략할 수 있어서, 블록체인 리플레이 과정에서 필요한 값비싼 연산 작업을 건너뛸 수 있습니다. 23 | 24 | 이러한 컨텍스트-프리 액션을 이용해서 블록체인간 통신의 오버헤드 대부분을 병렬로 처리할 수 있습니다. 기밀 거래(confidential transaction), 집합 증명(bulletproof), zkSNARK와 같은 많은 계산량이 필요한 정보 비공개 기법을 병렬 처리하고 오버헤드를 제거할 수 있습니다. 컨텍스트-프리 액션 사용을 장려하기 위해, 사용자가 일반적인 트랜잭션의 일부가 아니라 컨텍스트-프리 액션의 일부로 연산을 사용하면 블록 프로듀서는 CPU 사용량의 일부만 과금할 것입니다. 25 | 26 | ### 이벤트로 사용하는 컨텍스트-프리 인라인 액션 - Context-Free Inline Actions as Events 27 | EOS Dawn 2.0 개발자들이 기다린 기능 중 하나는 외부에서 처리된 이벤트를 효율적으로 생성하는 방법입니다. 이더리움에서는 이런 종류의 이벤트로 컨트랙트의 내부 동작에 대한 구조화된 정보를 리포트하는 데 사용합니다. 컨텍스트-프리 액션을 구현했기 때문에, 잠재적으로 컨텍스트-프리 인라인 액션을 사용할 수 있게 되었습니다. 인라인 액션은 컨트랙트 코드를 통해 생성되고 현재의 트랜잭션의 일부로 실행되는 액션입니다. 컨텍스트-프리 인라인 액션은 처리 비용이 낮고 병렬로 처리할 수 있습니다. 모든 인라인 액션이 머클 증명 루트에 포함되기 때문에, 외부 서비스와 다른 블록체인에 증명 가능한 알림을 보내는 용도로 이 액션을 사용할 수 있습니다. 28 | 29 | ### 트랜잭션 압축 - Transaction Compression 30 | 압축 가능한 데이터가 많은 트랜잭션의 종류가 많습니다. 그 가운데 절대 피할 수 없는 예가 컨트랙트 웹어셈블리 코드입니다. 다른 예로는 ABI 명세와 계정/컨트랙트가 참조하는 리카도 컨트랙트(Ricardian contract)입니다. 소셜 미디어와 같은 일부 어플리케이션은 블록체인에 압축 가능한 유저 콘텐츠를 올리고 싶어 할 수도 있습니다. 31 | 32 | 트랜잭션 압축을 이용해서 블록체인은 많은 수의 트랜잭션을 효율적으로 저장하고 전송하며 압축이 가능하지 않은 데이터를 담은 트랜잭션 대신 압축 가능한 데이터를 담은 트랜잭션을 사용하는 사용자에게 덜 과금할 수 있습니다. 33 | 34 | ### Interpreter & Just-In-Time Compilation 35 | Dawn 2.0에서 크게 바뀐 부분 중 하나는 웹어셈블리 런타임의 추상화 구현입니다. Dawn 3.0은 더 빠른 웹어셈블리 [JIT 컴파일러](https://github.com/WebAssembly/wasm-jit-prototype) 대신 [Binaryen](https://github.com/WebAssembly/binaryen) 웹어셈블리 인터프리터를 기본으로 사용합니다. 성능은 떨어지지만, 필요할 때 더 나은 성능의 JIT 환경으로 쉽게 바꿀 수 있게 만든, 안정성과 표준성을 높인 결정이었습니다. 인터프리터는 Dawn 2.0이 직면한 가장 큰 도전 과제인 컨트랙트 컴파일으로 발생하는 지연을 해결했습니다. 앞으로 백그라운드로 컨트랙트를 컴파일하고 최적화하는 동안에 인터프리터를 이용해서 새로 배포된 컨트랙트를 느리지만 대기 시간을 짧도록 실행할 수 있습니다. 이런 이중 구현은 모든 유닛 테스트로 컴파일된 코드와 인터프리터 코드 모두를 테스트한다는 사실을 의미합니다. 그래서 인터프리터와 JIT 컴파일러를 동시에 사용하는 하이브리드 방식을 도입하기 전에 잠재적인 비결정적이거나 비표준적인 동작을 감지할 수 있습니다. 36 | 37 | ### 자원 계량 사용 제한 - Resource Metering Rate Limiting 38 | Dawn 3.0에서 완전히 새로운 자원 사용 제한 시스템을 갖게 되었습니다. 아마 가장 큰 변화는 객관적인 인스트럭션 개수 계산(objective instruction-counting) 알고리즘의 도입입니다. EOSIO 개발에 착수한 초반에는, 자원 사용에 대해 완전히 주관적인 사용 제한과 강제(subjective rate limiting and enforcement)가 가능한 방식을 운용하려는 목표를 가졌습니다. 우리가 발견한 사실은 주관적 강제(subjective enforcement)의 비용이 객관적 강제(objective approach)와 거의 동일하다는 점입니다. 우리는 이제 하이브리드 방식을 사용합니다. 사용자는 객관적으로 측정된 사용량에 대해 과금하고, 블록 프로듀서는 컨트랙트에 주관적인 실행 소요 시간 제한을 겁니다. 이와 같은 주관적인 제한이 객관적 측정 결과 편차를 노린 남용을 방지합니다. 39 | 40 | 이런 결정을 내린 이유 중 하나는, 각각의 트랜잭션이 과거에 가능했던 연산보다 더 많은 연산을 처리할 수 있기 때문입니다. 과거의 모델에서 1 ms 이하에 실행해야 했던 모든 트랜잭션에 비해, 이제 실행에 100 ms가 소요되는 단일 트랜잭션을 블록에 포함시키는 게 이론적으로 가능합니다. 41 | 42 | 자원 사용 제한에 포함된 또 다른 변화는, 토큰 정의가 필요할 때 자원 제한을 따로 설정하도록 분리했다는 점입니다. 이를 통해 EOSIO를 이용해서 토큰 사용이 전혀 필요하지 않는 프라이빗하고 접근승인이 필요한 블록체인을 만들 수 있습니다. 퍼블릭 블록체인은 지분 참여(staking)라는 방법을 통해 제한을 구현한 시스템 컨트랙트를 채택할 수 있고, 커뮤니티는 실제 할당이 이루어지는 방식과 별개로 자원 할당 방식을 동적으로 업그레이드할 수 있습니다. 43 | 44 | ### 500ms Block Interval & BFT DPOS 45 | Dawn 3.0부터 블록 생성 주기를 3초에서 0.5초로 변경했습니다. 이로써 블록 확정까지 걸리는 시간을 크게 줄였습니다. BFT DPOS와 함께 사용하면 트랜잭션은 1초 이하로 변경 불가 확정 상태에 도달할 수 있습니다. 변경 불가 상태까지 걸리는 시간은 블록체인간 통신에서 중요한 함의를 가지는데, 외부 블록체인에 기록된 증명을 가져와서 이용하려면 변경 불가 확정 상태에 도달한 후여야 하기 때문입니다. 두 개의 EOSIO 기반 블록체인은 3초 이내에 왕복(round-trip) 통신이 가능해야 합니다. 비슷한 패턴의 통신이 이더리움에서는 9분, 비트코인에서는 3시간 이상 소요됩니다. 46 | 47 | BFT DPOS는 아직 구현되지 않았는데, 하드 포크하지 않아도 가능한 최적화 구현이라서 그렇습니다. EOSIO 1.0을 출시하기 전에 BFT DPOS를 구현할 예정입니다. 48 | 49 | ### BIOS Architecture 50 | Dawn 2.0에서 가장 많이 바뀐 부분이 BIOS 아키텍처입니다. Dawn 3.0에서는 블록체인 비즈니스 로직의 대부분을 하드 포크 없이 커뮤니티가 동적으로 업데이트할 수 있는 스마트 컨트랙트로 옮겨서 구현했습니다. 기본 EOSIO으로 생성한 블록체인은 단일 프로듀서로 동작하고 토큰, 투표, 위임 지분 증명 기능이 없습니다. 코어 블록체인 코드에 구현된 유일한 기능은 계정을 생성하고 컨트랙트를 배포하고 자원 제한 한도를 걸 수 있는 승인(permission) 시스템입니다. 블록체인을 위임 지분 증명 시스템으로 만들어주는 토큰, 투표, 지분 참여(stake), 자원 할당을 포함하는 모든 기능은 이제 웹어셈블리 기반의 시스템 컨트랙트로 구현됩니다. 51 | 52 | 이와 같은 새로운 아키텍처 아래 우리 팀은 블록체인의 정적인 비-웹어셈블리 부분을 구현하는 데 집중할 수 있었습니다. 이 부분은 안정성을 위해 가장 중요한 부분이고 업그레이드하기 가장 어려운 부분입니다. EOSIO Dawn 3.0과 EOSIO 1.0 출시 사이에 시스템 컨트랙트, 지분 참여, 투표 기능의 최종적인 세부 구현을 완성할 것입니다. 53 | 54 | ## 보안 기능 - Security Features 55 | 보안은 모든 컴퓨팅 시스템에서 중대한 주제이며, 우리는 EOSIO를 시장에 나온 가장 보안성 높은 블록체인이 되도록 설계해왔습니다. 보안은 해킹, 하드웨어 고장, 하드웨어 유실, 패스워드 유실의 리스크를 감안해야 하는 다차원 문제입니다. 하드웨어 지갑은 해킹을 방어하는 데 좋지만, 고장났을 경우 계정에 접근할 수 없게 됩니다. 하드웨어 지갑의 내용을 종이에 옮겨서 백업으로 삼아도 잃어버릴 수 있고 도난당할 수 있습니다. 56 | 57 | ### 보안 지연 트랜잭션 - Security Delayed Transactions 58 | Dawn 3.0의 가장 중요한 기능 중 하나는 액션마다 사용자가 지연 시간을 설정할 수 있는 기능입니다. 지연 시간이 설정되면, 트랜잭션은 그 내용이 적용되기 전 몇 시간이나 며칠 동안 블록체인에 브로드캐스트되어야 합니다. 지연 기간 동안 사용자는 상위 권한으로 계정을 리셋할 수 있는 조치를 강구할 수 있고, 트랜잭션을 취소할 수 있습니다. 이 기능은 조치를 취하기엔 너무 늦어버릴 때까지 해킹당했다는 사실을 모르는 다른 블록체인에 비하면 중요한 개선입니다. 59 | 60 | ### 패스워드 복구 - Lost Password Recovery 61 | 모든 계정은 "owner"와 "active"라는 적어도 두 가지 권한(permission)을 가집니다. owner 권한은 멀티시그를 구성하는 M개의 비밀키 중 N개의 비밀키가 되어야 하는데, N개의 키 중 owner key를 포함하지 않는 키는 없어야 합니다. owner 권한은 active 키를 잃어버렸거나 도난당했을 때 active 권한을 리셋할 수 있습니다. 62 | 63 | owner 키를 잃어버렸거나 멀티시그의 일부를 구성하는 파트너가 비협조적이라면, 해당 계정의 owner 권한이 30일 동안의 활동이 없었음을 확인한 후 해당 계정의 active 권한으로 owner 권한 리셋을 요청할 수 있습니다. owner 권한은 active 권한을 업데이트하는 방식으로 owner 권한 리셋 요청이 온지 7일 내에 대항할 수 있습니다. 64 | 65 | 이 모델을 이용하면 하나 이상의 하드웨어 지갑으로 관리하는 owner 권한은 해킹과 장비 고장이 발생해도 안전할 것입니다. 만약 장비가 하드웨어가 달린 애플 아이폰이고 지문/안면 인식으로 안전하게 비밀키를 보관한다면, 공격자는 멀티시그 파트너를 뚫고 물리적으로 휴대폰을 훔치고 지문이나 얼굴을 훔쳐야 합니다. 이상적으로는 멀티시그 파트너도 생체인식을 이용한 보안 하드웨어 장치를 사용하고 있을 것입니다. 66 | 67 | ### 거래 제안 시스템 - Transaction Proposal System 68 | 멀티시그 사용이 훨씬 쉬워졌습니다. 일반적인 트랜잭션이 요구하는 만료 제한 시간 동안 모든 서명을 모으지 않고, 각 사용자가 편한 시간에 독립적으로 자신의 권한을 추가하거나 제외할 수 있습니다. 거래 제안 시스템으로 누구나 트랜잭션을 제안할 수 있고, 트랜잭션과 연관된 당사자들이 단순히 승인하면 됩니다. 자신의 승인을 비롯한 정족수를 모으는 시간 동안, 자신의 승인을 철회할 수도 있습니다. 69 | 70 | 이런 시스템을 구현하려고 컨트랙트가 계정 권한의 집합이 특정 트랜잭션을 허용하기 충분한지를 평가할 수 있는 새로운 API를 추가했습니다. 이를 통해 하드 포크 없이 새로운 웹어셈블리를 배포해서 멀티시그 프로세스를 업그레이드할 수 있습니다. 71 | 72 | ## 컨트랙트 개발 단순화 - Simplified Contract Development 73 | EOSIO의 주요 목표 중 하나는 가능한한 컨트랙트 개발을 단순하고 괴롭지 않게 만드는 것입니다. C++로 메소드와 클래스를 구현할 줄 아는 개발자라면 boilerplate 약간으로 스마트 컨트랙트를 구현할 수 있어야 합니다. 74 | 75 | 단순한 몇 줄로 "hello world" 컨트랙트를 단순화할 수 있어서 기쁩니다. 컨트랙트 ABI 생성과 클래스에 구현한 메소드로 사용자 액션을 디스패치하는 과정을 툴체인으로 자동화했습니다. 지금까지 컨트랙트 개발은 이 정도로 쉽지 않았습니다. 76 | 77 | ``` 78 | #include 79 | #include 80 | using namespace eosio; 81 | 82 | struct hello : public contract { 83 | using contract::contract; 84 | 85 | void hi( name user ) { 86 | print( “Hello, “, user ); 87 | } 88 | }; 89 | 90 | EOSIO_ABI( hello, (hi) ) 91 | ``` 92 | 93 | ### 부동소수점 지원 - Floating Point Support 94 | 스마트 컨트랙트 개발을 단순화하는 데는 개발자들이 필요한 수학 알고리즘을 구현하기 편하게 해주는 작업이 있었습니다. 블록체인 개발의 가장 어려운 측면 중 하나는 부동소수점 연산과 제곱, 제곱근, 삼각 함수가 부족했다는 점입니다. 모든 계산을 에러나기 쉽고 메모리를 많이 사용하는 고정소수점 대신 부동소수점을 사용하면 Bancor 같은 알고리즘 구현이 무척 쉬워집니다. 95 | 96 | 하드웨어 부동소수점의 비결정론적인 특성을 보완하기 위해 웹어셈블리 컨트랙트에서 투명하게 사용하고 있는 소프트웨어로 구현한 부동소수점 라이브러리를 통합했습니다. 부동소수점을 소프트웨어로 구현해서 복잡한 계산의 경우 고정소수점을 사용하는 경우에 비해 너무 크지 않은 비용으로 결정론적으로 작동하는 혜택과 개발의 편의를 얻을 수 있습니다. 많은 경우, 고정소수점은 결정론적 부동소수점에 비해 오류가 발생하기 쉽거나 메모리 사용이 더 많습니다. 97 | 98 | ### C++ Standard Template Library Support 99 | EOSIO Dawn 3.0 출시를 위해 C++ 표준 템플릿 라이브러리의 대부분을 지원할 수 있도록 대단히 노력했습니다. 지원이 되면 개발자는 익숙한 툴, 라이브러리, 알고리즘을 사용할 수 있고, 그와 동시에 이런 알고리즘을 표준에 맞지 않게 구현한 코드가 일으킬 수 있는 잠재적인 버그를 제거할 수 있습니다. 100 | 101 | ### 예약 트랜잭션 - Scheduled Transactions 102 | 예약 트랜잭션(scheduled transaction)을 이용해서, 컨트랙트 실행에 충분한 대역폭을 지분 참여(stake)해두었다면, 개발자는 영원히 동작하는 컨트랙트를 작성할 수 있습니다. 다른 플랫폼은 적절한 시점에 컨트랙트를 구동시키기 위해 체인 바깥에 장치를 마련해야만 합니다. 예약 트랜잭션을 사용하면, 개발자가 컨트랙트를 계속 실행시키기 위해 자체 서버를 운영하지 않아도 되기 때문에 효율적이고 이용하기도 쉬워집니다. 103 | 104 | ### Automatic Scope Detection 105 | EOSIO Dawn 2.0의 모든 트랜잭션은 접근할 데이터 범위를 꼭 선언해야 했습니다. 개발자가 구현할 때 실수하기 쉬웠고 코드가 길어지는 편이었습니다. Dawn 3.0에서는 블록 프로듀서가 데이터 접근 범위를 결정하는 책임을 지고, 충돌이 있을 경우 해결합니다. 그래서 모든 트랜잭션이 더 작아졌으며 사용자, 개발자, 풀 노드가 감당했던 스케줄링 오버헤드를 블록 프로듀서가 책임지게 되었습니다. 106 | 107 | ### MultiIndex Database API 108 | EOSIO Dawn 3.0은 boost::multi_index_container를 본따서 만든 새로운 데이터베이스 API를 구현했습니다. 이 API를 이용해서 여러 개의 키로 정렬된 데이터베이스 테이블을 다루고, 원하는 값을 찾고, 검색시 하한/상한을 이용하고, 데이터베이스에서 앞으로 뒤로 iterate(반복)하는 작업이 수월해졌습니다. 새로운 API는 테이블을 스캔하는 성능을 극적으로 향상시켜주는 이터레이터 인터페이스를 사용합니다. 109 | 110 | 게다가 64비트 부동소수점 뿐만 아니라 64비트, 128비트, 256비트, 512비트 정수형도 인덱스로 사용할 수 있습니다. EOSIO 1.0 출시 전에 문자열 인덱스를 사용하는 기능을 구현할 것입니다. 테이블 하나에 인덱스한 필드를 무한히 가질 수 있기 때문에 유연성과 개발 편의의 측면에서 중대한 개선입니다. 111 | 112 | ## 성능과 초당 처리량 결과 - Performance & TPS results 113 | 실제 성능은 우리 팀이 면밀히 모니터해온 중요한 주제고, 이번에 내놓는 결과에 매우 기쁩니다. 앞으로 최적화를 구현함에 따른 성능의 하한과 상한을 이해하기 위해 몇 가지 다른 설정으로 소프트웨어의 성능을 벤치마크해왔습니다. 모든 테스트는 연산 복잡성의 측면에서 EOSIO를 이용한 토큰 이체가 비트코인 이체나 이더리움 ERC20 토큰 이체와 공평한 조건에서의 비교라고 가정합니다. 114 | 115 | ### 비교 기준 수치 - Worst Case - 1000 TPS 116 | 아무런 최적화 없는 비교 기준(baseline) 성능입니다. 싱글 쓰레드로 서명 검증을 하는 인터프리터로 동작하는 멀티 노드 네트워크를 사용할 때 1000 TPS를 유지할 수 있습니다. 117 | 118 | ### 평균 수치 - Average Case - 3000 TPS 119 | JIT 컴파일러를 활성화시키면, 싱글 쓰레드로 서명 검증을 하는 인터프리터로 동작하는 멀티 노드 네트워크로 3000 TPS를 유지할 수 있습니다. 120 | 121 | ### 최대 수치 - Best Case - 6000 TPS 122 | 병렬 서명 검증을 구현하면, 병렬 처리 수준과 서명의 수가 증가함에 따라 서명당 처리 소요 시간이 0에 가까워질 것이라고 가정할 수 있습니다. 서명 검증을 건너뛰는 방법으로 이런 시나리오를 시뮬레이션할 수 있습니다. 이 모델에서 JIT 컴파일러를 사용한 멀티 노드 네트워크로 6000 TPS까지 도달할 수 있습니다. 123 | 124 | ### 이론상 수치 - Theoretical Case - 8000 TPS 125 | 시뮬레이션 시나리오에서 P2P 네트워크 코드 동작을 빼고, 서명 검증을 끈 상태에서 JIT를 사용하는 CPU가 할 수 있는 작업에만 초점을 맞춰봅시다. 그러면 싱글 쓰레드로 8000 TPS까지 도달할 수 있습니다. 단일 체인에서 이 수치 이상의 성능을 얻기 위헤서는 웹어셈블리의 병렬 실행과 현재 구현보다 더 개선된 스케줄러를 구현해야 합니다. 동일한 시나리오에서 인터프리터 대신 JIT을 사용하면 2700 TPS에 도달할 수 있습니다. 이 결과를 보면 JIT를 활성화하는 상대적으로 단순한 변경만으로 토큰 이체 성능을 3배 높힐 수 있습니다. 모든 테스트 결과는 맥북 2.8GHz i7에서 실행한 결과입니다. 126 | 127 | ### 제한 없는 처리량 - Unlimited Transactions Per Second 128 | 보통의 "초당 트랜잭션 수" 정의로는 서로 비교가 안 되는 성질을 가진 둘을 비교하게 하는 상황을 자주 만듭니다. 블록체인간 통신을 사용하면 원하는 수의 블록체인으로 작업량을 분산시킬 수 있습니다. 서로 다른 블록체인 사이에 토큰을 확실하고 안전하게 이체할 수 있습니다. 같은 (또는 서로 다른) 블록 프로듀서들이 동시에 운영하는 1000개의 블록체인이 있다면 초당 수백만 건의 트랜잭션을 볼 수 있을 것입니다. 이 모습은 다른 블록체인에서 제시한 이론적인 확장 계획이 실제로 현실화된다는 점을 보여줍니다. 129 | 130 | EOSIO 소프트웨어로 런칭된 서로 다른 블록체인 퍼블릭 네트워크를 운영하는 블록 프로듀서들이 사용자 수요를 만족시킬 수 있을 만큼 많은 블록체인을 운영하기를 강력히 권합니다. 모든 블록체인이 지분 참여와 자원 할당을 하는데 동일한 토큰을 기초 단위로 사용할 수 있을 것입니다. 이렇게 해서 단일 토큰으로 최대한 가능한 네트워크 효과를 일으키고 높은 시장가치를 가진 토큰들이 만들어 온 신뢰와 안정성이라는 경제적인 인센티브를 누릴 수 있을 것입니다. 131 | 132 | 거래소, 환전소, 소셜 미디어 등의 서비스는 동시에 작동하는 여러 블록체인을 이용해서 연산을 쉽게 분산시킬 수 있습니다. 133 | 134 | ## 앞으로 나아갈 길 - The Road Ahead 135 | EOSIO Dawn 3.0 출시를 진행하면서 코어 플랫폼 기능의 안정성을 높히는 데 중점을 두었습니다. 다음 달에는 지분 참여, 투표, 거버넌스 기능을 모두 구현할 마지막 시스템 컨트랙트를 준비할 것입니다. 또한 토큰 표준을 완성할 것입니다. 136 | 137 | 이 시스템 컨트랙트가 마음에 들 정도로 충분히 다듬어지면 새로운 퍼블릭 테스트넷을 오픈할 예정입니다. 그때까지 사용할 수 있도록, 자체 테스트 네트워크를 구동시키고 어플리케이션를 구현하는 과정을 굉장히 단순화했습니다. 개발자들의 혼동을 최소화하기 위해 새로운 테스트넷을 준비하는 동안 현재의 퍼블릭 테스트넷을 몇 주 동안 꺼둡니다. 138 | 139 | ## 요약 - Summary 140 | EOSIO Dawn 3.0은 API를 안정화하고 "기능 구현 완료" 상태로 준비한 개발자 릴리즈입니다. 현재의 플랫폼이 어플리케이션를 실제로 개발하려는 개발자들이 어플리케이션 개발을 시작해도 될 만큼 충분히 안정적이라고 믿습니다. **우리가 1년 전에 상상해왔던 것 이상으로 EOSIO는 훨씬 더 강력해지고 개발하기 쉬워졌습니다.** 141 | 142 | 우리 팀은 점점 커지고 있고, 개발은 기록적인 속도로 진행되고 있습니다. 우리 저장소는 지난달 깃헙에 있는 모든 C++ 저장소 중 가장 활발한 저장소 가운데 하나였습니다. 모든 작업이 6월로 예정된 EOSIO 1.0의 고품질 공개 출시 일정에 맞게 순로조이 진행되고 있습니다! 143 | 144 | ## 번역 정보 145 | 146 | * https://medium.com/eosio/eosio-dawn-3-0-now-available-49a3b99242d7 (2018.04.06 KST) 147 | -------------------------------------------------------------------------------- /ko/translations/Smart-Contract.md: -------------------------------------------------------------------------------- 1 | # EOSIO 스마트 컨트랙트 2 | 3 | - [EOSIO 스마트 컨트랙트 들어가기](#EOSIO-스마트-컨트랙트-들어가기) 4 | - [필요한 사전 지식](#필요한-사전-지식) 5 | - [EOSIO 스마트 컨트랙트 기본](#EOSIO-스마트-컨트랙트-기본) 6 | - [스마트 컨트랙트 파일](#스마트-컨트랙트-파일) 7 | - [hpp](#hpp) 8 | - [cpp](#cpp) 9 | - [wast](#wast) 10 | - [abi](#abi) 11 | - [스마트 컨트랙트 디버깅하기](#스마트-컨트랙트-디버깅하기) 12 | - [방법](#방법) 13 | - [Print](#Print) 14 | - [예제](#예제) 15 | - [번역 정보](#번역-정보) 16 | 17 | ## EOSIO 스마트 컨트랙트 들어가기 18 | 19 | ### 필요한 사전 지식 20 | 21 | **C / C++ 경험** 22 | 23 | EOSIO 기반 블록체인은 [WebAssembly](http://webassembly.org/) (WASM)를 이용한 24 | 사용자 생성 응용 프로그램과 코드를 실행합니다. WASM은 Google, Microsoft, Apple 25 | 및 다른 기업들로부터 광범위한 지원을 받는 새로운 웹 표준입니다. 현재 WASM으로 26 | 컴파일되는 응용 프로그램을 빌드하는 데있어 가장 성숙한 툴체인은 27 | [clang/llvm](https://clang.llvm.org/)의 C/C++ 컴파일러입니다. 28 | 29 | 다른 개발 주체들이 만들고 있는 툴체인은 Rust, Python, Solidity가 있습니다. 30 | 이 언어들이 더 단순해 보일 수도 있지만, 각 언어마다의 성능은 작성하려는 31 | 응용 프로그램의 규모에 영향을 줄 수 있습니다. 고성능 보안 스마트 32 | 컨트랙트를 작성하고 C++를 가까운 미래에 사용할 계획인 경우, C++가 제일 좋은 33 | 언어가 될 것으로 기대합니다. 34 | 35 | **Linux / Mac OS 경험** 36 | 37 | EOSIO는 다음 환경을 지원합니다: 38 | - Amazon 2017.09 및 그 이상 버전 39 | - Centos 7 40 | - Fedora 25 및 그 이상 버전 (Fedora 27 추천) 41 | - Mint 18 42 | - Ubuntu 16.04 (Ubuntu 16.10 추천) 43 | - MacOS Darwin 10.12 및 그 이상 버전 (MacOS 10.13.x 추천) 44 | 45 | **커맨드 라인 지식** 46 | 47 | EOSIO와 함께 다양한 툴이 제공됩니다. 이 툴을 사용하려면 커맨드 라인으로 48 | 명령어를 이용할 수 있는 기본적인 지식이 필요합니다. 49 | 50 | ### EOSIO 스마트 컨트랙트 기본 51 | 52 | **통신 모델** 53 | 54 | EOSIO 스마트 컨트랙트는 액션과 공유 메모리 DB 접근을 통해 서로 통신합니다. 55 | 이를테면 하나의 컨트랙트는 해당 컨트랙트가 비동기적 방식 트랜잭션의 read 56 | scope에 포함되어 있다면 다른 컨트랙트의 DB 상태를 읽을 수 있습니다. 57 | 비동기 통신은 자원 제한 알고리즘이 해결해야 하는 스팸을 초래할 수 있습니다. 58 | 컨트랙트 안에서 정의된 두 가지 통신 모드를 살펴보겠습니다. 59 | 60 | - **Inline**. 인라인 액션은 현재 트랜잭션 내에서 실행되거나 unwind됨을 보장합니다. 성공과 실패에 무관하게 알림(notification)은 전달되지 않습니다. 인라인은 해당 인라인을 실행한 부모 트랜잭션이 가진 scope와 자격(authority)을 그대로 이어받아 동작합니다. 61 | 62 | - **Deferred**. 지연 액션은 블록 프로듀서의 재량에 따라 실행 스케줄이 정해집니다. 통신 결과를 전달하거나 그냥 만료될 수도 있습니다. 지연 액션은 다른 scope까지 접근할 수 있고 지연 액션을 보낸 컨트랙트의 자격(authority)을 그대로 사용할 수 있습니다. 63 | 64 | **액션 vs 트랜잭션** 65 | 66 | 액션은 단일 실행 단위입니다. 이와 비교하면, 트랜잭션은 하나 이상 액션의 67 | 모음입니다. 컨트랙트와 계정은 액션의 형태로 통신합니다. 액션은 하나씩 보낼 수 68 | 있고, 한꺼번에 실행해야 할 경우 합쳐서 보낼 수도 있습니다. 69 | 70 | *액션 하나로 구성된 트랜잭션*. 71 | 72 | ```base 73 | { 74 | "expiration": "2018-04-01T15:20:44", 75 | "region": 0, 76 | "ref_block_num": 42580, 77 | "ref_block_prefix": 3987474256, 78 | "net_usage_words": 21, 79 | "kcpu_usage": 1000, 80 | "delay_sec": 0, 81 | "context_free_actions": [], 82 | "actions": [{ 83 | "account": "eosio.token", 84 | "name": "issue", 85 | "authorization": [{ 86 | "actor": "eosio", 87 | "permission": "active" 88 | } 89 | ], 90 | "data": "00000000007015d640420f000000000004454f5300000000046d656d6f" 91 | } 92 | ], 93 | "signatures": [ 94 | "" 95 | ], 96 | "context_free_data": [] 97 | } 98 | ``` 99 | 100 | *여러 개의 액션으로 구성된 트랜잭션*, 이 액션들은 모두 성공하거나 모두 실패해야 합니다. 101 | ```base 102 | { 103 | "expiration": "...", 104 | "region": 0, 105 | "ref_block_num": ..., 106 | "ref_block_prefix": ..., 107 | "net_usage_words": .., 108 | "kcpu_usage": .., 109 | "delay_sec": 0, 110 | "context_free_actions": [], 111 | "actions": [{ 112 | "account": "...", 113 | "name": "...", 114 | "authorization": [{ 115 | "actor": "...", 116 | "permission": "..." 117 | } 118 | ], 119 | "data": "..." 120 | }, { 121 | "account": "...", 122 | "name": "...", 123 | "authorization": [{ 124 | "actor": "...", 125 | "permission": "..." 126 | } 127 | ], 128 | "data": "..." 129 | } 130 | ], 131 | "signatures": [ 132 | "" 133 | ], 134 | "context_free_data": [] 135 | } 136 | ``` 137 | 138 | **액션 이름 제한** 139 | 140 | 액션 타입은 실제로 **base32로 인코딩한 64-bit 정수형**입니다. 즉, 141 | 앞 12개의 문자는 a-z, 1-5, '.'로 제한됩니다. 만약 13번째 문자가 있다면 142 | 앞 16개의 문자는 '.'과 a-p로 제한됩니다. 143 | 144 | **트랜잭션 승인** 145 | 146 | 트랜잭션 해시를 받았다고 하더라도 트랜잭션이 승인되었다는 뜻은 아닙니다. 147 | 단지 노드가 트랜잭션을 에러 없이 수용했다는 뜻이고, 다른 프로듀서가 해당 148 | 트랜잭션을 수용할 확률 역시 높다는 뜻입니다. 149 | 150 | 승인이 되어야 트랜잭션이 포함된 블록 넘버를 통해 트랜잭션 이력 속에서 151 | 트랜잭션을 확인할 수 있습니다. 152 | 153 | ## 스마트 컨트랙트 파일 154 | 155 | 단순한 개발을 위해서 **[eosiocpp](https://github.com/EOSIO/eos/wiki/Programs-&-Tools#eosiocpp)** 라는 툴을 만들었습니다. 이 툴을 이용해서 새로운 스마트 156 | 컨트랙트를 개발하기 위한 기본 틀을 만들 수 있습니다. `eosiocpp`는 157 | 개발 시작을 위한 기본 틀로 3개의 스마트 컨트랙트 파일을 만들어줍니다. 158 | 159 | ```base 160 | $ eosiocpp -n ${contract} 161 | ``` 162 | 163 | 위와 같이 실행하면 `./${project}` 폴더에 기본 틀이 되는 아래 3개의 파일을 만듭니다. 164 | ```base 165 | ${contract}.abi ${contract}.hpp ${contract}.cpp 166 | ``` 167 | 168 | ### hpp 169 | 170 | `${contract}.hpp`는 `.cpp` 파일에서 참조하는 변수, 상수, 함수를 담는 헤더 파일입니다. 171 | 172 | ### cpp 173 | 174 | `${contract}.cpp` 파일은 컨트랙트의 함수를 담는 소스 코드입니다. 175 | 176 | `eosiocpp`로 `.cpp` 파일을 생성하면, 생성된 `.cpp` 파일은 아래와 같은 내용일 것입니다. 177 | 178 | ```base 179 | #include <${contract}.hpp> 180 | 181 | /** 182 | * The init() and apply() methods must have C calling convention so that the blockchain can lookup and 183 | * call these methods. 184 | */ 185 | extern "C" { 186 | 187 | /** 188 | * This method is called once when the contract is published or updated. 189 | */ 190 | void init() { 191 | eosio::print( "Init World!\n" ); // Replace with actual code 192 | } 193 | 194 | /// The apply method implements the dispatch of actions to this contract 195 | void apply( uint64_t code, uint64_t action ) { 196 | eosio::print( "Hello World: ", eosio::name(code), "->", eosio::name(action), "\n" ); 197 | } 198 | 199 | } // extern "C" 200 | ``` 201 | 202 | 이 예제에서는 `init`과 `apply` 함수만 보일 것입니다. 이 두 함수는 전달된 액션에 대한 로그를 남기고 다른 체크는 하지 않습니다. 블록 프로듀서가 허용하는 한 누구나 어떤 액션도 보낼 수 있습니다. 요구되는 서명도 없어서 컨트랙트는 사용한 대역폭만큼 과금됩니다. 203 | 204 | **init** 205 | 206 | `init` 함수는 배포 처음 한 번만 실행될 것입니다. 예를 들어 환전 컨트랙트를 위한 토큰 공급량과 같은 컨트랙트 변수를 초기화하는 데 사용합니다. 207 | 208 | **apply** 209 | 210 | `apply`는 액션 핸들러입니다. 모든 액션을 지켜보고 있다가 함수 내에 정의된 로직에 따라서 반응합니다. `apply` 함수는 `code`와 `action`이라는 두 개의 파라미터 입력이 필요합니다. 211 | 212 | **code filter** 213 | 214 | 특정 컨트랙트에 반응하기 위한 `apply` 함수의 구조는 아래와 같습니다. code filter를 생략하면 일반적인 컨트랙트에 반응하도록 구성할 수도 있습니다. 215 | 216 | ```base 217 | if (code == N(${contract_name}) { 218 | // your handler to respond to particular action 219 | } 220 | ``` 221 | 222 | 코드 블럭 안에서 각각의 액션에 대한 응답을 정의할 수도 있습니다. 223 | 224 | **action filter** 225 | 226 | 특정 액션에 반응하기 위한 `apply` 함수의 구조는 아래와 같습니다. 액션 필터는 보통 코드 필터와 결합하여 사용합니다. 227 | 228 | ```base 229 | if (action == N(${action_name}) { 230 | //your handler to respond to a particular action 231 | } 232 | ``` 233 | 234 | ### wast 235 | 236 | EOSIO 블록체인에 배포되는 모든 프로그램은 WASM 포맷으로 컴파일해야 합니다. 237 | 블록체인이 받아들이는 유일한 포맷입니다. 238 | 239 | CPP 파일이 준비된 상태가 되면, `eosiocpp` 툴로 WASM의 텍스트 버전(.wast)으로 240 | 컴파일할 수 있습니다. 241 | 242 | ```base 243 | $ eosiocpp -o ${contract}.wast ${contract}.cpp 244 | ``` 245 | ### abi 246 | 247 | Application Binary Interface(ABI)는 사용자 액션을 JSON과 바이너리 형태 사이에서변환하는 정의입니다. ABI는 DB 상태를 JSON으로 변환하는 방식을 정의합니다. 248 | ABI로 컨트랙트를 정의해놓으면 개발자와 사용자는 JSON으로 컨트랙트와 부드럽게 통신할 수 있을 것입니다. 249 | 250 | ABI 파일은 `eosiocpp` 툴로 `.hpp` 파일을 이용해서 생성합니다. 251 | 252 | ```base 253 | $ eosiocpp -g ${contract}.abi ${contract}.hpp 254 | ``` 255 | 256 | 아래는 껍데기 컨트랙트 ABI의 예제입니다. 257 | ```base 258 | { 259 | "types": [{ 260 | "new_type_name": "account_name", 261 | "type": "name" 262 | } 263 | ], 264 | "structs": [{ 265 | "name": "transfer", 266 | "base": "", 267 | "fields": { 268 | "from": "account_name", 269 | "to": "account_name", 270 | "quantity": "uint64" 271 | } 272 | },{ 273 | "name": "account", 274 | "base": "", 275 | "fields": { 276 | "account": "name", 277 | "balance": "uint64" 278 | } 279 | } 280 | ], 281 | "actions": [{ 282 | "action": "transfer", 283 | "type": "transfer" 284 | } 285 | ], 286 | "tables": [{ 287 | "table": "account", 288 | "type": "account", 289 | "index_type": "i64", 290 | "key_names" : ["account"], 291 | "key_types" : ["name"] 292 | } 293 | ] 294 | } 295 | ``` 296 | 297 | 이 ABI를 보면 `transfer` 타입의 `transfer` 액션의 정의를 볼 수 있습니다. 298 | 이 명세를 통해서 EOSIO는 `${account}->transfer` 액션이 보이면 전달된 데이터는 299 | `transfer` 타입이라는 사실을 알 수 있습니다. `transfer` 타입은 `structs` 300 | 배열 속 `name`이 `transfer`로 설정된 객체로 정의되어 있습니다. 301 | 302 | ```base 303 | ... 304 | "structs": [{ 305 | "name": "transfer", 306 | "base": "", 307 | "fields": { 308 | "from": "account_name", 309 | "to": "account_name", 310 | "quantity": "uint64" 311 | } 312 | },{ 313 | ... 314 | ``` 315 | 316 | ABI에는 `from`, `to`, `quantity`라는 필드가 있습니다. 이 필드는 각각 `account_name`, `uint64` 타입으로 정의되어 있습니다. `account_name`는 `uint64`로 base32 문자열을 표현하는 built-in 타입입니다. 사용할 수 있는 built-in 타입 정보는 [다음 코드](https://github.com/EOSIO/eos/blob/master/libraries/chain/contracts/abi_serializer.cpp)를 참고하세요. 317 | 318 | ```base 319 | { 320 | "types": [{ 321 | "new_type_name": "account_name", 322 | "type": "name" 323 | } 324 | ], 325 | ... 326 | ``` 327 | 328 | 위 `types` 배열에서는 앞서 정의한 타입의 alias 목록을 정의합니다. 즉, `account_name`의 alias로 `name`을 정의했습니다. 329 | 330 | ## 스마트 컨트랙트 디버깅하기 331 | 332 | 스마트 컨트랙트를 디버그하기 위해서 로컬 `nodeos` 노드를 셋업해야 합니다. 개별적으로 동작하는 프라이빗 테스트넷로 로컬 `nodeos` 노드를 셋업하거나 퍼블릭 테스트넷(혹은 공식 테스트넷)을 연결한 노드를 셋업해서 사용할 수도 있습니다. 333 | 334 | 처음 스마트 컨트랙트를 작성할 때 프라이빗 테스트에서 스마트 컨트랙트를 테스트하고 디버그하기를 권합니다. 왜나하면 블록체인 전체를 완전히 제어할 수 있기 때문입니다. 그렇게 하면 필요한 EOS를 무제한으로 확보할 수 있고 필요할 때마다 블록체인 상태를 리셋할 수 있습니다. 프러덕션에 올릴 준비가 되면 로컬 `nodeos`를 퍼블릭 테스트넷(또는 공식 테스트넷)에 연결해서 테스트를 진행하면 로컬 `nodeos`에서 테스트넷의 로그를 확인할 수 있습니다. 335 | 336 | 컨셉은 같습니다. 아래 가이드에서는 프라이빗 테스트넷에서 디버깅하는 방법을 다루겠습니다. 337 | 338 | 로컬 `nodeos`를 아직 셋업하지 않았다면 [로컬 셋업 가이드](https://github.com/eoseoul/docs/blob/master/ko/translations/Local-Environment.md)를 따라하세요. 339 | [퍼블릭 테스트넷(또는 공식 테스트넷) 연결 가이드](https://github.com/eosio/eos/wiki/Testnet%3A%20Public)를 따라서 `config.ini` 파일을 수정하지 않았다면, 기본 설정된 로컬 `nodeos`는 프라이빗 테스트넷 모드로 동작할 것입니다. 340 | 341 | ### 방법 342 | 스마트 컨트랙트를 디버그하는 가장 주된 방법은 **동굴 디버깅(caveman debugging)**인데, 변수 값을 확인하고 컨트랙트의 흐름을 체크하기 위해 print 기능을 이용하는 방법입니다. 스마트 컨트랙트에서 print는 Print API ([C](https://github.com/EOSIO/eos/blob/master/contracts/eosiolib/print.h)와 [C++](https://github.com/EOSIO/eos/blob/master/contracts/eosiolib/print.hpp))를 사용하면 됩니다. C++ API는 C API wrapper입니다. 그래서 대부분 C++ API만 사용하겠습니다. 343 | 344 | ### Print 345 | Print C API는 다음 데이터 타입을 지원합니다. 346 | - prints - null 문자로 끝나는 char array (string) 347 | - prints_l - 주어진 크기의 char array (string) 348 | - printi - 64비트 unsigned integer 349 | - printi128 - 128비트 unsigned integer 350 | - printd - 64비트 unsigned integer로 인코딩된 double 351 | - printn - 64비트 unsigned integer로 인코딩된 base32 문자열 352 | - printhex - 바이너리 데이터로 주어진 HEX 353 | 354 | Print C++ API는 위의 C API 일부를 print() 함수로 오버라이딩했고, 그래서 사용자는 사용하려는 필요에 맞는 print 함수를 결정할 필요가 없습니다. Print C++ API는 다음 데이터 타입을 지원합니다. 355 | - null 문자로 끝나는 char array (string) 356 | - integer (128-bit unsigned, 64-bit unsigned, 32-bit unsigned, signed, unsigned) 357 | - 64비트 unsigned integer로 인코딩된 base32 문자열 358 | - print() 메소드가 있는 struct 359 | 360 | ### 예제 361 | 이제 디버깅용 예제로 사용할 새로운 컨트랙트를 작성해봅시다. 362 | 363 | - debug.hpp 364 | ```cpp 365 | #include 366 | #include 367 | 368 | namespace debug { 369 | struct foo { 370 | account_name from; 371 | account_name to; 372 | uint64_t amount; 373 | void print() const { 374 | eosio::print("Foo from ", eosio::name(from), " to ",eosio::name(to), " with amount ", amount, "\n"); 375 | } 376 | }; 377 | } 378 | ``` 379 | - debug.cpp 380 | ```cpp 381 | #include 382 | 383 | extern "C" { 384 | 385 | void init() { 386 | } 387 | 388 | void apply( uint64_t code, uint64_t action ) { 389 | if (code == N(debug)) { 390 | eosio::print("Code is debug\n"); 391 | if (action == N(foo)) { 392 | eosio::print("Action is foo\n"); 393 | debug::foo f = eosio::current_message(); 394 | if (f.amount >= 100) { 395 | eosio::print("Amount is larger or equal than 100\n"); 396 | } else { 397 | eosio::print("Amount is smaller than 100\n"); 398 | eosio::print("Increase amount by 10\n"); 399 | f.amount += 10; 400 | eosio::print(f); 401 | } 402 | } 403 | } 404 | } 405 | } // extern "C" 406 | ``` 407 | - debug.hpp 408 | ```cpp 409 | { 410 | "structs": [{ 411 | "name": "foo", 412 | "base": "", 413 | "fields": { 414 | "from": "account_name", 415 | "to": "account_name", 416 | "amount": "uint64" 417 | } 418 | } 419 | ], 420 | "actions": [{ 421 | "action_name": "foo", 422 | "type": "foo" 423 | } 424 | ] 425 | } 426 | 427 | ``` 428 | 429 | 이제 배포하고 메시지를 보내봅시다. `debug` 계정을 만들었고 해당 계정의 키를 지갑에 import했다고 가정하겠습니다. 430 | ```bash 431 | $ eosiocpp -o debug.wast debug.cpp 432 | $ cleos set contract debug debug.wast debug.abi 433 | $ cleos push message debug foo '{"from":"inita", "to":"initb", "amount":10}' --scope debug 434 | ``` 435 | 436 | 로컬 `nodeos` 로그를 확인하면, 위 명령어를 실행한 후 아래와 같은 로그를 확인할 수 있습니다. 437 | 438 | ``` 439 | Code is debug 440 | Action is foo 441 | Amount is smaller than 100 442 | Increase amount by 10 443 | Foo from inita to initb with amount 20 444 | ``` 445 | 이렇게 해서 메시지가 원하는 흐름으로 제어되었고 금액도 제대로 업데이트되었다는 점을 확인할 수 있습니다. 위 메시지는 적어도 2번 이상 보게 되고, 이는 각 트랜잭션이 검증(verification), 블록 생성, 블록 적용에 이르는 단계마다 트랜잭션이 실행되기 때문이므로 정상입니다. 446 | 447 | ## 번역 정보 448 | 449 | * 원문 : https://github.com/EOSIO/eos/wiki/Smart%20Contract 450 | * 번역 기준 리비전 : 669211e579aa1fef575a0cb1ea0e6d14ced3371f 451 | -------------------------------------------------------------------------------- /ko/translations/Tutorial-Tic-Tac-Toe.md: -------------------------------------------------------------------------------- 1 | # 틱-택-토 2 | 3 | ### 목적 4 | 5 | 아래의 튜토리얼은 사용자가 간단한 플레이어 대 플레이어 게임 컨트랙트를 구축하는 샘플을 만드는 가이드입니다. 틱 택 토 게임을 이용해 이 과정을 보여드리겠습니다. 이 튜토리얼의 최종 결과는 [다음](https://github.com/EOSIO/eos/tree/master/contracts/tic_tac_toe)에서 보실 수 있습니다. 6 | 7 | 8 | ### 가정 9 | 이 게임을 위해 3x3 틱 택 토 판을 사용하겠습니다. 플레이어는 두 역할로 나뉩니다: **호스트**, **도전자**. 호스트는 항상 먼저 행동합니다. 각 플레이어 쌍(호스트-도전자)은 최대 동시에 두 게임까지**만** 진행할 수 있습니다. 한 쪽 게임에서는 첫 번째 플레이어가 호스트가 되며, 다른 쪽 게임에서는 두 번째 플레이어가 호스트가 됩니다. 10 | 11 | 12 | #### 판 13 | 보통 틱 택 토 게임에 사용되는 `o`, `x` 표시 대신, 호스트의 행동을 `1`로 표시하고, 도전자의 행동을 `2`로 표시하며, 빈 칸은 `0`으로 표시하겠습니다. 아울러, 판의 상황을 저장하기 위해 1차원 배열을 사용할 것입니다. 즉: 14 | 15 | | | (0,0) | (1,0) | (2,0) | 16 | | :-------: | :---: | :---: | :---: | 17 | | **(0,0)** | - | o | x | 18 | | **(0,1)** | - | x | - | 19 | | **(0,2)** | x | o | o | 20 | 21 | x가 호스트일 때, 위의 판은 다음 배열이 됩니다: `[0, 2, 1, 0, 1, 0, 1, 2, 2]` 22 | 23 | #### 액션 24 | 플레이어는 이 컨트랙트에서 상호작용하기 위해 다음과 같은 액션을 쓸 수 있습니다: 25 | - create: 새 게임을 시작합니다 26 | - restart: 진행중인 게임을 재시작합니다, 호스트나 도전자가 모두 이 액션을 실행할 수 있습니다 27 | - close: 현재 게임을 종료하며, 게임을 저장하기 위해 사용한 저장 공간을 반납합니다. 호스트만이 이 액션을 실행할 수 있습니다 28 | - move: 행동합니다 29 | 30 | 31 | #### 컨트랙트 계정 32 | 가이드에서 이후의 진행을 위해 컨트랙트를 `tic.tac.toe` 계정에 밀어넣을 것입니다. `tic.tac.toe` 계정명을 이미 누군가 사용중이라면, 다른 계정명을 만들고 코드 내의 `tic.tac.toe` 부분을 사용하고자 하는 계정명으로 바꾸시면 되겠습니다. 계정을 아직 만들지 않으셨다면, 일단 먼저 만드세요. 33 | 34 | ```bash 35 | $ cleos create account ${creator_name} ${contract_account_name} ${contract_pub_owner_key} ${contract_pub_active_key} --permission ${creator_name}@active 36 | # e.g. $ cleos create account inita tic.tac.toe EOS4toFS3YXEQCkuuw1aqDLrtHim86Gz9u3hBdcBw5KNPZcursVHq EOS7d9A3uLe6As66jzN8j44TXJUqJSK3bFjjEEqR4oTvNAB3iM9SA --permission inita@active 37 | ``` 38 | 지갑이 잠금해제돼 있는지 확인하시고, 생성자의 개인 활성화 키가 지갑에 임포트됐는지도 확인하세요. 안그러면 위의 명령어는 실행되지 못합니다. 39 | 40 | ### 시작! 41 | 세 파일을 만들도록 하겠습니다: 42 | - tic_tac_toe.hpp => 컨트랙트에서 사용하는 구조체들이 정의된 헤더 파일 43 | - tic_tac_toe.cpp => 컨트랙트의 주요 로직 44 | - tic_tac_toe.abi => 플레이어가 컨트랙트와 상호작용하기 위한 인터페이스 45 | 주의: 이 예제에서는 컨트랙트 계정명으로 N(tic.tac.toe)를 사용했습니다. 만약 컨트랙트 계정에 다른 이름을 사용하시려면, `tic.tac.toe` 부분을 사용하실 계정 명으로 바꿔주세요. 46 | 47 | 48 | ### 구조체 정의 49 | 헤더 파일부터 시작합시다. 일단 컨트랙트의 구조체를 정의합니다. **tic_tac_toe.hpp** 파일을 열어서 아래의 boilerplate 처럼 시작하세요. 50 | 51 | ```cpp 52 | // Import necessary library 53 | #include // Generic eosio library, i.e. print, type, math, etc 54 | 55 | using namespace eosio; 56 | namespace tic_tac_toe { 57 | static const account_name games_account = N(games); 58 | static const account_name code_account = N(tic.tac.toe); 59 | // Your code here 60 | } 61 | ``` 62 | 63 | #### 게임 테이블 64 | 이 컨트랙트를 위해 게임 리스트를 저장하는 테이블이 필요합니다. 이렇게 해봅시다: 65 | ```cpp 66 | ... 67 | namespace tic_tac_toe { 68 | ... 69 | typedef eosio::multi_index< games_account, game> games; 70 | } 71 | 72 | ``` 73 | - 템플릿 파라미터의 첫 번째는 테이블의 이름입니다 74 | - 템플릿 파라미터의 두 번째는 테이블이 저장할 구조체(다음 섹션에서 정의될)입니다 75 | 76 | 77 | #### 게임 구조체 78 | 게임에 쓰일 구조체를 정의합시다. 이 구조체 정의가 코드 상에서 테이블 정의보다 반드시 앞에 있어야 합니다. 79 | ```cpp 80 | ... 81 | namespace tic_tac_toe { 82 | static const uint32_t board_len = 9; 83 | struct game { 84 | game() {} 85 | game(account_name challenger, account_name host):challenger(challenger), host(host), turn(host) { 86 | // Initialize board 87 | initialize_board(); 88 | } 89 | account_name challenger; 90 | account_name host; 91 | account_name turn; // = account name of host/ challenger 92 | account_name winner = N(none); // = none/ draw/ account name of host/ challenger 93 | uint8_t board[9]; // 94 | 95 | // Initialize board with empty cell 96 | void initialize_board() { 97 | for (uint8_t i = 0; i < board_len ; i++) { 98 | board[i] = 0; 99 | } 100 | } 101 | 102 | // Reset game 103 | void reset_game() { 104 | initialize_board(); 105 | turn = host; 106 | winner = N(none); 107 | } 108 | 109 | auto primary_key() const { return challenger; } 110 | 111 | EOSLIB_SERIALIZE( game, (challenger)(host)(turn)(winner)(board) ) 112 | }; 113 | } 114 | ``` 115 | primary_key 메소드는 위의 게임을 위한 테이블 정의에서 필요한 것입니다. 테이블에서 어떤 필드가 검색에 사용되는 키인지 알 수 있게 합니다. 116 | 117 | 118 | #### 액션 구조체 119 | ##### Create 120 | 게임을 시작하기 위해서는 호스트 계정명과 도전자 계정명이 필요합니다. EOSLIB_SERIALIZE 매크로에는 액션을 컨트랙트와 nodeos 시스템 간에 전달할 수 있도록 직렬화/역직렬화 메소드가 포함돼 있습니다. 121 | 122 | ```cpp 123 | ... 124 | namespace tic_tac_toe { 125 | ... 126 | struct create { 127 | account_name challenger; 128 | account_name host; 129 | 130 | EOSLIB_SERIALIZE( create, (challenger)(host) ) 131 | }; 132 | ... 133 | } 134 | ``` 135 | ##### Restart 136 | 게임을 재시작하기 위해서는 게임을 식별할 수 있도록 호스트 계정명과 도전자 계정명이 필요합니다. 아울러, 누가 게임을 재시작하고자 하는지 지정해야 합니다. 그래야 포함된 서명의 유효성을 검증할 수 있습니다. 137 | ```cpp 138 | ... 139 | namespace tic_tac_toe { 140 | ... 141 | struct restart { 142 | account_name challenger; 143 | account_name host; 144 | account_name by; 145 | 146 | EOSLIB_SERIALIZE( restart, (challenger)(host)(by) ) 147 | }; 148 | ... 149 | } 150 | ``` 151 | ##### Close 152 | 게임을 종료하기 위해서는 게임을 식별할 수 있도록 호스트 계정명과 도전자 계정명이 필요합니다. 153 | ```cpp 154 | ... 155 | namespace tic_tac_toe { 156 | ... 157 | struct close { 158 | account_name challenger; 159 | account_name host; 160 | 161 | EOSLIB_SERIALIZE( close, (challenger)(host) ) 162 | }; 163 | ... 164 | } 165 | ``` 166 | ##### Move 167 | 행동을 위해서는 게임을 식별할 수 있도록 호스트 계정명과 도전자 계정명이 필요합니다. 아울러, 누가 행동을 했고 어떤 행동을 했는지 지정해 주어야 합니다. 168 | ```cpp 169 | ... 170 | namespace tic_tac_toe { 171 | ... 172 | struct movement { 173 | uint32_t row; 174 | uint32_t column; 175 | 176 | EOSLIB_SERIALIZE( movement, (row)(column) ) 177 | }; 178 | 179 | struct move { 180 | account_name challenger; 181 | account_name host; 182 | account_name by; // the account who wants to make the move 183 | movement mvt; 184 | 185 | EOSLIB_SERIALIZE( move, (challenger)(host)(by)(mvt) ) 186 | }; 187 | ... 188 | } 189 | ``` 190 | 완성된 tic_tac_toe.hpp 파일은 [여기](https://github.com/EOSIO/eos/blob/master/contracts/tic_tac_toe/tic_tac_toe.hpp) 서 확인하실 수 있습니다. 191 | 192 | ### Main 193 | tic_tac_toe.cpp 파일을 열고 아래의 boilerplate 처럼 시작하세요. 194 | ```cpp 195 | #include "tic_tac_toe.hpp" 196 | using namespace eosio; 197 | /** 198 | * The apply() method must have C calling convention so that the blockchain can lookup and 199 | * call these methods. 200 | */ 201 | extern "C" { 202 | 203 | using namespace tic_tac_toe; 204 | /// The apply method implements the dispatch of events to this contract 205 | void apply( uint64_t receiver, uint64_t code, uint64_t action ) { 206 | // Put your action handler here 207 | } 208 | 209 | } // extern "C" 210 | ``` 211 | 212 | #### 액션 핸들러 213 | tic_tac_toe 컨트랙트가 오직 `tic.tac.toe` 계정으로 전달되는 액션에만 반응하고, 액션의 타입에 따라 다르게 반응하기를 원합니다. 'on' 메소드를 오버로딩하여 다른 액션 타입들을 가질 impl 구조체를 추가해 보겠습니다(이 예제에서 이 과정은 오버스펙으로 보입니다만, 화폐 등의 다른 확장 가능한 컨트랙트에 이 패턴이 적용돼 있는 경우를 종종 보시게 될 겁니다). 214 | ```cpp 215 | using namespace eosio; 216 | namespace tic_tac_toe { 217 | struct impl { 218 | ... 219 | /// The apply method implements the dispatch of events to this contract 220 | void apply( uint64_t receiver, uint64_t code, uint64_t action ) { 221 | 222 | if (code == code_account) { 223 | if (action == N(create)) { 224 | impl::on(eosio::unpack_action_data()); 225 | } else if (action == N(restart)) { 226 | impl::on(eosio::unpack_action_data()); 227 | } else if (action == N(close)) { 228 | impl::on(eosio::unpack_action_data()); 229 | } else if (action == N(move)) { 230 | impl::on(eosio::unpack_action_data()); 231 | } 232 | } 233 | } 234 | 235 | }; 236 | } 237 | 238 | ... 239 | extern "C" { 240 | 241 | using namespace tic_tac_toe; 242 | /// The apply method implements the dispatch of events to this contract 243 | void apply( uint64_t receiver, uint64_t code, uint64_t action ) { 244 | impl().apply(receiver, code, action); 245 | } 246 | 247 | } // extern "C" 248 | ``` 249 | 250 | 먼저 `unpack_action_data()`를 특정 핸들러에 넘기기 전에 사용하고 있는 점에 주목하세요, `unpack_action_data()`는 컨트랙트가 받은 액션을 `struct T`로 변환합니다. 251 | 252 | 이 과정을 깔끔하게 하기 위해, 액션 핸들러를 `struct impl` 내로 캡슐화했습니다: 253 | ```cpp 254 | ... 255 | struct impl { 256 | ... 257 | /** 258 | * @param create - action to be applied 259 | */ 260 | void on(const create& c) { 261 | // Put code for create action here 262 | } 263 | 264 | /** 265 | * @brief Apply restart action 266 | * @param restart - action to be applied 267 | */ 268 | void on(const restart& r) { 269 | // Put code for restart action here 270 | } 271 | 272 | /** 273 | * @brief Apply close action 274 | * @param close - action to be applied 275 | */ 276 | void on(const close& c) { 277 | // Put code for close action here 278 | } 279 | 280 | /** 281 | * @brief Apply move action 282 | * @param move - action to be applied 283 | */ 284 | void on(const move& m) { 285 | // Put code for move action here 286 | } 287 | 288 | /// The apply method implements the dispatch of events to this contract 289 | void apply( uint64_t receiver, uint64_t code, uint64_t action ) { 290 | ... 291 | ``` 292 | 293 | #### Create 액션 핸들러 294 | Create 액션 핸들러에는 다음이 필요합니다: 295 | 1. 액션에 호스트의 서명이 있는지 보장합니다 296 | 2. 호스트와 도전자가 같지 않다는 것을 보장합니다 297 | 3. 진행중인 게임이 없다는 것을 보장합니다 298 | 4. 새로 시작된 게임을 DB에 저장합니다 299 | ```cpp 300 | struct impl { 301 | ... 302 | /** 303 | * @brief Apply create action 304 | * @param create - action to be applied 305 | */ 306 | void on(const create& c) { 307 | require_auth(c.host); 308 | eosio_assert(c.challenger != c.host, "challenger shouldn't be the same as host"); 309 | 310 | // Check if game already exists 311 | games existing_host_games(code_account, c.host); 312 | auto itr = existing_host_games.find( c.challenger ); 313 | eosio_assert(itr == existing_host_games.end(), "game already exists"); 314 | 315 | existing_host_games.emplace(c.host, [&]( auto& g ) { 316 | g.challenger = c.challenger; 317 | g.host = c.host; 318 | g.turn = c.host; 319 | }); 320 | } 321 | ... 322 | } 323 | 324 | ``` 325 | 326 | #### Restart 액션 핸들러 327 | Restart 액션 핸들러에는 다음이 필요합니다: 328 | 1. 액션에 호스트나 도전자의 서명이 있는지 보장합니다 329 | 2. 진행중인 게임이 있다는 것을 보장합니다 330 | 3. Restart 액션이 호스트나 도전자에게서 수행되는지 보장합니다 331 | 4. 게임을 리셋합니다 332 | 5. 변경된 게임 상태를 DB에 저장합니다 333 | ```cpp 334 | struct impl { 335 | ... 336 | /** 337 | * @brief Apply restart action 338 | * @param restart - action to be applied 339 | */ 340 | void on(const restart& r) { 341 | require_auth(r.by); 342 | 343 | // Check if game exists 344 | games existing_host_games(code_account, r.host); 345 | auto itr = existing_host_games.find( r.challenger ); 346 | eosio_assert(itr != existing_host_games.end(), "game doesn't exists"); 347 | 348 | // Check if this game belongs to the action sender 349 | eosio_assert(r.by == itr->host || r.by == itr->challenger, "this is not your game!"); 350 | 351 | // Reset game 352 | existing_host_games.modify(itr, itr->host, []( auto& g ) { 353 | g.reset_game(); 354 | }); 355 | } 356 | ... 357 | } 358 | 359 | ``` 360 | 361 | #### Close 액션 핸들러 362 | Close 액션 핸들러에는 다음이 필요합니다: 363 | 1. 액션에 호스트의 서명이 있는지 보장합니다 364 | 2. 진행중인 게임이 있다는 것을 보장합니다 365 | 3. 게임을 DB에서 삭제합니다 366 | ```cpp 367 | struct impl { 368 | ... 369 | /** 370 | * @brief Apply close action 371 | * @param close - action to be applied 372 | */ 373 | void on(const close& c) { 374 | require_auth(c.host); 375 | 376 | // Check if game exists 377 | games existing_host_games(code_account, c.host); 378 | auto itr = existing_host_games.find( c.challenger ); 379 | eosio_assert(itr != existing_host_games.end(), "game doesn't exists"); 380 | 381 | // Remove game 382 | existing_host_games.erase(itr); 383 | } 384 | ... 385 | } 386 | 387 | ``` 388 | 389 | #### Move 액션 핸들러 390 | Move 액션 핸들러에는 다음이 필요합니다: 391 | 1. 액션에 호스트나 도전자의 서명이 있는지 보장합니다 392 | 2. 진행중인 게임이 있는지 보장합니다 393 | 3. 게임이 아직 끝나지 않았음을 보장합니다 394 | 4. Move 액션이 호스트나 도전자에게서 수행되는지 보장합니다 395 | 5. 맞는 사용자 차례인지 보장합니다 396 | 6. 맞는 행동인지 보장합니다 397 | 7. 새 행동을 반영해 판을 변경합니다 398 | 8. move_turn을 다른 플레이어로 변경합니다 399 | 9. 승자가 있는지 확인합니다 400 | 10. 변경된 게임 상태를 DB에 저장합니다 401 | ```cpp 402 | struct impl { 403 | ... 404 | bool is_valid_movement(const movement& mvt, const game& game_for_movement) { 405 | // Put code here 406 | } 407 | 408 | account_name get_winner(const game& current_game) { 409 | // Put code here 410 | } 411 | ... 412 | /** 413 | * @brief Apply move action 414 | * @param move - action to be applied 415 | */ 416 | void on(const move& m) { 417 | require_auth(m.by); 418 | 419 | // Check if game exists 420 | games existing_host_games(code_account, m.host); 421 | auto itr = existing_host_games.find( m.challenger ); 422 | eosio_assert(itr != existing_host_games.end(), "game doesn't exists"); 423 | 424 | // Check if this game hasn't ended yet 425 | eosio_assert(itr->winner == N(none), "the game has ended!"); 426 | // Check if this game belongs to the action sender 427 | eosio_assert(m.by == itr->host || m.by == itr->challenger, "this is not your game!"); 428 | // Check if this is the action sender's turn 429 | eosio_assert(m.by == itr->turn, "it's not your turn yet!"); 430 | 431 | 432 | // Check if user makes a valid movement 433 | eosio_assert(is_valid_movement(m.mvt, *itr), "not a valid movement!"); 434 | 435 | // Fill the cell, 1 for host, 2 for challenger 436 | const auto cell_value = itr->turn == itr->host ? 1 : 2; 437 | const auto turn = itr->turn == itr->host ? itr->challenger : itr->host; 438 | existing_host_games.modify(itr, itr->host, [&]( auto& g ) { 439 | g.board[m.mvt.row * 3 + m.mvt.column] = cell_value; 440 | g.turn = turn; 441 | 442 | //check to see if we have a winner 443 | g.winner = get_winner(g); 444 | }); 445 | } 446 | ... 447 | } 448 | 449 | ``` 450 | #### 행동 검증 451 | 빈 칸에 행동하는 것을 맞는 행동으로 정의합니다: 452 | ```cpp 453 | struct impl { 454 | ... 455 | /** 456 | * @brief Check if cell is empty 457 | * @param cell - value of the cell (should be either 0, 1, or 2) 458 | * @return true if cell is empty 459 | */ 460 | bool is_empty_cell(const uint8_t& cell) { 461 | return cell == 0; 462 | } 463 | 464 | /** 465 | * @brief Check for valid movement 466 | * @detail Movement is considered valid if it is inside the board and done on empty cell 467 | * @param movement - the movement made by the player 468 | * @param game - the game on which the movement is being made 469 | * @return true if movement is valid 470 | */ 471 | bool is_valid_movement(const movement& mvt, const game& game_for_movement) { 472 | uint32_t movement_location = mvt.row * 3 + mvt.column; 473 | bool is_valid = movement_location < board_len && is_empty_cell(game_for_movement.board[movement_location]); 474 | return is_valid; 475 | } 476 | ... 477 | } 478 | ``` 479 | #### 승자 결정 480 | 먼저 가로나 세로, 대각선으로 3개의 자기 표시(`1` 혹은 `2`)를 놓은 플레이어를 승자로 정의합니다. 481 | ```cpp 482 | struct impl { 483 | ... 484 | /** 485 | * @brief Get winner of the game 486 | * @detail Winner of the game is the first player who made three consecutive aligned movement 487 | * @param game - the game which we want to determine the winner of 488 | * @return winner of the game (can be either none/ draw/ account name of host/ account name of challenger) 489 | */ 490 | account_name get_winner(const game& current_game) { 491 | if((current_game.board[0] == current_game.board[4] && current_game.board[4] == current_game.board[8]) || 492 | (current_game.board[1] == current_game.board[4] && current_game.board[4] == current_game.board[7]) || 493 | (current_game.board[2] == current_game.board[4] && current_game.board[4] == current_game.board[6]) || 494 | (current_game.board[3] == current_game.board[4] && current_game.board[4] == current_game.board[5])) { 495 | // - | - | x x | - | - - | - | - - | x | - 496 | // - | x | - - | x | - x | x | x - | x | - 497 | // x | - | - - | - | x - | - | - - | x | - 498 | if (current_game.board[4] == 1) { 499 | return current_game.host; 500 | } else if (current_game.board[4] == 2) { 501 | return current_game.challenger; 502 | } 503 | } else if ((current_game.board[0] == current_game.board[1] && current_game.board[1] == current_game.board[2]) || 504 | (current_game.board[0] == current_game.board[3] && current_game.board[3] == current_game.board[6])) { 505 | // x | x | x x | - | - 506 | // - | - | - x | - | - 507 | // - | - | - x | - | - 508 | if (current_game.board[0] == 1) { 509 | return current_game.host; 510 | } else if (current_game.board[0] == 2) { 511 | return current_game.challenger; 512 | } 513 | } else if ((current_game.board[2] == current_game.board[5] && current_game.board[5] == current_game.board[8]) || 514 | (current_game.board[6] == current_game.board[7] && current_game.board[7] == current_game.board[8])) { 515 | // - | - | - - | - | x 516 | // - | - | - - | - | x 517 | // x | x | x - | - | x 518 | if (current_game.board[8] == 1) { 519 | return current_game.host; 520 | } else if (current_game.board[8] == 2) { 521 | return current_game.challenger; 522 | } 523 | } else { 524 | bool is_board_full = true; 525 | for (uint8_t i = 0; i < board_len; i++) { 526 | if (is_empty_cell(current_game.board[i])) { 527 | is_board_full = false; 528 | break; 529 | } 530 | } 531 | if (is_board_full) { 532 | return N(draw); 533 | } 534 | } 535 | return N(none); 536 | } 537 | ... 538 | } 539 | ``` 540 | 완성된 tic_tac_toe.cpp 파일은 [여기](https://github.com/EOSIO/eos/blob/master/contracts/tic_tac_toe/tic_tac_toe.cpp)에서 확인하실 수 있습니다. 541 | 542 | ### ABI 만들기 543 | ABI(Application Binary Interface)가 있어야만 컨트랙트가 바이너리로 전송한 액션을 이해할 수 있습니다. 544 | tic_tac_toe.abi 파일을 열고 아래의 boilerplate 처럼 시작하세요: 545 | ```json 546 | { 547 | "types": [], 548 | "structs": [{ 549 | "name": "...", 550 | "base": "...", 551 | "fields": { ... } 552 | }, ...], 553 | "actions": [{ 554 | "name": "...", 555 | "type": "...", 556 | "ricardian_contract": "..." 557 | }, ...], 558 | "tables": [{ 559 | "name": "...", 560 | "type": "...", 561 | "index_type": "...", 562 | "key_names" : [...], 563 | "key_types" : [...] 564 | }, ...], 565 | "clauses: [...] 566 | ``` 567 | - types: 다른 자료구조체나 내장 자료형으로 표현되는 자료형의 리스트(c/c++의 typedef 같은) 568 | - structs: 컨트랙트에서 사용되는 액션이나 테이블 자료 구조형의 리스트 569 | - actions: 컨트랙트에서 사용할 수 있는 액션의 리스트 570 | - tables: 컨트랙트에서 사용할 수 있는 테이블의 리스트 571 | 572 | #### Table ABI 573 | tic_tac_toe.hpp 파일에서는 games라는 이름으로 단일 인덱스를 가지는 i64 테이블을 만들 것입니다. 여기에는 `game` 자료구조가 저장되며, `challenger`가 키입니다. `challenger`의 자료형은 `account_name`이기 때문에 abi는 다음과 같게 됩니다: 574 | 575 | ```json 576 | { 577 | ... 578 | "structs": [{ 579 | "name": "game", 580 | "base": "", 581 | "fields": [ 582 | {"name":"challenger", "type":"account_name"}, 583 | {"name":"host", "type":"account_name"}, 584 | {"name":"turn", "type":"account_name"}, 585 | {"name":"winner", "type":"account_name"}, 586 | {"name":"board", "type":"uint8[]"} 587 | ] 588 | },... 589 | ], 590 | "tables": [{ 591 | "name": "games", 592 | "type": "game", 593 | "index_type": "i64", 594 | "key_names" : ["challenger"], 595 | "key_types" : ["account_name"] 596 | } 597 | ], 598 | ... 599 | } 600 | ``` 601 | 602 | #### Actions ABI 603 | 액션을 위해 액션들을 `actions` 내부에 정의하고, 액션의 구조체를 `structs` 내부에 정의합니다. 604 | ```json 605 | { 606 | ... 607 | "structs": [{ 608 | ... 609 | },{ 610 | "name": "create", 611 | "base": "", 612 | "fields": [ 613 | {"name":"challenger", "type":"account_name"}, 614 | {"name":"host", "type":"account_name"} 615 | ] 616 | },{ 617 | "name": "restart", 618 | "base": "", 619 | "fields": [ 620 | {"name":"challenger", "type":"account_name"}, 621 | {"name":"host", "type":"account_name"}, 622 | {"name":"by", "type":"account_name"} 623 | ] 624 | },{ 625 | "name": "close", 626 | "base": "", 627 | "fields": [ 628 | {"name":"challenger", "type":"account_name"}, 629 | {"name":"host", "type":"account_name"} 630 | ] 631 | },{ 632 | "name": "movement", 633 | "base": "", 634 | "fields": [ 635 | {"name":"row", "type":"uint32"}, 636 | {"name":"column", "type":"uint32"} 637 | ] 638 | },{ 639 | "name": "move", 640 | "base": "", 641 | "fields": [ 642 | {"name":"challenger", "type":"account_name"}, 643 | {"name":"host", "type":"account_name"}, 644 | {"name":"by", "type":"account_name"}, 645 | {"name":"mvt", "type":"movement"} 646 | ] 647 | } 648 | ], 649 | "actions": [{ 650 | "name": "create", 651 | "type": "create", 652 | "ricardian_contract": "" 653 | },{ 654 | "name": "restart", 655 | "type": "restart", 656 | "ricardian_contract": "" 657 | },{ 658 | "name": "close", 659 | "type": "close", 660 | "ricardian_contract": "" 661 | },{ 662 | "name": "move", 663 | "type": "move", 664 | "ricardian_contract": "" 665 | } 666 | ], 667 | ... 668 | } 669 | ``` 670 | 671 | ### 컴파일! 672 | 이제 tic_tac_toe.cpp 파일을 컴파일해서 만든 tic_tac_toe.wast 파일을 이용해 컨트랙트를 nodeos에 배포할 것입니다. 673 | ```bash 674 | $ eosiocpp -o tic_tac_toe.wast tic_tac_toe.cpp 675 | ``` 676 | 677 | ### 배포! 678 | 이제 wast와 abi 파일(tic_tac_toe.wast, tic_tac_toe.abi)이 준비됐습니다. 배포의 시간입니다! 679 | 디렉토리(편의상 tic_tac_toe로 합시다)를 만들고 생성된 tic_tac_toe.wast, tic_tac_toe.abi 파일을 복사하세요. 680 | 681 | ```bash 682 | $ cleos set contract tic.tac.toe tic_tac_toe 683 | ``` 684 | 지갑이 잠금 해제되었고, `tic.tac.toe` 키가 임포트돼 있는지 확인하세요. 컨트랙트를 `tic.tac.toe`가 아닌 다른 계정으로 업로드하시려면, `tic.tac.toe` 부분을 여러분이 사용하실 계정명으로 바꾸고, 지갑에 해당 계정에 대한 키가 있는지 확인하세요. 685 | 686 | ### 플레이! 687 | 배포가 끝나 트랜잭션이 확정되면, 블록체인에서 컨트랙트를 쓸 수 있게 된 것입니다. 이제 플레이할 수 있습니다! 688 | 689 | #### Create 690 | ```bash 691 | $ cleos push action tic.tac.toe create '{"challenger":"inita", "host":"initb"}' --permission initb@active 692 | ``` 693 | #### Move 694 | ```bash 695 | $ cleos push action tic.tac.toe move '{"challenger":"inita", "host":"initb", "by":"initb", "mvt":{"row":0, "column":0} }' --permission initb@active 696 | $ cleos push action tic.tac.toe move '{"challenger":"inita", "host":"initb", "by":"inita", "mvt":{"row":1, "column":1} }' --permission inita@active 697 | ``` 698 | #### Restart 699 | ```bash 700 | $ cleos push action tic.tac.toe restart '{"challenger":"inita", "host":"initb", "by":"initb"}' --permission initb@active 701 | ``` 702 | #### Close 703 | ```bash 704 | $ cleos push action tic.tac.toe close '{"challenger":"inita", "host":"initb"}' --permission initb@active 705 | ``` 706 | #### 게임 상태 확인 707 | ``` 708 | $ cleos get table tic.tac.toe initb games 709 | { 710 | "rows": [{ 711 | "challenger": "inita", 712 | "host": "initb", 713 | "turn": "inita", 714 | "winner": "none", 715 | "board": [ 716 | 1, 717 | 0, 718 | 0, 719 | 0, 720 | 2, 721 | 0, 722 | 0, 723 | 0, 724 | 0 725 | ] 726 | } 727 | ], 728 | "more": false 729 | } 730 | ``` 731 | 732 | ## 번역 정보 733 | 734 | * 위키 원문 : https://github.com/EOSIO/eos/wiki/Tutorial-Tic-Tac-Toe 735 | * 번역 기준 리비전 : 0c18223ea118597c7b2476118091c4094be6af99 736 | --------------------------------------------------------------------------------