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) )

转载于:https://www.cnblogs.com/tyche116/p/11533593.html

EOS dice移到1.8版本的修改汇总相关推荐

  1. EOS测试链加入流程(代码版本与主网同步)

    测试网络 EOS 测试链加入流程 (代码版本与主网同步) caokun_8341 · 4 分钟前 · 5 次阅读 准备:测试链目前的版本是v1.7.3 一.生成一个密钥对,私钥一定保存好,不要泄露,公 ...

  2. linux下面升级 Python版本并修改yum属性信息

    最近需要在linux下使用python,故需要升级一下python版本,上网查询了一下相关资料,更新了一下linux下面的python环境,记录如下: linux下面升级 Python版本并修改yum ...

  3. linux python版本_linux下更新Python版本并修改默认版本

    linux下更新Python版本并修改默认版本,有需要的朋友可以参考下. 很多情况下拿到的服务器python版本很低,需要自己动手更改默认python版本 1.从官网下载python安装包(这个版本可 ...

  4. linux中更新python_linux下面升级 Python版本并修改yum属性信息

    最近需要在linux下使用python,故需要升级一下python版本,上网查询了一下相关资料,更新了一下linux下面的python环境,记录如下: linux下面升级 Python版本并修改yum ...

  5. mysql5.5与5.5版本关于修改字符集的方法

    mysql5.5与5.5版本关于修改字符集的方法 # vi /etc/my.cnf mysql5.5以下: 在[mysqld]下添加 default-character-set=utf8 在[clie ...

  6. python更新到什么版本_Linux更新Python版本及修改python默认版本的方法

    linux下更新Python版本并修改默认版本,有需要的朋友可以参考下. 很多情况下拿到的服务器python版本很低,需要自己动手更改默认python版本 1.从官网下载python安装包(这个版本可 ...

  7. mysql5.7版本怎么修改密码,mysql 5.7版本修改密码的简单方法

    mysql 5.7版本修改密码的简单方法 这是官方截图,mysql5.7安装后,会有一个默认密码,保存在mysql.log里面,找的他,并更改 官方文档地址 以上所述是小编给大家介绍的mysql 5. ...

  8. 网易云音乐推出的Linux版本安装包汇总

    网易云音乐推出的Linux版本安装包汇总 deepin15(32位):http://s1.music.126.net/download/pc/netease-cloud-music_0.9.0_i38 ...

  9. mysql workbench 修改密码_MySql8.0以上版本正确修改ROOT密码的方法

    部署环境: 安装版本red hat Cent 7.0 MYSQL 版本 8.0.2.0 成功部署完毕后出现故障情况: 1.      正常启动MYSQL服务后,敲Linux中root账户和密码进入不去 ...

最新文章

  1. 从Java类库看设计模式
  2. CFString​Transform
  3. 《COM组件开发实践》系列文章
  4. 出现java.lang.UnsupportedClassVersionError 错误的原因
  5. Eclipse 设置SVN忽略文件
  6. 解决 There are no resources that can be added or removed from the server
  7. 这些年Android面试的那些套路,社招面试心得
  8. 锁定表头和固定列(Fixed table head and columns)
  9. 使用 node.js 进行服务器端 JavaScript 编程
  10. HTML中input是啥意思,HTML中input是什么意思
  11. 中兴手机数据通道打不开_换了个新手机
  12. java基础算法题(入门题与简单题)
  13. camera驱动电源配置_电源行业发展前景如何?
  14. 深度学习小笔记04-魏秀参《解析深度学习-卷积神经网络原理与视觉实践》
  15. android 点赞源码,【Ctrl.js】微信给最新一条消息点赞源码
  16. Visual Studio内存泄露检测工具
  17. vue 有关于命名大小写的问题
  18. Fractions to Decimals
  19. 体验华为操作系统 openEuler 20.03 LTS linux
  20. 如何破解EXCEL的单元格保护密码

热门文章

  1. java 控制台输入
  2. 如何做到异构数据的同步一致性
  3. php 多核cpu,paip.提升性能--多核cpu中的java/.net/php/c++编程
  4. Ubuntu20.04浏览器上网慢解决方法——体验优化
  5. 微信小程序订单展示(3)
  6. 适合国人的6款免费远程桌面工具,适用于电脑和手机
  7. uniapp中登录注册页面以视频为背景
  8. pytest框架中setup、teardown和setup_class、teardown_class
  9. Markdown表格中换行、合并单元格
  10. hdwiki上传附件不显示bug解决办法