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

Merge pull request #7 from yottachain/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;
}
}
......@@ -19,7 +19,7 @@ wdurl=http://$wdaddr
# bioshost=$BIOS_HOSTNAME
# biosport=$BIOS_HTTP_PORT
# cnt_dir=$CONTRACT_DIR
# sys=$SYS_CONTRACT
# YTA=$SYS_CONTRACT
# where $BIOS_HOSTNAME is replaced by the hostname portion of the http-server-address configured
# for the nodeos instance running to bios producer
# ------ DO NOT ALTER THE NEXT LINE -------
......@@ -56,7 +56,7 @@ wcmd () {
}
cacmd () {
programs/cleos/cleos --wallet-url $wdurl --url http://$bioshost:$biosport system newaccount --transfer --stake-net "10000000.0000 SYS" --stake-cpu "10000000.0000 SYS" --buy-ram "10000000.0000 SYS" eosio $* >> $logfile 2>&1
programs/cleos/cleos --wallet-url $wdurl --url http://$bioshost:$biosport system newaccount --transfer --stake-net "10000000.0000 YTA" --stake-cpu "10000000.0000 YTA" --buy-ram "10000000.0000 YTA" eosio $* >> $logfile 2>&1
ecmd system regproducer $1 $2
ecmd system voteproducer prods $1 $1
}
......@@ -99,11 +99,11 @@ ecmd set contract eosio.msig contracts/eosio.msig eosio.msig.wasm eosio.msig.abi
ecmd set contract eosio.sudo contracts/eosio.sudo eosio.sudo.wasm eosio.sudo.abi
echo ===== Start: $step ============ >> $logfile
echo executing: cleos --wallet-url $wdurl --url http://$bioshost:$biosport push action eosio.token create '[ "eosio", "10000000000.0000 SYS" ]' -p eosio.token | tee -a $logfile
echo executing: cleos --wallet-url $wdurl --url http://$bioshost:$biosport push action eosio.token issue '[ "eosio", "1000000000.0000 SYS", "memo" ]' -p eosio | tee -a $logfile
echo executing: cleos --wallet-url $wdurl --url http://$bioshost:$biosport push action eosio.token create '[ "eosio", "10000000000.0000 YTA" ]' -p eosio.token | tee -a $logfile
echo executing: cleos --wallet-url $wdurl --url http://$bioshost:$biosport push action eosio.token issue '[ "eosio", "1000000000.0000 YTA", "memo" ]' -p eosio | tee -a $logfile
echo ----------------------- >> $logfile
programs/cleos/cleos --wallet-url $wdurl --url http://$bioshost:$biosport push action eosio.token create '[ "eosio", "10000000000.0000 SYS" ]' -p eosio.token >> $logfile 2>&1
programs/cleos/cleos --wallet-url $wdurl --url http://$bioshost:$biosport push action eosio.token issue '[ "eosio", "1000000000.0000 SYS", "memo" ]' -p eosio >> $logfile 2>&1
programs/cleos/cleos --wallet-url $wdurl --url http://$bioshost:$biosport push action eosio.token create '[ "eosio", "10000000000.0000 YTA" ]' -p eosio.token >> $logfile 2>&1
programs/cleos/cleos --wallet-url $wdurl --url http://$bioshost:$biosport push action eosio.token issue '[ "eosio", "1000000000.0000 YTA", "memo" ]' -p eosio >> $logfile 2>&1
echo ==== End: $step ============== >> $logfile
step=$(($step + 1))
......
......@@ -720,7 +720,7 @@ class Node(object):
@staticmethod
def currencyStrToInt(balanceStr):
"""Converts currency string of form "12.3456 SYS" to int 123456"""
"""Converts currency string of form "12.3456 YTA" to int 123456"""
assert(isinstance(balanceStr, str))
balanceStr=balanceStr.split()[0]
#balance=int(decimal.Decimal(balanceStr[1:])*10000)
......@@ -730,7 +730,7 @@ class Node(object):
@staticmethod
def currencyIntToStr(balance, symbol):
"""Converts currency int of form 123456 to string "12.3456 SYS" where SYS is symbol string"""
"""Converts currency int of form 123456 to string "12.3456 YTA" where YTA is symbol string"""
assert(isinstance(balance, int))
assert(isinstance(symbol, str))
balanceStr="%.04f %s" % (balance/10000.0, symbol)
......@@ -738,7 +738,7 @@ class Node(object):
return balanceStr
def validateFunds(self, initialBalances, transferAmount, source, accounts):
"""Validate each account has the expected SYS balance. Validate cumulative balance matches expectedTotal."""
"""Validate each account has the expected YTA balance. Validate cumulative balance matches expectedTotal."""
assert(source)
assert(isinstance(source, Account))
assert(accounts)
......@@ -849,7 +849,7 @@ class Node(object):
return servants
def getAccountEosBalanceStr(self, scope):
"""Returns SYS currency0000 account balance from cleos get table command. Returned balance is string following syntax "98.0311 SYS". """
"""Returns YTA currency0000 account balance from cleos get table command. Returned balance is string following syntax "98.0311 YTA". """
assert isinstance(scope, str)
amount=self.getTableAccountBalance("eosio.token", scope)
if Utils.Debug: Utils.Print("getNodeAccountEosBalance %s %s" % (scope, amount))
......@@ -857,7 +857,7 @@ class Node(object):
return amount
def getAccountEosBalance(self, scope):
"""Returns SYS currency0000 account balance from cleos get table command. Returned balance is an integer e.g. 980311. """
"""Returns YTA currency0000 account balance from cleos get table command. Returned balance is an integer e.g. 980311. """
balanceStr=self.getAccountEosBalanceStr(scope)
balance=Node.currencyStrToInt(balanceStr)
return balance
......
......@@ -58,14 +58,14 @@ BOOST_FIXTURE_TEST_CASE( get_scope_test, TESTER ) try {
// create currency
auto act = mutable_variant_object()
("issuer", "eosio")
("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 SYS"));
("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 YTA"));
push_action(N(eosio.token), N(create), N(eosio.token), act );
// issue
for (account_name a: accs) {
push_action( N(eosio.token), N(issue), "eosio", mutable_variant_object()
("to", name(a) )
("quantity", eosio::chain::asset::from_string("999.0000 SYS") )
("quantity", eosio::chain::asset::from_string("999.0000 YTA") )
("memo", "")
);
}
......@@ -134,14 +134,14 @@ BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try {
// create currency
auto act = mutable_variant_object()
("issuer", "eosio")
("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 SYS"));
("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 YTA"));
push_action(N(eosio.token), N(create), N(eosio.token), act );
// issue
for (account_name a: accs) {
push_action( N(eosio.token), N(issue), "eosio", mutable_variant_object()
("to", name(a) )
("quantity", eosio::chain::asset::from_string("10000.0000 SYS") )
("quantity", eosio::chain::asset::from_string("10000.0000 YTA") )
("memo", "")
);
}
......@@ -207,7 +207,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try {
BOOST_REQUIRE_EQUAL("9999.0000 AAA", result.rows[0]["balance"].as_string());
BOOST_REQUIRE_EQUAL("8888.0000 BBB", result.rows[1]["balance"].as_string());
BOOST_REQUIRE_EQUAL("7777.0000 CCC", result.rows[2]["balance"].as_string());
BOOST_REQUIRE_EQUAL("10000.0000 SYS", result.rows[3]["balance"].as_string());
BOOST_REQUIRE_EQUAL("10000.0000 YTA", result.rows[3]["balance"].as_string());
}
// get table: reverse ordered
......@@ -219,7 +219,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try {
BOOST_REQUIRE_EQUAL("9999.0000 AAA", result.rows[3]["balance"].as_string());
BOOST_REQUIRE_EQUAL("8888.0000 BBB", result.rows[2]["balance"].as_string());
BOOST_REQUIRE_EQUAL("7777.0000 CCC", result.rows[1]["balance"].as_string());
BOOST_REQUIRE_EQUAL("10000.0000 SYS", result.rows[0]["balance"].as_string());
BOOST_REQUIRE_EQUAL("10000.0000 YTA", result.rows[0]["balance"].as_string());
}
// get table: reverse ordered, with ram payer
......@@ -232,7 +232,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try {
BOOST_REQUIRE_EQUAL("9999.0000 AAA", result.rows[3]["data"]["balance"].as_string());
BOOST_REQUIRE_EQUAL("8888.0000 BBB", result.rows[2]["data"]["balance"].as_string());
BOOST_REQUIRE_EQUAL("7777.0000 CCC", result.rows[1]["data"]["balance"].as_string());
BOOST_REQUIRE_EQUAL("10000.0000 SYS", result.rows[0]["data"]["balance"].as_string());
BOOST_REQUIRE_EQUAL("10000.0000 YTA", result.rows[0]["data"]["balance"].as_string());
BOOST_REQUIRE_EQUAL("eosio", result.rows[0]["payer"].as_string());
BOOST_REQUIRE_EQUAL("eosio", result.rows[1]["payer"].as_string());
BOOST_REQUIRE_EQUAL("eosio", result.rows[2]["payer"].as_string());
......@@ -283,7 +283,7 @@ BOOST_FIXTURE_TEST_CASE( get_table_test, TESTER ) try {
BOOST_REQUIRE_EQUAL(1, result.rows.size());
BOOST_REQUIRE_EQUAL(true, result.more);
if (result.rows.size() >= 1) {
BOOST_REQUIRE_EQUAL("10000.0000 SYS", result.rows[0]["balance"].as_string());
BOOST_REQUIRE_EQUAL("10000.0000 YTA", result.rows[0]["balance"].as_string());
}
// get table: normal case, with bound & limit
......@@ -329,14 +329,14 @@ BOOST_FIXTURE_TEST_CASE( get_table_by_seckey_test, TESTER ) try {
// create currency
auto act = mutable_variant_object()
("issuer", "eosio")
("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 SYS"));
("maximum_supply", eosio::chain::asset::from_string("1000000000.0000 YTA"));
push_action(N(eosio.token), N(create), N(eosio.token), act );
// issue
for (account_name a: accs) {
push_action( N(eosio.token), N(issue), "eosio", mutable_variant_object()
("to", name(a) )
("quantity", eosio::chain::asset::from_string("10000.0000 SYS") )
("quantity", eosio::chain::asset::from_string("10000.0000 YTA") )
("memo", "")
);
}
......@@ -354,10 +354,10 @@ BOOST_FIXTURE_TEST_CASE( get_table_by_seckey_test, TESTER ) try {
);
};
bidname(N(inita), N(com), eosio::chain::asset::from_string("10.0000 SYS"));
bidname(N(initb), N(org), eosio::chain::asset::from_string("11.0000 SYS"));
bidname(N(initc), N(io), eosio::chain::asset::from_string("12.0000 SYS"));
bidname(N(initd), N(html), eosio::chain::asset::from_string("14.0000 SYS"));
bidname(N(inita), N(com), eosio::chain::asset::from_string("10.0000 YTA"));
bidname(N(initb), N(org), eosio::chain::asset::from_string("11.0000 YTA"));
bidname(N(initc), N(io), eosio::chain::asset::from_string("12.0000 YTA"));
bidname(N(initd), N(html), eosio::chain::asset::from_string("14.0000 YTA"));
produce_blocks(1);
// get table: normal case
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册