김선태
알쓸신블
Published in
9 min readAug 26, 2018

--

알쓸신블_1_블록체인 채굴 노드와 일반 노드의 차이점은 무엇일까?

알아두면 쓸모있는 신나는 블록체인 이야기

선 답안

채굴 노드와 일반 노드의 차이점

일반 노드와 채굴 노드는 트랜잭션을 수신하면 정상 여부를 판단(검증)하여 정상적이라면 네트워크에 전파하고, 그렇지 않다면 삭제하는것이 기본이다.

-> 네트워크 전체에 Ddos 공격이 가해지는것을 막기 위한 검증이다.

채굴 노드는 거기에 더하여 검증된 트랜잭션을 transaction pool에 담고, 채굴을 통해 블록에 포함하여 네트워크에 전파한다. 물론 일반 노드의 역할(트랜잭션 혹은 블록의 수신과 검증 및 전파)도 수행한다.

-> 잘못된 트랜잭션을 블록에 포함하여 배포하는 경우, 노드들이 블록을 수신하지 않아 채굴 보상을 받지 못하게 됨으로 그런 일이 일어나지 않도록하는 검증이다.

후 질문

채굴 노드에도 종류가 있을 까? nonce를 찾는 노드 / transaction을 검증하고, transaction pool에 담는 노드?? 역할이 분담 되있을까? 선택할 수 있는가?

BAAM 소속 알쓸신블 스터디팀의 질문함에 있던 질문이다.

질문자의 블록체인에 대한 이해도가 충분하지 않기 때문에, 질문 자체가 약간 혼란스러운점이 있다. 일단 질문을 분리하고 정리하는 1차적인 소화를 해보겠다.

정리

채굴 노드에도 종류가 있을까?

우선, 채굴 노드의 ‘종류’의 정의를 어떻게 하느냐에 따라 달라질것같다. 기본적으로 채굴이란건 적합한 nonce를 찾아 블록을 생성하여 네트워크에 전파하는것이다. 모든 채굴 노드는 블록 생성 보상이라는 ‘동일한 목적’을 가지고 nonce 채굴이라는 ‘동일한 행위’를 한다.

종류의 정의를 목적과 행위로 정리한다면, 채굴 노드에는 종류가 없다고 할 수 있다. 하지만 더 효율적인 채굴을 위해서 더 나은 알고리즘을 사용하여 채굴 소프트웨어를 만든다던지, 가벼운 운영체제나 하드웨어와의 호환성이 최적화된 운영체제를 사용한다던지, CPU/GPU/ASIC등으로 채굴한다던지 같은 소프트웨어/하드웨어 상의 차이점을 ‘종류’로 정의한다면, 종류는 아주 많아질 수 있다.

내 생각엔 채굴 노드 종류의 분류를 행위나 목적이 아닌 ‘소프트웨어 종류 및 버젼’으로 나누는게 좋다고 생각한다. 비트코인이나 이더리움이나 보통의 경우 프로토콜 사양이 버전업 되며 바뀌는 경우가 생기고, 그렇기 때문에 비트코인은 처음 피어를 맺을 때 노드 프로토콜 버전을 주고 받는다. 이는 이오스나 여타 블록체인도 마찬가지이다. 네트워크상의 합의를 단일화하기 위해선 연결된 모든 노드가 정해진 프로토콜에 맞춰 움직여야하기 때문에, 노드의 종류가 중요하다고 볼 수 있다.

nonce를 찾는 노드, Transaction을 검증하여 pool에 담는 노드의 역할이 분담되어 있고, 선택할 수 있을까?

nonce를 찾는다는건 채굴을 의미한다. ‘채굴을 한다’ = ‘적절한 nonce값을 찾는다’라는 명제가 성립되기 때문에. 반대로 ‘nonce를 찾는 노드는 모두 채굴 노드’라는 명제도 성립된다.

이 질문의 문제점은, 트랜잭션을 검증하는것과 채굴하는것이 실과 바늘처럼 따라 다니는 일련의 행위 집합이고 트랜잭션을 검증하는것이 채굴 노드뿐이라고 생각한다는것이다.

일단 정답을 말하자면, 비트코인의 경우 (또는 대부분의 블록체인의 경우) 모든 노드는 트랜잭션을 검증한다. 경량화를 위해 블록체인 데이터를 가지고 있지 않아, 연결된 풀노드에만 의존해야하는 SPV노드 조차도 트랜잭션 검증을 수행한다. 다만 검증에 사용되는 데이터가 연결된 풀노드를 향하여 의존(Dependent)적일 뿐이다.

Bitcoin wiki에서 비트코인 프로토콜의 트랜잭션 검증 규칙에 어떤것이 있는지 자세하게 확인할 수 있는데, 이것은 말 그대로 규약/약속(Protocol)임으로, 이것을 지키지 않는다면 비트코인 노드로 분류할 수 없다.

비트코인 노드는 이하 20개의 트랜잭션 검증을 모두 수행하면서 커스터마이징(예를 들어 특정 fee 미만은 처리하지 않는 등)을 추가하는것까지가 비트코인 노드의 약속이다.

Check syntactic correctness

Make sure neither in or out lists are empty

Size in bytes <= MAX_BLOCK_SIZE

Each output value, as well as the total, must be in legal money range

Make sure none of the inputs have hash=0, n=-1 (coinbase transactions)

Check that nLockTime <= INT_MAX[1], size in bytes >= 100[2], and sig opcount <= 2[3]

