Skip to content

Commit

Permalink
cyber.box #314
Browse files Browse the repository at this point in the history
  • Loading branch information
kaynarov committed Mar 5, 2020
1 parent 7d1b147 commit 427c0b8
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ add_subdirectory(cyber.stake)
add_subdirectory(cyber.govern)
add_subdirectory(cyber.rejector)
add_subdirectory(cyber.incomereject)
add_subdirectory(cyber.box)

add_subdirectory(scripts/base-genesis)

Expand Down
1 change: 1 addition & 0 deletions common/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace cyber { namespace config {
static const auto token_name = "cyber.token"_n;
static const auto stake_name = "cyber.stake"_n;
static const auto govern_name = "cyber.govern"_n;
static const auto box_name = "cyber.box"_n;
static const auto worker_name = "cyber.worker"_n;
static const auto names_name = "cyber.names"_n;
static const auto producers_name = "cyber.prods"_n;
Expand Down
12 changes: 12 additions & 0 deletions cyber.box/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
add_contract(cyber.box cyber.box ${CMAKE_CURRENT_SOURCE_DIR}/src/cyber.box.cpp)
install_contract(cyber.box)

target_include_directories(cyber.box.wasm
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/../cyber.token/include
${CMAKE_CURRENT_SOURCE_DIR}/..)

set_target_properties(cyber.box.wasm
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
40 changes: 40 additions & 0 deletions cyber.box/include/cyber.box/cyber.box.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once
#include <eosio/eosio.hpp>
#include <eosio/time.hpp>
#include <eosio/singleton.hpp>
#include <tuple>
#include <eosio/privileged.hpp>
#include <cyber.token/cyber.token.hpp>
#include <common/dispatchers.hpp>

namespace cyber {
using eosio::name;
class [[eosio::contract("cyber.box")]] box : public eosio::contract {
struct structures {
struct box {
uint64_t id;
name contract;
name treasurer;
name title;
name owner;
bool empty;
uint64_t primary_key()const { return id; }
using key_t = std::tuple<name, name, name>;
key_t by_key()const { return std::make_tuple(contract, treasurer, title); }
};
};
using box_key_index [[using eosio: order("contract"), order("treasurer"), order("title")]] =
eosio::indexed_by<"bykey"_n, eosio::const_mem_fun<structures::box, structures::box::key_t, &structures::box::by_key> >;
using boxes [[eosio::order("id")]] = eosio::multi_index<"box"_n, structures::box, box_key_index>;

void erase_box(name contract, name treasurer, name title, bool release);
public:
using contract::contract;
[[eosio::action]] void create(name contract, name treasurer, name title);
[[eosio::action]] void packup(name contract, name treasurer, name title);
[[eosio::action]] void unpack(name contract, name treasurer, name title);
[[eosio::action]] void burn(name contract, name treasurer, name title);
[[eosio::action]] void transfer(name contract, name treasurer, name title, name to, std::string memo);
//do we need to add the ability to put boxes in a box?
};
} /// namespace cyber
68 changes: 68 additions & 0 deletions cyber.box/src/cyber.box.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <cyber.box/cyber.box.hpp>
namespace cyber {

void box::create(name contract, name treasurer, name title) {
require_auth(treasurer);
boxes boxes_table(_self, _self.value);
auto boxes_idx = boxes_table.get_index<"bykey"_n>();
eosio::check(boxes_idx.find({contract, treasurer, title}) == boxes_idx.end(), "such a box already exists");
boxes_table.emplace(treasurer, [&](auto& b) { b = {
.id = boxes_table.available_primary_key(),
.contract = contract,
.treasurer = treasurer,
.title = title,
.owner = treasurer,
.empty = true
};});
}

void box::packup(name contract, name treasurer, name title) {
require_auth(contract);
boxes boxes_table(_self, _self.value);
auto boxes_idx = boxes_table.get_index<"bykey"_n>();
auto box_itr = boxes_idx.find({contract, treasurer, title});
eosio::check(box_itr != boxes_idx.end(), "box does not exist");
eosio::check(box_itr->empty, "the box is not empty");
eosio::check(box_itr->treasurer == box_itr->owner, "SYSTEM: invalid box owner");
boxes_idx.modify(box_itr, name(), [&](auto& b) { b.empty = false; });
}

void box::erase_box(name contract, name treasurer, name title, bool release) {
boxes boxes_table(_self, _self.value);
auto boxes_idx = boxes_table.get_index<"bykey"_n>();
auto box_itr = boxes_idx.find({contract, treasurer, title});
eosio::check(box_itr != boxes_idx.end(), "box does not exist");
require_auth(box_itr->owner);
if (!box_itr->empty && release) {
eosio::action(
eosio::permission_level{_self, config::active_name},
contract, "release"_n,
std::make_tuple(treasurer, title, box_itr->owner)
).send();
}
boxes_idx.erase(box_itr);
}

void box::unpack(name contract, name treasurer, name title) {
erase_box(contract, treasurer, title, true);
}

void box::burn(name contract, name treasurer, name title) {
erase_box(contract, treasurer, title, false);
}

void box::transfer(name contract, name treasurer, name title, name to, std::string memo) {
eosio::check(is_account(to), "to account does not exist");
boxes boxes_table(_self, _self.value);
auto boxes_idx = boxes_table.get_index<"bykey"_n>();
auto box_itr = boxes_idx.find({contract, treasurer, title});
eosio::check(box_itr != boxes_idx.end(), "box does not exist");
require_auth(box_itr->owner);
eosio::check(box_itr->owner != to, "cannot transfer to self");
eosio::check(!box_itr->empty, "cannot transfer an empty box");
require_recipient(box_itr->owner);
require_recipient(to);
boxes_idx.modify(box_itr, name(), [&](auto& b) { b.owner = to; });
}

} /// namespace cyber
2 changes: 2 additions & 0 deletions tests/contracts.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ struct contracts {
static std::vector<char> stake_abi() { return read_abi(cyberway_contracts + "/cyber.stake/cyber.stake.abi"); }
static std::vector<uint8_t> govern_wasm() { return read_wasm(cyberway_contracts + "/cyber.govern/cyber.govern.wasm"); }
static std::vector<char> govern_abi() { return read_abi(cyberway_contracts + "/cyber.govern/cyber.govern.abi"); }
static std::vector<uint8_t> box_wasm() { return read_wasm(cyberway_contracts + "/cyber.box/cyber.box.wasm"); }
static std::vector<char> box_abi() { return read_abi(cyberway_contracts + "/cyber.box/cyber.box.abi"); }

struct util {
static std::vector<uint8_t> test_api_wasm() { return read_wasm(cyberway_test_contracts + "/test_api.wasm"); }
Expand Down
48 changes: 48 additions & 0 deletions tests/cyber.box_test_api.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once
#include "test_api_helper.hpp"
#include "../common/config.hpp"

using eosio::chain::symbol_code;

namespace eosio { namespace testing {

struct cyber_box_api: base_contract_api {

public:
cyber_box_api(golos_tester* tester, name code)
: base_contract_api(tester, code){}

////actions
action_result create(name contract, name treasurer, name title, name signer = name()) {
return push(N(create), signer ? signer : treasurer,
args()("contract", contract)("treasurer", treasurer)("title", title));
}
action_result packup(name contract, name treasurer, name title, name signer = name()) {
return push(N(packup), signer ? signer : contract,
args()("contract", contract)("treasurer", treasurer)("title", title));
}
action_result unpack(name contract, name treasurer, name title, name signer) {
return push(N(unpack), signer,
args()("contract", contract)("treasurer", treasurer)("title", title));
}
action_result burn(name contract, name treasurer, name title, name signer) {
return push(N(burn), signer,
args()("contract", contract)("treasurer", treasurer)("title", title));
}
action_result transfer(name contract, name treasurer, name title, name to, std::string memo, name signer) {
return push(N(transfer), signer,
args()("contract", contract)("treasurer", treasurer)("title", title)("to", to)("memo", memo));
}

variant get_box(name contract, name treasurer, name title) {
auto all = _tester->get_all_chaindb_rows(_code, _code.value, N(box), false);
for(auto& v : all) {
if (v["contract"].as<name>() == contract && v["treasurer"].as<name>() == treasurer && v["title"].as<name>() == title) {
return v;
}
}
return variant();
}
};

}} // eosio::testing

0 comments on commit 427c0b8

Please sign in to comment.