EOS 토큰 컨트랙트와 램 가격 지불자 - Extales 블로그


EOS 토큰 컨트랙트와 램 가격 지불자 - Extales 블로그

얼마전 에어드랍(airdrop)을 대규모로 수행하다가, 램(ram)이 모자라는 상황에 맞닥뜨리게 되었다. 소규모 에어드랍에서는 별로 신경쓸일이 아니었지만, 만명 단위의 에어드랍에서는 cpu 사용량보다도 더 문제가 되었던 램 지불자(payer) 문제를 간단하게 언급해보고자 한다.

에어드랍을 통해서 하늘에서 떨어지는 코인을 받는다. 그냥 막 줘야 가치가 더 늘어나는 이상하고 재미난 세상이다.

eosio.token
eosio.token은 EOS의 토큰(token) 컨트랙트이며, 재미있는 사실은 우리가 흔히 알고 있는 EOS라는 것은 결국 eosio.token 컨트랙의 테이블에 적혀있는 숫자일 뿐이라는 것이다. 이 컨트랙트는 토큰의 생성, 발행, 소각, 전송 등을 가능하게 하며, 현재 토큰의 발행상황은 어떠한지, 누가 얼마를 들고 있는지를 관리하게 된다. 개별적으로 본인만의 토큰을 발행하여 이용하고 싶을 때엔, 자신이 직접 토큰 컨트랙트를 작성하여 이용하여도 되지만, 대부분은 가장 널리알려지고 또한 이미 검증된 eosio.token 컨트랙트를 복사하여 이용하는 편이기 때문에, 이 컨트랙트를 알아보고 공부해 본다면, EOS 블록체인 내에서 토큰 발행과 전송이란게 무엇인지 대부분 다 이해할 수 있게 된다.

eosio에서 램이란?
일반적으로 말하는 램은 컴퓨터 내부의 휘발성 메모리이지만, eosio에서 램이라 함은 블록체인 상의 일반적인 저장공간을 뜻한다. 가장 단순한 사용 예시로는 컨트랙트의 동작과 함께 생성되는 테이블의 내용이 적히는 공간이며, 따라서 그러한 저장공간을 더 만들때마다 램이 추가로 더 이용되고, 반대로 내용을 지울 때마다 해당 용량만큼의 램이 반환된다. 실제로 램은 블록체인상의 공용공간이기 때문에, 누구의 컴퓨터 혹은 누구의 블록체인에 있는 램을 이용한다는 개념이 없으며, 다만 블록체인 상의 저장공간인 램을 누구의 지불로 이용하고 있는지가 중요한 항목이 된다. 각 유저들은 자신이 사용할 수 있는 최대 램 공간과 현재 사용하고 있는 램 공간을 확인 할 수 있고, 할당된 램 용량안에서만 저장공간을 이용할 수 있다. 그 값을 넘어서 이용하려고 하면 트랜잭션은 취소되고 데이터는 롤백(rollback)된다.

eosio에서 토큰이란?
실세계에서 토큰을 만든다면, 물리적인 실체가 있는 어떤 물건을 만들고, 그것을 사람들에게 나누어 줌으로써 소유주가 자산을 관리하는 형식을 띠게 된다. 이와 다르게, 만약 어떠한 컴퓨터 시스템에서 토큰처럼 이용될 포인트가 발행된다면, 내부적으로는 시스템을 관리하는 컴퓨터의 DB에 각 유저별 포인트량을 적어두는 테이블을 만들고, 관리자가 포인트 사용에 따른 잔액을 고치는 형태가 될 것이다.

EOS 블록체인상의 토큰은 블록체인 상 저장공간에 해당 토큰의 잔고와 관련된 테이블을 만들고, 스마트 컨트랙트가 발행 및 전송에 따른 유저별 잔고값을 조절하게 함으로써 실제적으로 효력을 가지게 하는 방식이다. 따라서 물리적인 실체는 없지만, 잔고의 값은 숫자로써 존재하고, 중앙집중적인 관리자가 본인 소유의 DB에 그 잔고값을 적어두는 것이 아닌, 공개된 저장장소에 스마트 컨트랙트에 의하여 값을 적음으로써 그 존재를 증명하게 되는 것이다. (사설 토큰의 경우 스마트 컨트랙트의 주인이 그 값을 조절할 수 있지만, 본 글의 논점과 관련이 없으므로 일단 미뤄두도록 하자.)

