未验证 提交 93c5a913 编写于 作者: L luchiagogogo 提交者: GitHub

Merge pull request #6 from big4david/feature/ytaseo

merge Feature/ytaseo
......@@ -30,6 +30,7 @@ add_subdirectory(noop)
add_subdirectory(tic_tac_toe)
add_subdirectory(payloadless)
add_subdirectory(integration_test)
add_subdirectory(hddofficial)
file(GLOB SKELETONS RELATIVE ${CMAKE_SOURCE_DIR}/contracts "skeleton/*")
......
{
"____comment": "This file was generated with eosio-abigen. DO NOT EDIT Mon Apr 15 03:30:22 2019",
"version": "eosio::abi/1.1",
"structs": [
{
"name": "addhspace",
"base": "",
"fields": [
{
"name": "owner",
"type": "name"
},
{
"name": "hddaccount",
"type": "name"
},
{
"name": "space",
"type": "uint64"
}
]
},
{
"name": "addmprofit",
"base": "",
"fields": [
{
"name": "mname",
"type": "name"
},
{
"name": "space",
"type": "uint64"
}
]
},
{
"name": "buyhdd",
"base": "",
"fields": [
{
"name": "buyer",
"type": "name"
},
{
"name": "receiver",
"type": "name"
},
{
"name": "quant",
"type": "asset"
}
]
},
{
"name": "connector",
"base": "",
"fields": [
{
"name": "balance",
"type": "asset"
},
{
"name": "weight",
"type": "float64"
}
]
},
{
"name": "exchange_state",
"base": "",
"fields": [
{
"name": "supply",
"type": "asset"
},
{
"name": "base",
"type": "connector"
},
{
"name": "quote",
"type": "connector"
}
]
},
{
"name": "gethbalance",
"base": "",
"fields": [
{
"name": "owner",
"type": "name"
}
]
},
{
"name": "gethsum",
"base": "",
"fields": []
},
{
"name": "hbalance",
"base": "",
"fields": [
{
"name": "owner",
"type": "name"
},
{
"name": "last_hdd_balance",
"type": "uint64"
},
{
"name": "hdd_per_cycle_fee",
"type": "uint64"
},
{
"name": "hdd_per_cycle_profit",
"type": "uint64"
},
{
"name": "hdd_space",
"type": "uint64"
},
{
"name": "last_hdd_time",
"type": "uint64"
}
]
},
{
"name": "maccount",
"base": "",
"fields": [
{
"name": "ming_id",
"type": "uint64"
},
{
"name": "owner",
"type": "name"
}
]
},
{
"name": "newmaccount",
"base": "",
"fields": [
{
"name": "mname",
"type": "name"
},
{
"name": "owner",
"type": "name"
}
]
},
{
"name": "producer",
"base": "",
"fields": [
{
"name": "owner",
"type": "name"
},
{
"name": "producer_key",
"type": "public_key"
}
]
},
{
"name": "sellhdd",
"base": "",
"fields": [
{
"name": "account",
"type": "name"
},
{
"name": "quant",
"type": "uint64"
}
]
},
{
"name": "sethfee",
"base": "",
"fields": [
{
"name": "owner",
"type": "name"
},
{
"name": "fee",
"type": "uint64"
}
]
},
{
"name": "subhbalance",
"base": "",
"fields": [
{
"name": "owner",
"type": "name"
},
{
"name": "balance",
"type": "uint64"
}
]
},
{
"name": "subhspace",
"base": "",
"fields": [
{
"name": "owner",
"type": "name"
},
{
"name": "hddaccount",
"type": "name"
},
{
"name": "space",
"type": "uint64"
}
]
}
],
"types": [],
"actions": [
{
"name": "addhspace",
"type": "addhspace",
"ricardian_contract": ""
},
{
"name": "addmprofit",
"type": "addmprofit",
"ricardian_contract": ""
},
{
"name": "buyhdd",
"type": "buyhdd",
"ricardian_contract": ""
},
{
"name": "gethbalance",
"type": "gethbalance",
"ricardian_contract": ""
},
{
"name": "gethsum",
"type": "gethsum",
"ricardian_contract": ""
},
{
"name": "newmaccount",
"type": "newmaccount",
"ricardian_contract": ""
},
{
"name": "sellhdd",
"type": "sellhdd",
"ricardian_contract": ""
},
{
"name": "sethfee",
"type": "sethfee",
"ricardian_contract": ""
},
{
"name": "subhbalance",
"type": "subhbalance",
"ricardian_contract": ""
},
{
"name": "subhspace",
"type": "subhspace",
"ricardian_contract": ""
}
],
"tables": [
{
"name": "hbalance",
"type": "hbalance",
"index_type": "i64",
"key_names": [],
"key_types": []
},
{
"name": "hmarket",
"type": "exchange_state",
"index_type": "i64",
"key_names": [],
"key_types": []
},
{
"name": "maccount",
"type": "maccount",
"index_type": "i64",
"key_names": [],
"key_types": []
},
{
"name": "producer",
"type": "producer",
"index_type": "i64",
"key_names": [],
"key_types": []
}
],
"ricardian_clauses": [],
"variants": [],
"abi_extensions": []
}
\ No newline at end of file
#include "hdddata.hpp"
#include <eosiolib/eosio.hpp>
#include <eosiolib/print.hpp>
#include <eosiolib/serialize.hpp>
#include <eosiolib/multi_index.hpp>
#include <eosio.token/eosio.token.hpp>
using namespace eosio;
const uint32_t hours_in_one_day = 24;
const uint32_t minutes_in_one_day = hours_in_one_day * 60;
const uint32_t seconds_in_one_day = minutes_in_one_day * 60;
const uint32_t seconds_in_one_week = seconds_in_one_day * 7;
const uint32_t seconds_in_one_year = seconds_in_one_day * 365;
const name HDD_ACCOUNT = "hddofficial"_n;
// constructor
hdddata::hdddata( name s, name code, datastream<const char*> ds )
: eosio::contract(s, code, ds),
_hbalance(_self, _self.value),
_maccount(_self, _self.value),
_hmarket(_self, _self.value),
_producer(_self, _self.value) {
//todo initialize produers ?
print( "construct system\n" );
auto hbalance_itr = _hbalance.find(HDD_ACCOUNT.value);
if(hbalance_itr == _hbalance.end()) {
_hbalance.emplace(_self, [&](auto &row) {
//todo check the 1st time insert
row.last_hdd_balance=0;
row.hdd_per_cycle_fee=0;
row.hdd_per_cycle_profit=0;
row.hdd_space=0;
row.last_hdd_time = current_time();
});
}
auto itr = _hmarket.find(hddcore_symbol.raw());
if( itr == _hmarket.end() ) {
//auto system_token_supply = eosio::token(token_account).get_supply(eosio::symbol_type(system_token_symbol).name()).amount;
//auto system_token_supply = eosio::token::get_supply(token_account, yta_symbol.code() );
auto system_token_supply = 0;
if( system_token_supply > 0 ) {
itr = _hmarket.emplace( _self, [&]( auto& m ) {
m.supply.amount = 100000000000000ll;
m.supply.symbol = hddcore_symbol;
//m.base.balance.amount = int64_t(_gstate.free_ram());
m.base.balance.symbol = hdd_symbol;
//m.quote.balance.amount = system_token_supply.amount / 1000;
m.quote.balance.symbol = yta_symbol;
});
}
} else {
print( "hdd market already created" );
}
}
hdddata:: ~hdddata() {
}
symbol hdddata::core_symbol()const {
const static auto sym = get_core_symbol( _hmarket );
return sym;
}
//@abi action
void hdddata::gethbalance(name owner) {
// 当前余额=上次余额+(当前时间-上次余额时间)*(每周期收益-每周期费用)
require_auth(owner);
//hbalance_table hbalance(_self, _self.value);
auto hbalance_itr = _hbalance.find(owner.value);
if(hbalance_itr == _hbalance.end()) {
_hbalance.emplace(owner, [&](auto &row) {
//todo check the 1st time insert
row.last_hdd_balance=0;
row.hdd_per_cycle_fee=0;
row.hdd_per_cycle_profit=0;
row.hdd_space=0;
row.last_hdd_time = current_time();
});
} else {
_hbalance.modify(hbalance_itr, _self, [&](auto &row) {
//todo check overflow and time cycle
row.last_hdd_balance=
hbalance_itr->get_last_hdd_balance() +
//( current_time() - (hbalance_itr->last_hdd_time) )
10 * ( hbalance_itr->get_hdd_per_cycle_profit()-hbalance_itr->get_hdd_per_cycle_fee() );
row.last_hdd_time = current_time();
});
}
}
void hdddata::gethsum() {
require_auth(_self);
auto hbalance_itr = _hbalance.find(HDD_ACCOUNT.value);
if(hbalance_itr != _hbalance.end()) {
//todo check the 1st time insert
_hbalance.modify(hbalance_itr, _self, [&](auto &row) {
//todo check overflow and time cycle
row.last_hdd_balance=
hbalance_itr->get_last_hdd_balance() +
// todo ((uint64_t)( now()-hbalance_itr->last_hdd_time ))
10 *( hbalance_itr->get_hdd_per_cycle_profit()-hbalance_itr->get_hdd_per_cycle_fee() );
row.last_hdd_time = current_time();
});
}
}
//@abi action
void hdddata::sethfee(name owner, uint64_t fee) {
require_auth(_self);
require_auth(owner);
//hbalance_table _hbalance(owner, owner.value);
auto hbalance_itr = _hbalance.find(owner.value);
if(hbalance_itr != _hbalance.end()) {
//每周期费用 <= (占用存储空间*数据分片大小/1GB)*(记账周期/ 1年)
//eos_assert( xxx, "");
_hbalance.modify(hbalance_itr, owner, [&](auto &row) {
//todo check overflow
row.hdd_per_cycle_fee -=fee;
});
}
//每周期费用 <= (占用存储空间*数据分片大小/1GB)*(记账周期/ 1年)
}
//@abi action
void hdddata::subhbalance(name owner, uint64_t balance){
require_auth(_self);
require_auth(owner);
//hbalance_table hbalance(owner, owner.value);
auto hbalance_itr = _hbalance.find(owner.value);
if(hbalance_itr != _hbalance.end()) {
_hbalance.modify(hbalance_itr, owner, [&](auto &row) {
//todo check overflow
row.last_hdd_balance -=balance;
});
}
}
//@abi action
void hdddata::addhspace(name owner, name hddaccount, uint64_t space){
require_auth(owner);
require_auth(hddaccount);
//hbalance_table hbalance(_self, _self.value);
auto hbalance_itr = _hbalance.find(hddaccount.value);
if(hbalance_itr != _hbalance.end()) {
_hbalance.modify(hbalance_itr, hddaccount, [&](auto &row) {
//todo check overflow
row.hdd_space +=space;
});
}
}
//@abi action
void hdddata::subhspace(name owner, name hddaccount, uint64_t space){
require_auth(owner);
require_auth(hddaccount);
//hbalance_table hbalance(_self, _self.value);
auto hbalance_itr = _hbalance.find(hddaccount.value);
if(hbalance_itr != _hbalance.end()) {
_hbalance.modify(hbalance_itr, hddaccount, [&](auto &row) {
//todo check overflow
row.hdd_space -=space;
});
}
}
//@abi action
void hdddata::newmaccount(name mname, name owner) {
require_auth(mname);
//maccount_table _maccount(_self, _self.value);
auto maccount_itr = _maccount.find(mname.value);
if(maccount_itr == _maccount.end()) {
_maccount.emplace(mname, [&](auto &row) {
row.ming_id = mname.value;
row.owner = owner;
});
} else {
return ;
}
require_auth(owner);
//hbalance_table hbalance(_self, _self.value);
auto hbalance_itr = _hbalance.find(owner.value);
if(hbalance_itr == _hbalance.end()) {
_hbalance.emplace(owner, [&](auto &row) {
//todo check the 1st time insert
row.owner = owner;
row.hdd_space=0;
});
}
}
//@abi action
void hdddata::addmprofit(name mname, uint64_t space){
require_auth(mname);
//maccount_table _maccount(_self, _self.value);
auto maccount_itr = _maccount.find(mname.value);
if( maccount_itr != _maccount.end()) {
//hbalance_table _hbalance(_self, _self.value);
auto owner_id = maccount_itr->get_owner();
auto hbalance_itr = _hbalance.find(owner_id);
if(hbalance_itr == _hbalance.end()) {
_hbalance.emplace(_self, [&](auto &row) {
//todo check the 1st time insert
//row.owner = owner;
row.hdd_space=space;
});
} else {
//todo
}
}
//每周期收益 += (预采购空间*数据分片大小/1GB)*(记账周期/ 1年)
}
//@abi action
void hdddata::buyhdd(name buyer, name receiver, asset quant) {
require_auth(buyer);
eosio_assert( quant.amount > 0, "must purchase a positive amount" );
auto fee = quant;
fee.amount = ( fee.amount + 199 ) / 200; /// .5% fee (round up)
// fee.amount cannot be 0 since that is only possible if quant.amount is 0 which is not allowed by the assert above.
// If quant.amount == 1, then fee.amount == 1,
// otherwise if quant.amount > 1, then 0 < fee.amount < quant.amount.
auto quant_after_fee = quant;
quant_after_fee.amount -= fee.amount;
INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, {buyer,active_permission},
{ buyer, hdd_account, quant_after_fee, std::string("buy hdd") } );
if( fee.amount > 0 ) {
INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, {buyer,active_permission},
{ buyer, hddfee_account, fee, std::string("hdd fee") } );
}
int64_t bytes_out;
const auto& market = _hmarket.get(hddcore_symbol.raw(), "hdd market does not exist");
_hmarket.modify( market, same_payer, [&]( auto& es ) {
//bytes_out = es.convert( quant_after_fee, S(0,HDD) ).amount;
});
eosio_assert( bytes_out > 0, "must reserve a positive amount" );
//todo modify the hbalance table
}
//@abi action
void hdddata::sellhdd(name account, uint64_t quant){
require_auth(account);
}
extern "C" {
void apply(uint64_t receiver, uint64_t code, uint64_t action) {
if(code==receiver)
{
switch(action)
{
EOSIO_DISPATCH_HELPER( hdddata, (gethbalance)(gethsum)(sethfee)(newmaccount)(addmprofit)(subhbalance)(buyhdd)(sellhdd)(addhspace)(subhspace) )
}
}
else if(code==HDD_ACCOUNT.value && action=="transfer"_n.value) {
//execute_action( name(receiver), name(code), &hdddata::deposithdd );
}
}
};
#include <eosiolib/eosio.hpp>
#include <eosiolib/asset.hpp>
#include <eosiolib/time.hpp>
#include <eosiolib/singleton.hpp>
using namespace eosio;
using eosio::name;
using eosio::asset;
using eosio::symbol;
using eosio::symbol_code;
using eosio::indexed_by;
using eosio::const_mem_fun;
using eosio::microseconds;
using eosio::datastream;
typedef double real_type;
//todo copy from eosio.system
/**
* Uses Bancor math to create a 50/50 relay between two asset types. The state of the
* bancor exchange is entirely contained within this struct. There are no external
* side effects associated with using this API.
*/
struct [[eosio::table, eosio::contract("hdddata")]] exchange_state {
asset supply;
struct connector {
asset balance;
double weight = .5;
EOSLIB_SERIALIZE( connector, (balance)(weight) )
};
connector base;
connector quote;
uint64_t primary_key()const { return supply.symbol.raw(); }
asset convert_to_exchange( connector& c, asset in );
asset convert_from_exchange( connector& c, asset in );
asset convert( asset from, const symbol& to );
EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) )
};
//comment old style declaration
typedef multi_index<"hmarket"_n, exchange_state> hmarket_table;
CONTRACT hdddata : public contract
{
public:
using contract::contract;
hdddata( name s, name code, datastream<const char*> ds);
~hdddata();
ACTION gethbalance(name owner);
ACTION gethsum();
ACTION sethfee(name owner, uint64_t fee);
ACTION newmaccount(name mname, name owner);
ACTION addmprofit(name mname, uint64_t space);
ACTION subhbalance(name owner, uint64_t balance);
ACTION buyhdd(name buyer, name receiver, asset quant);
ACTION sellhdd(name account, uint64_t quant);
ACTION addhspace(name owner, name hddaccount, uint64_t space);
ACTION subhspace(name owner, name hddaccount, uint64_t space);
static constexpr symbol hddcore_symbol = symbol(symbol_code("HDDCORE"), 4);
static constexpr symbol hdd_symbol = symbol(symbol_code("HDD"), 0);
static constexpr symbol yta_symbol = symbol(symbol_code("YTA"), 4);
static constexpr eosio::name token_account{"eosio.token"_n};
static constexpr eosio::name hdd_account{"eosio.hdd"_n};
static constexpr eosio::name hddfee_account{"eosio.hddfee"_n};
static constexpr eosio::name active_permission{"active"_n};
static symbol get_core_symbol( name system_account = "hddofficial"_n ) {
hmarket_table rm(system_account, system_account.value);
const static auto sym = get_core_symbol( rm );
return sym;
}
private:
// Implementation details:
static symbol get_core_symbol( const hmarket_table& hdd ) {
auto itr = hdd.find(hddcore_symbol.raw());
check(itr != hdd.end(), "system contract must first be initialized");
return itr->quote.balance.symbol;
}
symbol core_symbol()const;
TABLE hbalance {
name owner;
uint64_t last_hdd_balance=0;
uint64_t hdd_per_cycle_fee=0;
uint64_t hdd_per_cycle_profit=0;
uint64_t hdd_space=0;
uint64_t last_hdd_time;
uint64_t primary_key() const { return owner.value; }
uint64_t get_last_hdd_balance() const { return last_hdd_balance; }
uint64_t get_hdd_per_cycle_fee() const { return hdd_per_cycle_fee; }
uint64_t get_hdd_per_cycle_profit() const { return hdd_per_cycle_profit; }
uint64_t get_hdd_space() const { return hdd_space; }
};
typedef multi_index<"hbalance"_n, hbalance,
indexed_by<"bybalance"_n, const_mem_fun<hbalance, uint64_t, &hbalance::get_last_hdd_balance>>,
indexed_by<"byfee"_n, const_mem_fun<hbalance, uint64_t, &hbalance::get_hdd_per_cycle_fee>>,
indexed_by<"byprofit"_n, const_mem_fun<hbalance, uint64_t, &hbalance::get_hdd_per_cycle_profit>>,
indexed_by<"byspace"_n, const_mem_fun<hbalance, uint64_t, &hbalance::get_hdd_space>>>
hbalance_table;
// ming account
TABLE maccount {
uint64_t ming_id;
name owner;
uint64_t primary_key() const { return ming_id; }
uint64_t get_owner() const { return owner.value; }
};
typedef multi_index<"maccount"_n, maccount,
indexed_by<"byowner"_n, const_mem_fun<maccount, uint64_t, &maccount::get_owner>>>
maccount_table;
TABLE producer {
name owner;
eosio::public_key producer_key;
uint64_t primary_key() const { return owner.value; }
};
typedef multi_index<"producer"_n, producer> producer_table;
private:
hbalance_table _hbalance;
maccount_table _maccount;
producer_table _producer;
hmarket_table _hmarket;
};
\ No newline at end of file
file(GLOB ABI_FILES "*.abi")
configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY)
add_wast_executable(TARGET hddofficial
INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}"
LIBRARIES libc++ libc eosiolib
DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR}
)
MIT License
Copyright (c) 2019 YTAChain
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# HDD Contract Code in YTAChain
YTAChain Token Symbol: HDD
The Web Interface is
\ No newline at end of file
{
"____comment": "This file was generated by eosio-abigen. DO NOT EDIT Wed Mar 20 01:36:38 2019",
"version": "eosio::abi/1.0",
"types": [],
"structs": [{
"name": "account",
"base": "",
"fields": [{
"name": "balance",
"type": "asset"
}
]
},{
"name": "currencystat",
"base": "",
"fields": [{
"name": "supply",
"type": "asset"
},{
"name": "max_supply",
"type": "asset"
},{
"name": "issuer",
"type": "name"
}
]
},{
"name": "create",
"base": "",
"fields": []
},{
"name": "claim",
"base": "",
"fields": [{
"name": "claimer",
"type": "name"
}
]
},{
"name": "signup",
"base": "",
"fields": [{
"name": "to",
"type": "name"
},{
"name": "memo",
"type": "string"
}
]
},{
"name": "issue",
"base": "",
"fields": [{
"name": "to",
"type": "name"
},{
"name": "quantity",
"type": "asset"
},{
"name": "memo",
"type": "string"
}
]
},{
"name": "transfer",
"base": "",
"fields": [{
"name": "from",
"type": "name"
},{
"name": "to",
"type": "name"
},{
"name": "quantity",
"type": "asset"
},{
"name": "memo",
"type": "string"
}
]
}],
"actions": [{
"name": "create",
"type": "create",
"ricardian_contract": ""
},{
"name": "claim",
"type": "claim",
"ricardian_contract": ""
},{
"name": "signup",
"type": "signup",
"ricardian_contract": ""
},{
"name": "issue",
"type": "issue",
"ricardian_contract": ""
},{
"name": "transfer",
"type": "transfer",
"ricardian_contract": ""
}],
"tables": [{
"name": "accounts",
"index_type": "i64",
"key_names": [
"balance"
],
"key_types": [
"asset"
],
"type": "account"
},{
"name": "stat",
"index_type": "i64",
"key_names": [
"supply"
],
"key_types": [
"asset"
],
"type": "currencystat"
}
],
"ricardian_clauses": [],
"error_messages": [],
"abi_extensions": []
}
#include "hddofficial.hpp"
namespace hdd {
void token::create(){
require_auth( _self );
account_name issuer = _self;
asset maximum_supply = asset(hdd::MAX_SUPPLY, hdd::SYMBOL);
stats statstable( _self, maximum_supply.symbol.name() );
auto existing = statstable.find( maximum_supply.symbol.name() );
eosio_assert( existing == statstable.end(), "token with symbol already exists" );
statstable.emplace( _self, [&]( auto& s ) {
s.supply.symbol = maximum_supply.symbol;
s.max_supply = maximum_supply;
s.issuer = issuer;
});
}
void token::claim( account_name claimer ) {
require_auth( claimer );
accounts acnts( _self, claimer );
asset empty = asset(0'0000, hdd::SYMBOL);
auto existing = acnts.find( empty.symbol.name() );
eosio_assert(existing == acnts.end(), "User already has a balance");
acnts.emplace( claimer, [&]( auto& a ){
a.balance = empty;
});
}
void token::signup( account_name to, string memo ) {
require_auth( to );
accounts acnts( _self, to );
asset empty = asset(0'0000, hdd::SYMBOL);
auto existing = acnts.find( empty.symbol.name() );
eosio_assert(existing == acnts.end(), "User already has a balance");
acnts.emplace( to, [&]( auto& a ){
a.balance = empty;
});
}
void token::issue( account_name to, asset quantity, string memo ) {
auto sym = quantity.symbol;
eosio_assert( sym.is_valid(), "invalid symbol name" );
eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );
auto sym_name = sym.name();
stats statstable( _self, sym_name );
auto existing = statstable.find( sym_name );
eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" );
const auto& st = *existing;
require_auth( st.issuer );
eosio_assert( quantity.is_valid(), "invalid quantity" );
eosio_assert( quantity.amount > 0, "must issue positive quantity" );
eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply");
statstable.modify( st, 0, [&]( auto& s ) {
s.supply += quantity;
});
add_balance( st.issuer, quantity, st.issuer );
if( to != st.issuer ) {
SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} );
}
}
void token::transfer( account_name from, account_name to, asset quantity, string memo ) {
eosio_assert( from != to, "cannot transfer to self" );
require_auth( from );
eosio_assert( is_account( to ), "to account does not exist");
auto sym = quantity.symbol.name();
stats statstable( _self, sym );
const auto& st = statstable.get( sym );
require_recipient( from );
require_recipient( to );
eosio_assert( quantity.is_valid(), "invalid quantity" );
eosio_assert( quantity.amount > 0, "must transfer positive quantity" );
eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" );
eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" );
sub_balance( from, quantity );
add_balance( to, quantity, from );
}
void token::sub_balance( account_name owner, asset value ) {
accounts from_acnts( _self, owner );
const auto& from = from_acnts.get( value.symbol.name(), "no balance object found" );
eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" );
if( from.balance.amount == value.amount ) {
from_acnts.erase( from );
} else {
from_acnts.modify( from, owner, [&]( auto& a ) {
a.balance -= value;
});
}
}
void token::add_balance( account_name owner, asset value, account_name ram_payer ) {
accounts to_acnts( _self, owner );
auto to = to_acnts.find( value.symbol.name() );
if( to == to_acnts.end() ) {
to_acnts.emplace( ram_payer, [&]( auto& a ){
a.balance = value;
});
} else {
to_acnts.modify( to, 0, [&]( auto& a ) {
a.balance += value;
});
}
}
}
EOSIO_ABI( hdd::token, (create)(claim)(signup)(issue)(transfer) )
#pragma once
#include <eosiolib/asset.hpp>
#include <eosiolib/eosio.hpp>
namespace hdd {
using namespace eosio;
using std::string;
static uint64_t SYMBOL = string_to_symbol(4, "HDD");
static int64_t MAX_SUPPLY = 1024*1024*1024*1024; // 2^40 1T
class token : public contract {
public:
token( account_name self ):contract(self){}
void create();
void claim( account_name claimer );
void signup( account_name to, string memo );
void issue( account_name to, asset quantity, string memo );
void transfer( account_name from,
account_name to,
asset quantity,
string memo );
inline asset get_supply( symbol_name sym )const;
inline asset get_balance( account_name owner, symbol_name sym )const;
private:
//@abi table accounts i64
struct account {
asset balance;
uint64_t primary_key()const { return balance.symbol.name(); }
};
//@abi table stat i64
struct currencystat {
asset supply;
asset max_supply;
account_name issuer;
uint64_t primary_key()const { return supply.symbol.name(); }
};
typedef eosio::multi_index<N(accounts), account> accounts;
typedef eosio::multi_index<N(stat), currencystat> stats;
void sub_balance( account_name owner, asset value );
void add_balance( account_name owner, asset value, account_name ram_payer );
};
asset token::get_supply( symbol_name sym )const
{
stats statstable( _self, sym );
const auto& st = statstable.get( sym );
return st.supply;
}
asset token::get_balance( account_name owner, symbol_name sym )const
{
accounts accountstable( _self, owner );
const auto& ac = accountstable.get( sym );
return ac.balance;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册