논문링크: https://bitcoin.org/bitcoin.pdf

한글번역판 링크: https://mincheol.im/wp/wp-content/uploads/2017/09/bitcoin_ko_v1.2.pdf

(한글번역판이 있다는걸 내가 직접 리뷰하던 도중 알게 됐지만, 나는 직접번역을 계속하려한다.)

 

읽기좋게 약간의 의역 및 생략/추가가 포함돼있다.

중간중간 내 생각은 다른 색깔로 표시돼 있다.

 

아래 논문을 보다보면 자주나오는 용어들이 있는데, 그에 대한 풀이를 먼저 기록해둔다.

용어집

신뢰기반모델: 기존 금융을 비판하기 위해 쓰인 용어 같은데 정확히 모르겠다. 검색도 원활하게는 안되는듯? 

신뢰집단: 개인간 대면거래가 아닌, 비대면 통신채널에서 거래를 하는데 있어서, 기존 금융에서는 반드시 필요한 집단. 

비가역거래: 거래는 비가역적이어야 하며, 기존 금융에선 이게 안된다고 하고 있다.

이중지불: 간단히 이야기하면 코인 복사를 해서 두번 지불하는걸 의미

지불=결제: payment가 문맥에 따라 지불 또는 결제로 번역되는데 같은 의미로 보면 된다.

 

hashcash:

  • (문과적설명) 만드는데는 짧은 시간이 걸리지만 문제를 푸는데는 긴 시간이 걸린다. 적절한 시간내에 문제를 풀었다면, 이 사용자는 유효한 사용자라는 것을 증명 할 수 있다.
  • (이과적설명) hashcash는 특정한 조건을 가지는 해시값을 찾는 것이다. 그 특정한 조건이란 특정한 해시를 계속 수행해서 해시된 결과의 앞자리 비트 몇개가 0인 것. 자세한 알고리즘은 여기가 이해가 편했다.

 

제목: Bitcoin: A Peer-to-Peer Electonic Cash System

 

Abstract

bitcoin으로 개인간 돈을 직접 전송한다.

전자서명으로는 위의 이슈를 일부 해결가능하나 이중지불 문제를 피할 수 없다(이 문장이 좀 모호한데 일단 넘어가자 ㅋ)

우리는 peer-to-peer network으로 이중지불 문제를 피할 수 있는 솔루션을 제시한다.

해당 네트워크는 해시베이스의 proof-of-work로 진행되는 체인에 트랜잭션 타임스탬프를 넣으며, 이것은 proof-of-work를 다시하기전까진 변조될 수 없다.

가장 긴 체인은 이벤트 증명으로서의 역할 뿐 아니라, 가장큰 CPU파워풀에서 나왔음을 증명한다.

가장큰 CPU power를 가진쪽이 공격자와 협력하지만 않는다면, 그들은 가장긴 체인을 만들어 공격자를 앞지를 것이다.

네트워크 자체는 minial structure를 요구한다. 

메시지는 best effort 기반으로 브로드캐스트 되며, 모든 노드는 네트워크를 참여하거나 떠날수 있다(이건 무슨말?)

가장긴 proof-of-work 체인을 그동안 지나온길로 받아들이며 .

 

1. 서론

인터넷 전자상거래는 전자지불을 처리하는 서드파티역할을 하는 금융기관에 거의 독점적으로 의존해왔다.

그 시스템은 대부분의 트랜잭션에 대해서 잘 동작하는 한편, 신뢰기반모델의 내재하는 약점에 여전히 고통받고 있다.

완전히 되돌릴수없는 거래는 가능하지 않다, 금융기관은 분쟁조정(mediating dispute)을 피할수 없기 때문이다.

중재비용은 거래비용을 증가시키고,

현실적인 최소 거래규모를 제한하며, 작고 캐주얼한 거래의 가능성을 잘라버린다. 

그리고 되돌릴수없는 서비스에 대한 되돌릴수없는 지불이 불가하기에 더 광범위한 비용이 존재한다. 

되돌릴수 없는 거래가 가능하지 않기 때문에, 신뢰에 대한 필요가 확산된다.

상거래자들은 고객에 대해 걱정해야하며, 필요이상의 더 많은 정보들로 인해 귀찮게 된다.

특정확률로 사기는 피할수 없다고 받아들여진다.

이러한 비용과 지불의 불확실성은 대면거래에서는 물리적화폐를 통해 피할수 있지만,

통신채널을 통해서는 신뢰집단없이는 기술적으로 불가하다.

필요한것은 암호신뢰증명에 기반한 전자적지불시스템이며, 이를 통해 두 집단간 거래는 제3의 신뢰집단없이 가능하다.

 

되돌리기가 계산적으로 불가능한 거래는 판매자를 사기로 부터 보호하며, 제3자예치(이게 머지?)방식은 구매자를 보호한다.

이 논문에서, 우리는 거래 시간순의 전산적 증명을 생성하는 peer-to-peer 분산 타임스탬프 서버를 사용한 이중지불문제의 솔루션을 제시한다.(뭔솔?)

이 시스템은 정직한 노드들의 합이 공격자 노드들 보다 많은 CPU파워를 컨트롤 한다면 안전하다.

 

2. 거래

우리는 전자적 코인을 전자서명의 체인으로 정의한다.

각 소유자는 전 거래의 hash 및 다음 소유자의 공개키에 전자서명함으로서 코인을 송금한다. 그리고 이걸 코인의 끝에 추가한다.

돈은 받는 사람은 이 서명들을 검증해서 소유권 체인을 검증할 수 있다.

일단 소유권 이전에 대해서 기록할 수 있다는 개념 정도는 이해된다.

 

(위 그림을 보면 이전 소유자와 다음소유자의 전자서명과 검증과정이 들어가는걸 볼 수 있고, 위의 구조가 minimal인지는 잘 모르겠네.

그냥 봐서는 좀 복잡해 보이는 느낌인데.전 거래의 해시가 들어가는건 당연할건데, 이걸 왜 이전 소유자의 전자서명을 해두는걸까? 

아마도 소유권 증명같은걸 위해서겠지?좀더 파보자.)

 

