노드 : p2p 네트워크를 구성하는 하나의 소프트웨어 (호스트) 를 말한다. 모든 노드는 동등하다.
비트코인의 정신이 탈 중앙화이기 때문에 특정 노드에게 더 권한을 준다거나 하는 것이 없다.
p2p 네트워크는 TCP를 기반으로 만들어진다.
그리고 이 네트워크에는 새로운 노드가 언제든 참여하고 떠날 수 있다.
노드로 참여할 때는 특정 사이트에서 비트코인을 돌리고 싶은 데 내 이웃 노드가 되어달라고 요청하고, 요청이 수락되면 연결을 짓는 식으로 네트워크에 참여하게 된다. (요청 보내는 대상 노드를 가리켜 시드 노드라고 한다.)
노드의 행동
각 노드의 행동 방식을 보기에 앞서 앨리스가 밥에게 비트코인을 보내는 트랜잭션을 만들었다고 해보자.
그러면 이 트랜잭션은 전체 비트코인 네트워크에 퍼져야만 한다.
앨리스는 월렛 프로그램의 도움으로 밥에게 비트코인을 보내고, 남은 잔액을 자신의 계좌로 보내고, 적절한 수수료를 책정하는 트랜잭션을 생성한 뒤, 비트코인 네트워크 전체에 뿌린다.
그러면 이 트랜잭션을 수신한 노드는 이 트랜잭션이 유효한지 (UTXO에서 끌어다 쓴 게 맞는지, lock time 은 잘 지켰는지, 스크립트가 실행 가능한지 = 비트코인에서 사용하는 방식의 스크립트인지 등) 검증한다.
또 이 트랜잭션이 내가 이미 본 트랜잭션인지도 확인한다. P2P 네트워크라서 내가 이미 본 트랜잭션을 다른 경로를 통해 또 받을 수 있다.
이럴 때는 중복으로 받은 트랜잭션을 무시한다.
그리고 이런 검증이 모두 끝났다면 이 트랜잭션을 풀에 넣는다.
트랜잭션 풀에는 블록에 들어갈 수 있는 대상 트랜잭션들이 저장되어 있다.
만약 내가 받은 트랜잭션이 이미 나의 풀에 들어있는 트랜잭션이라면 그 트랜잭션은 브로드캐스트 하지 않는다.
반면 나의 풀에 없는 트랜잭션이라면 풀에 추가하고 브로드캐스트까지 한다.
그런데 각각의 노드마다 트랜잭션을 수신하는 타이밍도 종류도 다를 수 있기 때문에
어떤 특정 시점에서 스냅샷을 찍으면 각 노드의 pool 은 조금씩 다를 수 있다.
이때 경쟁 상태가 발생할 수도 있다.
앨리스가 자신이 가진 같은 코인을 찰리에게 지불하는 트랜잭션과 밥에게 지불하는 트랜잭션을 생성해서 둘 다 뿌렸다고 해보자.
이때 블록 안에는 둘 중 하나의 트랜잭션만 유효한 것으로 간주되어 들어갈 수 있다.
그래서 각 노드마다 어떤 트랜잭션이 유효한지 서로 다르게 판단할 수 있다.
1. 트랜잭션의 도착 시점이 서로 달라서 내가 포함시킨 트랜잭션이 다른 노드의 블록에는 포함되지 않았을 수 있고
2. 하나의 주소에서 서로 다른 곳으로 나가는 트랜잭션 2개에 대해 맞다고 인정하는 트랜잭션이 다를 수 있다.
그래서 블록에 들어가는 트랜잭션은 다를 수 있고, 경쟁 상태에 대해서는 둘 다 서로 다른 블록으로 채굴이 되었다고 해도 두 트랜잭션이 모두 승인될 수는 없기 때문에 둘 중에 한가지 브랜치 블락이 길게 늘어나는 순간 그 블록에 있는 트랜잭션이 유효한 것으로 판정된다.
따라서 단기간에는 의견 불일치가 발생하더라도 장기적으로 보면 의견이 일치할 것이다.
그리고 만약 노드의 pool 에 들어있는 트랜잭션이 채굴이 되었다면 그 트랜잭션을 pool 에서 제거하고,
내가 찰리를 밀고 있었는데, 밥으로 보내는 트랜잭션이 채굴되어 길게 이어진다면, 찰리 역시 pool 에서 제거할 것이다.
블록을 생성할 때도 비슷한 상황이 발생한다.
내가 이미 하나의 100번 블록에 이어붙이는 101번 블록을 만들고 있었는데, 다른 100번 블록이 만들어졌다고 소식이 들려오면, 나는 굳이 그 블록 뒤에 다시 이어서 붙일 필요가 없다. 이미 기존 블록에 대해 이어붙이려고 해시 퍼즐을 풀고 있었는데, 새로운 블록으로 넘어가서 지금까지 연산했던 시간을 버릴 필요는 없기 때문이다.
또한 채굴하는 과정에서는 이전 블록을 검증하는 과정도 거친다.
먼저 블록 헤더를 보고 그 헤더의 값이 채굴 당시 타겟 넘버보다 작은지 검증하고, 그 블록에 포함된 트랜잭션들이 유효한지도 검증한다.
그림으로 보면 위와 같이 블록이 구성되어있다.
위 그림은 블록의 구조와 블록 헤더의 구조를 나타낸다.
블록에는 블록 크기, 블록 헤더, 트랜잭션 수, 각 트랜잭션 정보가 들어있고
블록 헤더에는 버전, 이전 블록 해시, 머클 트리 루트, 블록 생성 시간, 채굴 당시 난이도, 채굴에 성공했던 난스값이 들어있다.
블록을 특정할 때는 해시를 이용해서 특정하거나, 높이를 이용해서 특정할 수 있다.
블록 해시는 블록 헤더를 sha 256 알고리즘으로 두 번 해싱한 결과이다.
머클 트리 역시 2번 해시해서 구한다.
리프 노드에서부터 해시값을 차례대로 올려서 합치고 해시하는 과정을 반복하여 구한다.
만약 특정 트랜잭션이 이 머클트리에 제대로 들어있는지 확인하고 싶을 때는 다음과 같이 확인할 수 있다.
Hk를 확인한다면 파란색으로 칠해진 이미 계산된 해시값들을 이용해서 점선으로 표시한 블록의 해시값을 계산한다.
최종적으로 root 노드의 해시값이 내가 계산한 값과 같다면 Hk 가 들어있음을 확인할 수 있다.
(그러면 머클 트리 중간에 있는 계산값도 다 저장을 하는건가?)
Mining
채굴은 한마디로 비트코인 네트워크에서 일어나는 모든 거래 (트랜잭션) 에 대한 검증과정 (정산) 과 같다.
'CS > 블록체인' 카테고리의 다른 글
[블록체인] 12. 비트코인 script (2) (3) | 2024.10.25 |
---|---|
[블록체인] 12. 비트코인 script (1) (0) | 2024.10.25 |
[블록체인] 11. 비트코인 트랜잭션 (1) | 2024.10.25 |
[블록체인] 10. 비트코인이 해결하는 문제들 (1) | 2024.10.25 |
[블록체인] 9. 암호학 개념들 (0) | 2024.10.24 |