eos源碼賞析(十八):EOS智能合約之合約內(nèi)ram購買及資源抵押

昨天群內(nèi)有朋友問,智能合約內(nèi)是否可以實(shí)現(xiàn)幫用戶購買ram或者幫用戶抵押資源(cpu及net),以及如何來實(shí)現(xiàn)這個(gè)功能。今天我們一起來看下這個(gè)問題。文章的內(nèi)容分為以下兩個(gè)部分:

  • buyram及delegatebw的實(shí)現(xiàn)

  • 合約內(nèi)實(shí)現(xiàn)替用戶購買ram及抵押資源

image

1、buyram及delegatebw的實(shí)現(xiàn)

我們知道在執(zhí)行buyram的時(shí)候是分為兩種情況的:

  1. 以eos的單位來購買ram

  2. 以ram的單位來購買ram

那么buyram這個(gè)功能在哪里實(shí)現(xiàn)的呢,我們通過cleos中的main.cpp很容易查找到這兩個(gè)操作都是在系統(tǒng)合約eosio.system中實(shí)現(xiàn)的,以buyram為例,其分為了兩種,代碼如下:

 1   //這個(gè)action將會(huì)以市場價(jià)格且單位bytes的形式購買ram 2   void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { 3      auto itr = _rammarket.find(S(4,RAMCORE)); 4      auto tmp = *itr; 5      auto eosout = tmp.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL ); 6 7      buyram( payer, receiver, eosout ); 8   } 9   //當(dāng)購買ram的時(shí)候,支付的用戶會(huì)將eos交易至系統(tǒng)合約賬戶,而接收ram的用戶可以通過sellram這個(gè)action換回token,接收方支付這次action執(zhí)行所需內(nèi)存。10   void system_contract::buyram( account_name payer, account_name receiver, asset quant )11   {12      require_auth( payer );13      eosio_assert( quant.amount > 0, "must purchase a positive amount" );14      auto fee = quant;15      fee.amount = ( fee.amount + 199 ) / 200; /// .5% fee (round up)16      auto quant_after_fee = quant;17      quant_after_fee.amount -= fee.amount;18      INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)},19         { payer, N(eosio.ram), quant_after_fee, std::string("buy ram") } );20      if( fee.amount > 0 ) {21         INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)},22                                                       { payer, N(eosio.ramfee), fee, std::string("ram fee") } );23      }2425      int64_t bytes_out;2627      const auto& market = _rammarket.get(S(4,RAMCORE), "ram market does not exist");28      _rammarket.modify( market, 0, [&]( auto& es ) {29          bytes_out = es.convert( quant_after_fee,  S(0,RAM) ).amount;30      });3132      eosio_assert( bytes_out > 0, "must reserve a positive amount" );3334      _gstate.total_ram_bytes_reserved += uint64_t(bytes_out);35      _gstate.total_ram_stake          += quant_after_fee.amount;3637      user_resources_table  userres( _self, receiver );38      auto res_itr = userres.find( receiver );39      if( res_itr ==  userres.end() ) {40         res_itr = userres.emplace( receiver, [&]( auto& res ) {41               res.owner = receiver;42               res.ram_bytes = bytes_out;43            });44      } else {45         userres.modify( res_itr, receiver, [&]( auto& res ) {46               res.ram_bytes += bytes_out;47            });48      }49      set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount );50   }

可以看出,buyrambytes最終還是調(diào)用了buyram,當(dāng)購買ram的時(shí)候,支付的用戶會(huì)將eos交易至系統(tǒng)合約賬戶,而接收ram的用戶可以通過sellram這個(gè)action換回token,接收方支付這次action執(zhí)行所需內(nèi)存。我們大多已經(jīng)知道ram的價(jià)格是動(dòng)態(tài)變化的,因?yàn)槠涫褂昧薭ancor算法,就像現(xiàn)在大熱的fibos一樣,使用bancor算法可以更自主的給ram【定價(jià)】,本篇重點(diǎn)不在此,筆者正在嘗試使用該算法進(jìn)行測試,以后的文章中會(huì)逐步提及。同樣的,delegatebw的操作也是類似的,我們不再進(jìn)行代碼的粘貼,感興趣的朋友可以自行測試。

image

2、合約內(nèi)實(shí)現(xiàn)替用戶購買ram及抵押資源

為用戶抵押資源是可以解除質(zhì)押,最終是不消耗我們的token的,但是為用戶購買ram卻是消耗合約開發(fā)者自己的token的,我們假設(shè)一種情況如下,用戶支付我們10 EOS,我們便為其購買100kbytes的ram,而為其抵押10 EOS的資源,代碼如下:

 1void tianlongbabu::buysilver(account_name user,asset quanitity,string memo) 2{ 3    if (user != _this_contract && quanitity.symbol == S(4,EOS)) 4    { 5            //購買ram 6        action( 7              {permission_level{_this_contract,N(active)}},  8              N(eosio), N(buyrambytes), 9              std::make_tuple(_this_contract,user,quanitity.amount * 10)10              ).send(); 11            //抵押資源1213        asset delquan = quanitity;14        delquan.amount /= 10;15        action(16              {permission_level{_this_contract,N(active)}}, 17              N(eosio), N(delegatebw),18              std::make_tuple(_this_contract,user,delquan,delquan,true)19              ).send();20    }21}

通過上面的代碼我們可以看到,本合約調(diào)用了系統(tǒng)合約eosio.system,在代碼中的體現(xiàn)就是N(eosio),以及其對(duì)應(yīng)的action--buyrambytes以及delegatebw,inline action執(zhí)行之后,通過合約內(nèi)部為用戶購買ram以及質(zhì)押資源便可實(shí)現(xiàn)了。當(dāng)然購買和質(zhì)押實(shí)現(xiàn)之后,我們也可以實(shí)現(xiàn)賣出ram以及解除質(zhì)押資源,感興趣的話可以去嘗試下。

在合約部署成功之后,我們可以通過命令行簡單的測試下該合約是否生效:

1cleos  push action mycontract buysilver '["user","10.0000 EOS","test"]' -p user@active

本文從群內(nèi)朋友問題出發(fā),首先查看了eos中buyram的邏輯,然后以合約內(nèi)部調(diào)用調(diào)用系統(tǒng)合約eosio.system中的buyram及delegatebw來實(shí)現(xiàn)替用戶購買ram以及質(zhì)押資源,關(guān)于buyram中的bancor算法筆者會(huì)在后續(xù)的文章中繼續(xù)進(jìn)行說明及測試。

如果你覺得我的文章對(duì)你有一定的幫助,請(qǐng)點(diǎn)擊文章末尾的喜歡該作者。

如果你對(duì)eos開發(fā)感興趣,歡迎關(guān)注本公眾號(hào),一起學(xué)習(xí)eos開發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容