From 3b5e9280940c4b4bd573868be6d10f813883e917 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Thu, 7 Jul 2022 00:53:23 +0000 Subject: [PATCH] #357 secp256k1 lib from libbitcoin --- .gitmodules | 2 +- libraries/app/api.cpp | 57 -- libraries/app/application.cpp | 1 - libraries/app/database_api.cpp | 26 - libraries/app/include/graphene/app/api.hpp | 41 -- .../app/include/graphene/app/database_api.hpp | 12 - libraries/chain/confidential_evaluator.cpp | 104 ---- libraries/chain/db_notify.cpp | 25 +- .../include/graphene/chain/exceptions.hpp | 3 - .../graphene/chain/protocol/confidential.hpp | 51 +- .../graphene/chain/protocol/operations.hpp | 6 +- libraries/chain/protocol/confidential.cpp | 54 +- libraries/fc | 2 +- .../bitcoin/sign_bitcoin_transaction.cpp | 33 +- .../bitcoin/sign_bitcoin_transaction.hpp | 10 +- .../wallet/include/graphene/wallet/wallet.hpp | 159 ----- libraries/wallet/wallet.cpp | 575 ------------------ .../bitcoin_sign_tests.cpp | 4 +- tests/tests/confidential_tests.cpp | 134 ---- tests/tests/fee_tests.cpp | 206 ------- 20 files changed, 65 insertions(+), 1440 deletions(-) delete mode 100644 tests/tests/confidential_tests.cpp diff --git a/.gitmodules b/.gitmodules index e535465c..d9c387a6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,5 +5,5 @@ [submodule "libraries/fc"] path = libraries/fc url = https://gitlab.com/PBSA/tools-libs/peerplays-fc.git - branch = latest-fc + branch = develop ignore = dirty diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index f6b084f1..8dd18915 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -45,7 +45,6 @@ template class fc::api; template class fc::api; template class fc::api; template class fc::api; -template class fc::api; template class fc::api; template class fc::api; template class fc::api; @@ -90,8 +89,6 @@ void login_api::enable_api(const std::string &api_name) { _history_api = std::make_shared(_app); } else if (api_name == "network_node_api") { _network_node_api = std::make_shared(std::ref(_app)); - } else if (api_name == "crypto_api") { - _crypto_api = std::make_shared(); } else if (api_name == "asset_api") { _asset_api = std::make_shared(_app); } else if (api_name == "debug_api") { @@ -289,11 +286,6 @@ fc::api login_api::history() const { return *_history_api; } -fc::api login_api::crypto() const { - FC_ASSERT(_crypto_api); - return *_crypto_api; -} - fc::api login_api::asset() const { FC_ASSERT(_asset_api); return *_asset_api; @@ -522,55 +514,6 @@ vector history_api::get_market_history(std::string asset_a, std:: FC_CAPTURE_AND_RETHROW((asset_a)(asset_b)(bucket_seconds)(start)(end)) } -crypto_api::crypto_api(){}; - -commitment_type crypto_api::blind(const blind_factor_type &blind, uint64_t value) { - return fc::ecc::blind(blind, value); -} - -blind_factor_type crypto_api::blind_sum(const std::vector &blinds_in, uint32_t non_neg) { - return fc::ecc::blind_sum(blinds_in, non_neg); -} - -bool crypto_api::verify_sum(const std::vector &commits_in, const std::vector &neg_commits_in, int64_t excess) { - return fc::ecc::verify_sum(commits_in, neg_commits_in, excess); -} - -verify_range_result crypto_api::verify_range(const commitment_type &commit, const std::vector &proof) { - verify_range_result result; - result.success = fc::ecc::verify_range(result.min_val, result.max_val, commit, proof); - return result; -} - -std::vector crypto_api::range_proof_sign(uint64_t min_value, - const commitment_type &commit, - const blind_factor_type &commit_blind, - const blind_factor_type &nonce, - int8_t base10_exp, - uint8_t min_bits, - uint64_t actual_value) { - return fc::ecc::range_proof_sign(min_value, commit, commit_blind, nonce, base10_exp, min_bits, actual_value); -} - -verify_range_proof_rewind_result crypto_api::verify_range_proof_rewind(const blind_factor_type &nonce, - const commitment_type &commit, - const std::vector &proof) { - verify_range_proof_rewind_result result; - result.success = fc::ecc::verify_range_proof_rewind(result.blind_out, - result.value_out, - result.message_out, - nonce, - result.min_val, - result.max_val, - const_cast(commit), - proof); - return result; -} - -range_proof_info crypto_api::range_get_info(const std::vector &proof) { - return fc::ecc::range_get_info(proof); -} - // asset_api asset_api::asset_api(graphene::app::application &app) : _app(app), diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index afae81a7..1a3d3a8a 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -362,7 +362,6 @@ public: wild_access.allowed_apis.push_back("database_api"); wild_access.allowed_apis.push_back("network_broadcast_api"); wild_access.allowed_apis.push_back("history_api"); - wild_access.allowed_apis.push_back("crypto_api"); wild_access.allowed_apis.push_back("bookie_api"); wild_access.allowed_apis.push_back("affiliate_stats_api"); wild_access.allowed_apis.push_back("sidechain_api"); diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 1095bbeb..250413ee 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -237,9 +237,6 @@ public: // Proposed transactions vector get_proposed_transactions(const std::string account_id_or_name) const; - // Blinded balances - vector get_blinded_balances(const flat_set &commitments) const; - // Tournaments vector get_tournaments_in_state(tournament_state state, uint32_t limit) const; vector get_tournaments(tournament_id_type stop, unsigned limit, tournament_id_type start); @@ -2650,29 +2647,6 @@ vector database_api_impl::get_proposed_transactions(const std:: return result; } -////////////////////////////////////////////////////////////////////// -// // -// Blinded balances // -// // -////////////////////////////////////////////////////////////////////// - -vector database_api::get_blinded_balances(const flat_set &commitments) const { - return my->get_blinded_balances(commitments); -} - -vector database_api_impl::get_blinded_balances(const flat_set &commitments) const { - vector result; - result.reserve(commitments.size()); - const auto &bal_idx = _db.get_index_type(); - const auto &by_commitment_idx = bal_idx.indices().get(); - for (const auto &c : commitments) { - auto itr = by_commitment_idx.find(c); - if (itr != by_commitment_idx.end()) - result.push_back(*itr); - } - return result; -} - ////////////////////////////////////////////////////////////////////// // // // Tournament methods // diff --git a/libraries/app/include/graphene/app/api.hpp b/libraries/app/include/graphene/app/api.hpp index 98be16a6..68f2514a 100644 --- a/libraries/app/include/graphene/app/api.hpp +++ b/libraries/app/include/graphene/app/api.hpp @@ -289,33 +289,6 @@ private: std::function _on_pending_transaction; }; -class crypto_api { -public: - crypto_api(); - - fc::ecc::commitment_type blind(const fc::ecc::blind_factor_type &blind, uint64_t value); - - fc::ecc::blind_factor_type blind_sum(const std::vector &blinds_in, uint32_t non_neg); - - bool verify_sum(const std::vector &commits_in, const std::vector &neg_commits_in, int64_t excess); - - verify_range_result verify_range(const fc::ecc::commitment_type &commit, const std::vector &proof); - - std::vector range_proof_sign(uint64_t min_value, - const commitment_type &commit, - const blind_factor_type &commit_blind, - const blind_factor_type &nonce, - int8_t base10_exp, - uint8_t min_bits, - uint64_t actual_value); - - verify_range_proof_rewind_result verify_range_proof_rewind(const blind_factor_type &nonce, - const fc::ecc::commitment_type &commit, - const std::vector &proof); - - range_proof_info range_get_info(const std::vector &proof); -}; - /** * @brief */ @@ -359,7 +332,6 @@ extern template class fc::api; extern template class fc::api; extern template class fc::api; extern template class fc::api; -extern template class fc::api; extern template class fc::api; extern template class fc::api; @@ -394,8 +366,6 @@ public: fc::api history() const; /// @brief Retrieve the network node API fc::api network_node() const; - /// @brief Retrieve the cryptography API - fc::api crypto() const; /// @brief Retrieve the asset API fc::api asset() const; /// @brief Retrieve the debug API (if available) @@ -417,7 +387,6 @@ private: optional> _network_broadcast_api; optional> _network_node_api; optional> _history_api; - optional> _crypto_api; optional> _asset_api; optional> _debug_api; optional> _bookie_api; @@ -475,15 +444,6 @@ FC_API(graphene::app::network_node_api, (subscribe_to_pending_transactions) (unsubscribe_from_pending_transactions)) -FC_API(graphene::app::crypto_api, - (blind) - (blind_sum) - (verify_sum) - (verify_range) - (range_proof_sign) - (verify_range_proof_rewind) - (range_get_info)) - FC_API(graphene::app::asset_api, (get_asset_holders) (get_asset_holders_count) @@ -496,7 +456,6 @@ FC_API(graphene::app::login_api, (database) (history) (network_node) - (crypto) (asset) (debug) (bookie) diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 679d8a4c..abe65a2b 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -877,15 +877,6 @@ public: */ vector get_proposed_transactions(const std::string account_id_or_name) const; - ////////////////////// - // Blinded balances // - ////////////////////// - - /** - * @return the set of blinded balance objects by commitment ID - */ - vector get_blinded_balances(const flat_set &commitments) const; - ///////////////// // Tournaments // ///////////////// @@ -1198,9 +1189,6 @@ FC_API(graphene::app::database_api, // Proposed transactions (get_proposed_transactions) - // Blinded balances - (get_blinded_balances) - // Tournaments (get_tournaments_in_state) (get_tournaments_by_state) diff --git a/libraries/chain/confidential_evaluator.cpp b/libraries/chain/confidential_evaluator.cpp index 9946b492..fa4ac515 100644 --- a/libraries/chain/confidential_evaluator.cpp +++ b/libraries/chain/confidential_evaluator.cpp @@ -33,149 +33,45 @@ namespace graphene { namespace chain { void_result transfer_to_blind_evaluator::do_evaluate( const transfer_to_blind_operation& o ) { try { - const auto& d = db(); - - const auto& atype = o.amount.asset_id(db()); - FC_ASSERT( atype.allow_confidential() ); - FC_ASSERT( !atype.is_transfer_restricted() ); - FC_ASSERT( !(atype.options.flags & white_list) ); - - for( const auto& out : o.outputs ) - { - for( const auto& a : out.owner.account_auths ) - a.first(d); // verify all accounts exist and are valid - } return void_result(); } FC_CAPTURE_AND_RETHROW( (o) ) } void_result transfer_to_blind_evaluator::do_apply( const transfer_to_blind_operation& o ) { try { - db().adjust_balance( o.from, -o.amount ); - - const auto& add = o.amount.asset_id(db()).dynamic_asset_data_id(db()); // verify fee is a legit asset - db().modify( add, [&]( asset_dynamic_data_object& obj ){ - obj.confidential_supply += o.amount.amount; - FC_ASSERT( obj.confidential_supply >= 0 ); - }); - for( const auto& out : o.outputs ) - { - db().create( [&]( blinded_balance_object& obj ){ - obj.asset_id = o.amount.asset_id; - obj.owner = out.owner; - obj.commitment = out.commitment; - }); - } return void_result(); } FC_CAPTURE_AND_RETHROW( (o) ) } void transfer_to_blind_evaluator::pay_fee() { - if( db().head_block_time() >= HARDFORK_563_TIME ) - pay_fba_fee( fba_accumulator_id_transfer_to_blind ); - else - generic_evaluator::pay_fee(); } void_result transfer_from_blind_evaluator::do_evaluate( const transfer_from_blind_operation& o ) { try { - const auto& d = db(); - o.fee.asset_id(d); // verify fee is a legit asset - const auto& bbi = d.get_index_type(); - const auto& cidx = bbi.indices().get(); - for( const auto& in : o.inputs ) - { - auto itr = cidx.find( in.commitment ); - FC_ASSERT( itr != cidx.end() ); - FC_ASSERT( itr->asset_id == o.fee.asset_id ); - FC_ASSERT( itr->owner == in.owner ); - } return void_result(); } FC_CAPTURE_AND_RETHROW( (o) ) } void_result transfer_from_blind_evaluator::do_apply( const transfer_from_blind_operation& o ) { try { - db().adjust_balance( o.fee_payer(), o.fee ); - db().adjust_balance( o.to, o.amount ); - const auto& bbi = db().get_index_type(); - const auto& cidx = bbi.indices().get(); - for( const auto& in : o.inputs ) - { - auto itr = cidx.find( in.commitment ); - FC_ASSERT( itr != cidx.end() ); - db().remove( *itr ); - } - const auto& add = o.amount.asset_id(db()).dynamic_asset_data_id(db()); // verify fee is a legit asset - db().modify( add, [&]( asset_dynamic_data_object& obj ){ - obj.confidential_supply -= o.amount.amount + o.fee.amount; - FC_ASSERT( obj.confidential_supply >= 0 ); - }); return void_result(); } FC_CAPTURE_AND_RETHROW( (o) ) } void transfer_from_blind_evaluator::pay_fee() { - if( db().head_block_time() >= HARDFORK_563_TIME ) - pay_fba_fee( fba_accumulator_id_transfer_from_blind ); - else - generic_evaluator::pay_fee(); } void_result blind_transfer_evaluator::do_evaluate( const blind_transfer_operation& o ) { try { - const auto& d = db(); - o.fee.asset_id(db()); // verify fee is a legit asset - const auto& bbi = db().get_index_type(); - const auto& cidx = bbi.indices().get(); - for( const auto& out : o.outputs ) - { - for( const auto& a : out.owner.account_auths ) - a.first(d); // verify all accounts exist and are valid - } - for( const auto& in : o.inputs ) - { - auto itr = cidx.find( in.commitment ); - GRAPHENE_ASSERT( itr != cidx.end(), blind_transfer_unknown_commitment, "", ("commitment",in.commitment) ); - FC_ASSERT( itr->asset_id == o.fee.asset_id ); - FC_ASSERT( itr->owner == in.owner ); - } return void_result(); } FC_CAPTURE_AND_RETHROW( (o) ) } void_result blind_transfer_evaluator::do_apply( const blind_transfer_operation& o ) { try { - db().adjust_balance( o.fee_payer(), o.fee ); // deposit the fee to the temp account - const auto& bbi = db().get_index_type(); - const auto& cidx = bbi.indices().get(); - for( const auto& in : o.inputs ) - { - auto itr = cidx.find( in.commitment ); - GRAPHENE_ASSERT( itr != cidx.end(), blind_transfer_unknown_commitment, "", ("commitment",in.commitment) ); - db().remove( *itr ); - } - for( const auto& out : o.outputs ) - { - db().create( [&]( blinded_balance_object& obj ){ - obj.asset_id = o.fee.asset_id; - obj.owner = out.owner; - obj.commitment = out.commitment; - }); - } - const auto& add = o.fee.asset_id(db()).dynamic_asset_data_id(db()); - db().modify( add, [&]( asset_dynamic_data_object& obj ){ - obj.confidential_supply -= o.fee.amount; - FC_ASSERT( obj.confidential_supply >= 0 ); - }); - return void_result(); } FC_CAPTURE_AND_RETHROW( (o) ) } void blind_transfer_evaluator::pay_fee() { - if( db().head_block_time() >= HARDFORK_563_TIME ) - pay_fba_fee( fba_accumulator_id_blind_transfer ); - else - generic_evaluator::pay_fee(); } } } // graphene::chain diff --git a/libraries/chain/db_notify.cpp b/libraries/chain/db_notify.cpp index 62d6d2bf..2360a318 100644 --- a/libraries/chain/db_notify.cpp +++ b/libraries/chain/db_notify.cpp @@ -203,27 +203,10 @@ struct get_impacted_account_visitor _impacted.insert( op.issuer ); } - void operator()( const transfer_to_blind_operation& op ) - { - _impacted.insert( op.from ); - for( const auto& out : op.outputs ) - add_authority_accounts( _impacted, out.owner ); - } - - void operator()( const blind_transfer_operation& op ) - { - for( const auto& in : op.inputs ) - add_authority_accounts( _impacted, in.owner ); - for( const auto& out : op.outputs ) - add_authority_accounts( _impacted, out.owner ); - } - - void operator()( const transfer_from_blind_operation& op ) - { - _impacted.insert( op.to ); - for( const auto& in : op.inputs ) - add_authority_accounts( _impacted, in.owner ); - } + //! We don't use this operations + void operator()( const transfer_to_blind_operation& op ){} + void operator()( const blind_transfer_operation& op ){} + void operator()( const transfer_from_blind_operation& op ){} void operator()( const asset_settle_cancel_operation& op ) { diff --git a/libraries/chain/include/graphene/chain/exceptions.hpp b/libraries/chain/include/graphene/chain/exceptions.hpp index 406a235e..92c7c5dd 100644 --- a/libraries/chain/include/graphene/chain/exceptions.hpp +++ b/libraries/chain/include/graphene/chain/exceptions.hpp @@ -182,9 +182,6 @@ namespace graphene { namespace chain { GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( override_transfer ); GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( not_permitted, override_transfer, 1, "not permitted" ) - GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( blind_transfer ); - GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, "Attempting to claim an unknown prior commitment" ); - /* FC_DECLARE_DERIVED_EXCEPTION( addition_overflow, graphene::chain::chain_exception, 30002, "addition overflow" ) FC_DECLARE_DERIVED_EXCEPTION( subtraction_overflow, graphene::chain::chain_exception, 30003, "subtraction overflow" ) diff --git a/libraries/chain/include/graphene/chain/protocol/confidential.hpp b/libraries/chain/include/graphene/chain/protocol/confidential.hpp index 697ef35b..d1a28da3 100644 --- a/libraries/chain/include/graphene/chain/protocol/confidential.hpp +++ b/libraries/chain/include/graphene/chain/protocol/confidential.hpp @@ -111,12 +111,12 @@ struct stealth_confirmation /** * Packs *this then encodes as base58 encoded string. */ - operator string()const; + //operator string()const; /** * Unpacks from a base58 string */ - stealth_confirmation( const std::string& base58 ); - stealth_confirmation(){} + //stealth_confirmation( const std::string& base58 ); + //stealth_confirmation(){} public_key_type one_time_key; optional to; @@ -152,16 +152,17 @@ struct transfer_to_blind_operation : public base_operation uint32_t price_per_output = 5*GRAPHENE_BLOCKCHAIN_PRECISION; }; - asset fee; asset amount; account_id_type from; blind_factor_type blinding_factor; vector outputs; - account_id_type fee_payer()const { return from; } - void validate()const; - share_type calculate_fee(const fee_parameters_type& )const; + account_id_type fee_payer()const { return account_id_type{}; } + + //account_id_type fee_payer()const { return from; } + //void validate()const; + //share_type calculate_fee(const fee_parameters_type& )const; }; /** @@ -180,14 +181,15 @@ struct transfer_from_blind_operation : public base_operation blind_factor_type blinding_factor; vector inputs; - account_id_type fee_payer()const { return GRAPHENE_TEMP_ACCOUNT; } - void validate()const; + account_id_type fee_payer()const { return account_id_type{}; } - void get_required_authorities( vector& a )const - { - for( const auto& in : inputs ) - a.push_back( in.owner ); - } + //account_id_type fee_payer()const { return GRAPHENE_TEMP_ACCOUNT; } + //void validate()const; + //void get_required_authorities( vector& a )const + //{ + // for( const auto& in : inputs ) + // a.push_back( in.owner ); + //} }; /** @@ -243,17 +245,18 @@ struct blind_transfer_operation : public base_operation asset fee; vector inputs; vector outputs; - - /** graphene TEMP account */ - account_id_type fee_payer()const; - void validate()const; - share_type calculate_fee( const fee_parameters_type& k )const; - void get_required_authorities( vector& a )const - { - for( const auto& in : inputs ) - a.push_back( in.owner ); - } + account_id_type fee_payer()const { return account_id_type{}; } + + /** graphene TEMP account */ + //account_id_type fee_payer()const; + //void validate()const; + //share_type calculate_fee( const fee_parameters_type& k )const; + //void get_required_authorities( vector& a )const + //{ + // for( const auto& in : inputs ) + // a.push_back( in.owner ); + //} }; ///@} endgroup stealth diff --git a/libraries/chain/include/graphene/chain/protocol/operations.hpp b/libraries/chain/include/graphene/chain/protocol/operations.hpp index 83d347ab..8cbde2ac 100644 --- a/libraries/chain/include/graphene/chain/protocol/operations.hpp +++ b/libraries/chain/include/graphene/chain/protocol/operations.hpp @@ -106,9 +106,9 @@ namespace graphene { namespace chain { assert_operation, balance_claim_operation, override_transfer_operation, - transfer_to_blind_operation, - blind_transfer_operation, - transfer_from_blind_operation, + transfer_to_blind_operation, //! We don't use this operation + blind_transfer_operation, //! We don't use this operation + transfer_from_blind_operation, //! We don't use this operation asset_settle_cancel_operation, // VIRTUAL asset_claim_fees_operation, fba_distribute_operation, // VIRTUAL diff --git a/libraries/chain/protocol/confidential.cpp b/libraries/chain/protocol/confidential.cpp index 2e8fbc68..4bca850d 100644 --- a/libraries/chain/protocol/confidential.cpp +++ b/libraries/chain/protocol/confidential.cpp @@ -22,12 +22,10 @@ * THE SOFTWARE. */ #include -#include -#include -#include #include +/* namespace graphene { namespace chain { void transfer_to_blind_operation::validate()const @@ -47,19 +45,6 @@ void transfer_to_blind_operation::validate()const FC_ASSERT( !outputs[i].owner.is_impossible() ); } FC_ASSERT( out.size(), "there must be at least one output" ); - - auto public_c = fc::ecc::blind(blinding_factor,net_public); - - FC_ASSERT( fc::ecc::verify_sum( {public_c}, out, 0 ), "", ("net_public",net_public) ); - - if( outputs.size() > 1 ) - { - for( auto out : outputs ) - { - auto info = fc::ecc::range_get_info( out.range_proof ); - FC_ASSERT( info.max_value <= GRAPHENE_MAX_SHARE_SUPPLY ); - } - } } share_type transfer_to_blind_operation::calculate_fee( const fee_parameters_type& k )const @@ -79,31 +64,15 @@ void transfer_from_blind_operation::validate()const vector in(inputs.size()); vector out; int64_t net_public = fee.amount.value + amount.amount.value; - out.push_back( fc::ecc::blind( blinding_factor, net_public ) ); - for( uint32_t i = 0; i < in.size(); ++i ) - { - in[i] = inputs[i].commitment; - /// by requiring all inputs to be sorted we also prevent duplicate commitments on the input - if( i > 0 ) FC_ASSERT( in[i-1] < in[i], "all inputs must be sorted by commitment id" ); - } - FC_ASSERT( in.size(), "there must be at least one input" ); - FC_ASSERT( fc::ecc::verify_sum( in, out, 0 ) ); } -/** - * If fee_payer = temp_account_id, then the fee is paid by the surplus balance of inputs-outputs and - * 100% of the fee goes to the network. - */ account_id_type blind_transfer_operation::fee_payer()const { return GRAPHENE_TEMP_ACCOUNT; } -/** - * This method can be computationally intensive because it verifies that input commitments - output commitments add up to 0 - */ void blind_transfer_operation::validate()const { try { vector in(inputs.size()); @@ -122,17 +91,6 @@ void blind_transfer_operation::validate()const FC_ASSERT( !outputs[i].owner.is_impossible() ); } FC_ASSERT( in.size(), "there must be at least one input" ); - FC_ASSERT( fc::ecc::verify_sum( in, out, net_public ), "", ("net_public", net_public) ); - - if( outputs.size() > 1 ) - { - for( auto out : outputs ) - { - auto info = fc::ecc::range_get_info( out.range_proof ); - FC_ASSERT( info.max_value <= GRAPHENE_MAX_SHARE_SUPPLY ); - } - } - FC_ASSERT( fc::ecc::verify_sum( in, out, net_public ), "", ("net_public", net_public) ); } FC_CAPTURE_AND_RETHROW( (*this) ) } share_type blind_transfer_operation::calculate_fee( const fee_parameters_type& k )const @@ -140,16 +98,12 @@ share_type blind_transfer_operation::calculate_fee( const fee_parameters_type& k return k.fee + outputs.size() * k.price_per_output; } -/** - * Packs *this then encodes as base58 encoded string. - */ + stealth_confirmation::operator string()const { return fc::to_base58( fc::raw::pack( *this ) ); } -/** - * Unpacks from a base58 string - */ + stealth_confirmation::stealth_confirmation( const std::string& base58 ) { *this = fc::raw::unpack( fc::from_base58( base58 ) ); @@ -157,6 +111,8 @@ stealth_confirmation::stealth_confirmation( const std::string& base58 ) } } // graphene::chain +*/ + GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::transfer_to_blind_operation::fee_parameters_type ) GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::transfer_from_blind_operation::fee_parameters_type ) GRAPHENE_EXTERNAL_SERIALIZATION( /*not extern*/, graphene::chain::blind_transfer_operation::fee_parameters_type ) diff --git a/libraries/fc b/libraries/fc index e7369949..156b0c4e 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit e7369949bea26f3201d8442ba78286a88df74762 +Subproject commit 156b0c4e41c9215eadb2af8009b05e0f38c16dda diff --git a/libraries/plugins/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.cpp b/libraries/plugins/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.cpp index afad2093..e40ea329 100644 --- a/libraries/plugins/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.cpp +++ b/libraries/plugins/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.cpp @@ -1,4 +1,5 @@ #include +#include #include @@ -6,8 +7,8 @@ namespace graphene { namespace peerplays_sidechain { namespace bitcoin { -const secp256k1_context_t *btc_context() { - static secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); +const secp256k1_context *btc_context() { + static secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); return ctx; } @@ -31,20 +32,14 @@ fc::sha256 get_signature_hash(const bitcoin_transaction &tx, const bytes &script return fc::sha256::hash(fc::sha256::hash(vec.data(), vec.size())); } -std::vector privkey_sign(const bytes &privkey, const fc::sha256 &hash, const secp256k1_context_t *context_sign) { +std::vector privkey_sign(const bytes &privkey, const fc::sha256 &hash, const secp256k1_context *context_sign) { bytes sig; sig.resize(72); int sig_len = sig.size(); - FC_ASSERT(secp256k1_ecdsa_sign( - context_sign, - reinterpret_cast(hash.data()), - reinterpret_cast(sig.data()), - &sig_len, - reinterpret_cast(privkey.data()), - secp256k1_nonce_function_rfc6979, - nullptr)); // TODO: replace assert with exception - + secp256k1_ecdsa_signature sign; + FC_ASSERT(secp256k1_ecdsa_sign(context_sign, &sign, (const unsigned char *)hash.data(), (const unsigned char *)privkey.data(), secp256k1_nonce_function_rfc6979, nullptr)); + FC_ASSERT(secp256k1_ecdsa_signature_serialize_der(context_sign, (unsigned char *)sig.data(), (size_t *)&sig_len, &sign)); sig.resize(sig_len); return sig; @@ -52,7 +47,7 @@ std::vector privkey_sign(const bytes &privkey, const fc::sha256 &hash, con std::vector sign_witness_transaction_part(const bitcoin_transaction &tx, const std::vector &redeem_scripts, const std::vector &amounts, const bytes &privkey, - const secp256k1_context_t *context_sign, int hash_type) { + const secp256k1_context *context_sign, int hash_type) { FC_ASSERT(tx.vin.size() == redeem_scripts.size() && tx.vin.size() == amounts.size()); FC_ASSERT(!privkey.empty()); @@ -77,17 +72,23 @@ void sign_witness_transaction_finalize(bitcoin_transaction &tx, const std::vecto } } -bool verify_sig(const bytes &sig, const bytes &pubkey, const bytes &msg, const secp256k1_context_t *context) { +bool verify_sig(const bytes &sig, const bytes &pubkey, const bytes &msg, const secp256k1_context *context) { std::vector sig_temp(sig.begin(), sig.end()); std::vector pubkey_temp(pubkey.begin(), pubkey.end()); std::vector msg_temp(msg.begin(), msg.end()); - int result = secp256k1_ecdsa_verify(context, msg_temp.data(), sig_temp.data(), sig_temp.size(), pubkey_temp.data(), pubkey_temp.size()); + secp256k1_pubkey pub_key; + FC_ASSERT(secp256k1_ec_pubkey_parse(context, &pub_key, (const unsigned char *)pubkey_temp.data(), pubkey_temp.size())); + + secp256k1_ecdsa_signature sign; + FC_ASSERT(secp256k1_ecdsa_signature_parse_der(context, &sign, (const unsigned char *)sig_temp.data(), sig_temp.size())); + + int result = secp256k1_ecdsa_verify(context, &sign, (const unsigned char *)msg_temp.data(), &pub_key); return result == 1; } std::vector> sort_sigs(const bitcoin_transaction &tx, const std::vector &redeem_scripts, - const std::vector &amounts, const secp256k1_context_t *context) { + const std::vector &amounts, const secp256k1_context *context) { FC_ASSERT(redeem_scripts.size() == amounts.size()); using data = std::pair; diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp index 41808562..34f8eb89 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/bitcoin/sign_bitcoin_transaction.hpp @@ -8,23 +8,23 @@ namespace graphene { namespace peerplays_sidechain { namespace bitcoin { class bitcoin_transaction; -const secp256k1_context_t *btc_context(); +const secp256k1_context *btc_context(); fc::sha256 get_signature_hash(const bitcoin_transaction &tx, const bytes &scriptPubKey, int64_t amount, size_t in_index, int hash_type, bool is_witness); -std::vector privkey_sign(const bytes &privkey, const fc::sha256 &hash, const secp256k1_context_t *context_sign = nullptr); +std::vector privkey_sign(const bytes &privkey, const fc::sha256 &hash, const secp256k1_context *context_sign = nullptr); std::vector sign_witness_transaction_part(const bitcoin_transaction &tx, const std::vector &redeem_scripts, const std::vector &amounts, const bytes &privkey, - const secp256k1_context_t *context_sign = nullptr, int hash_type = 1); + const secp256k1_context *context_sign = nullptr, int hash_type = 1); void sign_witness_transaction_finalize(bitcoin_transaction &tx, const std::vector &redeem_scripts, bool use_mulisig_workaround = true); -bool verify_sig(const bytes &sig, const bytes &pubkey, const bytes &msg, const secp256k1_context_t *context); +bool verify_sig(const bytes &sig, const bytes &pubkey, const bytes &msg, const secp256k1_context *context); std::vector> sort_sigs(const bitcoin_transaction &tx, const std::vector &redeem_scripts, - const std::vector &amounts, const secp256k1_context_t *context); + const std::vector &amounts, const secp256k1_context *context); void add_signatures_to_transaction_multisig(bitcoin_transaction &tx, std::vector> &signature_set); diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 02790e19..185db897 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -68,80 +68,12 @@ enum authority_type active }; -/** - * Contains the confirmation receipt the sender must give the receiver and - * the meta data about the receipt that helps the sender identify which receipt is - * for the receiver and which is for the change address. - */ -struct blind_confirmation -{ - struct output - { - string label; - public_key_type pub_key; - stealth_confirmation::memo_data decrypted_memo; - stealth_confirmation confirmation; - authority auth; - string confirmation_receipt; - }; - - signed_transaction trx; - vector outputs; -}; - -struct blind_balance -{ - asset amount; - public_key_type from; ///< the account this balance came from - public_key_type to; ///< the account this balance is logically associated with - public_key_type one_time_key; ///< used to derive the authority key and blinding factor - fc::sha256 blinding_factor; - fc::ecc::commitment_type commitment; - bool used = false; -}; - -struct blind_receipt -{ - std::pair from_date()const { return std::make_pair(from_key,date); } - std::pair to_date()const { return std::make_pair(to_key,date); } - std::tuple to_asset_used()const { return std::make_tuple(to_key,amount.asset_id,used); } - const commitment_type& commitment()const { return data.commitment; } - - fc::time_point date; - public_key_type from_key; - string from_label; - public_key_type to_key; - string to_label; - asset amount; - string memo; - authority control_authority; - stealth_confirmation::memo_data data; - bool used = false; - stealth_confirmation conf; -}; - -struct by_from; -struct by_to; -struct by_to_asset_used; -struct by_commitment; - -typedef multi_index_container< blind_receipt, - indexed_by< - ordered_unique< tag, const_mem_fun< blind_receipt, const commitment_type&, &blind_receipt::commitment > >, - ordered_unique< tag, const_mem_fun< blind_receipt, std::pair, &blind_receipt::to_date > >, - ordered_non_unique< tag, const_mem_fun< blind_receipt, std::tuple, &blind_receipt::to_asset_used > >, - ordered_unique< tag, const_mem_fun< blind_receipt, std::pair, &blind_receipt::from_date > > - > -> blind_receipt_index_type; - - struct key_label { string label; public_key_type key; }; - struct by_label; struct by_key; typedef multi_index_container< @@ -195,7 +127,6 @@ struct wallet_data map pending_witness_registrations; key_label_index_type labeled_keys; - blind_receipt_index_type blind_receipts; std::map committed_game_moves; @@ -872,74 +803,10 @@ class wallet_api bool set_key_label( public_key_type, string label ); string get_key_label( public_key_type )const; - /** - * Generates a new blind account for the given brain key and assigns it the given label. - */ - public_key_type create_blind_account( string label, string brain_key ); - - /** - * @return the total balance of all blinded commitments that can be claimed by the - * given account key or label - */ - vector get_blind_balances( string key_or_label ); - /** @return all blind accounts */ - map get_blind_accounts()const; - /** @return all blind accounts for which this wallet has the private key */ - map get_my_blind_accounts()const; /** @return the public key associated with the given label */ public_key_type get_public_key( string label )const; ///@} - /** - * @return all blind receipts to/form a particular account - */ - vector blind_history( string key_or_account ); - - /** - * Given a confirmation receipt, this method will parse it for a blinded balance and confirm - * that it exists in the blockchain. If it exists then it will report the amount received and - * who sent it. - * - * @param confirmation_receipt - a base58 encoded stealth confirmation - * @param opt_from - if not empty and the sender is a unknown public key, then the unknown public key will be given the label opt_from - * @param opt_memo - optional memo - */ - blind_receipt receive_blind_transfer( string confirmation_receipt, string opt_from, string opt_memo ); - - /** - * Transfers a public balance from from_account_id_or_name to one or more blinded balances using a - * stealth transfer. - * - * @param from_account_id_or_name account id or name - * @param asset_symbol asset symbol - * @param to_amounts map from key or label to amount - * @param broadcast true to broadcast the transaction on the network - * @returns blind confirmation structure - */ - blind_confirmation transfer_to_blind( string from_account_id_or_name, - string asset_symbol, - vector> to_amounts, - bool broadcast = false ); - - /** - * Transfers funds from a set of blinded balances to a public account balance. - */ - blind_confirmation transfer_from_blind( - string from_blind_account_key_or_label, - string to_account_id_or_name, - string amount, - string asset_symbol, - bool broadcast = false ); - - /** - * Used to transfer from one set of blinded balances to another - */ - blind_confirmation blind_transfer( string from_key_or_label, - string to_key_or_label, - string amount, - string symbol, - bool broadcast = false ); - /** Place a limit order attempting to sell one asset for another. * * Buying and selling are the same operation on Graphene; if you want to buy BTS @@ -2547,16 +2414,6 @@ class wallet_api void network_add_nodes( const vector& nodes ); vector< variant > network_get_connected_peers(); - /** - * Used to transfer from one set of blinded balances to another - */ - blind_confirmation blind_transfer_help( string from_key_or_label, - string to_key_or_label, - string amount, - string symbol, - bool broadcast = false, - bool to_temp = false ); - std::map> get_result_formatters() const; /** @@ -2607,9 +2464,6 @@ class wallet_api extern template class fc::api; FC_REFLECT( graphene::wallet::key_label, (label)(key) ) -FC_REFLECT( graphene::wallet::blind_balance, (amount)(from)(to)(one_time_key)(blinding_factor)(commitment)(used) ) -FC_REFLECT( graphene::wallet::blind_confirmation::output, (label)(pub_key)(decrypted_memo)(confirmation)(auth)(confirmation_receipt) ) -FC_REFLECT( graphene::wallet::blind_confirmation, (trx)(outputs) ) FC_REFLECT( graphene::wallet::plain_keys, (keys)(checksum) ) @@ -2620,7 +2474,6 @@ FC_REFLECT( graphene::wallet::wallet_data, (extra_keys) (pending_account_registrations)(pending_witness_registrations) (labeled_keys) - (blind_receipts) (committed_game_moves) (ws_server) (ws_user) @@ -2639,9 +2492,6 @@ FC_REFLECT( graphene::wallet::exported_account_keys, (account_name)(encrypted_pr FC_REFLECT( graphene::wallet::exported_keys, (password_checksum)(account_keys) ) -FC_REFLECT( graphene::wallet::blind_receipt, - (date)(from_key)(from_label)(to_key)(to_label)(amount)(memo)(control_authority)(data)(used)(conf) ) - FC_REFLECT( graphene::wallet::approval_delta, (active_approvals_to_add) (active_approvals_to_remove) @@ -2814,15 +2664,6 @@ FC_API( graphene::wallet::wallet_api, (set_key_label) (get_key_label) (get_public_key) - (get_blind_accounts) - (get_my_blind_accounts) - (get_blind_balances) - (create_blind_account) - (transfer_to_blind) - (transfer_from_blind) - (blind_transfer) - (blind_history) - (receive_blind_transfer) (list_sports) (list_event_groups) (list_betting_market_groups) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 35b9ab1c..09aa5bdc 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -134,8 +134,6 @@ public: std::string operator()(const T& op)const; std::string operator()(const transfer_operation& op)const; - std::string operator()(const transfer_from_blind_operation& op)const; - std::string operator()(const transfer_to_blind_operation& op)const; std::string operator()(const account_create_operation& op)const; std::string operator()(const account_update_operation& op)const; std::string operator()(const asset_create_operation& op)const; @@ -3472,70 +3470,6 @@ public: return ss.str(); }; - - m["get_blind_balances"] = [this](variant result, const fc::variants& a) - { - auto r = result.as>( GRAPHENE_MAX_NESTED_OBJECTS ); - vector asset_recs; - std::transform(r.begin(), r.end(), std::back_inserter(asset_recs), [this](const asset& a) { - return get_asset(a.asset_id); - }); - - std::stringstream ss; - for( unsigned i = 0; i < asset_recs.size(); ++i ) - ss << asset_recs[i].amount_to_pretty_string(r[i]) << "\n"; - - return ss.str(); - }; - m["transfer_to_blind"] = [this](variant result, const fc::variants& a) - { - auto r = result.as( GRAPHENE_MAX_NESTED_OBJECTS ); - std::stringstream ss; - r.trx.operations[0].visit( operation_printer( ss, *this, operation_result() ) ); - ss << "\n"; - for( const auto& out : r.outputs ) - { - asset_object a = get_asset( out.decrypted_memo.amount.asset_id ); - ss << a.amount_to_pretty_string( out.decrypted_memo.amount ) << " to " << out.label << "\n\t receipt: " << out.confirmation_receipt <<"\n\n"; - } - return ss.str(); - }; - m["blind_transfer"] = [this](variant result, const fc::variants& a) - { - auto r = result.as( GRAPHENE_MAX_NESTED_OBJECTS ); - std::stringstream ss; - r.trx.operations[0].visit( operation_printer( ss, *this, operation_result() ) ); - ss << "\n"; - for( const auto& out : r.outputs ) - { - asset_object a = get_asset( out.decrypted_memo.amount.asset_id ); - ss << a.amount_to_pretty_string( out.decrypted_memo.amount ) << " to " << out.label << "\n\t receipt: " << out.confirmation_receipt <<"\n\n"; - } - return ss.str(); - }; - m["receive_blind_transfer"] = [this](variant result, const fc::variants& a) - { - auto r = result.as( GRAPHENE_MAX_NESTED_OBJECTS ); - std::stringstream ss; - asset_object as = get_asset( r.amount.asset_id ); - ss << as.amount_to_pretty_string( r.amount ) << " " << r.from_label << " => " << r.to_label << " " << r.memo <<"\n"; - return ss.str(); - }; - m["blind_history"] = [this](variant result, const fc::variants& a) - { - auto records = result.as>( GRAPHENE_MAX_NESTED_OBJECTS ); - std::stringstream ss; - ss << "WHEN " - << " " << "AMOUNT" << " " << "FROM" << " => " << "TO" << " " << "MEMO" <<"\n"; - ss << "====================================================================================\n"; - for( auto& r : records ) - { - asset_object as = get_asset( r.amount.asset_id ); - ss << fc::get_approximate_relative_time_string( r.date ) - << " " << as.amount_to_pretty_string( r.amount ) << " " << r.from_label << " => " << r.to_label << " " << r.memo <<"\n"; - } - return ss.str(); - }; m["get_upcoming_tournaments"] = m["get_tournaments"] = m["get_tournaments_by_state"] = [this](variant result, const fc::variants& a) { const vector tournaments = result.as >( GRAPHENE_MAX_NESTED_OBJECTS ); @@ -4396,26 +4330,6 @@ std::string operation_printer::operator()(const T& op)const out << " result: " << str_result; return ""; } -std::string operation_printer::operator()(const transfer_from_blind_operation& op)const -{ - auto a = wallet.get_asset( op.fee.asset_id ); - auto receiver = wallet.get_account( op.to ); - - out << receiver.name - << " received " << a.amount_to_pretty_string( op.amount ) << " from blinded balance"; - return ""; -} -std::string operation_printer::operator()(const transfer_to_blind_operation& op)const -{ - auto fa = wallet.get_asset( op.fee.asset_id ); - auto a = wallet.get_asset( op.amount.asset_id ); - auto sender = wallet.get_account( op.from ); - - out << sender.name - << " sent " << a.amount_to_pretty_string( op.amount ) << " to " << op.outputs.size() << " blinded balance" << (op.outputs.size()>1?"s":"") - << " fee: " << fa.amount_to_pretty_string( op.fee ); - return ""; -} string operation_printer::operator()(const transfer_operation& op) const { out << "Transfer " << wallet.get_asset(op.amount.asset_id).amount_to_pretty_string(op.amount) @@ -6186,495 +6100,6 @@ bool wallet_api::set_key_label( public_key_type key, string label } return false; } -map wallet_api::get_blind_accounts()const -{ - map result; - for( const auto& item : my->_wallet.labeled_keys ) - result[item.label] = item.key; - return result; -} -map wallet_api::get_my_blind_accounts()const -{ - FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); - map result; - for( const auto& item : my->_wallet.labeled_keys ) - { - if( my->_keys.find(item.key) != my->_keys.end() ) - result[item.label] = item.key; - } - return result; -} - -public_key_type wallet_api::create_blind_account( string label, string brain_key ) -{ - FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); - - auto label_itr = my->_wallet.labeled_keys.get().find(label); - if( label_itr != my->_wallet.labeled_keys.get().end() ) - FC_ASSERT( !"Key with label already exists" ); - brain_key = fc::trim_and_normalize_spaces( brain_key ); - auto secret = fc::sha256::hash( brain_key.c_str(), brain_key.size() ); - auto priv_key = fc::ecc::private_key::regenerate( secret ); - public_key_type pub_key = priv_key.get_public_key(); - - FC_ASSERT( set_key_label( pub_key, label ) ); - - my->_keys[pub_key] = graphene::utilities::key_to_wif( priv_key ); - - save_wallet_file(); - return pub_key; -} - -vector wallet_api::get_blind_balances( string key_or_label ) -{ - vector result; - map balances; - - vector used; - - auto pub_key = get_public_key( key_or_label ); - auto& to_asset_used_idx = my->_wallet.blind_receipts.get(); - auto start = to_asset_used_idx.lower_bound( std::make_tuple(pub_key,asset_id_type(0),false) ); - auto end = to_asset_used_idx.lower_bound( std::make_tuple(pub_key,asset_id_type(uint32_t(0xffffffff)),true) ); - while( start != end ) - { - if( !start->used ) - { - auto answer = my->_remote_db->get_blinded_balances( {start->commitment()} ); - if( answer.size() ) - balances[start->amount.asset_id] += start->amount.amount; - else - used.push_back( start->commitment() ); - } - ++start; - } - for( const auto& u : used ) - { - auto itr = my->_wallet.blind_receipts.get().find( u ); - my->_wallet.blind_receipts.modify( itr, []( blind_receipt& r ){ r.used = true; } ); - } - for( auto item : balances ) - result.push_back( asset( item.second, item.first ) ); - return result; -} - -blind_confirmation wallet_api::transfer_from_blind( string from_blind_account_key_or_label, - string to_account_id_or_name, - string amount_in, - string symbol, - bool broadcast ) -{ try { - transfer_from_blind_operation from_blind; - - - auto fees = my->_remote_db->get_global_properties().parameters.current_fees; - fc::optional asset_obj = get_asset(symbol); - FC_ASSERT(asset_obj.valid(), "Could not find asset matching ${asset}", ("asset", symbol)); - auto amount = asset_obj->amount_from_string(amount_in); - - from_blind.fee = fees->calculate_fee( from_blind, asset_obj->options.core_exchange_rate ); - - auto blind_in = asset_obj->amount_to_string( from_blind.fee + amount ); - - - auto conf = blind_transfer_help( from_blind_account_key_or_label, - from_blind_account_key_or_label, - blind_in, symbol, false, true/*to_temp*/ ); - FC_ASSERT( conf.outputs.size() > 0 ); - - auto to_account = my->get_account( to_account_id_or_name ); - from_blind.to = to_account.id; - from_blind.amount = amount; - from_blind.blinding_factor = conf.outputs.back().decrypted_memo.blinding_factor; - from_blind.inputs.push_back( {conf.outputs.back().decrypted_memo.commitment, authority() } ); - from_blind.fee = fees->calculate_fee( from_blind, asset_obj->options.core_exchange_rate ); - - idump( (from_blind) ); - conf.trx.operations.push_back(from_blind); - ilog( "about to validate" ); - conf.trx.validate(); - - if( broadcast && conf.outputs.size() == 2 ) { - - // Save the change - blind_confirmation::output conf_output; - blind_confirmation::output change_output = conf.outputs[0]; - - // The wallet must have a private key for confirmation.to, this is used to decrypt the memo - public_key_type from_key = get_public_key(from_blind_account_key_or_label); - conf_output.confirmation.to = from_key; - conf_output.confirmation.one_time_key = change_output.confirmation.one_time_key; - conf_output.confirmation.encrypted_memo = change_output.confirmation.encrypted_memo; - conf_output.confirmation_receipt = conf_output.confirmation; - //try { - receive_blind_transfer( conf_output.confirmation_receipt, from_blind_account_key_or_label, "@"+to_account.name ); - //} catch ( ... ){} - } - - ilog( "about to broadcast" ); - conf.trx = sign_transaction( conf.trx, broadcast ); - - return conf; -} FC_CAPTURE_AND_RETHROW( (from_blind_account_key_or_label)(to_account_id_or_name)(amount_in)(symbol) ) } - -blind_confirmation wallet_api::blind_transfer( string from_key_or_label, - string to_key_or_label, - string amount_in, - string symbol, - bool broadcast ) -{ - return blind_transfer_help( from_key_or_label, to_key_or_label, amount_in, symbol, broadcast, false ); -} -blind_confirmation wallet_api::blind_transfer_help( string from_key_or_label, - string to_key_or_label, - string amount_in, - string symbol, - bool broadcast, - bool to_temp ) -{ - blind_confirmation confirm; - try { - - FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); - public_key_type from_key = get_public_key(from_key_or_label); - public_key_type to_key = get_public_key(to_key_or_label); - - fc::optional asset_obj = get_asset(symbol); - FC_ASSERT(asset_obj.valid(), "Could not find asset matching ${asset}", ("asset", symbol)); - - blind_transfer_operation blind_tr; - blind_tr.outputs.resize(2); - - auto fees = my->_remote_db->get_global_properties().parameters.current_fees; - - auto amount = asset_obj->amount_from_string(amount_in); - - asset total_amount = asset_obj->amount(0); - - vector blinding_factors; - - //auto from_priv_key = my->get_private_key( from_key ); - - blind_tr.fee = fees->calculate_fee( blind_tr, asset_obj->options.core_exchange_rate ); - - vector used; - - auto& to_asset_used_idx = my->_wallet.blind_receipts.get(); - auto start = to_asset_used_idx.lower_bound( std::make_tuple(from_key,amount.asset_id,false) ); - auto end = to_asset_used_idx.lower_bound( std::make_tuple(from_key,amount.asset_id,true) ); - while( start != end ) - { - auto result = my->_remote_db->get_blinded_balances( {start->commitment() } ); - if( result.size() == 0 ) - { - used.push_back( start->commitment() ); - } - else - { - blind_tr.inputs.push_back({start->commitment(), start->control_authority}); - blinding_factors.push_back( start->data.blinding_factor ); - total_amount += start->amount; - - if( total_amount >= amount + blind_tr.fee ) - break; - } - ++start; - } - for( const auto& u : used ) - { - auto itr = my->_wallet.blind_receipts.get().find( u ); - my->_wallet.blind_receipts.modify( itr, []( blind_receipt& r ){ r.used = true; } ); - } - - FC_ASSERT( total_amount >= amount+blind_tr.fee, "Insufficent Balance", ("available",total_amount)("amount",amount)("fee",blind_tr.fee) ); - - auto one_time_key = fc::ecc::private_key::generate(); - auto secret = one_time_key.get_shared_secret( to_key ); - auto child = fc::sha256::hash( secret ); - auto nonce = fc::sha256::hash( one_time_key.get_secret() ); - auto blind_factor = fc::sha256::hash( child ); - - auto from_secret = one_time_key.get_shared_secret( from_key ); - auto from_child = fc::sha256::hash( from_secret ); - auto from_nonce = fc::sha256::hash( nonce ); - - auto change = total_amount - amount - blind_tr.fee; - fc::sha256 change_blind_factor; - fc::sha256 to_blind_factor; - if( change.amount > 0 ) - { - idump(("to_blind_factor")(blind_factor) ); - blinding_factors.push_back( blind_factor ); - change_blind_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() - 1 ); - wdump(("change_blind_factor")(change_blind_factor) ); - } - else // change == 0 - { - blind_tr.outputs.resize(1); - blind_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() ); - idump(("to_sum_blind_factor")(blind_factor) ); - blinding_factors.push_back( blind_factor ); - idump(("nochange to_blind_factor")(blind_factor) ); - } - fc::ecc::public_key from_pub_key = from_key; - fc::ecc::public_key to_pub_key = to_key; - - blind_output to_out; - to_out.owner = to_temp ? authority() : authority( 1, public_key_type( to_pub_key.child( child ) ), 1 ); - to_out.commitment = fc::ecc::blind( blind_factor, amount.amount.value ); - idump(("to_out.blind")(blind_factor)(to_out.commitment) ); - - - if( blind_tr.outputs.size() > 1 ) - { - to_out.range_proof = fc::ecc::range_proof_sign( 0, to_out.commitment, blind_factor, nonce, 0, 0, amount.amount.value ); - - blind_output change_out; - change_out.owner = authority( 1, public_key_type( from_pub_key.child( from_child ) ), 1 ); - change_out.commitment = fc::ecc::blind( change_blind_factor, change.amount.value ); - change_out.range_proof = fc::ecc::range_proof_sign( 0, change_out.commitment, change_blind_factor, from_nonce, 0, 0, change.amount.value ); - blind_tr.outputs[1] = change_out; - - - blind_confirmation::output conf_output; - conf_output.label = from_key_or_label; - conf_output.pub_key = from_key; - conf_output.decrypted_memo.from = from_key; - conf_output.decrypted_memo.amount = change; - conf_output.decrypted_memo.blinding_factor = change_blind_factor; - conf_output.decrypted_memo.commitment = change_out.commitment; - conf_output.decrypted_memo.check = from_secret._hash[0]; - conf_output.confirmation.one_time_key = one_time_key.get_public_key(); - conf_output.confirmation.to = from_key; - conf_output.confirmation.encrypted_memo = fc::aes_encrypt( from_secret, fc::raw::pack( conf_output.decrypted_memo ) ); - conf_output.auth = change_out.owner; - conf_output.confirmation_receipt = conf_output.confirmation; - - confirm.outputs.push_back( conf_output ); - } - blind_tr.outputs[0] = to_out; - - blind_confirmation::output conf_output; - conf_output.label = to_key_or_label; - conf_output.pub_key = to_key; - conf_output.decrypted_memo.from = from_key; - conf_output.decrypted_memo.amount = amount; - conf_output.decrypted_memo.blinding_factor = blind_factor; - conf_output.decrypted_memo.commitment = to_out.commitment; - conf_output.decrypted_memo.check = secret._hash[0]; - conf_output.confirmation.one_time_key = one_time_key.get_public_key(); - conf_output.confirmation.to = to_key; - conf_output.confirmation.encrypted_memo = fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) ); - conf_output.auth = to_out.owner; - conf_output.confirmation_receipt = conf_output.confirmation; - - confirm.outputs.push_back( conf_output ); - - /** commitments must be in sorted order */ - std::sort( blind_tr.outputs.begin(), blind_tr.outputs.end(), - [&]( const blind_output& a, const blind_output& b ){ return a.commitment < b.commitment; } ); - std::sort( blind_tr.inputs.begin(), blind_tr.inputs.end(), - [&]( const blind_input& a, const blind_input& b ){ return a.commitment < b.commitment; } ); - - confirm.trx.operations.emplace_back( std::move(blind_tr) ); - ilog( "validate before" ); - confirm.trx.validate(); - confirm.trx = sign_transaction(confirm.trx, broadcast); - - if( broadcast ) - { - for( const auto& out : confirm.outputs ) - { - try { receive_blind_transfer( out.confirmation_receipt, from_key_or_label, "" ); } catch ( ... ){} - } - } - - return confirm; -} FC_CAPTURE_AND_RETHROW( (from_key_or_label)(to_key_or_label)(amount_in)(symbol)(broadcast)(confirm) ) } - - - -/** - * Transfers a public balance from @from to one or more blinded balances using a - * stealth transfer. - */ -blind_confirmation wallet_api::transfer_to_blind( string from_account_id_or_name, - string asset_symbol, - /** map from key or label to amount */ - vector> to_amounts, - bool broadcast ) -{ try { - FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); - idump((to_amounts)); - - blind_confirmation confirm; - account_object from_account = my->get_account(from_account_id_or_name); - - fc::optional asset_obj = get_asset(asset_symbol); - FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_symbol)); - - transfer_to_blind_operation bop; - bop.from = from_account.id; - - vector blinding_factors; - - asset total_amount = asset_obj->amount(0); - - for( auto item : to_amounts ) - { - auto one_time_key = fc::ecc::private_key::generate(); - auto to_key = get_public_key( item.first ); - auto secret = one_time_key.get_shared_secret( to_key ); - auto child = fc::sha256::hash( secret ); - auto nonce = fc::sha256::hash( one_time_key.get_secret() ); - auto blind_factor = fc::sha256::hash( child ); - - blinding_factors.push_back( blind_factor ); - - auto amount = asset_obj->amount_from_string(item.second); - total_amount += amount; - - - fc::ecc::public_key to_pub_key = to_key; - blind_output out; - out.owner = authority( 1, public_key_type( to_pub_key.child( child ) ), 1 ); - out.commitment = fc::ecc::blind( blind_factor, amount.amount.value ); - if( to_amounts.size() > 1 ) - out.range_proof = fc::ecc::range_proof_sign( 0, out.commitment, blind_factor, nonce, 0, 0, amount.amount.value ); - - - blind_confirmation::output conf_output; - conf_output.label = item.first; - conf_output.pub_key = to_key; - conf_output.decrypted_memo.amount = amount; - conf_output.decrypted_memo.blinding_factor = blind_factor; - conf_output.decrypted_memo.commitment = out.commitment; - conf_output.decrypted_memo.check = secret._hash[0]; - conf_output.confirmation.one_time_key = one_time_key.get_public_key(); - conf_output.confirmation.to = to_key; - conf_output.confirmation.encrypted_memo = fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) ); - conf_output.confirmation_receipt = conf_output.confirmation; - - confirm.outputs.push_back( conf_output ); - - bop.outputs.push_back(out); - } - bop.amount = total_amount; - bop.blinding_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() ); - - /** commitments must be in sorted order */ - std::sort( bop.outputs.begin(), bop.outputs.end(), - [&]( const blind_output& a, const blind_output& b ){ return a.commitment < b.commitment; } ); - - confirm.trx.operations.push_back( bop ); - my->set_operation_fees( confirm.trx, my->_remote_db->get_global_properties().parameters.current_fees); - confirm.trx.validate(); - confirm.trx = sign_transaction(confirm.trx, broadcast); - - if( broadcast ) - { - for( const auto& out : confirm.outputs ) - { - try { receive_blind_transfer( out.confirmation_receipt, "@"+from_account.name, "from @"+from_account.name ); } catch ( ... ){} - } - } - - return confirm; -} FC_CAPTURE_AND_RETHROW( (from_account_id_or_name)(asset_symbol)(to_amounts) ) } - -blind_receipt wallet_api::receive_blind_transfer( string confirmation_receipt, string opt_from, string opt_memo ) -{ - FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); - stealth_confirmation conf(confirmation_receipt); - FC_ASSERT( conf.to ); - - blind_receipt result; - result.conf = conf; - - auto to_priv_key_itr = my->_keys.find( *conf.to ); - FC_ASSERT( to_priv_key_itr != my->_keys.end(), "No private key for receiver", ("conf",conf) ); - - - auto to_priv_key = wif_to_key( to_priv_key_itr->second ); - FC_ASSERT( to_priv_key ); - - auto secret = to_priv_key->get_shared_secret( conf.one_time_key ); - auto child = fc::sha256::hash( secret ); - - auto child_priv_key = to_priv_key->child( child ); - //auto blind_factor = fc::sha256::hash( child ); - - auto plain_memo = fc::aes_decrypt( secret, conf.encrypted_memo ); - auto memo = fc::raw::unpack( plain_memo ); - - result.to_key = *conf.to; - result.to_label = get_key_label( result.to_key ); - if( memo.from ) - { - result.from_key = *memo.from; - result.from_label = get_key_label( result.from_key ); - if( result.from_label == string() ) - { - result.from_label = opt_from; - set_key_label( result.from_key, result.from_label ); - } - } - else - { - result.from_label = opt_from; - } - result.amount = memo.amount; - result.memo = opt_memo; - - // confirm the amount matches the commitment (verify the blinding factor) - auto commtiment_test = fc::ecc::blind( memo.blinding_factor, memo.amount.amount.value ); - FC_ASSERT( fc::ecc::verify_sum( {commtiment_test}, {memo.commitment}, 0 ) ); - - blind_balance bal; - bal.amount = memo.amount; - bal.to = *conf.to; - if( memo.from ) bal.from = *memo.from; - bal.one_time_key = conf.one_time_key; - bal.blinding_factor = memo.blinding_factor; - bal.commitment = memo.commitment; - bal.used = false; - - auto child_pubkey = child_priv_key.get_public_key(); - auto owner = authority(1, public_key_type(child_pubkey), 1); - result.control_authority = owner; - result.data = memo; - - auto child_key_itr = owner.key_auths.find( child_pubkey ); - if( child_key_itr != owner.key_auths.end() ) - my->_keys[child_key_itr->first] = key_to_wif( child_priv_key ); - - // my->_wallet.blinded_balances[memo.amount.asset_id][bal.to].push_back( bal ); - - result.date = fc::time_point::now(); - my->_wallet.blind_receipts.insert( result ); - my->_keys[child_pubkey] = key_to_wif( child_priv_key ); - - save_wallet_file(); - - return result; -} - -vector wallet_api::blind_history( string key_or_account ) -{ - vector result; - auto pub_key = get_public_key( key_or_account ); - - if( pub_key == public_key_type() ) - return vector(); - - for( auto& r : my->_wallet.blind_receipts ) - { - if( r.from_key == pub_key || r.to_key == pub_key ) - result.push_back( r ); - } - std::sort( result.begin(), result.end(), [&]( const blind_receipt& a, const blind_receipt& b ){ return a.date > b.date; } ); - return result; -} /////////////// // peerplays // diff --git a/tests/peerplays_sidechain/bitcoin_sign_tests.cpp b/tests/peerplays_sidechain/bitcoin_sign_tests.cpp index 82a121c9..c2b5908a 100644 --- a/tests/peerplays_sidechain/bitcoin_sign_tests.cpp +++ b/tests/peerplays_sidechain/bitcoin_sign_tests.cpp @@ -13,8 +13,8 @@ using namespace fc::ecc; BOOST_AUTO_TEST_SUITE(bitcoin_sign_tests) -const secp256k1_context_t *btc_context() { - static secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); +const secp256k1_context *btc_context() { + static secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); return ctx; } diff --git a/tests/tests/confidential_tests.cpp b/tests/tests/confidential_tests.cpp deleted file mode 100644 index 792a300e..00000000 --- a/tests/tests/confidential_tests.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2015 Cryptonomex, Inc., and contributors. - * - * The MIT License - * - * 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. - */ - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include "../common/database_fixture.hpp" - -using namespace graphene::chain; - -BOOST_FIXTURE_TEST_SUITE( confidential_tests, database_fixture ) -BOOST_AUTO_TEST_CASE( confidential_test ) -{ try { - ACTORS( (dan)(nathan) ) - const asset_object& core = asset_id_type()(db); - - transfer(account_id_type()(db), dan, core.amount(1000000)); - - transfer_to_blind_operation to_blind; - to_blind.amount = core.amount(1000); - to_blind.from = dan.id; - - auto owner1_key = fc::ecc::private_key::generate(); - auto owner1_pub = owner1_key.get_public_key(); - auto owner2_key = fc::ecc::private_key::generate(); - auto owner2_pub = owner2_key.get_public_key(); - - blind_output out1, out2; - out1.owner = authority( 1, public_key_type(owner1_pub), 1 ); - out2.owner = authority( 1, public_key_type(owner2_pub), 1 ); - - - auto InB1 = fc::sha256::hash("InB1"); - auto InB2 = fc::sha256::hash("InB2"); - auto nonce1 = fc::sha256::hash("nonce"); - auto nonce2 = fc::sha256::hash("nonce2"); - - out1.commitment = fc::ecc::blind(InB1,250); - out1.range_proof = fc::ecc::range_proof_sign( 0, out1.commitment, InB1, nonce1, 0, 0, 250 ); - - out2.commitment = fc::ecc::blind(InB2,750); - out2.range_proof = fc::ecc::range_proof_sign( 0, out2.commitment, InB1, nonce2, 0, 0, 750 ); - - to_blind.blinding_factor = fc::ecc::blind_sum( {InB1,InB2}, 2 ); - to_blind.outputs = {out2,out1}; - - trx.operations = {to_blind}; - sign( trx, dan_private_key ); - db.push_transaction(trx); - trx.clear_signatures(); - - BOOST_TEST_MESSAGE( "Transfering from blind to blind with change address" ); - auto Out3B = fc::sha256::hash("Out3B"); - auto Out4B = fc::ecc::blind_sum( {InB2,Out3B}, 1 ); // add InB2 - Out3b - blind_output out3, out4; - out3.commitment = fc::ecc::blind(Out3B,300); - out3.range_proof = fc::ecc::range_proof_sign( 0, out3.commitment, InB1, nonce1, 0, 0, 300 ); - out4.commitment = fc::ecc::blind(Out4B,750-300-10); - out4.range_proof = fc::ecc::range_proof_sign( 0, out3.commitment, InB1, nonce1, 0, 0, 750-300-10 ); - - - blind_transfer_operation blind_tr; - blind_tr.fee = core.amount(10); - blind_tr.inputs.push_back( {out2.commitment, out2.owner} ); - blind_tr.outputs = {out3,out4}; - blind_tr.validate(); - trx.operations = {blind_tr}; - sign( trx, owner2_key ); - db.push_transaction(trx); - - BOOST_TEST_MESSAGE( "Attempting to double spend the same commitments" ); - blind_tr.fee = core.amount(11); - - Out4B = fc::ecc::blind_sum( {InB2,Out3B}, 1 ); // add InB2 - Out3b - out4.commitment = fc::ecc::blind(Out4B,750-300-11); - auto out4_amount = 750-300-10; - out4.range_proof = fc::ecc::range_proof_sign( 0, out3.commitment, InB1, nonce1, 0, 0, 750-300-11 ); - blind_tr.outputs = {out4,out3}; - trx.operations = {blind_tr}; - BOOST_REQUIRE_THROW( db.push_transaction(trx, ~0), graphene::chain::blind_transfer_unknown_commitment ); - - - BOOST_TEST_MESSAGE( "Transfering from blind to nathan public" ); - out4.commitment = fc::ecc::blind(Out4B,750-300-10); - - transfer_from_blind_operation from_blind; - from_blind.fee = core.amount(10); - from_blind.to = nathan.id; - from_blind.amount = core.amount( out4_amount - 10 ); - from_blind.blinding_factor = Out4B; - from_blind.inputs.push_back( {out4.commitment, out4.owner} ); - trx.operations = {from_blind}; - trx.clear_signatures(); - db.push_transaction(trx); - - BOOST_REQUIRE_EQUAL( get_balance( nathan, core ), 750-300-10-10 ); - -} FC_LOG_AND_RETHROW() } - - - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/tests/fee_tests.cpp b/tests/tests/fee_tests.cpp index 86dd3d7f..5faf4038 100644 --- a/tests/tests/fee_tests.cpp +++ b/tests/tests/fee_tests.cpp @@ -741,212 +741,6 @@ BOOST_AUTO_TEST_CASE( account_create_fee_scaling ) // FC_LOG_AND_RETHROW() // } -BOOST_AUTO_TEST_CASE( stealth_fba_test ) -{ - try - { - ACTORS( (alice)(bob)(chloe)(dan)(izzy)(philbin)(tom) ); - upgrade_to_lifetime_member(philbin_id); - - generate_blocks( HARDFORK_538_TIME ); - generate_blocks( HARDFORK_555_TIME ); - generate_blocks( HARDFORK_563_TIME ); - generate_blocks( HARDFORK_572_TIME ); - generate_blocks( HARDFORK_599_TIME ); - - // Philbin (registrar who registers Rex) - - // Izzy (initial issuer of stealth asset, will later transfer to Tom) - // Alice, Bob, Chloe, Dan (ABCD) - // Rex (recycler -- buyback account for stealth asset) - // Tom (owner of stealth asset who will be set as top_n authority) - - // Izzy creates STEALTH - asset_id_type stealth_id = create_user_issued_asset( "STEALTH", izzy_id(db), - disable_confidential | transfer_restricted | override_authority | white_list | charge_market_fee ).id; - - /* - // this is disabled because it doesn't work, our modify() is probably being overwritten by undo - - // - // Init blockchain with stealth ID's - // On a real chain, this would be done with #define GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET - // causing the designated_asset fields of these objects to be set at genesis, but for - // this test we modify the db directly. - // - auto set_fba_asset = [&]( uint64_t fba_acc_id, asset_id_type asset_id ) - { - db.modify( fba_accumulator_id_type(fba_acc_id)(db), [&]( fba_accumulator_object& fba ) - { - fba.designated_asset = asset_id; - } ); - }; - - set_fba_asset( fba_accumulator_id_transfer_to_blind , stealth_id ); - set_fba_asset( fba_accumulator_id_blind_transfer , stealth_id ); - set_fba_asset( fba_accumulator_id_transfer_from_blind, stealth_id ); - */ - - // Izzy kills some permission bits (this somehow happened to the real STEALTH in production) - { - asset_update_operation update_op; - update_op.issuer = izzy_id; - update_op.asset_to_update = stealth_id; - asset_options new_options; - new_options = stealth_id(db).options; - new_options.issuer_permissions = charge_market_fee; - new_options.flags = disable_confidential | transfer_restricted | override_authority | white_list | charge_market_fee; - // after fixing #579 you should be able to delete the following line - new_options.core_exchange_rate = price( asset( 1, stealth_id ), asset( 1, asset_id_type() ) ); - update_op.new_options = new_options; - signed_transaction tx; - tx.operations.push_back( update_op ); - set_expiration( db, tx ); - sign( tx, izzy_private_key ); - PUSH_TX( db, tx ); - } - - // Izzy transfers issuer duty to Tom - { - asset_update_operation update_op; - update_op.issuer = izzy_id; - update_op.asset_to_update = stealth_id; - update_op.new_issuer = tom_id; - // new_options should be optional, but isn't...the following line should be unnecessary #580 - update_op.new_options = stealth_id(db).options; - signed_transaction tx; - tx.operations.push_back( update_op ); - set_expiration( db, tx ); - sign( tx, izzy_private_key ); - PUSH_TX( db, tx ); - } - - // Tom re-enables the permission bits to clear the flags, then clears them again - // Allowed by #572 when current_supply == 0 - { - asset_update_operation update_op; - update_op.issuer = tom_id; - update_op.asset_to_update = stealth_id; - asset_options new_options; - new_options = stealth_id(db).options; - new_options.issuer_permissions = new_options.flags | charge_market_fee; - update_op.new_options = new_options; - signed_transaction tx; - // enable perms is one op - tx.operations.push_back( update_op ); - - new_options.issuer_permissions = charge_market_fee; - new_options.flags = charge_market_fee; - update_op.new_options = new_options; - // reset wrongly set flags and reset permissions can be done in a single op - tx.operations.push_back( update_op ); - - set_expiration( db, tx ); - sign( tx, tom_private_key ); - PUSH_TX( db, tx ); - } - - // Philbin registers Rex who will be the asset's buyback, including sig from the new issuer (Tom) - account_id_type rex_id; - { - buyback_account_options bbo; - bbo.asset_to_buy = stealth_id; - bbo.asset_to_buy_issuer = tom_id; - bbo.markets.emplace( asset_id_type() ); - account_create_operation create_op = make_account( "rex" ); - create_op.registrar = philbin_id; - create_op.extensions.value.buyback_options = bbo; - create_op.owner = authority::null_authority(); - create_op.active = authority::null_authority(); - - signed_transaction tx; - tx.operations.push_back( create_op ); - set_expiration( db, tx ); - sign( tx, philbin_private_key ); - sign( tx, tom_private_key ); - - processed_transaction ptx = PUSH_TX( db, tx ); - rex_id = ptx.operation_results.back().get< object_id_type >(); - } - - // Tom issues some asset to Alice and Bob - set_expiration( db, trx ); // #11 - issue_uia( alice_id, asset( 1000, stealth_id ) ); - issue_uia( bob_id, asset( 1000, stealth_id ) ); - - // Tom sets his authority to the top_n of the asset - { - top_holders_special_authority top2; - top2.num_top_holders = 2; - top2.asset = stealth_id; - - account_update_operation op; - op.account = tom_id; - op.extensions.value.active_special_authority = top2; - op.extensions.value.owner_special_authority = top2; - - signed_transaction tx; - tx.operations.push_back( op ); - - set_expiration( db, tx ); - sign( tx, tom_private_key ); - - PUSH_TX( db, tx ); - } - - // Wait until the next maintenance interval for top_n to take effect - generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); - - // Do a blind op to add some fees to the pool. - fund( chloe_id(db), asset( 100000, asset_id_type() ) ); - - auto create_transfer_to_blind = [&]( account_id_type account, asset amount, const std::string& key ) -> transfer_to_blind_operation - { - fc::ecc::private_key blind_key = fc::ecc::private_key::regenerate( fc::sha256::hash( key+"-privkey" ) ); - public_key_type blind_pub = blind_key.get_public_key(); - - fc::sha256 secret = fc::sha256::hash( key+"-secret" ); - fc::sha256 nonce = fc::sha256::hash( key+"-nonce" ); - - transfer_to_blind_operation op; - blind_output blind_out; - blind_out.owner = authority( 1, blind_pub, 1 ); - blind_out.commitment = fc::ecc::blind( secret, amount.amount.value ); - blind_out.range_proof = fc::ecc::range_proof_sign( 0, blind_out.commitment, secret, nonce, 0, 0, amount.amount.value ); - - op.amount = amount; - op.from = account; - op.blinding_factor = fc::ecc::blind_sum( {secret}, 1 ); - op.outputs = {blind_out}; - - return op; - }; - - { - transfer_to_blind_operation op = create_transfer_to_blind( chloe_id, asset( 5000, asset_id_type() ), "chloe-key" ); - op.fee = asset( 1000, asset_id_type() ); - - signed_transaction tx; - tx.operations.push_back( op ); - set_expiration( db, tx ); - sign( tx, chloe_private_key ); - - PUSH_TX( db, tx ); - } - - // wait until next maint interval - generate_blocks(db.get_dynamic_global_properties().next_maintenance_time); - - idump( ( get_operation_history( chloe_id ) ) ); - idump( ( get_operation_history( rex_id ) ) ); - idump( ( get_operation_history( tom_id ) ) ); - } - catch( const fc::exception& e ) - { - elog( "caught exception ${e}", ("e", e.to_detail_string()) ); - throw; - } -} // added test from bitshares for issues: // https://github.com/bitshares/bitshares-core/issues/429 // https://github.com/bitshares/bitshares-core/issues/433