이 글은 Medium 채널 CryptoKnights에도 게시되어 있습니다.
Sorry, we are Unable to locate the Transaction History
얼마 전 뜨거웠던 Status ICO에 참여하셨던 분들은 다들 이런 화면을 한 번쯤, 아니 대부분 수십 번은 보셨을 겁니다.
MyEtherWallet에서는 분명히 트랜잭션이 성공적으로 생성되었다고 나오는데 왜 트랜잭션을 찾을 수 없는 걸까요? ICO에 정상적으로 참여는 된 걸까요? 심지어 각종 거래소들에서 출금한 것들도 거래소에서는 정상적으로 출금된 것으로 표시되고 Txid도 발급되었는데, 막상 etherscan.io에는 뜨지 않고 지갑에도 들어오지 않으니 점점 불안해집니다. 집 나간 이더를 영영 찾을 수 없는 것은 아닐까요?
결론부터 말하자면, etherscan에서 트랜잭션이 나오지 않는다면 그 트랜잭션은 생성되지 않은 것이 맞습니다. 보다 정확하게는 트랜잭션을 생성했지만 이더리움 네트워크에서 버려져 이더리움 블록에 트랜잭션이 기록되지 않은 것입니다. 생성되었지만 버려진 것이니 생성되지 않은 것이라고 보아도 무방하겠지요. 어쨋든 개인지갑에서 출금한 것이라면 다시 보내면 되고, 거래소에서 출금한 것이라면 거래소에 문의를 넣어 다시 보내달라고 하면 됩니다.
거래소에서 출금할 때는 Txid가 생성되면 정상적으로 출금된 것으로 간주하기 때문에 해당 트랜잭션이 버려지면 거래소에서 다시 출금처리(Rebroadcast)를 해 주어야 합니다. etherscan에 해당 Txid가 보이지 않는다면 안심하고 거래소에 문의하세요.
그렇다면 도대체 왜 이런 현상이 일어난 것일까요?
트랜잭션 홍수가 찾아오다
이더리움 트랜잭션이 생성되면 내가 연결되어 있는 동료 노드(Peer Node)들에게 해당 트랜잭션이 전송됩니다. 아직 기록되지 않은 트랜잭션들은 노드들 사이에 전파되어 채굴자(Miner) 노드에 전달됩니다. 채굴자들은 전송된 트랜잭션들을 블록에 기록하고, 트랜잭션들이 기록된 블록을 이더리움 네트워크에 전송함으로써 이더리움 블록이 생성됩니다(그리고 보상을 받습니다).
평상시라면 이더리움 블록에 트랙잭션이 기록될 공간은 넉넉합니다. 블록 생성 기록을 살펴보면 블록에 기록되는 트랜잭션의 수는 적게는 몇 개부터 많게는 100개 남짓, 심지어는 0개일 때도 있습니다. 일반적으로는 이더를 전송하면 해당 트랜잭션은 다음 혹은 다다음 블록에 기록됩니다.
하지만, ICO 시작 시간이 다가오면 상황은 전혀 달라집니다. ICO가 런칭하기 전부터 수천개의 트랜잭션이 네트워크에 흘러들어오기 시작합니다. "ICO에 참여하는 팁" 같은 글을 읽어보면 트랜잭션이 네트워크에 전파되어 기록될 때 까지의 시간을 고려하여 시작 블록의 1~2개 전에 송금하라는 내용은 빠지지 않는 내용이기도 하죠.
사실 ICO 시작 몇 블록 전에 트랜잭션을 생성하는 것은 양반입니다. 대기열 방식을 사용했던 Civic ICO를 제외하고 가장 최근에 있었던 Status ICO의 경우를 살펴보면 수 없는 공지에도 불구하고 사람들은 펀딩 주소가 사전에 공개되자마자 이더를 송금하기 시작했습니다. 덕분에 ICO 수 시간 전부터 이더리움 네트워크가 마비되기 시작했고, 거래소에서 출금해 ICO에 참여하려고 했다가 거래소에서 지갑으로 보내는 트랜잭션이 사라져서 ICO에 참여조차 하지 못하는 분들이 속출하기 시작했습니다. 엎친 데 덮친 격으로 Status ICO의 높은 펀딩 금액과 동적 상한선(Dynamic Ceiling)으로 인해 ICO는 오랫동안 진행되었고 만 하루 동안 이더리움 네트워크는 마비 상태가 되었습니다.
트랜잭션은 왜 없어졌을까?
앞에서 트랜잭션이 생성되면 동료 노드들을 통해 이더리움 네트워크로 전파되고, 채굴자 노드들이 트랜잭션을 받아서 블록에 기록한다고 설명했습니다. 채굴자 노드를 포함한 이더리움 네트워크의 노드들(이더리움 클라이언트)에는 아직 이더리움 블록에 기록되지 않은 트랜잭션들을 보관하는 대기열(이하 Tx-pool)이 있습니다. 이것을 트랜잭션 풀(transaction pool; geth
) 혹은 트랜잭션 큐(Transaction queue; parity
)라고 부릅니다(비트코인의 mempool
과 같은 개념입니다). 각 노드들은 여기에 트랜잭션을 보관하고 있다가 이더리움 블록에 트랜잭션이 기록되면 새로운 트랜잭션을 받을 수 있도록 대기열을 비우게 됩니다.
그렇다면 트랜잭션의 홍수가 일어날 때는 어떻게 될까요? 이더리움 네트워크는 이더리움 블록이 특정 시간 간격으로 생성되도록 난이도를 자동으로 조절하게 되어 있기 때문에 처리할 수 있는 트랜잭션의 수가 정해져 있습니다. 마이닝 풀에서 시간당 처리할 수 있는 트랜잭션의 수는 정해져 있는데 트랜잭션이 쏟아져 들어오니 대기열이 꽉 차버립니다. 대기열이 꽉 차면 정해진 규칙(Eviction Rule)에 따라 이후에 도착하는 트랜잭션들은 버려집니다. (트랜잭션이 버려지는 규칙이 궁금하다면 Geth 소스코드를 직접 살펴보세요)
공식 이더리움 클라이언트인 Geth 소스코드를 살펴보면 Tx-pool 설정을 저장하는 TxPoolConfig
라는 자료구조가 있습니다. 여기에 GlobalSlots
라는 변수가 대기열에 들어갈 수 있는 트랜잭션의 총 수를 결정합니다. Geth 1.6.2 버전 기준 GlobalSlots
의 기본값은 4,096
으로 설정되어 있습니다. 대기열에 쌓여있는 트랜잭션 개수가 4,096개가 넘어가면 버려지는 것입니다. ICO 기간이 되면 이 숫자는 터무니없이 적은 숫자가 됩니다.
Geth만큼 널리 쓰이는 Parity 클라이언트에도 Tx-pool 크기를 설정할 수 있는 옵션인 --tx-queue-size
가 있습니다. 버전 1.6.8 기준으로 기본값이 1,024
개 밖에 안 됩니다. 재미있게도 Parity 클라이언트에는 대기열에 쌓여 있는 트랜잭션을 볼 수 있는 D-App인 TX-Queue Viewer가 기본으로 탑재되어 있습니다. (Application 탭에서 직접 확인해 볼 수 있습니다)
이제 Tx-pool의 크기를 크게 잡아주세요
불과 한달 전에 일 평균 10만개 내외였던 트랜잭션 수가 점점 증가해 Status ICO가 있었던 지난 6월 20일에는 일 트랜잭션 수가 308,488개에 육박했습니다. 들리는 소식으로는 일부 이더리움 마이닝 풀에서 이미 Tx-pool 크기를 늘렸다고 합니다. 앞으로도 많은 ICO가 기다리고 있고, ICO는 점점 가열되고 있습니다. 이제는 정말 이더리움 네트워크 노드들이 클라이언트의 Tx-pool 크기를 늘려야 할 때입니다.
글에 잘못된 점이 있거나 보충하면 좋을 만한 내용, 혹은 글에 대한 다른 피드백 또한 언제나 환영합니다. 언제든지 댓글 혹은 이메일(bskim45@gmail.com)로 남겨주세요.
※ 글 내용 이외에 ICO에 관한 개인적인 문의는 더 이상 받지 않습니다.