그렇다면, 실제로 토큰이 어떻게 동작하는가?
다음은 eosio.token 컨트랙이 생성하는 2종류의 테이블인 stats와 accounts의 형태이다.

eosio.token의 대표 테이블 2개

stats 테이블에는 실제 발행량, 전체 공급가능량, 소유주 정보가 적히고, accounts 테이블에는 특정 유저의 자산값(토큰량)이 적히게 된다. (accounts 테이블에 유저이름이 적히지 않은 이유는 scope을 유저마다 다르게 갖고 가기 때문에 해당 유저의 scope으로 열어야만 값이 보이기 때문이다. 따라서 따로 유저를 특정하지 않아도 해당 유저의 값만 보인다.) 이 때, 토큰이 발행되면 stats 테이블에 발행되는 양이 적히고, 어떤 유저에게 전송이 되면, 그 유저의 accounts 테이블에 전송받은 자산수량이 적히게 됨으로써 토큰은 동작하게 된다. 만약 토큰을 가지고 있는 유저A가 다른 유저B에게 토큰을 전송하면, A의 accounts 테이블의 값은 감소할 것이고, B의 accounts 테이블 값은 동일한 수량으로 증가할 것이다. 당연히 이러한 테이블 값의 변경은 유저들이 임의로 할 수 없고 eosio.token의 권한으로 스마트 컨트랙트의 규칙에 따라 수행 될 것이다.

지금 유저A가 토큰을 가지고 있고, 유저B에게 전송을 하는 과정을 생각해보자. 다음의 transfer 펑션을 호출하여 진행할 수 있다.

eosio.token의 transfer 펑션

두가지 핵심 펑션을 다시 호출하게 되는데, 1) add_balance, 2) sub_balance 가 바로 그것이다. 각각 1)은 전송받은 B유저의 accounts 테이블에 값을 더해주는 과정을, 2)는 전송해줄 A유저의 accounts 테이블에서 값을 빼주는 과정을 수행하게 되는데, 다만, 부가적으로 add 과정에서는 액션을 호출하는 유저가 보내는 사람과 받는 사람의 권한을 모두 가지고 있을 경우 받는 사람의 이름으로 램을 소모한다는 과정이 살짝 엿보인다. (그렇게 중요한 파트가 아니므로 가볍게 넘어가도 된다. 또한 add와 sub순서도 중요하지 않다. 어차피 트랜잭션이 깨지게 되면 모든 내용이 롤백되기 때문이다.)

중요한 부분은 add와 sub과정에서 램값 지불자(payer)가 어떻게 변경되고 있는가이다. 이는 우선 add 과정에서 테이블을 누구를 지불자로 생성하는지부터 살펴보면서 찾아볼 수 있다.

eosio.token의 add_balance 펑션

add의 과정에서는 accounts 테이블을 새로 생성하는 경우 이미 앞에서 계산한 payer(보통의 경우 전송하려는 유저)를 지불 당사자로 처리하고, 이미 존재하는 테이블을 수정하는 경우에는 기존의 지불 당사자를 그대로 이용하는 것을 알 수 있다. 따라서 일반적인 경우 토큰을 가지고 있지 않아서 accounts 테이블이 존재하지 않다가 새로 생성하는 경우라면, 전송하려는 유저A를 지불 당사자로 테이블이 생성될 것이고, 이는 토큰을 전송받으려는 유저B가 충분한 램을 가지고 있지 않더라도 유저A의 램만으로도 전송이 가능하게 하므로, 전송을 해주는 입장에서 편리한 부분이 있다는 것을 알 수 있다. 만약 이미 유저B가 해당 토큰의 accounts 테이블을 가지고 있는 경우라면, 새로운 테이블을 생성할 필요가 없이, 기존의 테이블을 그대로 이용하면서 값만 새로 적으면 되므로 지불자는 바뀌지 않는다.

다음으로 sub의 과정을 살펴보도록 하자.

eosio.token의 sub_balance 펑션

이미 존재하는 토큰자산을 옮기는 것이므로, accounts 테이블은 누가 지불하고 있던지 어쨌든 반드시 존재하는 경우이다. 이 때 수정을 하면서 토큰의 소유자가 램값을 지불하도록 설정되어 있으므로, A의 accounts 테이블의 지불자는 과거에 누구였든지 간에 이제는 유저A로 확정된다. 따라서 결론적으로, add이건 sub이건 불확실한 부분에 대해서는 전송을 하려고 하는 유저A를 지불자로 두고 테이블이 생성, 수정되므로, 전송을 하는 사람이 전체 트랜잭션을 관리 할 수 있는 장점이 잘 살아나며, 이후에 실제 이용하는 순간 해당 유저가 본인 테이블의 램가격을 지불하도록 변경 확정하므로, 효율적인 관리가 가능하게 된다.

