비트코인의 최신 기술 동향을 따라잡고 싶다면 트위터에서 브라이언 비숍(https://twitter.com/kanzure)을 팔로우 하기를 권합니다. 비트코인 기술에 대한 발표 영상이나 팟캐스트를 실시간으로 받아쓰기 해서 텍스트의 형태로 접할 수 있게 해주는 고마운 분입니다. 긴 영상을 하염없이 듣고있을 필요가 없다는게 저에게 접근성을 한껏 높여주네요.
남의 발표 내용이 아니라 브라이언이 직접 발표한 좋은 개념 정리가 있어서 소개해봅니다.
포크, 리오그, 리플레이 프로텍션 개념 정리 입니다.
http://diyhpl.us/wiki/transcripts/scalingbitcoin/tokyo-2018/edgedevplusplus/reorgs/
컨펌
비트코인 트랜잭션은 컨펌이라는 과정을 겪습니다. 트랜잭션이 블록체인에 포함되어 들어가는 것입니다. 여러번 컨펌을 받아서 블록체인에 깊이 묻힐수록 트랜잭션은 확실하게 굳어졌다고 할 수 있습니다. 0컨펌에서 받았다고 간주하는 것은 위험합니다. 기다려서 컨펌을 받아야 확실해집니다. 특이한 케이스로, 라이트닝 네트워크에서는 0컨펌에 완료됩니다.
몇 컨펌이 나야 확실해지는지 확률계산은 비트코인 화이트페이퍼 섹션11에 나와있습니다. 보통 6컨펌이면 확실하다는 인식이 널리 퍼져있습니다. 그 이후에는 완전히 확정되어 되돌릴 수 없다는 생각이지만, 만약에 커뮤니티 전반에 걸친 여론이 받쳐준다면 6컨펌 넘은 트랜잭션도 삭제될 수 있습니다. 만약 그런일이 있다면 일종의 대격변이긴 할겁니다.
컨펌이 없다면 더블스펜딩이 가능해지고 그러면 화폐의 자격과 의미가 약해집니다. 지불하고 나면 지불된 채로 있어야 하며 그걸 다른 곳에 사용할 수 있어선 안됩니다. 또한 그 기록이 남아야 합니다.
비트코인 화이트페이퍼 섹션11에 보면 공격자가 비트코인 네트워크에 맞서서 이길 수 있는 확률을 계산한 부분이 있습니다. 다른 채굴자들과 경쟁해서 이길 만큼의 충분한 에너지를 소모해서 블록생성을 몇번 해내면, 준비해둔 트랜잭션 세트를 임의로 포함시키거나 배제시키거나 할 수 있습니다. 그렇게 해서 트랜잭션 검열을 해볼 수도 있고 소비한 코인을 되가져와서 더블 스펜딩 어택을 시도할 수 있습니다.
https://people.xiph.org/~greg/attack_success.html
링크에서 시뮬레이션을 돌려보면, 공격자가 40%의 해쉬파워를 가지고 6컨펌 받은 블록을 노릴 때, 50% 의 확률로 블록을 공격자가 준비한 블록으로 바꿔넣을 수 있습니다.
리오그
블록체인에서 최근 몇개의 연속된 블록이 변경되어 버린다면 리오그가 발생한 겁니다.
그림에서 까만 블록들이 베스트 체인인데 최근(가장 오른쪽 부분)에 보라색 블록이 두개까지 생성되었다가 까만 블록이 하나 더 생기면서 더 많은 Proof Of Work 이 쌓였고 결국 비트코인 블록체인의 규칙에 더 부합하는 체인으로 판단되어 리오그가 발생합니다. 잘못된 갈래의 블록들이 컨펌을 한두개 받았음에도 삭제됩니다.
가장 흔한 리오그는 네트워크 연결 속도로 인해 의도치 않은 orphan 이 나는 상황입니다. 때로는 나쁜 의도를 가진 공격자가 이런 상황을 재현하며 해쉬레이트를 사거나 빌려서 준비해둔 블록들을 집어넣는 경우도 있으니 비트코인 입출금을 처리하는 사업자라면 알아둬야 합니다.
리오그 대처
가장 쉬운 방법은 대충 200블록쯤 지나면 리오그로부터 안전하다고 볼 수 있으니 200컨펌을 기다려서 처리하는 겁니다. 근데 그러면 고객들이 싫어하겠죠. 그러니 그보다 빠르게 처리하되 리오그에 대한 대비를 구현해두는게 낫습니다.
먼저, 현재 최선의 체인으로 보이는 블록체인과 로컬 풀노드에서 만들어진 블록이 다른것을 모두 찾아 나열합니다.
그중에서 로컬체인에서의 트랜잭션이 베스트체인에서는 사라졌거나 달라진것을 추려냈다가 리오그 발생시에 달라진 내용을 적용해야 합니다. 이미 컨펌이 났던 트랜잭션을 추후에 올바른 체인에 맞춰서 수정해야 하는 겁니다. 노드를 블록체인에 동기화 시킨다고 생각하면 좀더 이해가 쉽습니다. 과장해서 6개월간 노드를 오프라인으로 돌리다가 블록체인에 동기화를 시작한다면 지난 6개월간의 블록을 따라잡아야 하는 겁니다.
거래소에서 알트코인에 51% 어택이 있을 경우에 입금처리를 해줘 버리면 사용자가 다른 코인으로 거래해서 출금해 가버리는 수가 있습니다. 그 51% 어택이 있었던 코인은 리오그 발생하면서 입금자의 지갑으로 되돌아가 버립니다. 이런 출금 공격을 여러번 반복하다보면 거래소 지갑엔 잔액이 부족해집니다.
이런 사태를 막기위해 거래소에서는 테인팅(tainting) 이라는 기법을 사용할 수 있습니다.
일단 입금받은 코인은 모두 taint 시켜둡니다. 입금받은 주소에서 출금시켜주는 주소로 전송하면 출금주소의 코인 출처가 직접적으로 연관 되면서 taint 됩니다.
혹시 리오그나 해쉬레이트 공격이 있을 시에 입금받은 코인과 출금해줄 코인이 taint 되어 있으면 입금받은 트랜잭션이 사라졌으므로 출금도 자동으로 막히게 됩니다.
소프트포크와 하드포크
포크는 비트코인 블록체인에서 다른 규칙을 가진 지갑 버젼이 돌아갈 때 발생합니다. 소프트포크는 이전 버젼과 서로 호환이 되는 컨센서스 규칙입니다. 그래서 소프트포크에서는 기존 버전의 노드들이 볼 때, 소프트포크 코드가 들어간 새버전의 노드가 만들어내는 데이터가 여전히 유효합니다. 그러나 소프트포크의 새로운 규칙은 기존 규칙의 일부만 허용하도록 제한을 겁니다. 새로운 규칙에 동의하는 노드가 늘어나면서 점점 더 새로운 규칙이 부드럽게 안착시키고 싶을 때 유용합니다.
하드포크는 꽤나 단순한 방법으로, 이전 버전의 규칙과 호환이 안되고 서로 잘못된 규칙이라고 거절하도록 하는 포크입니다.
하드포크도 소프트포크도 둘다 리오그를 염두에 둬야 합니다. 비트코인 네트워크에 새 버젼의 소프트웨어를 배포해서 돌리도록 할 때, 새 버젼으로 업데이트를 하지 않는 노드들과 채굴자들이 있다는 것을 고려해야만 합니다. 그래서 리오그가 여러번 발생하면서 롤백을 거듭하고 데이터가 이리저리 왔다갔다 할 수도 있습니다. 포크를 설계할 때 알고 있어야 할 내용입니다. 예를 들어 허접하게 설계한 포크가 발생하면 리오그 때문에 한번 있어야 할 포크가 여러번 일어날 수도 있습니다. 컨센서스 변경으로 발생할 모든 시나리오를 다 대비해두지 않았다면 포크는 계획보다 더 여러 갈래로 일어날 수 있습니다.
리플레이 프로텍션
포크 관련해서 리플레이 프로텍션 얘기를 빼놓을 수 없습니다. 포크가 체인 분리로 이어지면 기업들과 지갑들은 허겁지겁 대처하지 않을 수 없습니다.
포크가 나서 비트코인2 라는게 생겨나면 비트코인 노드는 비트코인2의 블록을 거절하고 비트코인2 노드는 비트코인 블록을 거절합니다. 이 때 리플레이 프로텍션이 되어있지 않다면 한 체인에서 트랜잭션을 보냈을 때 다른 체인에서도 리플레이가 발생하며 그 트랜잭션이 전송되어 버립니다. 예를 들어 거래소에 비트코인2를 입금시키려고 보냈더니 보내기 싫은 내 비트코인도 자동으로 보내져 버리고 거래소에선 둘중에 하나만 입금처리 해주는 혼란이 발생할 수가 있습니다.
최선의 방법은, 포크 이후에 채굴된 물량의 코인을 전송하면 다른 체인에 그게 없으므로 리플레이가 발생하지 않습니다. 오직 해당 체인에서만 그 트랜잭션이 실행됩니다.
또는, 포크 이후에 채굴된 코인과 포크 이전 코인을 섞어서(taint) 사용합니다. 포크 이후에 새로 채굴된 물량은 귀하기 때문에 구하기가 쉽지 않아 보통 테인팅 기법으로 리플레이에 대처합니다.
저는 비트코인 문외한이지만 고맙습니다~^^
리오그가 궁금했는데 덕분에 조금 이해가 되었네요. 좋은 글 소개해 주셔서 감사합니다.
모닝님 오랜만의 좋은 포스팅 반가워요~.
포스팅으로 좀 더 자주 뵈었으면 좋겠네요.^^
네 감사합니다... 이제 좀더 자주 활동예쩡입니다
오타인지
아니면 애교를 섞은건지
잘 모르겠지만 재미있네요 ㅋ
눈도침침 손가락 관절도 예전같지않고............ 오타입니다
ㅜㅜ
테인팅이 헷갈리는데 앞서 말한 과정을 통틀어서 테인팅이라고 부르나요, 아니면 따로 테인팅이라는 과정이 있는건가요?
어떤 주소가 코인을 가지고 있으면 그 코인은 반드시 출처가 있죠. 그 출처를 섞는 것이 테인팅입니다.
저는 비트코인에 관심이 거의 없어서
(아예 없는건 아니고..)
추천해주신건 찾아가지 않겠지만
님께서 오랜만에 올려주신 글을 보니
참 반갑네요
Hey there @morning!
I was trying to make a simple interface for an application idea I have for Steemit. In relation to this I came across your steemeasy plugin. The publishing part of the plugin seems to not work, but the feed part and everything works fine... Do you know if I am doing something wrong? Is there any way I can get the publish part to work?
I just update plugin bugfix. out-dated SteemConnect was the reason for bug.
Thanks for that @morning, will check out the update asap! :)