From 9945bd3c1f7e79a7f61f57f4480b9453385f4a4a Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Fri, 28 Jul 2017 01:05:58 -0300 Subject: [PATCH 1/6] Add more types to AbiSerializer (wip) --- libraries/types/AbiSerializer.cpp | 49 ++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/libraries/types/AbiSerializer.cpp b/libraries/types/AbiSerializer.cpp index 2856d765180..863592a2d28 100644 --- a/libraries/types/AbiSerializer.cpp +++ b/libraries/types/AbiSerializer.cpp @@ -22,6 +22,7 @@ namespace eos { namespace types { for( const auto& a : abi.actions ) actions[a.action] = a.type; + for( const auto& t : abi.tables ) tables[t.table] = t.type; @@ -36,7 +37,7 @@ namespace eos { namespace types { } bool AbiSerializer::isType( const TypeName& type )const { - static const std::set native = {"Name","UInt64"}; + static const std::set native = {"Name", "UInt8", "UInt32", "UInt64", "UInt128", "Time", "String"}; if( native.find(type) != native.end() ) return true; if( typedefs.find(type) != typedefs.end() ) return isType( typedefs.find(type)->second ); if( structs.find(type) != structs.end() ) return true; @@ -87,6 +88,7 @@ namespace eos { namespace types { obj( field.name, binaryToVariant( resolveType(field.type), stream ) ); } } + fc::variant AbiSerializer::binaryToVariant(const TypeName& type, fc::datastream& stream )const { TypeName rtype = resolveType( type ); @@ -95,11 +97,36 @@ namespace eos { namespace types { fc::raw::unpack( stream, temp ); return fc::variant(temp); } + else if( rtype == "UInt8" ) { + unsigned char temp; + fc::raw::unpack( stream, temp ); + return fc::variant(temp); + } + else if( rtype == "UInt32" ) { + uint32_t temp; + fc::raw::unpack( stream, temp ); + return fc::variant(temp); + } else if( rtype == "UInt64" ) { uint64_t temp; fc::raw::unpack( stream, temp ); return fc::variant(temp); } + else if( rtype == "UInt128" ) { + UInt128 temp; + fc::raw::unpack( stream, temp ); + return fc::variant(temp); + } + else if( rtype == "Time" ) { + Time temp; + fc::raw::unpack( stream, temp ); + return fc::variant(temp); + } + else if( rtype == "String" ) { + String temp; + fc::raw::unpack( stream, temp ); + return fc::variant(temp); + } fc::mutable_variant_object mvo; binaryToVariant( rtype, stream, mvo ); return fc::variant( std::move(mvo) ); @@ -118,10 +145,26 @@ namespace eos { namespace types { fc::raw::pack( ds, var.as() ); return; } + else if( rtype == "UInt8" ) { + fc::raw::pack( ds, var.as() ); + return; + } + else if( rtype == "UInt32" ) { + fc::raw::pack( ds, var.as() ); + return; + } else if( rtype == "UInt64" ) { fc::raw::pack( ds, var.as() ); return; } + else if( rtype == "UInt128" ) { + fc::raw::pack( ds, var.as() ); + return; + } + else if( rtype == "Time" ) { + fc::raw::pack( ds, var.as() ); + return; + } else if( rtype == "String" ) { fc::raw::pack( ds, var.as() ); return; @@ -144,9 +187,7 @@ namespace eos { namespace types { } } - - - Bytes AbiSerializer::variantToBinary(const TypeName& type, const fc::variant& var)const { + Bytes AbiSerializer::variantToBinary(const TypeName& type, const fc::variant& var)const { if( !isType(type) ) return var.as(); From eb6abd181f38f496a7c4b93ae60f07e9a0b983fd Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Fri, 28 Jul 2017 01:07:35 -0300 Subject: [PATCH 2/6] * Add cancel_buy / cancel_sell actions to exchange contract * Fix asks table name * Handle open_orders per account --- contracts/exchange/exchange.cpp | 49 ++++++++++++++++++++++++++++++++- contracts/exchange/exchange.hpp | 2 +- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/contracts/exchange/exchange.cpp b/contracts/exchange/exchange.cpp index 0f0b405a257..d2377b57342 100644 --- a/contracts/exchange/exchange.cpp +++ b/contracts/exchange/exchange.cpp @@ -148,6 +148,7 @@ void apply_exchange_buy( BuyOrder order ) { print( "\n No asks found, saving buyer account and storing bid\n" ); assert( !order.fill_or_kill, "order not completely filled" ); Bids::store( bid ); + buyer_account.open_orders++; save( buyer_account ); return; } @@ -162,6 +163,7 @@ void apply_exchange_buy( BuyOrder order ) { match( bid, buyer_account, lowest_ask, seller_account ); if( lowest_ask.quantity == CurrencyTokens(0) ) { + seller_account.open_orders--; save( seller_account ); save( buyer_account ); Asks::remove( lowest_ask ); @@ -175,6 +177,7 @@ void apply_exchange_buy( BuyOrder order ) { } print( "lowest_ask >= bid.price or buyer's bid has been filled\n" ); + if( bid.quantity && !order.fill_or_kill ) buyer_account.open_orders++; save( buyer_account ); print( "saving buyer's account\n" ); if( bid.quantity ) { @@ -209,6 +212,7 @@ void apply_exchange_sell( SellOrder order ) { assert( !order.fill_or_kill, "order not completely filled" ); print( "\n No bids found, saving seller account and storing ask\n" ); Asks::store( ask ); + seller_account.open_orders++; save( seller_account ); return; } @@ -220,6 +224,7 @@ void apply_exchange_sell( SellOrder order ) { match( highest_bid, buyer_account, ask, seller_account ); if( highest_bid.quantity == EosTokens(0) ) { + buyer_account.open_orders--; save( seller_account ); save( buyer_account ); Bids::remove( highest_bid ); @@ -231,13 +236,49 @@ void apply_exchange_sell( SellOrder order ) { break; // buyer's bid should be filled } } - + + if( ask.quantity && !order.fill_or_kill ) seller_account.open_orders++; save( seller_account ); if( ask.quantity ) { assert( !order.fill_or_kill, "order not completely filled" ); print( "saving ask\n" ); Asks::store( ask ); + return; } + + print( "ask filled\n" ); +} + +void apply_exchange_cancel_buy( OrderID order ) { + requireAuth( order.name ); + + Bid bid_to_cancel; + assert( BidsById::get( order, bid_to_cancel ), "bid with this id does not exists" ); + + auto buyer_account = getAccount( order.name ); + buyer_account.eos_balance += bid_to_cancel.quantity; + buyer_account.open_orders--; + + Bids::remove( bid_to_cancel ); + save( buyer_account ); + + print( "bid removed\n" ); +} + +void apply_exchange_cancel_sell( OrderID order ) { + requireAuth( order.name ); + + Ask ask_to_cancel; + assert( AsksById::get( order, ask_to_cancel ), "ask with this id does not exists" ); + + auto seller_account = getAccount( order.name ); + seller_account.currency_balance += ask_to_cancel.quantity; + seller_account.open_orders--; + + Asks::remove( ask_to_cancel ); + save( seller_account ); + + print( "ask removed\n" ); } } // namespace exchange @@ -266,6 +307,12 @@ extern "C" { case N(sell): apply_exchange_sell( currentMessage() ); break; + case N(cancel_buy): + apply_exchange_cancel_buy( currentMessage() ); + break; + case N(cancel_sell): + apply_exchange_cancel_sell( currentMessage() ); + break; default: assert( false, "unknown action" ); } diff --git a/contracts/exchange/exchange.hpp b/contracts/exchange/exchange.hpp index dd44eb40158..da83d5f961e 100644 --- a/contracts/exchange/exchange.hpp +++ b/contracts/exchange/exchange.hpp @@ -50,7 +50,7 @@ namespace exchange { using Accounts = Table; TABLE2(Bids,exchange,exchange,bids,Bid,BidsById,OrderID,BidsByPrice,Price); - TABLE2(Asks,exchange,exchange,bids,Ask,AsksById,OrderID,AsksByPrice,Price); + TABLE2(Asks,exchange,exchange,asks,Ask,AsksById,OrderID,AsksByPrice,Price); struct BuyOrder : public Bid { uint8_t fill_or_kill = false; }; From b4618acec827a7bc53e858dee075e77580b9eaaa Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Fri, 28 Jul 2017 01:10:22 -0300 Subject: [PATCH 3/6] Add abi spec for exchange contract --- contracts/exchange/exchange.abi | 70 +++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 contracts/exchange/exchange.abi diff --git a/contracts/exchange/exchange.abi b/contracts/exchange/exchange.abi new file mode 100644 index 00000000000..313d8e2c5ec --- /dev/null +++ b/contracts/exchange/exchange.abi @@ -0,0 +1,70 @@ +{ + "types": [{ + "newTypeName": "AccountName", + "type": "Name" + } + ], + "structs": [{ + "name": "OrderID", + "fields": { + "name" : "AccountName", + "id" : "UInt64" + } + },{ + "name" : "Bid", + "fields" : { + "buyer" : "OrderID", + "price" : "UInt128", + "quantity" : "UInt64", + "expiration" : "Time" + } + },{ + "name" : "Ask", + "fields" : { + "seller" : "OrderID", + "price" : "UInt128", + "quantity" : "UInt64", + "expiration" : "Time" + } + },{ + "name" : "Account", + "fields" : { + "owner" : "AccountName", + "eos_balance" : "UInt64", + "currency_balance" : "UInt64", + "open_orders" : "UInt32" + } + },{ + "name" : "BuyOrder", + "base" : "Bid", + "fields" : { + "fill_or_kill" : "UInt8" + } + },{ + "name" : "SellOrder", + "base" : "Ask", + "fields" : { + "fill_or_kill" : "UInt8" + } + } + ], + "actions": [{ + "action": "buy", + "type": "BuyOrder" + },{ + "action": "sell", + "type": "SellOrder" + },{ + "action": "cancel_buy", + "type": "OrderID" + },{ + "action": "cancel_sell", + "type": "OrderID" + } + ], + "tables": [ + {"table":"bids","type":"Bid"}, + {"table":"asks","type":"Ask"}, + {"table":"account","type":"Account"} + ] +} From b28f5cf63318f3ff9cf77ade2a72ba407c72f98d Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Fri, 28 Jul 2017 01:13:59 -0300 Subject: [PATCH 4/6] Add get_table_rows_i128i128_primary api --- plugins/chain_api_plugin/chain_api_plugin.cpp | 1 + plugins/chain_plugin/chain_plugin.cpp | 44 +++++++++++++++++++ .../include/eos/chain_plugin/chain_plugin.hpp | 22 ++++++++++ 3 files changed, 67 insertions(+) diff --git a/plugins/chain_api_plugin/chain_api_plugin.cpp b/plugins/chain_api_plugin/chain_api_plugin.cpp index 6f27708f414..16168da71db 100644 --- a/plugins/chain_api_plugin/chain_api_plugin.cpp +++ b/plugins/chain_api_plugin/chain_api_plugin.cpp @@ -52,6 +52,7 @@ void chain_api_plugin::plugin_startup() { CHAIN_RO_CALL(get_block), CHAIN_RO_CALL(get_account), CHAIN_RO_CALL(get_table_rows_i64), + CHAIN_RO_CALL(get_table_rows_i128i128_primary), CHAIN_RO_CALL(abi_json_to_bin), CHAIN_RW_CALL(push_block), CHAIN_RW_CALL(push_transaction) diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index fbedd98b76c..43b05fe20b9 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,7 @@ using chain::account_object; using chain::key_value_object; using chain::by_name; using chain::by_scope_key; +using chain::uint128_t; class chain_plugin_impl { @@ -237,6 +239,48 @@ read_only::get_table_rows_i64_result read_only::get_table_rows_i64( const read_o return result; } +read_only::get_table_rows_i128i128_primary_result read_only::get_table_rows_i128i128_primary( const read_only::get_table_rows_i128i128_primary_params& p )const { + read_only::get_table_rows_i128i128_primary_result result; + const auto& d = db.get_database(); + const auto& code_account = d.get( p.code ); + + types::AbiSerializer abis; + if( code_account.abi.size() > 4 ) { /// 4 == packsize of empty Abi + eos::types::Abi abi; + fc::datastream ds( code_account.abi.data(), code_account.abi.size() ); + fc::raw::unpack( ds, abi ); + abis.setAbi( abi ); + } + + const auto& idx = d.get_index(); + auto lower = idx.lower_bound( boost::make_tuple( p.scope, p.code, p.table, p.lower_bound ) ); + auto upper = idx.upper_bound( boost::make_tuple( p.scope, p.code, p.table, p.upper_bound ) ); + + vector data; + + auto start = fc::time_point::now(); + auto end = fc::time_point::now() + fc::microseconds( 1000*10 ); /// 10ms max time + + int count = 0; + auto itr = lower; + for( itr = lower; itr != upper; ++itr ) { + data.resize( sizeof(uint128_t)*2 + itr->value.size() ); + memcpy( data.data(), &itr->primary_key, sizeof(itr->primary_key) ); + memcpy( data.data()+sizeof(uint128_t), &itr->secondary_key, sizeof(itr->secondary_key) ); + memcpy( data.data()+sizeof(uint128_t)*2, itr->value.data(), itr->value.size() ); + + if( p.json ) + result.rows.emplace_back( abis.binaryToVariant( abis.getTableType(p.table), data ) ); + else + result.rows.emplace_back( fc::variant(data) ); + if( ++count == p.limit || fc::time_point::now() > end ) + break; + } + if( itr != upper ) + result.more = true; + return result; +} + read_only::get_block_results read_only::get_block(const read_only::get_block_params& params) const { try { if (auto block = db.fetch_block_by_id(fc::json::from_string(params.block_num_or_id).as())) diff --git a/plugins/chain_plugin/include/eos/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eos/chain_plugin/chain_plugin.hpp index 62ac6401201..6c0b87e6255 100644 --- a/plugins/chain_plugin/include/eos/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eos/chain_plugin/chain_plugin.hpp @@ -14,6 +14,7 @@ namespace eos { using namespace appbase; using chain::Name; using fc::optional; + using chain::uint128_t; namespace chain_apis { struct empty{}; @@ -106,6 +107,23 @@ class read_only { }; get_table_rows_i64_result get_table_rows_i64( const get_table_rows_i64_params& params )const; + + struct get_table_rows_i128i128_primary_params { + bool json = false; + Name scope; + Name code; + Name table; + uint128_t lower_bound = 0; + uint128_t upper_bound = uint128_t(-1); + uint32_t limit = 10; + }; + + struct get_table_rows_i128i128_primary_result { + vector rows; ///< one row per item, either encoded as hex String or JSON object + bool more; ///< true if last element in data is not the end and sizeof data() < limit + }; + + get_table_rows_i128i128_primary_result get_table_rows_i128i128_primary( const get_table_rows_i128i128_primary_params& params )const; }; class read_write { @@ -172,6 +190,10 @@ FC_REFLECT( eos::chain_apis::read_only::get_table_rows_i64_params, (json)(scope)(code)(table)(lower_bound)(upper_bound)(limit) ); FC_REFLECT( eos::chain_apis::read_only::get_table_rows_i64_result, (rows)(more) ); +FC_REFLECT( eos::chain_apis::read_only::get_table_rows_i128i128_primary_params, + (json)(scope)(code)(table)(lower_bound)(upper_bound)(limit) ); +FC_REFLECT( eos::chain_apis::read_only::get_table_rows_i128i128_primary_result, + (rows)(more) ); FC_REFLECT( eos::chain_apis::read_only::get_account_results, (name)(eos_balance)(staked_balance)(unstaking_balance)(last_unstaking_time)(producer)(abi) ) FC_REFLECT( eos::chain_apis::read_only::get_account_params, (name) ) FC_REFLECT( eos::chain_apis::read_only::producer_info, (name) ) From 331c2eced4f26da6cc00d3a6de54e95ec812d9e3 Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Fri, 28 Jul 2017 01:16:29 -0300 Subject: [PATCH 5/6] Fix previously introduced error when calling contract apply function --- libraries/chain/wasm_interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chain/wasm_interface.cpp b/libraries/chain/wasm_interface.cpp index 3eeff2c8059..87c4b4a172f 100644 --- a/libraries/chain/wasm_interface.cpp +++ b/libraries/chain/wasm_interface.cpp @@ -390,7 +390,7 @@ DEFINE_INTRINSIC_FUNCTION1(env,free,free,none,i32,ptr) { FC_ASSERT( getFunctionType(call)->parameters.size() == 2 ); // idump((current_validate_context->msg.code)(current_validate_context->msg.type)(current_validate_context->code)); - std::vector args = { Value(uint64_t(current_validate_context->code)), + std::vector args = { Value(uint64_t(current_validate_context->msg.code)), Value(uint64_t(current_validate_context->msg.type)) }; auto& state = *current_state; From 5bdceadc80cee549da00a76044d42fc4b9a5453f Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Fri, 28 Jul 2017 01:21:44 -0300 Subject: [PATCH 6/6] Add liquid_balance to initial producers in genesis.json --- genesis.json | 63 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/genesis.json b/genesis.json index a654097db59..0a5a75d192f 100644 --- a/genesis.json +++ b/genesis.json @@ -14,87 +14,108 @@ "initial_accounts": [{ "name": "inita", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initb", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initc", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initd", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "inite", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initf", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initg", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "inith", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initi", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initj", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initk", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initl", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initm", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initn", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "inito", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initp", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initq", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initr", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "inits", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initt", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" },{ "name": "initu", "owner_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", - "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV" + "active_key": "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", + "liquid_balance": "1000000.00000000 EOS" }], "initial_producers": [{ "owner_name": "inita",