#include <eosio/eosio.hpp>
#include <eosio/asset.hpp>
#include <eosio/transaction.hpp>
#include <eosio/crypto.hpp>
#include <eosio/time.hpp>
#include <eosio/system.hpp>
#include <eosio/print.hpp>
using namespace eosio;
using namespace std;
CONTRACT pvpbetwallet : public contract {
? public:
? ? ? using contract::contract;
? ? ? pvpbetwallet( name receiver, name code, datastream<const char*> ds )
? ? ? ? : contract(receiver, code, ds), boardtable(receiver, receiver.value), bettable(receiver, receiver.value) {}
? ? ? ACTION transfer(name from, name to, asset quantity, string memo);
? ? ? ACTION reveal(const uint64_t &table_id, const checksum256 &seed);
? ? ? ACTION send(const int &index, const name &winner, const uint64_t &table_id);? ? ?
? ? ? ? // EOSIO network
? ? const string symbol_name = "EOS";
? ? // Contract network
? ? const symbol network_symbol = symbol(symbol_name, 4);
? ? const name & lord? = name("suwzhaoihuan");
? ? const name & wallet = name("pvpbetwallet");
? ? const int values[16][3] = {
? ? ? ? {1000, 1960, 40},
? ? ? ? {1960, 3840, 80},
? ? ? ? {3840, 7520, 160},
? ? ? ? {7520, 14720, 320},
? ? ? ? {14720, 28800, 640},
? ? ? ? {28800, 56320, 1280},
? ? ? ? {56320, 110080, 2560},
? ? ? ? {110080, 215040, 5120},
? ? ? ? {215040, 419840, 10240},
? ? ? ? {419840, 819200, 20480},
? ? ? ? {819200, 1597440, 40960},
? ? ? ? {1597440, 3112960, 81920},
? ? ? ? {3112960, 6062080, 163840},
? ? ? ? {6062080, 11796480, 327680},
? ? ? ? {11796480, 22937600, 655360},
? ? ? ? {22937600, 44564480, 1310720}
? ? };
? ? time_point next(){
? ? ? ? return current_time_point() + seconds(360);
? ? }
? ? int findIndex(asset quantity){
? ? ? ? for (int i = 0; i < 16; i++){
? ? ? ? ? ? if (quantity.amount == values[i][0]){
? ? ? ? ? ? ? ? return i;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? check(false, "quantity index not found");
? ? }
? ? void split(const std::string &s, vector<std::string> &v, const std::string &c){
? ? ? ? std::string::size_type pos1, pos2;
? ? ? ? pos2 = s.find(c);
? ? ? ? pos1 = 0;
? ? ? ? while (std::string::npos != pos2){
? ? ? ? ? ? v.push_back(s.substr(pos1, pos2 - pos1));
? ? ? ? ? ? pos1 = pos2 + c.size();
? ? ? ? ? ? pos2 = s.find(c, pos1);
? ? ? ? }
? ? ? ? if (pos1 != s.length()){
? ? ? ? ? ? v.push_back(s.substr(pos1));
? ? ? ? }
? ? }
TABLE board_table {
? ? ? ? ? ? // 僅有一條記錄
? ? ? ? ? ? uint64_t id;
? ? ? ? ? ? // 登頂時間
? ? ? ? ? ? time_point top_time;
? ? ? ? ? ? // 目前積累的獎賞
? ? ? ? ? ? asset pool;
? ? ? ? ? ? // 當(dāng)前頭部用戶
? ? ? ? ? ? name player_name;
? ? ? ? ? ? // 頭部用戶投注額分紅后進行減半操作
? ? ? ? ? ? asset quantity;
? ? ? ? ? ? // 進行下次分紅的時間诈皿。
? ? ? ? ? ? time_point next_time;
? ? ? ? ? ? uint64_t primary_key() const { return id; }
? ? ? ? ? };
? ? ? ? ? // typedef eosio::multi_index<N(表名),表的對象類型> 實例化變量名
? ? ? ? ? typedef eosio::multi_index<"boardtablea"_n, board_table> board_tables;
? ? ? ? TABLE bet_table {
? ? ? ? ? ? // 桌子的標(biāo)識
? ? ? ? ? ? uint64_t id;
? ? ? ? ? ? // 有效時間
? ? ? ? ? ? time_point valid_time;
? ? ? ? ? ? // 投注額
? ? ? ? ? ? asset quantity;
? ? ? ? ? ? // 桌子的哈希
? ? ? ? ? ? checksum256 table_hash;
? ? ? ? ? ? // 玩家1名稱
? ? ? ? ? ? name p1_name;
? ? ? ? ? ? // 玩家2名稱
? ? ? ? ? ? name p2_name;
? ? ? ? ? ? // 玩家1哈希
? ? ? ? ? ? checksum256 p1_hash;
? ? ? ? ? ? // 玩家2哈希
? ? ? ? ? ? checksum256 p2_hash;
? ? ? ? ? ? // 桌子的種子
? ? ? ? ? ? checksum256 table_seed;
? ? ? ? ? ? // 玩家1種子
? ? ? ? ? ? checksum256 p1_seed;
? ? ? ? ? ? // 玩家2種子
? ? ? ? ? ? checksum256 p2_seed;
? ? ? ? ? ? uint64_t primary_key() const { return id; }
? ? ? ? ? };
? ? ? ? ? typedef eosio::multi_index<"bettablea"_n, bet_table> bet_tables;
? ? ? using transfer_action = action_wrapper<"transfer"_n, &pvpbetwallet::transfer>;
? ? ? using reveal_action = action_wrapper<"reveal"_n, &pvpbetwallet::reveal>;
? ? ? using send_action = action_wrapper<"send"_n, &pvpbetwallet::send>;
? ? ? board_tables boardtable;
? bet_tables bettable;
};
ACTION pvpbetwallet::transfer(name from, name to, asset quantity, std::string memo){
? if (from == lord){
? ? // 補充能量
? ? return;
? }
? require_auth(_self);
? eosio::check(from != to, "cannot transfer to self");
? eosio::check(_self == to, "must transfer to this contract");
? eosio::check(memo.size() <= 256, "memo must smaller than 256");
? eosio::check(quantity.symbol == eosio::symbol("EOS", 4), "only accepts EOS");
? eosio::check(quantity.is_valid(), "invalid token transfer");
? int index = pvpbetwallet::findIndex(quantity);
? eosio::check(-1 != index, "quantity not found");
? // composed by user_id-table_hash-user_hash-user_seed-player_hash
? std::vector<std::string> memos;
? pvpbetwallet::split(memo, memos, "-");
? std::string user_id = memos[0];
? std::string table_hash = memos[1];
? std::string user_hash = memos[2];
? std::string user_seed = memos[3];
? std::string player_hash = memos[4];
? // 調(diào)試
? eosio::print("user_id:" + memos[0]);
? eosio::print("table_hash:" + memos[1]);
? eosio::print("user_hash:" + memos[2]);
? eosio::print("user_seed:" + memos[3]);
? eosio::print("player_hash:" + memos[4]);
// 驗證給定數(shù)據(jù)和其sha256哈希值是否匹配
//void assert_sha256( const char* data, uint32_t length, const eosio::checksum256& hash );
? // 選手需要檢查user_hash為user_seed生成芦疏。
? //const char* seed_sha256 = const_cast<char*>(user_seed.c_str());
? eosio::assert_sha256(user_seed.c_str, std::strlen(user_seed), user_hash);
? auto player_id = atoi(user_id.c_str);
? auto table_id = player_id / 2;
? // bet_tables bets(_code, _code.value);
? auto bet = bets.find(table_id);
? if (bet == bets.end()){
? ? bets.emplace(_self, [&](auto &bet) {
? ? ? ? bet.id = table_id;
? ? ? ? bet.valid_time = eosio::current_time_point() + 180000;
? ? ? ? bet.quantity = quantity;
? ? ? ? bet.table_hash = table_hash;
? ? ? ? bet.p1_name = from;
? ? ? ? bet.p1_hash = user_hash;
? ? ? ? bet.p2_hash = player_hash;
? ? ? ? bet.p1_seed = user_seed;
? ? });
? }else{
? ? // 選手需要檢查user_hash為user_seed生成儡蔓,
? ? // 同時檢查p1_hash與player_hash相等,同時檢查p2_hash與user_hash相等蛉抓,
? ? // 同時檢查table_hash與數(shù)據(jù)庫的table_hash相等,同時檢查數(shù)量相等。
? ? eosio::check(bet->valid_time >= eosio::current_time_point(), "time expired");
? ? eosio::check(quantity.amount == bet->quantity.amount, "must equal quantity");
? ? eosio::check(player_hash == bet->p1_hash, "must match player hash");
? ? eosio::check(user_hash == bet->p2_hash, "must match user hash");
? ? eosio::check(table_hash == bet->table_hash, "must match table hash");
? ? bets.modify(bet, _self, [&](auto &bet) {
? ? ? ? bet.p2_name = from;
? ? ? ? bet.p2_seed = user_seed;
? ? });
? }
}
ACTION pvpbetwallet::reveal(const uint64_t &table_id, const eosio::checksum256 &seed){
}
ACTION pvpbetwallet::send(const int &index, const name &winner, const uint64_t &table_id){
}