Skip to content
isdnetworks
Go back

코인마다 입금 조회가 다르다

(수정됨)

입금 감시 워커에 새 토큰을 추가해야 해서 기존 분류에 넣고 돌렸더니 입금이 하나도 안 잡혔다.

Table of contents

Open Table of contents

증상 — 입금이 아예 안 잡혔다

기존 분류 집합에 새 토큰 하나를 더했다.

const ETH_LIKE_COINS = new Set([..., '<새 토큰>']);

ETH_LIKE_COINS 에 넣었더니 사용자가 보냈다는 txid 로 조회해도 이 응답이 돌아왔다.

해당 주소로 들어온 입금을 찾을 수 없습니다

값이 틀린 것이 아니라 대조 자체가 아예 안 걸리는 모양이었다.

검증 — 값을 대조했다

사용자가 준 txid 의 트랜잭션과 우리 입금 주소를 나란히 놓고 봤다.

트랜잭션의 to       0x…(토큰 컨트랙트 주소)
트랜잭션의 value    0
트랜잭션의 input    0xa9059cbb…(transfer 호출)
로그의 Transfer     _to = 0x…(우리 입금 주소), _value = 토큰 수량

우리 주소는 to 가 아니라 로그의 _to 에 있었고 수량은 value 가 아니라 _value 에 있었다.

이 토큰을 ETH_LIKE_COINS 에 넣었으니 to 와 value 로 조회한다. 컨트랙트 주소와 0 을 보고 있었으니 결과가 나올 리가 없었다.

원인 — 필드에 든 다른 값

to 에 든 컨트랙트 주소가 무슨 값인지 따로 봤다.

토큰 전송은 코인을 보내는 것이 아니라 컨트랙트의 transfer 함수를 부르는 것이라 트랜잭션의 받는 쪽은 컨트랙트이고 보내는 코인은 없다. 받는 사람과 수량은 EIP-20 명세가 정한 대로 transfer 가 반드시 발생시켜야 하는 Transfer 이벤트의 _to 와 _value 에 실린다.

to 와 value 라는 이름이 내용을 보장하지 않는다는 것이 여기서 드러났다.

to / value

to 와 value 는 받는 주소와 금액이라는 뜻인데 코인 종류에 따라 다른 것이 들어 있었다.

ETH 만 볼 때는 다 같은 의미였겠지만 토큰이 늘면서 의미가 갈렸고 트랜잭션 구조를 바꿀 수는 없으니 같은 필드가 다형적이 됐다.

판단 기준 — 패턴이 셋

기존 코인들의 분류를 다시 정리해 보니 셋으로 갈렸다.

① UTXO 계열     블록의 출력(vout)에서 우리 주소와 금액을 읽음 — BTC·LTC
② 계정 계열     트랜잭션의 to 와 value 를 읽음 — ETH
③ 토큰          컨트랙트 로그의 Transfer 이벤트 _to 와 _value 를 읽음 — ERC20

새 토큰은 ③ 토큰 이었고 그 계열은 이벤트 하나가 입금 하나를 가리키는 1:1이다.

1:1 이라 그 뒤의 계산 쪽은 그대로 쓸 수 있었다. 블록 높이로 confirmations 를 세고 잔액에 반영하는 부분은 ETH 와 같고 조회 방법만 다른 것이다.

조치 — 고칠 데가 넷

분류를 정하고 나니 실제로 고쳐야 할 자리가 넷이었다.

① 집합에 추가 (TOKEN_COINS)
② 분류 분기
③ 전용 조회 구조 (eth_getLogs 에 컨트랙트 주소·Transfer 토픽 필터)
④ 전용 파싱 (_value 를 토큰의 decimals 로 나눔)

처음에 내가 한 것은 ETH_LIKE_COINS 에 넣은 것뿐이었다.

집합에만 넣으면 분기가 여전히 옛 경로를 타고 내려간다. 넷 중 하나라도 빠지면 어딘가에서 조용히 안 되는 상태가 된다. decimals 를 빠뜨리면 조회는 되는데 수량이 10의 몇 제곱 배로 틀리는 더 나쁜 상태가 된다.

재발 방지 — 신규 코인 절차

이 뒤로 신규 코인을 붙일 때의 절차를 적어 두었다.

1. 그 코인의 실제 입금 트랜잭션을 하나 뽑는다
2. 트랜잭션 필드와 로그를 나란히 놓는다
3. 우리 주소와 수량이 어디에 있는지 본다

값 대조 하나면 ① ② ③ 중 무엇인지가 그 자리에서 정해진다.

패턴을 안 정하고 집합부터 고치는 것 대신 대조부터 하는 쪽을 골랐다. 이유는 패턴이 정해지면 넷을 다 고치고 계산 쪽은 건드리지 않아도 돼서다. 새 코인을 붙이는 비용이 패턴을 정하는 것과 네 자리를 고치는 것으로 끝났다.

정리


Share this post on:

Previous Post
노드가 밖에서 안으로가 아니라 안에서 밖으로 붙었다
Next Post
정렬 없는 first가 엉뚱한 걸 복원한다