Contract의 지출 자동 로깅

in #eos6 years ago (edited)

EOS 플랫폼에서 게임을 만드려고 공부하시는 분들은 대부분 dice app을 많이 참고하는데, 이 샘플은 권한 이슈가 있습니다. Contract에서 직접 유저의 EOS를 출금하기 때문에 유저가 contract에 active 권한을 승인해 줘야 합니다.

<p dir="auto">이 방법 말고 더 쉽고 간단한 방법이 있는데, 유저가 컨트랙트로 입금을 할때 Contract의 특정코드가 자동으로 실행되게 하는 방식입니다. <a href="https://(https://github.com/EOSIO/eos/blob/master/contracts/eosio.token/eosio.token.cpp#L74" target="_blank" rel="nofollow noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">eosio.token 컨트랙트를 보면 transfer 시점에 require_recipient 함수를 통해 from과 to 쪽에 모두 notification이 보내지는 것을 볼 수 있습니다. <pre><code>void token::transfer(...) { ... require_recipient( from ); require_recipient( to ); } <p dir="auto">받는 쪽의 contract에서 이 notification을 받아서 처리할 수 있는데, 자세한 내용은 <a href="https://eosio.stackexchange.com/q/421/54" target="_blank" rel="nofollow noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">eos stackexchange의 글을 참고하거나, 몬스터 eos가 구현한 <a href="https://github.com/leordev/monstereos/blob/master/contracts/pet/pet.cpp#L269" target="_blank" rel="nofollow noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">코드를 참고하시면 될 것 같습니다. 여기까지는 이미 어느정도 공유가 된 내용입니다. <p dir="auto">여기서 부터가 본격적인 내용입니다. require_recipient 기능을 이용하면 입금 기능말고 출금을 자동으로 로깅하게 할 수 있습니다. 컨트랙트에서 출금이 발생했을 때 지출 내역이라면 해당 내용을 기록 하는 것입니다. 이를 통해 자동으로 잔고 관리가 가능합니다. <pre><code>//@abi table expenseslog i64 struct expenseslog { uint64_t no = 0; uint32_t at = 0; asset amount; name to; std::string memo; ... } void transfer(uint64_t sender, uint64_t receiver) { ... // 출금시 if (transfer_data.from == self) { auto to = to_name(transfer_data.to); auto player = players.find(to); // 유저의 withdraw가 아니고, 주주에게 보내는 쉐어가 아니라면 출금 내역 기록 if (player == players.cend() && admin_controller.is_stock_holder(to) == false) { // 내부에서 expenseslog 테이블에 데이터를 쌓는다 admin_controller.add_expenses(transfer_data.quantity, to, transfer_data.memo); } } // 입금시 if (transfer_data.to == self) { // 유저 입금 처리 } } <p dir="auto">자그럼 한번 테스트 해보겠습니다. 이와 같은 컨트랙트 코드를 작성후 컨트랙트를 배포한다음 0.1 EOS 만큼의 램을 구매해 보겠습니다. <pre><code>$ cleos -u $url system buyram eosknightsio eosknightsio '0.1000 EOS' -p eosknightsio 1148081ms thread-0 main.cpp:429 create_action ] result: {"binargs":"401dce8db9093155401dce8db9093155e80300000000000004454f5300000000"} arg: {"code":"eosio","action":"buyram","args":{"payer":"eosknightsio","receiver":"eosknightsio","quant":"0.1000 EOS"}} executed transaction: 2fd4568358775e1e440cf81a4a9a5c6d7f6fc3463728bdd94bcf0e4ca0178b83 128 bytes 3468 us # eosio <= eosio::buyram {"payer":"eosknightsio","receiver":"eosknightsio","quant":"0.1000 EOS"} # eosio.token <= eosio.token::transfer {"from":"eosknightsio","to":"eosio.ram","quantity":"0.0995 EOS","memo":"buy ram"} # eosknightsio <= eosio.token::transfer {"from":"eosknightsio","to":"eosio.ram","quantity":"0.0995 EOS","memo":"buy ram"} # eosio.ram <= eosio.token::transfer {"from":"eosknightsio","to":"eosio.ram","quantity":"0.0995 EOS","memo":"buy ram"} # eosio.token <= eosio.token::transfer {"from":"eosknightsio","to":"eosio.ramfee","quantity":"0.0005 EOS","memo":"ram fee"} # eosknightsio <= eosio.token::transfer {"from":"eosknightsio","to":"eosio.ramfee","quantity":"0.0005 EOS","memo":"ram fee"} # eosio.ramfee <= eosio.token::transfer {"from":"eosknightsio","to":"eosio.ramfee","quantity":"0.0005 EOS","memo":"ram fee"} warning: transaction executed locally, but may not be confirmed by the network yet <p dir="auto">로깅이 잘 되었나 봐볼까요? <pre><code>$ cleos -u $url get table eosknightsio eosknightsio expenseslog { "rows": [{ "no": 0, "at": 31203548, "amount": "0.0995 EOS", "to": "eosio.ram", "memo": "buy ram" },{ "no": 1, "at": 31203548, "amount": "0.0005 EOS", "to": "eosio.ramfee", "memo": "ram fee" } ], "more": false } <p dir="auto">ram과 ram.fee가 잘 기록되었네요. <p dir="auto">UI를 이런식으로 붙이면 보기더 좋겠죠?<br /> <img src="https://images.hive.blog/768x0/https://cdn.steemitimages.com/DQmPT2HXd8aSttmWSywAwjCVzeaiKB3B4qg1daMHGyZS9nF/image.png" srcset="https://images.hive.blog/768x0/https://cdn.steemitimages.com/DQmPT2HXd8aSttmWSywAwjCVzeaiKB3B4qg1daMHGyZS9nF/image.png 1x, https://images.hive.blog/1536x0/https://cdn.steemitimages.com/DQmPT2HXd8aSttmWSywAwjCVzeaiKB3B4qg1daMHGyZS9nF/image.png 2x" /> <p dir="auto">이상 컨트랙트를 잘 활용해서 지출내역을 자동으로 기록하는 방법이였습니다. 이 코드는 <a href="http://eosknights.io" target="_blank" rel="nofollow noreferrer noopener" title="This link will take you away from hive.blog" class="external_link">eosknights 컨트랙트 코드의 일부이고 조만간 전체 코드를 공개하도록 하겠습니다.
Sort:  

포스팅 잘보았습니다~~ 풀보팅드려용

감사합니다~ 누군가에게 도움이 되었으면 좋겠네요~

코드 오픈했습니다! 컨트랙 코드는 아래 링크에서 확인 가능합니다.
https://github.com/bada-studio/knights_contract