문제는 수신자가 이중지불이 되지 않았는지 검증이 힘들다는 것이다.

일반적인 해결책은 믿을만한 중앙통제기관이나 조폐국을 두고 모든 거래에 대해 이중지불을 체크하는 것이다.

거래마다, 코인은 조폐국으로 반납돼서 새 코인이 발급되고, 이것만 이중지불 되지 않았음을 보장한다.

(위에서 소유권 체인을 만들었음에도 이중지불 문제가 남아있는 이유는 뭘까? 뒤에 나오지만 소유자가 반복해서 거래 노드를 만들수 있다면 가능할 것이다.)

이 방법의 문제점은 전체 화폐시스템이 조폐국을 운영하는 특정회사에 의존한다는 점이다. 모든 트랙잭션에 대해. 마치 은행처럼.

수신자입장에서 이전 소유자들이 앞 전 거래들에 어러번 싸인을 하지 않았음을 알아야만 한다.

유일한 방법은 기존 모든 거래를 인식하고, 이어서 수신된 최초로 싸인된 거래를 차례대로 승인하는 방법이다. 

조폐국 없이 이를 수행하려면 거래는 공개적으로 알려져야 하고, 모든 참가자들이 단일한 이력에 대해 합의 하는 시스템이 필요하다.

수금자는 각 거래의 시점에 그게 최초로 받은 거래임을 노드 다수가 동의했다는 증명을 요한다.

 

3. 타임스탬프 서버

우리는 이 문제 해결을 위해 타임스탬프 서버를 제안한다.(왜 갑자기 타임스탬프 이야기가 나오지?)

이 서버는 아이템 블록을 타임스탬프와 함께 해시하고 신문이나 유즈넷게시물처럼 널리 배포하는 식으로 동작한다.

타임스탬프는 해당 아이템이 특정 시간에 존재했음을 증명한다. 각 타임스탬프는 이전 타임스탬프를 해시에 포함한다. 이로서 하나씩 연장하는 체인을 형성한다.

 

(이 3번단락은 내용도 짧고 내용도 타임스탬프를 넣어서 시간정보를 기록한다는 내용 뿐이라 왜 굳이 단락을 할당했는지 모르겠다. 이중지불 문제가 타임스탬프로 단순하게 풀린다는 것처럼 써있는데, 그 논리도 잘 이해가 안된다. 뒤에 다시 타임스탬프 언급이 나오는지 살펴보자.)

 

4. 작업증명

 

P2P 베이스로 분산 타임스탬프 서버를 구현하기 위해, 뉴스나 유즈넷보다는 아담백의 hashcash같은 작업증명시스템이 필요하다.

(여기서 hashcash이야기가 나오는데, 먼저 공부하고 와도 좋을 것 같다.)

작업증명은 SHA256등으로 해시된 결과가 몇 개의 제로비트로 시작되는걸 스캔하는 작업을 포함한다.

제로비트 개수에 따라 필요한 작업은 지수적으로 증가하는 반면, 검증은 hash한번으로 쉽게 된다.

우리의 타임스탬프 네트웍을 위해서, 우리는 nonce를 증가시키면서 주어진 블럭의 해시결과가 필요한 제로비트 개수를 포함하도록 작업증명시스템을 구현했다.

한번 CPU써서 작업증명을 만족시키면 이 작업을 다시하지 않는한 블럭은 바뀌지 않는다.

블럭뒤에 다른 블럭이 붙기 때문에, 바꾸려고 하면 이 모두를 다시 작업 수행해야한다.

 

작업 증명은 또한 다수결 의사 결정에서 대표성을 결정하는 문제(릉?)를 해결한다.

다수결을 IP주소당 한개의 투표권을 기반으로 한다면, 많은 IP를 할당할 수 있는 사람이 이겨버리는 문제가 생긴다.

작업증명은 기본적으로 CPU당 한표이다. 다수결은 가장 긴 사슬로 표현되며, 가장 큰 작업 증명 노력이 투자된 것이다.

CPU대부분이 정직하게 제어되는 경우, 정직한 체인이 가장 빠르게 성장하고 체인 경쟁에서 다른 체인을 능가한다.

 

과거 블록을 변조하기 위해서는 공격자가 해당블록과 그 이후의 모든 블록의 작업 증명을 다시 실행한 다음 정직한 노드의 작업을 따라잡고 능가해야 한다.

후속 블록이 추가됨에 따라 더 느린 공격자가 따라잡을 확률이 기하급수적으로 감소한다는 것을 나중에 보여줄 것이다.

시간이 지남에 따라 증가하는 하드웨어 속도와 노드 실행에 대한 다양한 관심을 보상하기 위해 작업 증명 난이도는 시간당 평균 블록 수를 목표로 하는 이동 평균으로 결정되고, 너무 빨리 생성되면 난이도가 높아진다.

 

5. 네트워크

네트워크를 실행하는 단계는 다음과 같다.
1) 새로운 트랜잭션은 모든 노드에 브로드캐스트된다.(블럭은 뭐고 노드는 뭐지, 노드는 네트워크 참여자를 의미하는걸까..그런듯)

2) 각 노드는 새로운 트랜잭션을 블록으로 수집한다.(이 노드들은 어떻게 서로가 서로를 알고 소통할까)

3) 각 노드는 해당 블록에 대한 (까다로운) 작업 증명을 수행하려고 노력한다.

4) 노드가 작업 증명을 찾으면 블록을 모든 노드에 브로드캐스트한다.

5) 노드는 모든 트랜잭션이 유효하고 아직 사용되지 않은 경우에만 블록을 수락한다.

6) 노드는 승인된 블록의 해시를 이전 해시로 사용하여 체인에서 다음 블록을 생성하는 작업을 통해 블록 승인을 표현한다.

 

