EOS dice移到1.8版本的修改汇总
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版本的修改汇总的更多相关文章
- linux下面升级 Python版本并修改yum属性信息
最近需要在linux下使用python,故需要升级一下python版本,上网查询了一下相关资料,更新了一下linux下面的python环境,记录如下: linux下面升级 Python版本并修改yum ...
- Python 如何移除旧的版本特性,如何迎接新的特性?
2020 年 4 月 20 日,Python 2 的最后一个版本 2.7.18 发布了,这意味着 Python 2 是真正的 EOL(end of life)了,一个时代终于落幕了. Python 2 ...
- Git技法:.gitignore、移除暂存与撤销修改
1. .gitignore常见项目添加 1.1 .gitignore模板 .gitignore针对每个语言都有对应的模板,在GitHub创建项目时就可以选择(你可以在GitHub提供的.gitigno ...
- RedHat 和 Mirantis OpenStack 产品的版本和功能汇总和对比(持续更新)
Mirantis 和 Red Hat 作为 OpenStack 商业化产品领域的两大领军企业,在行业内有重要的地位.因此,研究其产品版本发布周期和所支持的功能,对制定 OpenStack 产品的版本和 ...
- 第五次团队作业——【Alpha版本】随笔汇总
031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬涛 [Alp ...
- Debian下查看系统版本信息命令汇总
Debian下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等等,整个CPU信息一目了然. 1.odoo@debian64:~$ uname -a(Debian查看版本当前操 ...
- iOS——Command-Line 查看当前SDK版本并修改默认SDK版本
在工作中可能会碰到用命令行编译.打包iOS应用程序的情况(xcodebuild相关命令). 但是由于SDK版本问题,会报错,说某SDK版本不对,可能是因为升级Xcode导致的SDK版本升级,为了避免高 ...
- 【转发】查看Linux版本系统信息方法汇总
Linux下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等等,整个CPU信息一目了然. 1.# uname -a (Linux查看版本当前操作系统内核信息) L ...
- 查看Linux版本系统信息方法汇总
Linux下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等等,整个CPU信息一目了然. 1.# uname -a (Linux查看版本当前操作系统内核信息) Lin ...
随机推荐
- 2019-07-31 C#基础知识学习
什么是进程:进程是系统中正在运行的一个程序,程序一旦运行就是进程. 什么是线程:线程是进程的一个实体,是进程的一条执行路径. 进程和线程的区别体现在以下几个方面: 1.地址空间和其他资源(如打开文件) ...
- acm java入门(转载)
ACM中java的使用 http://www.cnblogs.com/XBWer/archive/2012/06/24/2560532.html 这里指的java速成,只限于java语法,包括输入输出 ...
- PAT B1022 D进制的A+B
课本AC代码 #include <cstdio> int main() { int a, b, d; scanf("%d%d%d", &a, &b, & ...
- DRF 序列化组件 序列化的两种方式 反序列化 反序列化的校验
序列化组件 django自带的有序列化组件不过不可控不建议使用(了解) from django.core import serializers class Books(APIView): def ge ...
- CNN中卷积层 池化层反向传播
参考:https://blog.csdn.net/kyang624823/article/details/78633897 卷积层 池化层反向传播: 1,CNN的前向传播 a)对于卷积层,卷积核与输入 ...
- 【多重背包】Transport Ship
[来源] 2018年焦作网络赛 [参考博客] https://blog.csdn.net/baymax520/article/details/82719454 [题意] 有N种船只,每种船只的载货量为 ...
- lua的数据类型
Lua 是动态(弱)类型的语言,它有一下几种数据结构: nil(空) nil 类型表示一种没有任何有效值,它只有一个值 -- nil,例如打印一个没有赋值的变量,便会输出一个 nil 值: print ...
- 23-Perl 面向对象
1.Perl 面向对象Perl 中有两种不同地面向对象编程的实现:一是基于匿名哈希表的方式,每个对象实例的实质就是一个指向匿名哈希表的引用.在这个匿名哈希表中,存储来所有的实例属性.二是基于数组的方式 ...
- Python算法题(二)——国际象棋棋盘(排列组合问题,最小的K个数)
题目一(输出国际象棋棋盘) 分析: 用i控制行,j来控制列,根据i+j的和的变化来控制输出黑方格,还是白方格. 主要代码: for i in range(8): for j in range(8 ...
- 初识python之了解其背景和安装
1.Python的发展 Python语言诞生于1990年,由Guido van Rossum设计并领导开发.1989年12月,Guido考虑启动一个开发项目以打发圣诞节前后的时间,所以决定为当时正在构 ...