zoukankan      html  css  js  c++  java
  • EOS dice移到1.8版本的修改汇总

    EOS dice移到1.8版本的修改汇总

    1. CORE_SYMBOL 被去掉了,需要自己在文件中声明
    eg:

     1 uint64_t string_to_symbol_c(uint8_t precision, const char* str) {
     2          uint32_t len = 0;
     3          while (str[len]) ++len;
     4 
     5          uint64_t result = 0;
     6          // No validation is done at compile time
     7          for (uint32_t i = 0; i < len; ++i) {
     8             result |= (uint64_t(str[i]) << (8*(1+i)));
     9          }
    10 
    11          result |= uint64_t(precision);
    12          return result;
    13       }
    14 
    15 #define CORE_SYMBOL string_to_symbol_c(4,"SYS")


    2. account_name 替换成了 name 结构

    3. 合约contract的声明改成了下面结构
    contract( name receiver, name code, datastream<const char*> ds )

    dice合约变为:dice(name s, name code, eosio::datastream<const char*> ds):eosio::contract(s,code,ds)

    4. 因为account_name变为了name结构,多索引结构的初始化改为:
    offers(_self, _self.value),
    games(_self, _self.value),
    global_dices(_self, _self.value),
    accounts(_self, _self.value)

    5. 宏N变为了_n
    eg:N(commitment) 改为 "commitment"_n

    6. checksum256 改成 capi_checksum256

    7. key256 改成 fixed_bytes<32>

    8. find函数后面跟的name类型,需要添加.value,以供查找

    9. modify函数三个参数中间的0,改成_self账户或者相应的账户

    10. EOSIO_ABI 改成 EOSIO_DISPATCH

    11. 添加相应的头文件,修改为新的合约格式 [[eosio::action]],[[eosio::contract("dice")]],[[eosio::table]]等

    12. 该合约不支持除了EOS的其他资产,因此自己做了一点修改以支持测试的自定义资产,供自己测试

    完整修改代码如下:

      1 /**
      2  *  @file
      3  *  @copyright defined in eos/LICENSE.txt
      4  */
      5 #include <utility>
      6 #include <vector>
      7 #include <string>
      8 #include <eosiolib/eosio.hpp>
      9 #include <eosiolib/time.hpp>
     10 #include <eosiolib/asset.hpp>
     11 #include <eosiolib/contract.hpp>
     12 #include <eosiolib/crypto.h>
     13 #include <eosiolib/fixed_bytes.hpp>
     14 #include <eosiolib/symbol.hpp>
     15 
     16 using eosio::fixed_bytes;
     17 using eosio::indexed_by;
     18 using eosio::const_mem_fun;
     19 using eosio::asset;
     20 using eosio::permission_level;
     21 using eosio::action;
     22 using eosio::print;
     23 using eosio::name;
     24 using eosio::symbol;
     25 
     26 uint64_t string_to_symbol_c(uint8_t precision, const char* str) {
     27          uint32_t len = 0;
     28          while (str[len]) ++len;
     29 
     30          uint64_t result = 0;
     31          // No validation is done at compile time
     32          for (uint32_t i = 0; i < len; ++i) {
     33             result |= (uint64_t(str[i]) << (8*(1+i)));
     34          }
     35 
     36          result |= uint64_t(precision);
     37          return result;
     38       }
     39 
     40 #define CORE_SYMBOL string_to_symbol_c(4,"SYS")
     41 
     42 
     43 class [[eosio::contract("dice")]] dice : public eosio::contract {
     44    public:
     45       using contract::contract;
     46          
     47       const uint32_t FIVE_MINUTES = 5*60;
     48 
     49       dice(name s, name code, eosio::datastream<const char*> ds):eosio::contract(s,code,ds),
     50        offers(_self, _self.value),
     51        games(_self, _self.value),
     52        global_dices(_self, _self.value),
     53        accounts(_self, _self.value)
     54       {}
     55 
     56       [[eosio::action]]
     57       void offerbet(const asset& bet, const name player, const capi_checksum256& commitment) {
     58 
     59          //eosio_assert( bet.symbol == symbol(CORE_SYMBOL), "only core token allowed" );
     60          eosio_assert( bet.is_valid(), "invalid bet" );
     61          eosio_assert( bet.amount > 0, "must bet positive quantity" );
     62 
     63          eosio_assert( !has_offer( commitment ), "offer with this commitment already exist" );
     64          require_auth( player );
     65 
     66          auto cur_player_itr = accounts.find( player.value );
     67          eosio_assert(cur_player_itr != accounts.end(), "unknown account");
     68 
     69          // Store new offer
     70          auto new_offer_itr = offers.emplace(_self, [&](auto& offer){
     71             offer.id         = offers.available_primary_key();
     72             offer.bet        = bet;
     73             offer.owner      = player;
     74             offer.commitment = commitment;
     75             offer.gameid     = 0;
     76          });
     77 
     78          // Try to find a matching bet
     79          auto idx = offers.template get_index<"bet"_n>();
     80          auto matched_offer_itr = idx.lower_bound( (uint64_t)new_offer_itr->bet.amount );
     81 
     82          if( matched_offer_itr == idx.end()
     83             || matched_offer_itr->bet != new_offer_itr->bet
     84             || matched_offer_itr->owner == new_offer_itr->owner ) {
     85 
     86             // No matching bet found, update player's account
     87             accounts.modify( cur_player_itr, player, [&](auto& acnt) {
     88                //eosio_assert( acnt.eos_balance >= bet, "insufficient balance" );
     89                //acnt.eos_balance -= bet;
     90                for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
     91                if(iter->symbol == bet.symbol){
     92                   eosio_assert( (*iter) >= bet, "insufficient balance" );
     93                   (*iter) -= bet;
     94                   print( "offerbet1 : ", asset{bet} );
     95                   break;
     96                }
     97                }
     98                acnt.open_offers++;
     99             });
    100 
    101          } else {
    102             // Create global game counter if not exists
    103             auto gdice_itr = global_dices.begin();
    104             if( gdice_itr == global_dices.end() ) {
    105                gdice_itr = global_dices.emplace(_self, [&](auto& gdice){
    106                   gdice.nextgameid=0;
    107                });
    108             }
    109 
    110             // Increment global game counter
    111             global_dices.modify(gdice_itr, _self, [&](auto& gdice){
    112                gdice.nextgameid++;
    113             });
    114 
    115             // Create a new game
    116             auto game_itr = games.emplace(_self, [&](auto& new_game){
    117                new_game.id       = gdice_itr->nextgameid;
    118                new_game.bet      = new_offer_itr->bet;
    119                new_game.deadline = eosio::time_point_sec(0);
    120 
    121                new_game.player1.commitment = matched_offer_itr->commitment;
    122                memset(&new_game.player1.reveal, 0, sizeof(capi_checksum256));
    123 
    124                new_game.player2.commitment = new_offer_itr->commitment;
    125                memset(&new_game.player2.reveal, 0, sizeof(capi_checksum256));
    126             });
    127 
    128             // Update player's offers
    129             idx.modify(matched_offer_itr, _self, [&](auto& offer){
    130                offer.bet.amount = 0;
    131                offer.gameid = game_itr->id;
    132             });
    133 
    134             offers.modify(new_offer_itr, _self, [&](auto& offer){
    135                offer.bet.amount = 0;
    136                offer.gameid = game_itr->id;
    137             });
    138 
    139             // Update player's accounts
    140             accounts.modify( accounts.find( matched_offer_itr->owner.value ), matched_offer_itr->owner, [&](auto& acnt) {
    141                acnt.open_offers--;
    142                acnt.open_games++;
    143             });
    144 
    145             accounts.modify( cur_player_itr, player, [&](auto& acnt) {
    146                //eosio_assert( acnt.eos_balance >= bet, "insufficient balance" );
    147                // acnt.eos_balance -= bet;
    148                for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
    149                if(iter->symbol == bet.symbol){
    150                   eosio_assert( (*iter) >= bet, "insufficient balance" );
    151                   (*iter) -= bet;
    152                   print( "offerbet2 : ", asset{bet} );
    153                   break;
    154                }
    155                }
    156                acnt.open_games++;
    157             });
    158          }
    159       }
    160 
    161       [[eosio::action]]
    162       void canceloffer( const capi_checksum256& commitment ) {
    163 
    164          auto idx = offers.template get_index<"commitment"_n>();
    165          auto offer_itr = idx.find( offer::get_commitment(commitment) );
    166 
    167          eosio_assert( offer_itr != idx.end(), "offer does not exists" );
    168          eosio_assert( offer_itr->gameid == 0, "unable to cancel offer" );
    169          require_auth( offer_itr->owner );
    170 
    171          auto acnt_itr = accounts.find(offer_itr->owner.value);
    172          accounts.modify(acnt_itr, offer_itr->owner, [&](auto& acnt){
    173             acnt.open_offers--;
    174             // acnt.eos_balance += offer_itr->bet;
    175 
    176             for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
    177                if(iter->symbol == offer_itr->bet.symbol){
    178                   (*iter) += offer_itr->bet;
    179                   print( "canceloffer : ", asset{offer_itr->bet} );
    180                   break;
    181                }
    182             }
    183          });
    184 
    185          idx.erase(offer_itr);
    186       }
    187 
    188       [[eosio::action]]
    189       void reveal( const capi_checksum256& commitment, const capi_checksum256& source ) {
    190 
    191          assert_sha256( (char *)&source, sizeof(source), (const capi_checksum256 *)&commitment );
    192 
    193          auto idx = offers.template get_index<"commitment"_n>();
    194          auto curr_revealer_offer = idx.find( offer::get_commitment(commitment)  );
    195 
    196          eosio_assert(curr_revealer_offer != idx.end(), "offer not found");
    197          eosio_assert(curr_revealer_offer->gameid > 0, "unable to reveal");
    198 
    199          auto game_itr = games.find( curr_revealer_offer->gameid );
    200 
    201          player curr_reveal = game_itr->player1;
    202          player prev_reveal = game_itr->player2;
    203 
    204          if( !is_equal(curr_reveal.commitment, commitment) ) {
    205             std::swap(curr_reveal, prev_reveal);
    206          }
    207 
    208          eosio_assert( is_zero(curr_reveal.reveal) == true, "player already revealed");
    209 
    210          if( !is_zero(prev_reveal.reveal) ) {
    211 
    212             capi_checksum256 result;
    213             sha256( (char *)&game_itr->player1, sizeof(player)*2, &result);
    214 
    215             auto prev_revealer_offer = idx.find( offer::get_commitment(prev_reveal.commitment) );
    216 
    217             int winner = result.hash[1] < result.hash[0] ? 0 : 1;
    218 
    219             if( winner ) {
    220                pay_and_clean(*game_itr, *curr_revealer_offer, *prev_revealer_offer);
    221             } else {
    222                pay_and_clean(*game_itr, *prev_revealer_offer, *curr_revealer_offer);
    223             }
    224 
    225          } else {
    226             games.modify(game_itr, _self, [&](auto& game){
    227 
    228                if( is_equal(curr_reveal.commitment, game.player1.commitment) )
    229                   game.player1.reveal = source;
    230                else
    231                   game.player2.reveal = source;
    232 
    233                game.deadline = eosio::time_point_sec(now() + FIVE_MINUTES);
    234             });
    235          }
    236       }
    237 
    238       [[eosio::action]]
    239       void claimexpired( const uint64_t gameid ) {
    240 
    241          auto game_itr = games.find(gameid);
    242 
    243          eosio_assert(game_itr != games.end(), "game not found");
    244          eosio_assert(game_itr->deadline != eosio::time_point_sec(0) && eosio::time_point_sec(now()) > game_itr->deadline, "game not expired");
    245 
    246          auto idx = offers.template get_index<"commitment"_n>();
    247          auto player1_offer = idx.find( offer::get_commitment(game_itr->player1.commitment) );
    248          auto player2_offer = idx.find( offer::get_commitment(game_itr->player2.commitment) );
    249 
    250          if( !is_zero(game_itr->player1.reveal) ) {
    251             eosio_assert( is_zero(game_itr->player2.reveal), "game error");
    252             pay_and_clean(*game_itr, *player1_offer, *player2_offer);
    253          } else {
    254             eosio_assert( is_zero(game_itr->player1.reveal), "game error");
    255             pay_and_clean(*game_itr, *player2_offer, *player1_offer);
    256          }
    257 
    258       }
    259 
    260       [[eosio::action]]
    261       void deposit( const name from, const asset& quantity ) {
    262          
    263          eosio_assert( quantity.is_valid(), "invalid quantity" );
    264          eosio_assert( quantity.amount > 0, "must deposit positive quantity" );
    265 
    266          auto itr = accounts.find(from.value);
    267          if( itr == accounts.end() ) {
    268             itr = accounts.emplace(_self, [&](auto& acnt){
    269                acnt.owner = from;
    270             });
    271          }
    272 
    273          action(
    274             permission_level{ from, "active"_n },
    275             "eosio.token"_n, "transfer"_n,
    276             std::make_tuple(from, _self, quantity, std::string(""))
    277          ).send();
    278 
    279          accounts.modify( itr, from, [&]( auto& acnt ) {
    280             //acnt.eos_balance += quantity;
    281             bool isfound = false;
    282             for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
    283                if(iter->symbol == quantity.symbol){
    284                   (*iter) += quantity;
    285                   isfound = true;
    286                   print( "deposit more : ", asset{quantity} );
    287                   break;
    288                }
    289             }
    290             if(!isfound){
    291                acnt.eos_balance.emplace_back(quantity);
    292                print( "deposit add : ", asset{quantity} );
    293             }
    294          });
    295 
    296       }
    297 
    298       [[eosio::action]]
    299       void withdraw( const name to, const asset& quantity ) {
    300          require_auth( to );
    301 
    302          eosio_assert( quantity.is_valid(), "invalid quantity" );
    303          eosio_assert( quantity.amount > 0, "must withdraw positive quantity" );
    304 
    305          auto itr = accounts.find( to.value );
    306          eosio_assert(itr != accounts.end(), "unknown account");
    307 
    308          accounts.modify( itr, to, [&]( auto& acnt ) {
    309             // eosio_assert( acnt.eos_balance >= quantity, "insufficient balance" );
    310             // acnt.eos_balance -= quantity;
    311 
    312             for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
    313                if(iter->symbol == quantity.symbol){
    314                   eosio_assert( (*iter) >= quantity, "insufficient balance" );
    315                   (*iter) -= quantity;
    316                   print( "withdraw : ", asset{quantity} );
    317                   break;
    318                }
    319             }
    320          });
    321 
    322          action(
    323             permission_level{ _self, "active"_n },
    324             "eosio.token"_n, "transfer"_n,
    325             std::make_tuple(_self, to, quantity, std::string(""))
    326          ).send();
    327 
    328          if( itr->is_empty() ) {
    329             accounts.erase(itr);
    330          }
    331       }
    332 
    333    private:
    334       //@abi table offer i64
    335       struct [[eosio::table]] offer {
    336          uint64_t          id;
    337          name              owner;
    338          asset             bet;
    339          capi_checksum256  commitment;
    340          uint64_t          gameid = 0;
    341 
    342          uint64_t primary_key()const { return id; }
    343 
    344          uint64_t by_bet()const { return (uint64_t)bet.amount; }
    345 
    346          fixed_bytes<32> by_commitment()const { return get_commitment(commitment); }
    347 
    348          static fixed_bytes<32> get_commitment(const capi_checksum256& commitment) {
    349             const uint64_t *p64 = reinterpret_cast<const uint64_t *>(&commitment);
    350             return fixed_bytes<32>::make_from_word_sequence<uint64_t>(p64[0], p64[1], p64[2], p64[3]);
    351          }
    352 
    353          EOSLIB_SERIALIZE( offer, (id)(owner)(bet)(commitment)(gameid) )
    354       };
    355 
    356       // typedef eosio::multi_index< N(offer), offer,
    357       //    indexed_by< N(bet), const_mem_fun<offer, uint64_t, &offer::by_bet > >,
    358       //    indexed_by< N(commitment), const_mem_fun<offer, fixed_bytes<32>,  &offer::by_commitment> >
    359       // > offer_index;
    360 
    361       typedef eosio::multi_index< "offers"_n, offer,
    362          indexed_by< "bet"_n, const_mem_fun<offer, uint64_t, &offer::by_bet > >,
    363          indexed_by< "commitment"_n, const_mem_fun<offer, fixed_bytes<32>,  &offer::by_commitment> >
    364       > offer_index_table;
    365 
    366 
    367 
    368       struct [[eosio::table]] player {
    369          capi_checksum256 commitment;
    370          capi_checksum256 reveal;
    371 
    372          EOSLIB_SERIALIZE( player, (commitment)(reveal) )
    373       };
    374 
    375       //@abi table game i64
    376       struct [[eosio::table]] game {
    377          uint64_t id;
    378          asset    bet;
    379          eosio::time_point_sec deadline;
    380          player   player1;
    381          player   player2;
    382 
    383          uint64_t primary_key()const { return id; }
    384 
    385          EOSLIB_SERIALIZE( game, (id)(bet)(deadline)(player1)(player2) )
    386       };
    387 
    388       // typedef eosio::multi_index< N(game), game> game_index;
    389       typedef eosio::multi_index< "games"_n, game> game_index_table;
    390 
    391       //@abi table global i64
    392       struct [[eosio::table]] global_dice {
    393          uint64_t id = 0;
    394          uint64_t nextgameid = 0;
    395 
    396          uint64_t primary_key()const { return id; }
    397 
    398          EOSLIB_SERIALIZE( global_dice, (id)(nextgameid) )
    399       };
    400 
    401       // typedef eosio::multi_index< N(global), global_dice> global_dice_index;
    402       typedef eosio::multi_index< "globals"_n, global_dice> global_dice_index_table;
    403 
    404       //@abi table account i64
    405       struct [[eosio::table]] account {
    406          account( name o = name() ):owner(o){}
    407 
    408          name         owner;
    409          // asset        eos_balance;
    410          std::vector<asset> eos_balance;
    411          uint32_t     open_offers = 0;
    412          uint32_t     open_games = 0;
    413 
    414          // bool is_empty()const { return !( eos_balance.amount | open_offers | open_games ); }
    415          bool is_empty()const { return !( !eos_balance.empty() | open_offers | open_games ); }
    416 
    417          uint64_t primary_key()const { return owner.value; }
    418 
    419          EOSLIB_SERIALIZE( account, (owner)(eos_balance)(open_offers)(open_games) )
    420       };
    421 
    422       // typedef eosio::multi_index< N(account), account> account_index;
    423       typedef eosio::multi_index< "accounts"_n, account> account_index_table;
    424 
    425       offer_index_table       offers;
    426       game_index_table        games;
    427       global_dice_index_table global_dices;
    428       account_index_table     accounts;
    429 
    430       bool has_offer( const capi_checksum256& commitment )const {
    431          auto idx = offers.template get_index<"commitment"_n>();
    432          auto itr = idx.find( offer::get_commitment(commitment) );
    433          return itr != idx.end();
    434       }
    435 
    436       bool is_equal(const capi_checksum256& a, const capi_checksum256& b)const {
    437          return memcmp((void *)&a, (const void *)&b, sizeof(capi_checksum256)) == 0;
    438       }
    439 
    440       bool is_zero(const capi_checksum256& a)const {
    441          const uint64_t *p64 = reinterpret_cast<const uint64_t*>(&a);
    442          return p64[0] == 0 && p64[1] == 0 && p64[2] == 0 && p64[3] == 0;
    443       }
    444 
    445       void pay_and_clean(const game& g, const offer& winner_offer,
    446           const offer& loser_offer) {
    447 
    448          // Update winner account balance and game count
    449          auto winner_account = accounts.find(winner_offer.owner.value);
    450          accounts.modify( winner_account, winner_offer.owner, [&]( auto& acnt ) {
    451             for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
    452                if(iter->symbol == g.bet.symbol){
    453                   (*iter) += 2*g.bet;
    454                   print( "pay_and_clean : ", asset{2*g.bet} );
    455                   break;
    456                }
    457             }
    458             // acnt.eos_balance += 2*g.bet;
    459             acnt.open_games--;
    460          });
    461 
    462          // Update losser account game count
    463          auto loser_account = accounts.find(loser_offer.owner.value);
    464          accounts.modify( loser_account, loser_offer.owner, [&]( auto& acnt ) {
    465             acnt.open_games--;
    466          });
    467 
    468          if( loser_account->is_empty() ) {
    469             accounts.erase(loser_account);
    470          }
    471 
    472          games.erase(g);
    473          offers.erase(winner_offer);
    474          offers.erase(loser_offer);
    475       }
    476 };
    477 
    478 EOSIO_DISPATCH( dice, (offerbet)(canceloffer)(reveal)(claimexpired)(deposit)(withdraw) )
  • 相关阅读:
    Confluence未授权模板注入/代码执行(CVE-2019-3396)
    Python实现批量处理扫描特定目录
    windows10 缺失 msvcp140.dll 解决办法
    nessus 故障处理
    python 处理json数据
    python 实现两个文本文件内容去重
    python3 实现多域名批量访问特定目录(一)
    python 简单的实现文件内容去重
    python 实现爬取网站下所有URL
    php强大的filter过滤用户输入
  • 原文地址:https://www.cnblogs.com/tyche116/p/11533593.html
Copyright © 2011-2022 走看看