노드는 항상 가장 긴 체인을 올바른 체인으로 간주하고 계속해서 확장 작업을 수행한다. 두 노드가 다음 블록의 다른 버전을 동시에 브로드캐스트하는 경우 일부 노드는 하나 또는 다른 하나를 먼저 수신할 수 있다. 그런 경우, 그들은 받은 첫 번째 블록으로 작업하지만 더 길어질 경우를 대비하여 다른 분기를 저장합니다. 다음 작업 증명이 발견되고 한 가지가 더 길어지면 타이가 해결됨. 그러면 다른 분기에서 작업하던 노드는 더 긴 것으로 전환한다. 새로운 트랜잭션 브로드캐스트가 반드시 모든 노드에 도달할 필요는 없다. 그들이 많은 노드에 도달하는 한, 그들은 머지 않아 블록에 들어갈 것입니다(이건 왜글지?). 블록 브로드캐스트는 삭제된 메시지도 처리된다. 노드가 블록을 수신하지 않으면 다음 블록을 수신하고 누락된 블록을 깨달았을 때 요청한다.

 

6. 인센티브

일반적으로 블록의 첫 번째 트랜잭션은 블록 작성자가 소유한 새 코인을 시작하는 특별한 트랜잭션인다(블럭마다 그 블럭을 생성한 생성자가 새코인을 발행하고 그걸 가진다는 이야기) 이것은 노드가 네트워크를 지원하도록 인센티브를 추가하고, 발행할 중앙 기관이 없기 때문에 초기에 코인을 유통에 배포하는 방법을 제공한다. 일정한 양의 새로운 코인을 꾸준히 추가하는 것은 금 채굴자가 금유통을 늘리기 위해 자원을 소비하는 것과 유사하다.우리의 경우 소비되는 것은 CPU 시간과 전력이다. 

인센티브는 거래 수수료로 조달할 수도 있다. 트랜잭션의 출력 금액이 입력 금액보다 작은 경우 차이는 수수료이다. 미리 정해진 수의 코인이 유통에 들어가면 인센티브는 완전히 거래 수수료로 전환되고 인플레이션이 전혀 없다(많은 사람들의 오해와 다르게 채굴이 종료되어도 네트웍이 유지될 수 있겠네(수수료지급은 계속 되므로))

 

인센티브는 노드가 정직함을 유지하도록 장려하는 데 도움이 될 수 있다.

탐욕스러운 공격자가 모든 정직한 노드보다 더 많은 CPU 파워를 모을 수 있다면, 그는 이를 사용하여 지불금을 훔쳐 사람들을 기만할 것인지, 아니면 새 코인을 생성하는 데 사용할 것인지 선택해야 한다. 그는 다른 모든 사람을 합친 것보다 더 많은 새 주화로 자신에게 유리한 규칙을 따르는 것이 시스템과 자신의 부의 유효성을 훼손하는 것보다 더 수익성이 있음을 알아야 한다(심지어 51%공격이 가능한 사람이 나오더라도, 그냥 건전하게 채굴이나 계속하는게 신규코인을 계속 받을 수 있으니 유리하다는 논리까지 이미 갖추고 있었네)

 

7. 디스크 공간 회수

코인의 최신 트랜잭션이 충분한 블록 아래에 묻히면 디스크 공간을 절약하기 위해 이전에 사용한 트랜잭션을 폐기할 수 있습니다. 블록의 해시를 손상시키지 않고 이를 용이하게 하기 위해 트랜잭션은 블록의 해시에 포함된 루트만 포함하여 Merkle Tree[7][2][5]에서 해시됩니다. 그런 다음 오래된 블록은 가지치기를 통해 압축할 수 있습니다. 내부 해시는 저장할 필요가 없습니다.

(음 자세한 로직은 잘 모르겠고 왜 트리구조인지도 잘 모르겠지만, 어쨌든 너무 길어지면 뭔가 압축되는 과정이 원래부터 고려된건 신기하네..근데 블록 안에서만 압축되는건가?)

트랜잭션이 없는 블록 헤더는 약 80바이트입니다.(블록안에 트랜잭션이 많으면?, 년도가 쌓이면?) 10분마다 블록이 생성된다고 가정하면 연간 80바이트 * 6 * 24 * 365 = 4.2MB입니다. 2008년 현재 일반적으로 2GB의 RAM으로 판매되는 컴퓨터 시스템과 현재 연간 1.2GB의 성장을 예측하는 무어의 법칙을 고려할 때 블록 헤더를 메모리에 보관해야 하는 경우에도 스토리지는 문제가 되지 않습니다.

 

8. 단순화된 지불 검증

(그러니까 위의 압축, 머클트리 이런걸로 단순화 시켰을때 약점이 존재한다는걸 짚은거 같은데, 전반적으로 뭔소린지 모르게 기술돼 있다. 이해하려고 하면 관련 논문이나 추가자료를 봐야할듯?)

전체 네트워크 노드를 동원하지 않고도 결제를 확인할 수 있습니다. 

사용자는 그가 최장 작업증명 사슬을 가졌다고 확신할 때까지 네트워크 노드를 조회해, 얻을 수 있는 가장 긴 사슬의 블록 헤더 사본을 유지하면서, 해당 거래 를 타임스탬프가 찍힌 블록에 연결한 머클 분기를 얻기만 하면 된다(대체 뭔솔? 갑자기 왠 사용자?)

그는 트랜잭션을 직접 확인할 수는 없지만 체인의 한 장소에 연결하면 네트워크 노드가 이를 수락하고 네트워크가 수락했음을 추가로 확인한 후에 추가된 블록을 볼 수 있습니다(뭔소리냐고..)

따라서 검증은 정직한 노드가 네트워크를 제어하는 한 신뢰할 수 있지만 네트워크가 공격자에 의해 압도되는 경우 더 취약합니다. (why?)