Reject “nonstandard” transactions: scriptSig doing anything other than pushing numbers on the stack, or scriptPubkey not matching the two usual forms[4]

Reject if we already have matching tx in the pool, or in a block in the main branch

For each input, if the referenced output exists in any other tx in the pool, reject this transaction.[5]

For each input, look in the main branch and the transaction pool to find the referenced output transaction. If the output transaction is missing for any input, this will be an orphan transaction. Add to the orphan transactions, if a matching transaction is not in there already.

For each input, if the referenced output transaction is coinbase (i.e. only 1 input, with hash=0, n=-1), it must have at least COINBASE_MATURITY (100) confirmations; else reject this transaction

For each input, if the referenced output does not exist (e.g. never existed or has already been spent), reject this transaction[6]

Using the referenced output transactions to get input values, check that each input value, as well as the sum, are in legal money range

Reject if the sum of input values < sum of output values

Reject if transaction fee (defined as sum of input values minus sum of output values) would be too low to get into an empty block

Verify the scriptPubKey accepts for each input; reject if any are bad

Add to transaction pool[7]

“Add to wallet if mine”

Relay transaction to peers

For each orphan transaction that uses this one as one of its inputs, run all these steps (including this one) recursively on that orphan

자 그러면 이제 틀린 부분을 바로 잡았으니, 브로드한 접근을 통해 처음부터 끝까지 개념을 다잡아보자.

트랜잭션 검증은 모든 노드가 수행한다. 왜?

블록체인 네트워크는 모든 트랜잭션을 모든 노드가 처리하기 때문에 악성 트랜잭션이 전파되면 큰 문제가 발생할 수 있다. 처리를 하지 않더라도 ‘전파’되는것 자체가 자원을 소모하는 일이다. 채굴자의 검증으로 인해 블록에 포함되지 않는다면 블록의 크기나 연산 부채를 늘리진 못하지만, 네트워크 트래픽 자원의 소모만으로도 충분히 치명적이다.

만약 채굴 노드만 검증을 수행한다고 치자. 일반 노드들은 검증을 수행하지 않고 무작정 트랜잭션을 전파한다면 어떤 문제가 발생할까?

악성 행위자가 고의로 잘못된 트랜잭션을 발생 시키는 경우, 행위자와 연결된 (최초로 트랜잭션을 수신하는 1 hop상의) 노드는 트랜잭션 크기 만큼의 네트워크 자원을 소모하고, 다시 그것을 전파하는대에 컴퓨터 자원을 소모하게 될것이다. 잘못된 트랜잭션은 또 다른 노드로 전파되고, 처리되고, 또 다시 전파되어 5초 내로 99%의 노드에 도달한다. 잘못된 트랜잭션을 ‘수신’한 일반 노드가, 잘못된 트랜잭션을 ‘전파’하는 악성 노드로 변질된다는것이다.

전체 노드가 만 개일때, 행위자는 단 하나의 트랜잭션 발생으로 만개의 노드가 잘못된 트랜잭션을 처리하게 만들 수 있다.

잘못된 트랜잭션을 전파하는 악성 노드의 수가 많아진다면, 블록체인 네트워크상에 쓰레기 트랜잭션이 너무 많아질거고, 그것을 검증하고 선정해 풀에 담아야하는 채굴 노드의 자원 소모는 더 커질것이며, 이는 블록체인 네트워크를 느리고 공격에 취약하도록 만들것이다. 이 경우 블록체인 네트워크는 절대 유지될 수 없을것이다.

두번째로, 채굴노드가 전파한 블록(에 담겨있는 트랜잭션들)을 수신한 일반 노드에서의 블록 진위 확인이 힘들다. 잘못된 트랜잭션이 포함된 블록을 노드가 수신하게 되는 경우 이 블록체인은 신뢰할 수 없다. 그렇기 때문에 모든 노드는 어차피 전파 받은 블록내에 악성 트랜잭션이 없는지 확인해야한다.

그렇다면 모든 노드가 수신한 트랜잭션을 검증하여 얻는 이득은 무엇인가?

쉽다. 이 경우 악성 행위자가 악성 트랜잭션을 수십만번 반복하여 전송하여도, 그것은 2hop 이상 전파되지 않는다. 마치 단단한 피부를 가진 한마리의 유기동물 처럼, 세균(악성 트랜잭션)이 피부 밑(2hop 이상의 노드)으로 뚫고 들어가 피를 통해 온몸(블록체인 네트워크)에 전파되는것을 막아준다.

악성 트랜잭션의 양이 감당할 수 없을만큼 큰 경우, 이것이 네트워크 전체에 전파되면 모든 노드들에 과부하가 걸릴것이다. 그러나 검증을 통해 전파하는 경우, 최초로 트랜잭션을 수신하는 1hop의 노드에만 과부하가 걸리고, 그 이상 전파되지 않기 때문에 악성 행위자의 트랜잭션은 전파되지 못하고 사라진다. 만약 프로토콜을 임의로 수정해 검증 부분을 삭제한 노드를 만든다 해도. 그 노드 또한 2hop 이상 악성 트랜잭션을 전파하지 못하기 때문에, 블록체인 네트워크는 공격으로 부터 안전할 수 있다.

--

--

김선태
알쓸신블

삶을 즐기는 사람들과 대화하는게 즐거운 사람입니다. 과거엔 화이트 해커 지금은 글 쓰고 기획 하는 개발자입니다