램가격 지불자의 변경 예시
간단한 예를 다시 들어보자. 최초에 유저A에게 토큰이 있고, 1) 이를 유저B에게 보내고, 2) 다시 유저B는 이를 유저C에게 보내는 과정이 있다고 하자. 이 때 램가격 지불자는 다음과 같이 변경된다.

유저 A->B->C로 토큰이 전송될 때 각 테이블의 지불자 변경

핵심과정은 테이블B에 대한 가격을 누가 지불했는가를 추적하면 알 수 있다. 최초에는 유저A가 지불하고, 이 후 유저B가 해당 토큰을 사용하지 않는한 계속 유저A의 부담으로 남지만, 한번이라도 유저B가 토큰을 사용하게 되면, 그 순간 테이블B에 대한 가격부담은 유저B로 변경되고, 앞으로 계속 유저B의 부담으로 남게 되는 것이다. 꽤나 합리적인 과정이라는 생각이 든다. 원하지 않는 토큰을 받게 됨으로써 자신의 램을 낭비하지 않을수 있고, 해당 유저에게 효용이 생기는 순간 테이블 공간의 가격부담을 가져오게 되니 말이다.

이것은 어떤 문제를 만드는가?
토큰 전송과 관리를 효율적으로 할 수 있음에도 불구하고, 이 과정은 에어드랍을 할 때 많은 유저들의 램값 부담을 전송하는 쪽에서 거의 전부 책임져야 하는 상황을 만든다. 스마트 컨트랙트의 액션을 이용하여 에어드랍을 수행하는 경우 많은 사람들이 내가 사용할 수 있는 CPU의 양이 얼마인가에 관심을 두게 되는데, 막상 진행을 하게 되면, 24시간 단위로 다시 재충전이 되는 CPU와는 달리, 거의 항구적으로 돌아오지 않을 램값이 모자람을 알 수 있게 된다. 정말 효용가치가 높은 토큰의 경우라도 에어드랍의 순간에서는 전송자가 모든 램값을 지불하여야 하고, 이후에 램이 해제되는 과정을 거쳐야 하므로 불편한 부분이 있을 수 있다.

그렇다면 에어드랍할때 램은 과연 얼마나 필요한가?
이미 테이블이 있는 경우에는 추가 램이 필요하지 않다는 것을 알 수 있지만, 에어드랍은 신규 토큰의 경우가 많고, 그 토큰이 없는 자에게 보내는 것을 목표로 하므로, 전부 신규 테이블이라고 간주하는 것이 속편하다. 테스트 결과 1인당 약 250 바이트 정도가 소모 되었는데(이는 토큰 컨트랙에 따라 다를수 있다.), 그러면 만명을 기준으로 2.5MB정도가 필요하고, 현재 시세는 1 EOS당 약 11kB 이므로 (2019년 10월 기준) 모두 230 EOS 정도가 필요하다. 대략적인 업비트 시세인 3,800원을 적용하면, 실제로 1만명에 대한 에어드랍을 하기 위하여 원화로 90만원 가량이 나오는데, 이는 결고 적지 않은 금액으로 느껴질 것이다.

앞서 우리는 에어드랍을 할 때 cpu 뿐만 아니라, 램도 소모가 된다는 사실을 되짚어 보았고, 이러한 램 지출은 에어드랍을 받은 사람이 해당 토큰을 사용하지 않는 이상 계속 보내는쪽에서 부담을 해야 하는 자원이니 만큼 꽤나 신경을 써야 할 상황이라는 것을 알 수 있었다.

– 본 글은 엑스테일즈(Extales)의 cys에 의하여 작성되었습니다.



Source link

Register at Binance

EOS 토큰 컨트랙트와 램 가격 지불자 - Extales 블로그
EOS 토큰 컨트랙트와 램 가격 지불자 - Extales 블로그
EOS 토큰 컨트랙트와 램 가격 지불자 - Extales 블로그
EOS 토큰 컨트랙트와 램 가격 지불자 - Extales 블로그
EOS 토큰 컨트랙트와 램 가격 지불자 - Extales 블로그

EOS 토큰 컨트랙트와 램 가격 지불자 - Extales 블로그

EOS 토큰 컨트랙트와 램 가격 지불자 - Extales 블로그