네트워크 노드가 자체적으로 트랜잭션을 확인할 수 있지만 공격자가 네트워크를 계속 압도할 수 있는 한 공격자의 조작된 트랜잭션에 의해 단순화된 방법을 속일 수 있습니다. (그러니까 뭔소리냐고)

이를 방지하기 위한 한 가지 전략은 네트워크 노드가 유효하지 않은 블록을 감지할 때 경고를 발송하여, 사용자의 소프트웨어가 전체 블록을 다운로드하도록 하고 불일치를 확인하도록 하는 것입니다.

빈번한 지불을 받는 기업은 더 독립적인 보안과 더 빠른 검증을 위해 여전히 자체 노드를 실행하기를 원할 것입니다.(노드는 오픈환경에서 서로 경쟁하는거 아닌가? 자체 노드를 돌린다는게 무슨뜻이지? 단순히 오픈환경에 여러노드를 참여시킨다는 정도의 의미인가? 그렇다면 이게 왜 더 유리하지?)

 

9. 가치 결합 및 분할

코인을 1개씩 개별적으로 취급하는 것은 가능하지만, 이체 시 1코인마다 별도의 트랜잭션처리를 하는 것은 현명하지 않다. 가치를 분할 및 결합할 수 있도록 트랜잭션에는 입출력이 여러개이다. 일반적으로 이전 트랜잭션의 큰 단일 입력 또는 더 적은 금액을 결합한 여러 입력이 있으며 최대 두 개의 출력이 있습니다.두개의 출력중 하나는 지불을 위한 것이고 다른 하나는 거스름돈이 있는 경우 송금인에게 다시 반환하는 것입니다.

 

트랜잭션이 여러 트랜잭션에 의존하고 이러한 트랜잭션이 더 많은 트랜잭션에 의존하는 팬아웃은 여기서 문제가 되지 않는다는 점에 유의해야 합니다. 트랜잭션의 완전한 기록사본을 추출할 필요가 없습니다(대충 원래 트렌잭션 추적을 제대로 하려면 트리구조가 나오는데, 그걸 몰라도 된다는 내용인거 같은데, 자세히는 모르겠다)

 

10. 개인 정보 보호

(걍 실명제가 아니라서 프라이버시가 보장된다는 내용을 길게도 써놨네)

전통적인 뱅킹 모델은 관련 당사자 및 신뢰할 수 있는 제3자에게만 정보에 대한 액세스를 제한함으로써 개인 정보 보호 수준을 달성합니다. 비트코인에서는 모든 거래를 공개적으로 발표해야 하는 필요성 때문에 이 방법은 못쓰지만,

공개키 익명성을 보존 해 다른 장소에서 정보의 흐름을 끊는 걸로 여전히 프라이버시가 보장될 수 있다.

대중은 누군가가 다른 사람에게 금액을 보내고 있음을 알 수 있지만 거래를 누구와 연결하는 정보는 없습니다.

이는 개인 거래의 시간과 규모인 '테이프'를 공개하되 당사자가 누구인지는 밝히지 않은 증권거래소가 공개하는 정보 수준과 비슷하다.

 

추가적인 방화벽으로서, 각 트랜잭션에 대해 새 키 쌍을 사용하여 공통 소유자와 연결되지 않도록 해야 합니다. 일부 연결은 다중 입력 트랜잭션에서 여전히 피할 수 없으며, 이는 해당 입력이 동일한 소유자의 소유임을 필연적으로 나타냅니다. 위험은 키 소유자가 공개될 경우 연결 시 동일한 소유자에게 속한 다른 트랜잭션이 공개될 수 있다는 것입니다.

(뭐여.. 일부 한계가 있다는 점을 쿨하게 인정하고 넘어감?)

 

11. 계산

공격자가 정직한 체인보다 빠르게 대체 체인을 생성하려는 시나리오를 고려해보자.

