EOSIO DApp Inline Transfer

in #extales8 years ago

EOSIO DApp(댑) 개발 과정 중, 컨트랙 내부에서 인라인 액션을 이용하여 토큰 전송을 하는 방법에 대해 간단하게 적어본다.

개요

EOSIO의 컨트랙으로 특정 입력을 보내면, 조건에 맞을 경우 해당 컨트랙이 유저에게 일정량의 토큰을 전송해주는 DApp code를 생각해보자. 즉, userX 라는 사람이 contractY로 [유저이름, 전송조건, 전송토큰량] 을 보내면, 컨트랙은 전송조건이 true인 경우 컨트랙에 잡혀있는 토큰잔고에서 전송토큰량만큼을 유저이름에게 보내면 된다.

핵심코드

컨트랙 내부에 transfer를 할 수 있는 펑션을 만들고 실행시켜줘야 하는데, 이 부분이 inline action이다.

action(
  permission_level{ _self, N(active) },
  N(eosio.token), N(transfer),
  std::make_tuple( _self, user, asset(10000), std::string("test from cys"))
).send();

EOSIO는 아직 자료가 많지 않아서, 완전하게 동작하는 예제를 찾기도 쉽지가 않다. 여기에서 _self는 컨트랙 자신을 뜻하고, user는 userX를 넣으면 된다. asset(10000)은 토큰 10000개를 전송한다는 이야기인데, 로컬 테스트넷의 토큰은 보통 S(4, SYS)로 이용하므로, precision은 소수점아래 4자리, 토큰기호는 SYS인 것을 10000단위 보내게 되어 총 1.0000 SYS가 전송된다. "test from cys"부분은 memo가 되어 영수증에서 보일 것이다.

참고할 부분

Inline action으로 transfer를 실행시킬 경우, 컨트랙이 자신의 토큰을 외부로 꺼내게 되므로, 보안상 매우 위험할 여지가 있다. 따라서 일반적인 방법으로 그냥 컨트랙을 실행시키면 자체적으로 에러가 나며 다음과 같다. (참고사항: 개발에 eosio.cdt를 이용하고 있으며, 블로깅을 위해서 약간의 편집을 하므로 오타가 생길수 있다.)

root@server# eosio-cpp -o contractY.wasm contractY.cpp -abigen
root@server# cleos set contract contractY /home/contractY -p contractY@active
root@server# cleos push action contractY myFuntion '["userX", true, 10000]' -p userX@active
Error 3090003: Provided keys, permissions, and delays do not satisfy declared authorizations Ensure that you have the related private keys inside your wallet and your wallet is unlocked.

당연히 wallet은 unlock되어 있는 상태인데, 퍼미션 에러가 발생하는 것을 알 수 있다. 이 때, contractY의 active권한 밑에 이러한 inline action transfer를 실행해도 된다는 특별한 권한을 추가해줘야 한다.

root@server# cleos set account permission contractY active '{"threshold": 1,"keys": [{"key": "PUBLIC_KEY_OF_CONTRACTY_HERE","weight": 1}], "accounts": [{"permission":{"actor":"contractY","permission":"eosio.code"},"weight":1}]}' -p contractY@owner

포인트 사항 중 하나는 permission 이 active가 아니라 eosio.code 이며, 이는 특별한 퍼미션이다. 이제 실행을 시켜보면 다음과 같은 로그가 뜨면서 잘 실행이 되는 것을 알 수 있다.

#   eosio.token <= eosio.token::transfer        {"from":"contractY","to":"userX","quantity":"1.0000 SYS","memo":"test from cys"}
#     contractY <= eosio.token::transfer        {"from":"contractY","to":"userX","quantity":"1.0000 SYS","memo":"test from cys"}
#         userX <= eosio.token::transfer        {"from":"contractY","to":"userX","quantity":"1.0000 SYS","memo":"test from cys"}
warning: transaction executed locally, but may not be confirmed by the network yet         ]

추가로 몇가지 더 이야기하면, 블록체인을 연구, 개발하다 보면 불편한 부분들이 몇가지 있는데

  1. 참고자료가 많지 않다.
  2. 로그를 찍는 것이 잘 되어 있지 않다. 나의 경우 docker(도커)를 이용하여 eosio를 돌리고 있고, DApp 내부에서는 eosiolib/print.hpp를 이용하여 print로 결과를 트레이스하는데, print문이 한줄밖에 나오지 않는다. "\n"을 쓰면 뒤가 다 잘리니 docker logs --tail 10 eosio 같은 명령을 이용해서 docker내 메시지를 수동으로 확인해야 한다.
  3. 많은 에러가 그냥 에러메시지 하나로 퉁쳐지는 경우가 많다.
    Error 3050003: eosio_assert_message assertion failure
    와 같은 에러를 만나는 경우, 혹시 오타가 있는게 아닌지 잘 찾아보아야 한다.

— Written by cys with Extales

Coin Marketplace

STEEM 0.04
TRX 0.33
JST 0.080
BTC 62544.99
ETH 1664.38
USDT 1.00
SBD 0.42