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

Merge pull request #4 from big4david/feature/ytaseo

Feature/ytaseo merge to master
......@@ -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/*")
......
#include "hdddata.hpp"
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 n )
: t_hddbalance(_self, _self.value),
t_miningaccount(_self, _self.value),
t_hddmarket(_self, _self.value),
t_producer(_self, _self.value) {
//todo initialize produers ?
auto hddbalance_itr = t_hddbalance.get(HDD_ACCOUNT.value);
if(hddbalance_itr == t_hddbalance.end()) {
t_hddbalance.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 = now();
});
}
auto itr = t_hddmarket.find(S(4,HDDCORE));
if( itr == t_hddmarket.end() ) {
auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount;
if( system_token_supply > 0 ) {
itr = t_hddmarket.emplace( _self, [&]( auto& m ) {
m.supply.amount = 100000000000000ll;
m.supply.symbol = S(4,HDDCORE);
m.base.balance.amount = int64_t(_gstate.free_ram());
m.base.balance.symbol = S(0,HDD);
m.quote.balance.amount = system_token_supply / 1000;
m.quote.balance.symbol = YTA;
});
}
} else {
//print( "hdd market already created" );
}
}
//@abi action
void hdddata::get_hdd_balance(name owner) {
// 当前余额=上次余额+(当前时间-上次余额时间)*(每周期收益-每周期费用)
require_auth(owner);
//hddbalance_table t_hddbalance(_self, _self.value);
auto hddbalance_itr = t_hddbalance.get(owner.value);
if(hddbalance_itr == t_hddbalance.end()) {
t_hddbalance.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.ast_hdd_time = now();
});
} else {
t_hddbalance.modify(owner, [&](auto &row) {
//todo check overflow and time cycle
row.last_hdd_balance=
hddbalance_itr.get_last_hdd_balance() +
( now()-*hddbalance_itr.last_hdd_time )*( hddbalance_itr.get_hdd_per_cycle_profit()-hddbalance_itr.get_hdd_per_cycle_fee() );
row.last_hdd_time = now();
});
}
}
void hdddata::get_hdd_sum_balance() {
require_auth(_self);
auto hddbalance_itr = t_hddbalance.get(HDD_ACCOUNT.value);
if(hddbalance_itr != t_hddbalance.end()) {
//todo check the 1st time insert
t_hddbalance.modify(_self, [&](auto &row) {
//todo check overflow and time cycle
row.last_hdd_balance=
hddbalance_itr.get_last_hdd_balance() +
( now()-*hddbalance_itr.last_hdd_time )*( hddbalance_itr.get_hdd_per_cycle_profit()-hddbalance_itr.get_hdd_per_cycle_fee() );
row.last_hdd_time = now();
});
}
}
//@abi action
void hdddata::set_hdd_per_cycle_fee(name owner, uint64_t fee) {
require_auth(_self);
require_auth(owner);
//hddbalance_table t_hddbalance(owner, owner.value);
auto hddbalance_itr = t_hddbalance.find(owner.value);
if(hddbalance_itr != t_hddbalance.end()) {
//每周期费用 <= (占用存储空间*数据分片大小/1GB)*(记账周期/ 1年)
eos_assert( xxx, "");
t_hddbalance.modify(owner, [&](auto &row) {
//todo check overflow
row.hdd_per_cycle_fee -=fee;
});
}
//每周期费用 <= (占用存储空间*数据分片大小/1GB)*(记账周期/ 1年)
}
//@abi action
void hdddata::sub_hdd_balance(name owner, uint64_t balance){
require_auth(_self);
require_auth(owner);
//hddbalance_table t_hddbalance(owner, owner.value);
auto hddbalance_itr = t_hddbalance.find(owner.value);
if(hddbalance_itr != t_hddbalance.end()) {
t_hddbalance.modify(owner, [&](auto &row) {
//todo check overflow
row.balance -=balance;
});
}
}
//@abi action
void hdddata::add_hdd_space(name owner, name hddaccount, uint64_t space){
require_auth(owner);
require_auth(hddaccount);
//hddbalance_table t_hddbalance(_self, _self.value);
auto hddbalance_itr = t_hddbalance.find(hddaccount.value);
if(hddbalance_itr != t_hddbalance.end()) {
t_hddbalance.modify(hddaccount, [&](auto &row) {
//todo check overflow
row.hdd_space +=space;
});
}
}
//@abi action
void hdddata::sub_hdd_space(name owner, name hddaccount, uint64_t space){
require_auth(owner);
require_auth(hddaccount);
//hddbalance_table t_hddbalance(_self, _self.value);
auto hddbalance_itr = t_hddbalance.find(hddaccount.value);
if(hddbalance_itr != t_hddbalance.end()) {
t_hddbalance.modify(hddaccount, [&](auto &row) {
//todo check overflow
row.hdd_space -=space;
});
}
}
//@abi action
void hdddata::create_mining_account(name mining_name, name owner) {
require_auth(mining_name);
//mining_account t_miningaccount(_self, _self.value);
auto mining_account_itr = t_miningaccount.get(mining_name.value, "Mining Id does not exist");
if(mining_account_itr == t_miningaccount.end()) {
t_miningaccount.emplace(mining_account, [&](auto &row) {
row.mining_name = mining_name;
row.owner = owner;
});
} else {
return ;
}
require_auth(owner);
//hddbalance_table t_hddbalance(_self, _self.value);
auto hddbalance_itr = t_hddbalance.get(owner.value);
if(hddbalance_itr == t_hddbalance.end()) {
t_hddbalance.emplace(owner, [&](auto &row) {
//todo check the 1st time insert
row.owner = owner;
row.hdd_space=0;
});
}
}
//@abi action
void hdddata::add_mining_profit(name mining_name, uint64_t space){
require_auth(mining_name);
//mining_account t_miningaccount(_self, _self.value);
auto mining_account_itr = t_miningaccount.get(mining_name.value, "Mining Id does not exist");
auto owner_id = mining_account_itr.get_owner();
if( owner_id != mining_account.end()) {
//hddbalance_table t_hddbalance(_self, _self.value);
auto hddbalance_itr = t_hddbalance.get(owner_id);
if(hddbalance_itr == t_hddbalance.end()) {
t_hddbalance.emplace(owner, [&](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)( N(eosio.token), {payer,N(active)},
{ payer, N(eosio.hdd), quant_after_fee, std::string("buy hdd") } );
if( fee.amount > 0 ) {
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)},
{ payer, N(eosio.hddfee), fee, std::string("hdd fee") } );
}
int64_t bytes_out;
const auto& market = t_hddmarket.get(S(4,HDDCORE), "hdd market does not exist");
t_hddmarket.modify( market, 0, [&]( 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 hddbalance 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, (get_hdd_balance)(set_hdd_per_cycle_fee)(create_mining_account)(add_mining_profit)(sub_hdd_balance)(buyhdd)(sellhdd)(add_hdd_space)(sub_hdd_space) )
}
}
else if(code==hdd_account.value && action=="transfer"_n.value) {
execute_action( name(receiver), name(code), &hdddata::deposithdd );
}
}
};
\ No newline at end of file
#include <eosiolib/eosio.hpp>
#include <eosiolib/asset.hpp>
#include <eosiolib/time.hpp>
#include <eosiolib/singleton.hpp>
using namespace eosio;
typedef double real_type;
CONTRACT hdddata : public contract
{
public:
using contract::contract;
hdddata( name n );
~hdddata();
ACTION get_hdd_balance(name owner);
ACTION get_hdd_sum_balance();
ACTION set_hdd_per_cycle_fee(name owner, uint64_t fee);
ACTION create_mining_account(name mining_name, name owner);
ACTION add_mining_profit(name mining_name, uint64_t space);
ACTION sub_hdd_balance(name owner, uint64_t balance);
ACTION buyhdd(name buyer, name receiver, asset quant);
ACTION sellhdd(name account, uint64_t quant);
ACTION add_hdd_space(name owner, name hddaccount, uint64_t space);
ACTION sub_hdd_space(name owner, name hddaccount, uint64_t space);
private:
hddbalance_table t_hddbalance;
mining_account_table t_miningaccount;
producer_table t_producer;
private:
TABLE hddbalance {
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_spacel=0;
time_point_sec 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<"hddbalance"_n, hddbalance,
indexed_by<"bybalance"_n, const_mem_fun<hddbalance, uint64_t, &hddbalance::get_last_hdd_balance>>,
indexed_by<"byfee"_n, const_mem_fun<hddbalance, uint64_t, &hddbalance::get_hdd_per_cycle_fee>>,
indexed_by<"byprofit"_n, const_mem_fun<hddbalance, uint64_t, &hddbalance::get_hdd_per_cycle_profit>>,
indexed_by<"byspace"_n, const_mem_fun<hddbalance, uint64_t, &hddbalance::get_hdd_space>>>
hddbalance_table;
TABLE mining_account {
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<"mining_account"_n, mining_account,
indexed_by<"byowner"_n, const_mem_fun<mining_account, uint64_t, &mining_account::get_owner>>>
mining_account_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;
//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 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; }
asset convert_to_exchange( connector& c, asset in );
asset convert_from_exchange( connector& c, asset in );
asset convert( asset from, symbol_type to );
EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) )
};
//comment old style declaration
typedef multi_index<"hddmarket"_n, exchange_state> _hddmarket;
};
\ 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.
先完成此消息的编辑!
想要评论请 注册