그런일이 발생해도, 허공에서 가치를 창출하거나 공격자의 소유가 아닌 돈을 빼앗는 것과 같은 임의의 변경까지 시스템이 허용하진 않는다(진짜?

노드는 유효하지 않은 거래를 지불로 수락하지 않으며 정직한 노드는 이를 포함하는 블록을 수락하지 않습니다.(왜?)

공격자는 최근에 지출한 돈을 회수하기 위해 자신의 거래 중 하나만 변경할 수 있습니다.(왜일까.. 최근이 아니면 너무 변경할게 많아서 그런거고 자신의 거래가 아니면 키관련 문제가 있어서 그럴까?) 정직한 체인과 공격자 체인 간의 경쟁은 이항 랜덤 워크(Binomial Random Walk)로 특징지을 수 있습니다. 

성공 이벤트는 정직한 체인이 한 블록 확장되어 리드가 +1 증가하는 이벤트이고, 실패 이벤트는 공격자의 체인이 한 블록 확장되어 격차가 -1만큼 감소하는 것입니다. 

공격자가 주어진 격차를 따라잡을 확률은 도박꾼의 파멸(Gambler's Ruin) 문제와 유사합니다. 

(도박꾼의 파산은 유한한 초기 자산을 가지고 일련의 공평한 도박을 하는 도박꾼은 거의 확실하게 자산이 0이 되어 파산하게 된다는 정리이다. 위키백과)

신용이 무제한인 도박꾼이 적자에서 시작하여 손익분기점에 도달하기 위해 잠재적으로 무한한 시도를 한다고 가정합니다. 다음과 같이 공격자가 손익분기점에 도달하거나 공격자가 정직한 체인을 따라잡을 확률을 계산할 수 있습니다.

 

이담에 수학적인 식들이 나오는데, 결국 공격이 힘들다는 내용이므로 일단 지금은 생략하자.

 

12. 결론

우리는 신뢰에 의존하지 않는 전자 거래를 위한 시스템을 제안했습니다.

우리는 소유권에 대한 강력한 제어를 제공하지만 이중 지출을 방지할 방법이 없으면 불완전한 디지털 서명으로 만든 코인의 일반적인 프레임워크로 시작했습니다.이 문제를 해결하기 위해 우리는 작업 증명을 사용하는 P2P 네트워크를 제안하여 정직한 노드가 CPU 성능의 대부분을 제어하는 ​​경우 공격자가 변경할 수 있는 계산적으로 빠르게 비실용적이 되는 트랜잭션의 공개 이력을 기록합니다. 네트워크는 구조화되지 않은 단순성으로 인해 강력합니다. 노드는 약간의 조정으로 한 번에 모두 작동합니다. 메시지가 특정 위치로 라우팅되지 않고 최선을 다해 전달되기만 하면 되므로 식별할 필요가 없습니다. 노드는 네트워크를 떠나고 다시 참여할 수 있으며 작업 증명 체인을 네트워크가 없는 동안 발생한 일의 증거로 받아들입니다. 그들은 CPU 파워로 투표를 하여 유효한 블록을 확장하는 작업을 통해 승인을 표현하고 작업을 거부하여 유효하지 않은 블록을 거부합니다. 이 합의 메커니즘을 통해 필요한 모든 규칙과 인센티브를 시행할 수 있습니다.

 

반응형

'비트코인' 카테고리의 다른 글

이더리움 관련 Q&A(자문자답)  (0) 2022.03.23
비트코인 관련 Q&A (자문자답)  (0) 2021.12.30
블럭체인의 원리  (0) 2020.07.31
md5, sha  (0) 2017.12.12
비트코인 분석 연재를 시작하며  (0) 2017.12.10

3D 엔진을 내손으로 직접 만들어보는 프로젝트!

 

3D 드로잉은 좀 더 풀어서 설명하면, 3차원 공간을 2차원 평면에 표현하는 과정이고,

2D 드로잉은 2차원 공간을 2차원 평면에 표현하는 과정이다.

따라서 3D 드로잉이 2D보다 조금 어려운게 아니라 많이! 더 어렵다.

 

어려운점1 : 투사!

3D 드로잉은 3차원 공간을 2차원 평면에 표현하기 위해 아래처럼 투사라는 과정이 추가로 들어간다.

투사를 표현한 그림. canvas라는 평면에 투사되어 우리눈에 보인다.

투사는 개념은 이해하기 쉽지만 막상 코딩을 하려고 하면 어질어질 해진다.

 

어려운점2 : 4x4 행렬연산 이해하기!

거기에다 물체의 회전, 이동등의 움직임을 효율적으로 계산하기 위해서 보통 행렬이 쓰이는데, 이게 또 난이도를 올리는 원인이된다. 게다가 3차원이면 3x3행렬이 쓰일거 같은데, "이동변환" 때문에 4x4행렬이 쓰이는점도 이해하기 쉽지 않다.

 

어려운점3 : 수많은 수학적인 용어들과 싸우기!

게다가 좌표계와 변환에 대한 내용이다 보니, 수학적으로 한없이 현학적으로 들어갈 수 있어, 관련자료를 공부하는 과정에서 쉽게 지치고 포기하게 되는 포인트가 된다.

오일러회전, 쿼터니언, 선형변환, 아핀변환, 물체좌표, 월드좌표, 카메라좌표, 스크린좌표, 직교좌표계, 호모지니어스(동차) 좌표계, 로컬좌표계, 글로벌좌표계, 포인트, 벡터 등등 이름만 들어도 어질어질 해진다 ㅠ

 

언어와 라이브러리 고르기

언어는 내 취향대로 C++을 골랐고,

아직 C++에서 native로 drawing을 지원하지 않기 때문에 SFML 라이브러리를 사용하기로 했다.

OS 및 개발환경에 따른 SFML초기환경 세팅은 여기를 참고하자. (필자는 Windows 10 / Visual Studio 2019 환경)

 

SFML로 기본적인 2D 드로잉 해보기

아래 코드를 입력해서 기본 drawing canvas를 띄워보자

#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;

int main(void)
{
	RenderWindow window(VideoMode(800, 600), "2D");

	while (window.isOpen())
	{
		Event e;
		while (window.pollEvent(e))
		{
			if (e.type == Event::Closed) window.close();
		}
		window.clear(Color::Blue);
		window.display();
	}
	return 0;
}

가장 간단한 기본 형태인데 왜 while문이 2개나 있는지 궁금하실 수 있는데, 아주 간단하게 언급하고 넘어가자면, while문 형태의 무한루프가 없으면 return 0;으로 프로그램이 바로 종료되어 버리기 때문이다, 그리고 움직임을 표현하려면 반복적으로 그려주는게 필요해서 기본적으로 while 무한루프형태가 필요하고, 창을 닫는등의 이벤트를 받기위해 간단한형태의 이벤트 루프가 필요하기 때문에  안쪽의 while루프 하나가 더 들어간다고 보면 된다. (이런 이벤트 루프가 없으면 창을 닫아도 c프로그램에서 알 방법이 없기 때문에 while문들을 다 벗어나서 return 0;으로 프로그램을 종료할 방법이 없다.)

실행결과

아래 코드를 입력해서, 랜덤색깔을 가진 점들을 랜덤위치에 표시해보자.

#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;

int main(void)
{
	RenderWindow window(VideoMode(800, 600), "2D");

	auto draw_dots = [&]()
	{
		for (int i = 0; i < 1000000; i++)
		{
			Vertex point(sf::Vector2f(rand()%800, rand()%600), Color(rand()%255, rand()%255, rand()%255));
			window.draw(&point, 1, Points);
		}
	};

	while (window.isOpen())
	{
		Event e;
		while (window.pollEvent(e))
		{
			if (e.type == Event::Closed) window.close();
		}
		window.clear(Color::Blue);
		draw_dots();
		window.display();
	}
	return 0;
}

랜덤 점찍기 실행결과

 

아래 코드를 입력해서, 랜덤색깔을 가진 선들을 랜덤위치에 표시해보자.

#include <SFML/Graphics.hpp>
using namespace std;
using namespace sf;

int main(void)
{
	RenderWindow window(VideoMode(800, 600), "2D");

	auto draw_lines = [&]()
	{
		for (int i = 0; i < 1000; i++)
		{
			Color c1 = Color(rand() % 255, rand() % 255, rand() % 255);
			Color c2 = Color(rand() % 255, rand() % 255, rand() % 255);
			sf::Vertex line[2] = { 
				{Vector2f(rand() % 800, rand() % 600), c1},
				{Vector2f(rand() % 800, rand() % 600), c2}, };
			window.draw(line, 2, Lines);

		}
	};

	while (window.isOpen())
	{
		Event e;
		while (window.pollEvent(e))
		{
			if (e.type == Event::Closed) window.close();
		}
		window.clear(Color::Blue);
		draw_lines();
		window.display();
	}
	return 0;
}

랜덤 선찍기 실행결과

 

반응형

 

먼저 다음과 같이, PC버전 텔레그램을 깔고 Search창에 BotFather라고 친다.

 

 

 

 

아래와 같이 검색되면.. 채팅창에 /newbot이라고 친다.

그다음 원하는 이름을 치고(위 예에서는 "코댕이"), _bot으로 끝나는 username을 부여한다(위 예에서는 sevity_coin3_bot)

 

그럼 위에 빨간색 박스친영역에서 보이듯이, 만들어진 챗봇과 대화할수 있는 대화방 링크(t_me로 시작하는 링크)와,

프로그램에서 봇으로 챗을 보낼 수 있는 토큰이 만들어진다. (여기서 토큰은 공개하면 좋지않다. 자세한건 여기 참조)

 

대화방 링크를 눌러서 다음과 같이 봇과의 채팅방에 진입해보자.

START버튼을 눌러서 대화를 시작하자.

 

근데 황당하게도 이게 끝이 아니다.

파이선등에서 저 봇으로 메시지를 보내려면 위에서 발급받은 토큰만 알면 되는게 아니라, chat id란걸 알아야 하는데, 이걸 알아내는 과정이 조금 골때린다.

 

먼저 다음처럼 채팅창에서 아무 메시니나 적은다음

그담에 귀찮게도 브라우저에서 다음주소로 접속하면

https://api.telegram.org/bot{Token}/getUpdates

다음처럼 chat_id가 포함된 텍스트를 볼 수 있다.

{"ok":true,"result":[{"update_id":528577497,
"message":{"message_id":5,"from":{"id":170583240,"is_bot":false,"first_name":"\uc138","last_name":"\ube44\ud2f0","username":"sevity","language_code":"ko"},"chat":{"id":170583240,"first_name":"\uc138","last_name":"\ube44\ud2f0","username":"sevity","type":"private"},"date":1624032696,"text":"a"}}]}

위에서 "id"라고 된 부분이 chat_id가 되겠다.

이제 토큰과 chat_id가 있으면 텔레그램에서 메시지를 보낼 수 있다.

 

나중에 token을 까먹었을때는 botfather와 채팅창을 다시 열어서 예전 기록을 보면 token기록이 남아 있는걸 볼 수 있다.

chat_id는 원래와 동일한 방법으로 복원가능하다.

반응형

'utility' 카테고리의 다른 글

최고의 윈도우용 영어사전 LINGOES  (1) 2017.11.14

TLS와 SSL(Secure Socket Layer)의 차이는 무엇일까?

둘 다 웹서버와 사용자의 웹브라우저간 통신을 암호화 하는데 사용되는 프로토콜.

(또는 꼭 웹이 아니더라도 HTTP를 사용하는 OAuth등에서도 마찬가지)

HTTP상에서 동작하므로 TCP/IP네트워크를 사용하는 통신에 적용, 전송계층 종단간 보안과 데이터 무결성 확보

 

공개키와 개인키를 교환하여(?) 보안 세션을 생성하여 통신을 암호화 하는 방식을 사용

클라이언트 서버간 초반 handshaking의 대략적인 흐름

1. 클라이언트가 서버에 접속한 후 가능한 TLS버전등을 보낸다.
2. 서버에서는 인증서를 보낸다.
3. 클라이언트에서 서버인증서를 검증하고 신뢰한다면 client의 session key를 생성하여 서버로 부터 받은 공개키로 암호화 하여 보낸다.
4. 서버에서는 해당 암호문을 개인키로 복호하여 session key를 확보(이를 이후 통신에 사용)
5. 이제 서버와 클라이언트는 동일한 session key를 가지게 되었으므로, 이를 사용해 대칭키 암호를 사용하는 통신을 수행

TLS는 MAC함수 생성(?)을 위해 다른 암호화 알고리즘을 사용하며, 이는 이전 버전의 SSL보다 많은 경고코드(?)를 포함하고 있다.

 

SSL이 먼저 세상에 나왔다.

Netscpae에서 개발

 

TLS는 그 다음

SSL 3.0을 기초로 해서 IETF(?)가 만든 프로토콜로 이는 SSL3.0을 보다 안전하고, 스펙을 더 정확하게 하는 목적으로 고안

 

DV, OV, EV

SSL인증서는 인증기관(CA)의 심사 수준에 따라 DV, OV, EV로 구분됨

DV: Domain Validation

도메인 소유권 심사를 통해 발급되는 가장 쉽고 빠른 SSL인증서

도메인만 확인해주기 때문에 회사 확인은 일체 되지 않음

DV인증서는 고객의 신뢰도가 높지 않기 때문에, 민감한 정보를 다루는 사이트에는 적합하지 않음

OV: Organization Validation

도메인 소유권 심사에 추가로 비지니스 적법성 검증까지 하고 발급되는 인증서

검증된 회사정보는 인증서에 표시되며, 사이트의 소유권을 확인할 수 있음

여기서의 시리얼번호는 보통 사업자등록번호

EV: Extended Validation

DV, OV보다 까다로운 검증을 통해 기업의 실존성을 강화한 인증서

EV인증서는 브라우저에서 도메인 소유회사의 이름이 표시되며, Green Address Bar를 통해 안전한 사이트임을 확인

mTLS

Mutual TLS의 약자이며, 단순히 서버의 인증서만 검증하는 것에서 추가적으로 클라이언트의 인증서도 검증하는 것

https://en.wikipedia.org/wiki/Mutual_authentication

 

Mutual authentication - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search Two parties authenticating each other at the same time Mutual authentication or two-way authentication (not to be confused with two-factor authentication) refers to two parties authent

en.wikipedia.org

 

인증서 파일형식

PEM(Privacy Enhanced Mail)방식

확장자: .pem

X.509 v3 파일의 한 형태, Base64로 인코딩된 ASCII text file 방식

원래는 secure email에 사용되는 인코딩 포맷이었는데, 더이상 email쪽에는 잘 쓰이지 않음

 

der, crt등 나머지 확장자 방식은 여기 참조

 

 

반응형

'재무 금융' 카테고리의 다른 글

Direct Indexing  (0) 2022.05.04
금리와 채권의 관계  (0) 2022.04.08
오픈뱅킹 정보제공자 인증관련  (0) 2021.05.31
마이데이터 관점에서 본 OAuth2.0  (0) 2020.09.23
공인인증서와 전자서명  (0) 2020.07.30

 

오픈뱅킹은 정보제공자와 이용기관 사이에 금결원 오픈뱅킹센터를 단일로 두고 운영한다.

 

OAuth2.0을 사용하며, 인증방식은 네 가지 유형중 Client Credentials Grant 방식을 사용하여 정보제공자에게 자원에 대한 접근 권한을 부여 받음. 네가지 유형에 대한 정보는 여기 참조

 

정보제공자는 인증에 필요한 인증정보(Client ID, Client Secret)를 발급하여 센터에 전달해야함

이때 전달방법은 이메일등으로 1회성으로 하는 것 같다(확인 필요)

 

센터와 정보제공자 간에는 2-legged 토큰만 사용하는 듯(확인 필요)

 

토큰발급

센터는 정보제공자에서 발급한 인증정보(Client ID, Client Secret)를 사용하여 해당 정보제공자에 대한 Access Token을 발급 받는다.

정보제공자 입장에서는 django-oauth등의 패키지를 사용하면 자동으로 인증정보를 발급할 수 있다.

 

 

통신채널 암호화

인터넷망을 통한 송수신자간 안전한 통신을 위하여 TLS기반 상호인증 및 전송구간 암호화를 사용

공인된 CA기관으로 부터 발급받은 OV(Organization Validation)등급 이상 TLS인증서 사용

TLS 1.3버전 이상 적용

정보제공자는 오픈뱅킹센터의 접속정보(TLS인증서의 serial number, IP등)을 관리하여 접근통제 수행

오픈뱅킹센터는 EV등급의 TLS인증서를 송신하며, 정보제공자는 인증서 내 serial number를 검증 완료후 업무 처리를 진행해야함

(상기 문구는 보통 서버인증서만 사용하는 TLS케이스와 다르게 상호 인증을 해야한다는 이야기 같음(확인필요))

 

 

반응형

'재무 금융' 카테고리의 다른 글

금리와 채권의 관계  (0) 2022.04.08
TLS(Transport Layer Security)  (0) 2021.05.31
마이데이터 관점에서 본 OAuth2.0  (0) 2020.09.23
공인인증서와 전자서명  (0) 2020.07.30
배당금과 수정주가  (0) 2019.01.28

vim -d a.cpp b.cpp 하면 기본적으로 diff모드로 두 파일을 열어준다.

 

]c 또는 [c로 다음, 이전 변경사항으로 커서를 이동한다.

 

zr로 묶인 부분을 풀어준다.

반응형

'Programming > Linux' 카테고리의 다른 글

하둡(Hadoop)  (0) 2023.07.29
Docker 설치, 초기설정, 명령어가이드  (0) 2023.07.17
X Window System(X11) - 여러 호스트에서 ssh로 붙어서 사용하기  (0) 2021.01.08
Ansible  (1) 2020.10.22
tmux and byobu  (0) 2020.09.21

ssh를 통해서 tkinter 프로그램을 돌리느라 x11을 사용하게 되었는데, 

여러군데서 ssh를 접속하는 경우 DISPLAY문제로 원하는 호스트 쪽에서 제대로 app이 뜨지 않는 문제(hang)가 발견돼서 며칠고생했다.


해결한 방법은 결국 x11 커맨드라기 보다는,

w 명령어를 통해 다음과 같이 접속한 ssh세션을 나열하고, pkill -9 -t pts/0 이런 명령어를 통해 원치 않는 호스트쪽 세션을 정리하는 거였다.


여기참조함

반응형

'Programming > Linux' 카테고리의 다른 글

Docker 설치, 초기설정, 명령어가이드  (0) 2023.07.17
vimdiff  (0) 2021.04.07
Ansible  (1) 2020.10.22
tmux and byobu  (0) 2020.09.21
vim  (0) 2020.09.20

개인적으로 python으로 GUI프로그램을 하나 작성할일이 생겨서, 여기에 그 과정을 기록해본다.

 

여기를 참고해서 파이선에 기본적으로 딸려 나온다는 Tkinter를 사용해보기로 결정했다.

처음 tutorial은 여기를 참고했는데, 기본적으로 딸려 나오는 모듈이라그런지 사용도 무척 쉬웠다.

만약 리눅스에 ssh로 접속하고 있다면 x-server를 사용해야하는데,

나의 경우 라즈베리파이에 깔린 라즈비안에 윈도우에서 MobaXTerm으로 접속하는데, 메뉴에서 Start X-Server만 해주면 바로 동작했다.

(집과 회사등 여러군데에서 ssh로 접속하는 경우는 실행할때 충돌나면서 안되는 경우가 있었는데, 이때는 여기참조해서 터미널(?) 하나를 죽여주면 잘 동작함을 확인)

 

한글로 레이블을 만들면 텍스트가 깨져보이는데, 이게 생각보다 고치기 쉽지 않네 ㅠ 검색도 잘 안되고.. 일단 그냥 영어버전으로 만들기로 하고(...) 넘어감

String으로 된 radiobutton 컨트롤의 경우 위링크에서 추가적으로 여기를 참조해야 초기값 세팅이 가능했다.

위젯간 align을 위해서 grid()를 사용하거나 pack()을 사용하거나 place()를 사용하는거 같은데, 나는 단순하게 하기 위해서 grid()를 사용했다(위의 tutorial에서 소개한 방법이기도 하고).. 섞어 쓰기 보다는 하나만 선택해서 써야하는 것 같은 인상을 받았다.

그런데 grid()의 경우 columnspan을 사용하거나, Frame()으로 그룹핑해주지 않으면 가상의 테이블 때문에 내가 원하는대로 배치가 되지 않는 현상이 있었다. 위짓간 align을 위해서는 sticky라는 키워드를 사용해야했는데, 좀 거지 같은 설계인것 같다.

 

 

 

 

반응형

'Programming > Python' 카테고리의 다른 글

mypy / pytype  (1) 2023.10.07
python 한글 스트링 인코딩 핸들링  (0) 2021.11.30
파이선환경 그리고 requirements.txt  (0) 2020.09.20
Google Colab(Colaboratory Lab) 팁  (0) 2019.03.07
python array (indexing and slicing)  (0) 2019.02.28

여기 참조

 

왜사용?

하나의 서버에서 다른 서버들을 원격으로 관리하면서, 배포같은 작업을 수행하고자 할 때 편함

ansible 내부적으로 원격으로 다른 서버를 조작하는데는 ssh가 쓰임

ansible설치는 하나의 서버에만 하면됨. (조작을 당하는 서버에는 ansible설치 필요 없음)

python으로 만들어진듯

 

할수 있는 일

설치 yum, apt-get, ...

다운로드 git, get_url, ...

실행 shell, task, ...

 

 

설치

centos기준  $sudo yum install ansible

 

host설정

원격으로 관리할 서버들을 지정해준다.

sudo vi /etc/ansible/hosts를 열어서 열거해주면 된다. 그룹도 지원.

예를들면 다음과 같이 써준다.

1
2
3
[myhome]
127.0.0.1
 
cs

 

host별로 ssh-key복사해주기

여기보고 따라하면 된다.

$ ssh-keygen -t rsa -C "userid@127.0.0.1" 이걸로 ssh-key만들어주고

$ ssh-copy-id userid@127.0.0.1 이걸로 host마다 복사해주면됨

 

ping날려보기

host설정이 잘된지 확인하기 위해 다음 명령어를 날려볼 수 있다.

$ ansible myhome -m ping

전반적인 single line, adhoc command에 대해서는 여기 참조 < 강추.. 하나씩 따라해보자

 

playbook사용해서 여러줄 동시에 실행하기

여기, 여기, 여기 참조 < 이것도 두번째 링크 강추 

 

 

 

playbook은 yaml 문법을 사용하고, jinja문법으로 분기등 약간의 프로그래밍이 가능하다, 

 

로깅

/etc/ansible/ansible.cfg에 log_path를 정해준대로 로깅이 된다.

 

 

task만으로도 playbook을 돌릴 수 있는데, role이 별도로 필요한 이유는 뭘까?

jenkins와의 차이점은 뭐지?

 

 

Agentless automation tool?

Ansible does not add a database, and there will be no daemons to start or keep running.

 

play book을 yaml을 사용해서 기술

반응형

'Programming > Linux' 카테고리의 다른 글

vimdiff  (0) 2021.04.07
X Window System(X11) - 여러 호스트에서 ssh로 붙어서 사용하기  (0) 2021.01.08
tmux and byobu  (0) 2020.09.21
vim  (0) 2020.09.20
리눅스 퍼미션 개념(파일 권한 관련)  (0) 2020.04.10

여기, 여기, 여기 참조


OAuth란

접근 위임을 위한 개방형 표준, HTTPS사용

resource owner, client, resource server, authorization server 이렇게 내가지 역할이 있는데,

마이데이터로 보면 정보주체, 마이데이터사업자, 정보제공자 자원서버/인증서버 이렇게 매칭된다고 볼 수 있음(마지막 2가지는 합쳐서 볼수도 있음)


정보주체의 권한을 마이데이터 사업자에게 위임 하는데 있어서, 비밀번호를 직접주면 위험하니, 접근토큰을 발급하는 방식을 사용 

 


Client Registration

실제 프로토콜이 진행되기전에 사전단계로, 정보제공자 인증서버에 마이데이터 사업자정보를 등록하고 client_id, secret을 발급받는 절차가 있음

OAuth 스펙에서는 구체적인 방법을 제한하지는 않는데, 보통 웹에서 수기로 등록하는 경우도 많음

(마이데이터는 종합포털에서 등록절차를 대행해주는 방식을 사용하며 역시나 OAuth스펙에 위반되지 않음)

client_id, client_secret

Client등록 과정에서 마이데이터 사업자가 정보제공자 서버에 로그인하기위한 id/pwd 개념이라고 보면 됨

또는 코인에서 api_key와 secret_key개념으로 봐도 좋다.

차이점은 일반 id/pwd는 모두 유저가 만들지만 여기서는 모두 정보제공자서버에서 만들어서 발급한다는 점


client_id: 정보제공자인증서버에서 발행하는 unique string. 공개되는 정보라 client인증에 사용되어서는 안됨



Grant types

OAuth2에서는 다음 4가지 grant type을 제공하는데, 

  • Authorization Code Grant
  • Implicit Grant
  • Resource Owner Password Credentials Grant
  • Client Credentials Grant
마이데이터에서는 Authorization Code Grant만 고정적으로 사용


Authorization Code Grant Flow




반응형

+ Recent posts