ERC20 토큰에 대한 불편한 사실들

1. 탈중앙화된 네트워크 안에 있는 중앙화된 데이터베이스

사실 모든 token holder들에 대한 balance 와 approval은 모두 이 두 개의 mapping변수에 기록되는데
사용자의 잔액을 보관하는 balance는
mapping (address => uint256) public balances에
사용자의 계좌에서 상대방이 토큰을 빼올 수 있는 수를 정의하는 allowance는
mapping(address => mapping (address => uint256)) public allowance에
보관합니다.
사실 ERC20 token의 전송 과정을 정확히 표현하면
토큰을 말 그대로 “보내는 게” 아니라 저 하나의 스마트 컨트랙트한테 state(상태) 업데이트 해달라고 보내는 겁니다.
결국 토큰을 블록체인에서 보내는 게 아니라 ERC20 token 스마트 컨트랙트에 있는 CRUD 데이터베이스를 바꾸는 거고 매번 dapp에서 balance()로 확인을 해줘야 할 수 있습니다. 다행히 solidity나 vyper에는(다른 데도 있겠지만) event가 있기에 매번 물어보지 않아도 Transfer() 이벤트를 추적하면 throttling으로 dapp이 계속 스마트컨트랙트에게 쿼리를 던지는 경우는 피할 수 있습니다.
아래는 Web3.js로 event를 추적하는 코드 예시입니다.

그런데 이 토큰을 보내는 주체가 사람이 요청하는 거였는데
스마트 컨트랙트가 토큰을 받았으면 어떻게 될까?
2. 계? 약? 서?

못 보냅니다.
스마트 컨트랙트는 따로 ERC20 token과 관련이 없는 이상 transfer() 함수를 못쓰니 token을 못 보내고 동결되게 되는데요. 문제는 이런 사례가 꽤 많이 발생했다는 겁니다.

이더리움 스마트 컨트랙트는 기본적으로 이더를 안받게 하는 일종의 보호장치가 있습니다. payable 키워드를 이용해 필요할 때만 이더를 받죠. 하지만 erc20토큰은 그렇지 않습니다.
실수가 대부분일 것 같지만
일부러 한다면 누가 왜 어떠한 이유로 굳이 저 토큰들을 보내는 걸까요?
추정되는 쓰임새

가격 조정이 가능할 수도 있습니다.
사실 다르게 말하면 이건 burn()함수를 token holder한테 줘버린 모양입니다만 코인 가격이 낮을 때 가격을 올리고자 Circulating token량을 바꾸는 식으로 사용할 수도 있습니다.
아래는 ICO team이 토큰 가격을 측정하는 방법을 게시하는 글입니다.
예를 들었을 때 이런 계산이 나오고 Market Cap을 MC, Max Supply를 MS, In circulation을 IC, Token Price를 TP라고 가정해보면
- Market Cap: $1,800,000,000
- Max Supply: 200,000,000
- In Circulation: 100,000,000 (50%)
- Token Price: $18/token
MS는 개무시하고 MC/IC = TP로 측정되는 것을 알 수 있습니다.
그럼 그냥 거래소에 돌아다니는 token을 아무데나 던져버리면 가격이 오를까요?
이제까지 40원이던 모스랜드는 코인을 던지면 가격이 오를 수 있을까요?
모르겠는데요. 이짓이 항상 가능하다는 것을 짐작하면 판을 짜볼 수도 있긴 할텐데 제 돈을 쓰면서까지 이 짓을 하고 싶지는 않네요.
아무튼 이러한 문제로 여러가지 대안이 제시되고 있기는 합니다.
해결책
1. Recoverable Token
발행자의 권한으로 계약에 갇힌 토큰을 다시 빼오는 방법입니다.
save()라는 함수를 이용하여 계약이라는 게 판단되면 발행자한테 다시 빼옵니다.
2. ERC223
아예 처음부터 contract receiver가 없으면 차단해버립니다.
스마트 컨트랙트가 특정한 조건을 만족하지 않으면 트랜젝션을 취소시켜버리는 거죠.
