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

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

 uint64_t string_to_symbol_c(uint8_t precision, const char* str) {
uint32_t len = ;
while (str[len]) ++len; uint64_t result = ;
// No validation is done at compile time
for (uint32_t i = ; i < len; ++i) {
result |= (uint64_t(str[i]) << (*(+i)));
} result |= uint64_t(precision);
return result;
} #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的其他资产,因此自己做了一点修改以支持测试的自定义资产,供自己测试

完整修改代码如下:

 /**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#include <utility>
#include <vector>
#include <string>
#include <eosiolib/eosio.hpp>
#include <eosiolib/time.hpp>
#include <eosiolib/asset.hpp>
#include <eosiolib/contract.hpp>
#include <eosiolib/crypto.h>
#include <eosiolib/fixed_bytes.hpp>
#include <eosiolib/symbol.hpp> using eosio::fixed_bytes;
using eosio::indexed_by;
using eosio::const_mem_fun;
using eosio::asset;
using eosio::permission_level;
using eosio::action;
using eosio::print;
using eosio::name;
using eosio::symbol; uint64_t string_to_symbol_c(uint8_t precision, const char* str) {
uint32_t len = ;
while (str[len]) ++len; uint64_t result = ;
// No validation is done at compile time
for (uint32_t i = ; i < len; ++i) {
result |= (uint64_t(str[i]) << (*(+i)));
} result |= uint64_t(precision);
return result;
} #define CORE_SYMBOL string_to_symbol_c(4,"SYS") class [[eosio::contract("dice")]] dice : public eosio::contract {
public:
using contract::contract; const uint32_t FIVE_MINUTES = *; dice(name s, name code, eosio::datastream<const char*> ds):eosio::contract(s,code,ds),
offers(_self, _self.value),
games(_self, _self.value),
global_dices(_self, _self.value),
accounts(_self, _self.value)
{} [[eosio::action]]
void offerbet(const asset& bet, const name player, const capi_checksum256& commitment) { //eosio_assert( bet.symbol == symbol(CORE_SYMBOL), "only core token allowed" );
eosio_assert( bet.is_valid(), "invalid bet" );
eosio_assert( bet.amount > , "must bet positive quantity" ); eosio_assert( !has_offer( commitment ), "offer with this commitment already exist" );
require_auth( player ); auto cur_player_itr = accounts.find( player.value );
eosio_assert(cur_player_itr != accounts.end(), "unknown account"); // Store new offer
auto new_offer_itr = offers.emplace(_self, [&](auto& offer){
offer.id = offers.available_primary_key();
offer.bet = bet;
offer.owner = player;
offer.commitment = commitment;
offer.gameid = ;
}); // Try to find a matching bet
auto idx = offers.template get_index<"bet"_n>();
auto matched_offer_itr = idx.lower_bound( (uint64_t)new_offer_itr->bet.amount ); if( matched_offer_itr == idx.end()
|| matched_offer_itr->bet != new_offer_itr->bet
|| matched_offer_itr->owner == new_offer_itr->owner ) { // No matching bet found, update player's account
accounts.modify( cur_player_itr, player, [&](auto& acnt) {
//eosio_assert( acnt.eos_balance >= bet, "insufficient balance" );
//acnt.eos_balance -= bet;
for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
if(iter->symbol == bet.symbol){
eosio_assert( (*iter) >= bet, "insufficient balance" );
(*iter) -= bet;
print( "offerbet1 : ", asset{bet} );
break;
}
}
acnt.open_offers++;
}); } else {
// Create global game counter if not exists
auto gdice_itr = global_dices.begin();
if( gdice_itr == global_dices.end() ) {
gdice_itr = global_dices.emplace(_self, [&](auto& gdice){
gdice.nextgameid=;
});
} // Increment global game counter
global_dices.modify(gdice_itr, _self, [&](auto& gdice){
gdice.nextgameid++;
}); // Create a new game
auto game_itr = games.emplace(_self, [&](auto& new_game){
new_game.id = gdice_itr->nextgameid;
new_game.bet = new_offer_itr->bet;
new_game.deadline = eosio::time_point_sec(); new_game.player1.commitment = matched_offer_itr->commitment;
memset(&new_game.player1.reveal, , sizeof(capi_checksum256)); new_game.player2.commitment = new_offer_itr->commitment;
memset(&new_game.player2.reveal, , sizeof(capi_checksum256));
}); // Update player's offers
idx.modify(matched_offer_itr, _self, [&](auto& offer){
offer.bet.amount = ;
offer.gameid = game_itr->id;
}); offers.modify(new_offer_itr, _self, [&](auto& offer){
offer.bet.amount = ;
offer.gameid = game_itr->id;
}); // Update player's accounts
accounts.modify( accounts.find( matched_offer_itr->owner.value ), matched_offer_itr->owner, [&](auto& acnt) {
acnt.open_offers--;
acnt.open_games++;
}); accounts.modify( cur_player_itr, player, [&](auto& acnt) {
//eosio_assert( acnt.eos_balance >= bet, "insufficient balance" );
// acnt.eos_balance -= bet;
for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
if(iter->symbol == bet.symbol){
eosio_assert( (*iter) >= bet, "insufficient balance" );
(*iter) -= bet;
print( "offerbet2 : ", asset{bet} );
break;
}
}
acnt.open_games++;
});
}
} [[eosio::action]]
void canceloffer( const capi_checksum256& commitment ) { auto idx = offers.template get_index<"commitment"_n>();
auto offer_itr = idx.find( offer::get_commitment(commitment) ); eosio_assert( offer_itr != idx.end(), "offer does not exists" );
eosio_assert( offer_itr->gameid == , "unable to cancel offer" );
require_auth( offer_itr->owner ); auto acnt_itr = accounts.find(offer_itr->owner.value);
accounts.modify(acnt_itr, offer_itr->owner, [&](auto& acnt){
acnt.open_offers--;
// acnt.eos_balance += offer_itr->bet; for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
if(iter->symbol == offer_itr->bet.symbol){
(*iter) += offer_itr->bet;
print( "canceloffer : ", asset{offer_itr->bet} );
break;
}
}
}); idx.erase(offer_itr);
} [[eosio::action]]
void reveal( const capi_checksum256& commitment, const capi_checksum256& source ) { assert_sha256( (char *)&source, sizeof(source), (const capi_checksum256 *)&commitment ); auto idx = offers.template get_index<"commitment"_n>();
auto curr_revealer_offer = idx.find( offer::get_commitment(commitment) ); eosio_assert(curr_revealer_offer != idx.end(), "offer not found");
eosio_assert(curr_revealer_offer->gameid > , "unable to reveal"); auto game_itr = games.find( curr_revealer_offer->gameid ); player curr_reveal = game_itr->player1;
player prev_reveal = game_itr->player2; if( !is_equal(curr_reveal.commitment, commitment) ) {
std::swap(curr_reveal, prev_reveal);
} eosio_assert( is_zero(curr_reveal.reveal) == true, "player already revealed"); if( !is_zero(prev_reveal.reveal) ) { capi_checksum256 result;
sha256( (char *)&game_itr->player1, sizeof(player)*, &result); auto prev_revealer_offer = idx.find( offer::get_commitment(prev_reveal.commitment) ); int winner = result.hash[] < result.hash[] ? : ; if( winner ) {
pay_and_clean(*game_itr, *curr_revealer_offer, *prev_revealer_offer);
} else {
pay_and_clean(*game_itr, *prev_revealer_offer, *curr_revealer_offer);
} } else {
games.modify(game_itr, _self, [&](auto& game){ if( is_equal(curr_reveal.commitment, game.player1.commitment) )
game.player1.reveal = source;
else
game.player2.reveal = source; game.deadline = eosio::time_point_sec(now() + FIVE_MINUTES);
});
}
} [[eosio::action]]
void claimexpired( const uint64_t gameid ) { auto game_itr = games.find(gameid); eosio_assert(game_itr != games.end(), "game not found");
eosio_assert(game_itr->deadline != eosio::time_point_sec() && eosio::time_point_sec(now()) > game_itr->deadline, "game not expired"); auto idx = offers.template get_index<"commitment"_n>();
auto player1_offer = idx.find( offer::get_commitment(game_itr->player1.commitment) );
auto player2_offer = idx.find( offer::get_commitment(game_itr->player2.commitment) ); if( !is_zero(game_itr->player1.reveal) ) {
eosio_assert( is_zero(game_itr->player2.reveal), "game error");
pay_and_clean(*game_itr, *player1_offer, *player2_offer);
} else {
eosio_assert( is_zero(game_itr->player1.reveal), "game error");
pay_and_clean(*game_itr, *player2_offer, *player1_offer);
} } [[eosio::action]]
void deposit( const name from, const asset& quantity ) { eosio_assert( quantity.is_valid(), "invalid quantity" );
eosio_assert( quantity.amount > , "must deposit positive quantity" ); auto itr = accounts.find(from.value);
if( itr == accounts.end() ) {
itr = accounts.emplace(_self, [&](auto& acnt){
acnt.owner = from;
});
} action(
permission_level{ from, "active"_n },
"eosio.token"_n, "transfer"_n,
std::make_tuple(from, _self, quantity, std::string(""))
).send(); accounts.modify( itr, from, [&]( auto& acnt ) {
//acnt.eos_balance += quantity;
bool isfound = false;
for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
if(iter->symbol == quantity.symbol){
(*iter) += quantity;
isfound = true;
print( "deposit more : ", asset{quantity} );
break;
}
}
if(!isfound){
acnt.eos_balance.emplace_back(quantity);
print( "deposit add : ", asset{quantity} );
}
}); } [[eosio::action]]
void withdraw( const name to, const asset& quantity ) {
require_auth( to ); eosio_assert( quantity.is_valid(), "invalid quantity" );
eosio_assert( quantity.amount > , "must withdraw positive quantity" ); auto itr = accounts.find( to.value );
eosio_assert(itr != accounts.end(), "unknown account"); accounts.modify( itr, to, [&]( auto& acnt ) {
// eosio_assert( acnt.eos_balance >= quantity, "insufficient balance" );
// acnt.eos_balance -= quantity; for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
if(iter->symbol == quantity.symbol){
eosio_assert( (*iter) >= quantity, "insufficient balance" );
(*iter) -= quantity;
print( "withdraw : ", asset{quantity} );
break;
}
}
}); action(
permission_level{ _self, "active"_n },
"eosio.token"_n, "transfer"_n,
std::make_tuple(_self, to, quantity, std::string(""))
).send(); if( itr->is_empty() ) {
accounts.erase(itr);
}
} private:
//@abi table offer i64
struct [[eosio::table]] offer {
uint64_t id;
name owner;
asset bet;
capi_checksum256 commitment;
uint64_t gameid = ; uint64_t primary_key()const { return id; } uint64_t by_bet()const { return (uint64_t)bet.amount; } fixed_bytes<> by_commitment()const { return get_commitment(commitment); } static fixed_bytes<> get_commitment(const capi_checksum256& commitment) {
const uint64_t *p64 = reinterpret_cast<const uint64_t *>(&commitment);
return fixed_bytes<>::make_from_word_sequence<uint64_t>(p64[], p64[], p64[], p64[]);
} EOSLIB_SERIALIZE( offer, (id)(owner)(bet)(commitment)(gameid) )
}; // typedef eosio::multi_index< N(offer), offer,
// indexed_by< N(bet), const_mem_fun<offer, uint64_t, &offer::by_bet > >,
// indexed_by< N(commitment), const_mem_fun<offer, fixed_bytes<32>, &offer::by_commitment> >
// > offer_index; typedef eosio::multi_index< "offers"_n, offer,
indexed_by< "bet"_n, const_mem_fun<offer, uint64_t, &offer::by_bet > >,
indexed_by< "commitment"_n, const_mem_fun<offer, fixed_bytes<>, &offer::by_commitment> >
> offer_index_table; struct [[eosio::table]] player {
capi_checksum256 commitment;
capi_checksum256 reveal; EOSLIB_SERIALIZE( player, (commitment)(reveal) )
}; //@abi table game i64
struct [[eosio::table]] game {
uint64_t id;
asset bet;
eosio::time_point_sec deadline;
player player1;
player player2; uint64_t primary_key()const { return id; } EOSLIB_SERIALIZE( game, (id)(bet)(deadline)(player1)(player2) )
}; // typedef eosio::multi_index< N(game), game> game_index;
typedef eosio::multi_index< "games"_n, game> game_index_table; //@abi table global i64
struct [[eosio::table]] global_dice {
uint64_t id = ;
uint64_t nextgameid = ; uint64_t primary_key()const { return id; } EOSLIB_SERIALIZE( global_dice, (id)(nextgameid) )
}; // typedef eosio::multi_index< N(global), global_dice> global_dice_index;
typedef eosio::multi_index< "globals"_n, global_dice> global_dice_index_table; //@abi table account i64
struct [[eosio::table]] account {
account( name o = name() ):owner(o){} name owner;
// asset eos_balance;
std::vector<asset> eos_balance;
uint32_t open_offers = ;
uint32_t open_games = ; // bool is_empty()const { return !( eos_balance.amount | open_offers | open_games ); }
bool is_empty()const { return !( !eos_balance.empty() | open_offers | open_games ); } uint64_t primary_key()const { return owner.value; } EOSLIB_SERIALIZE( account, (owner)(eos_balance)(open_offers)(open_games) )
}; // typedef eosio::multi_index< N(account), account> account_index;
typedef eosio::multi_index< "accounts"_n, account> account_index_table; offer_index_table offers;
game_index_table games;
global_dice_index_table global_dices;
account_index_table accounts; bool has_offer( const capi_checksum256& commitment )const {
auto idx = offers.template get_index<"commitment"_n>();
auto itr = idx.find( offer::get_commitment(commitment) );
return itr != idx.end();
} bool is_equal(const capi_checksum256& a, const capi_checksum256& b)const {
return memcmp((void *)&a, (const void *)&b, sizeof(capi_checksum256)) == ;
} bool is_zero(const capi_checksum256& a)const {
const uint64_t *p64 = reinterpret_cast<const uint64_t*>(&a);
return p64[] == && p64[] == && p64[] == && p64[] == ;
} void pay_and_clean(const game& g, const offer& winner_offer,
const offer& loser_offer) { // Update winner account balance and game count
auto winner_account = accounts.find(winner_offer.owner.value);
accounts.modify( winner_account, winner_offer.owner, [&]( auto& acnt ) {
for(auto iter = acnt.eos_balance.begin(); iter != acnt.eos_balance.end(); iter++){
if(iter->symbol == g.bet.symbol){
(*iter) += *g.bet;
print( "pay_and_clean : ", asset{*g.bet} );
break;
}
}
// acnt.eos_balance += 2*g.bet;
acnt.open_games--;
}); // Update losser account game count
auto loser_account = accounts.find(loser_offer.owner.value);
accounts.modify( loser_account, loser_offer.owner, [&]( auto& acnt ) {
acnt.open_games--;
}); if( loser_account->is_empty() ) {
accounts.erase(loser_account);
} games.erase(g);
offers.erase(winner_offer);
offers.erase(loser_offer);
}
}; EOSIO_DISPATCH( dice, (offerbet)(canceloffer)(reveal)(claimexpired)(deposit)(withdraw) )

EOS dice移到1.8版本的修改汇总的更多相关文章

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

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

  2. Python 如何移除旧的版本特性,如何迎接新的特性?

    2020 年 4 月 20 日,Python 2 的最后一个版本 2.7.18 发布了,这意味着 Python 2 是真正的 EOL(end of life)了,一个时代终于落幕了. Python 2 ...

  3. Git技法:.gitignore、移除暂存与撤销修改

    1. .gitignore常见项目添加 1.1 .gitignore模板 .gitignore针对每个语言都有对应的模板,在GitHub创建项目时就可以选择(你可以在GitHub提供的.gitigno ...

  4. RedHat 和 Mirantis OpenStack 产品的版本和功能汇总和对比(持续更新)

    Mirantis 和 Red Hat 作为 OpenStack 商业化产品领域的两大领军企业,在行业内有重要的地位.因此,研究其产品版本发布周期和所支持的功能,对制定 OpenStack 产品的版本和 ...

  5. 第五次团队作业——【Alpha版本】随笔汇总

    031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬涛 [Alp ...

  6. Debian下查看系统版本信息命令汇总

    Debian下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等等,整个CPU信息一目了然. 1.odoo@debian64:~$ uname -a(Debian查看版本当前操 ...

  7. iOS——Command-Line 查看当前SDK版本并修改默认SDK版本

    在工作中可能会碰到用命令行编译.打包iOS应用程序的情况(xcodebuild相关命令). 但是由于SDK版本问题,会报错,说某SDK版本不对,可能是因为升级Xcode导致的SDK版本升级,为了避免高 ...

  8. 【转发】查看Linux版本系统信息方法汇总

    Linux下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等等,整个CPU信息一目了然.   1.# uname -a   (Linux查看版本当前操作系统内核信息)   L ...

  9. 查看Linux版本系统信息方法汇总

    Linux下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等等,整个CPU信息一目了然.  1.# uname -a   (Linux查看版本当前操作系统内核信息)  Lin ...

随机推荐

  1. 骨牌摆放方案数n*m(状压DP)

    题意:https://www.nitacm.com/problem_show.php?pid=1378 如题. 思路: 从第一行for到最后一行,枚举每一行的所有状态,进行转移,注意答案是dp[最后一 ...

  2. PHP数组和对象之间的互换

    今天在和前端对接接口的时候,从后台返回数据给前端的时候出现如下JSON格式数据 "goods": [ { "id": "dEQ144800584Lx& ...

  3. 同一台服务器请求easyswoole的一个websocket接口报错

    求助大神啊!file_get_contents报这个错:failed to open stream: Connection timed out换成curl又报这个错:couldn't connect ...

  4. Jmeter的基础使用一安装、启动、关联、断言

    一.下载Jmeter,配置环境变量 下载完解压即可, 环境变量配置: -------在环境变量中添加新变量JMETER_HOME:D:\jmeter\apache-jmeter-4.0 ------- ...

  5. 深入理解Redux之手写React-Redux

    React-Redux主要由两部分组成,一是Provider(提供者),顾名思义作用就是提供状态数据. 另一部分是connect函数,它的作用是把UI组件和状态数据“连接”起来,实现了Model和Vi ...

  6. 你懂什么是分布式系统吗?Redis分布式锁都不会?

    分布式系统涉及到很多的技术.理论与协议,很多人也说,分布式系统是“入门容易,深入难”,有一些人简历上写着熟悉分布式系统,很多人都是管中窥豹只见一斑. 究竟什么是分布式系统? 分布式系统是由一组通过网络 ...

  7. C#面向对象10 继承

    1.继承: **** 我们可能会在一些类中,写一些重复的成员.我们可以将这些重复的成员,单独的封装到一个类中,作为这些类的父类. Student,Teacher,Driver ----子类  派生类 ...

  8. 在Global.asax中 注册Application_Error事件 捕获全局异常

    参考于:https://shiyousan.com/post/635813858052755170 在ASP.NET MVC中,通过应用程序生命周期中的Application_Error事件可以捕获到 ...

  9. Laravel 查询或写入Enum字段出错的bug解决办法

    查询: if($request->filled('type')){ $where[] = ['type', strval(intval($request->input('type')))] ...

  10. vue进阶:vuex(数据池)

    非父子组件传值 vuex 一.非父子组件传值 基于父子组件通信与传值实现非父子组件传值的示例关键代码: <template> <div> <!-- 学员展示 --> ...