Remove confidential transfer operations
This commit is contained in:
parent
4490c3fa48
commit
1e2fafe9c3
3 changed files with 0 additions and 369 deletions
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Cryptonomex, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
|
||||
* the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted until September 8, 2015, provided that the following conditions are met:
|
||||
*
|
||||
* 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
/**
|
||||
* @class blinded_balance_object
|
||||
* @brief tracks a blinded balance commitment
|
||||
* @ingroup object
|
||||
* @ingroup protocol
|
||||
*/
|
||||
class blinded_balance_object : public graphene::db::abstract_object<blinded_balance_object>
|
||||
{
|
||||
public:
|
||||
static const uint8_t space_id = protocol_ids;
|
||||
static const uint8_t type_id = blinded_balance_object_type;
|
||||
|
||||
fc::ecc::commitment_type commitment;
|
||||
asset_id_type asset_id;
|
||||
static_variant<address,account_id_type> owner;
|
||||
};
|
||||
|
||||
struct by_asset;
|
||||
struct by_owner;
|
||||
struct by_commitment;
|
||||
|
||||
/**
|
||||
* @ingroup object_index
|
||||
*/
|
||||
typedef multi_index_container<
|
||||
blinded_balance_object,
|
||||
indexed_by<
|
||||
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
|
||||
hashed_unique< tag<by_commitment>, member<blinded_balance_object, commitment_type, &blinded_balance_object::commitment> >
|
||||
>
|
||||
> blinded_balance_object_multi_index_type;
|
||||
typedef generic_index<blinded_balance_object, blinded_balance_object_multi_index_type> balance_index;
|
||||
|
||||
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT( graphene::chain::blinded_balance_object, (commitment)(asset_id)(last_update_block_num)(owner) )
|
||||
|
|
@ -465,182 +465,6 @@ namespace graphene { namespace chain {
|
|||
acc.adjust( to, amount );
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @defgroup stealth Stealth Transfer
|
||||
* @brief Operations related to stealth transfer of value
|
||||
*
|
||||
* Stealth Transfers enable users to maintain their finanical privacy against even
|
||||
* though all transactions are public. Every account has three balances:
|
||||
*
|
||||
* 1. Public Balance - every can see the balance changes and the parties involved
|
||||
* 2. Blinded Balance - everyone can see who is transacting but not the amounts involved
|
||||
* 3. Stealth Balance - both the amounts and parties involved are obscured
|
||||
*
|
||||
* Account owners may set a flag that allows their account to receive(or not) transfers of these kinds
|
||||
* Asset issuers can enable or disable the use of each of these types of accounts.
|
||||
*
|
||||
* Using the "temp account" which has no permissions required, users can transfer a
|
||||
* stealth balance to the temp account and then use the temp account to register a new
|
||||
* account. In this way users can use stealth funds to create anonymous accounts with which
|
||||
* they can perform other actions that are not compatible with blinded balances (such as market orders)
|
||||
*
|
||||
* @section referral_program Referral Progam
|
||||
*
|
||||
* Stealth transfers that do not specify any account id cannot pay referral fees so 100% of the
|
||||
* transaction fee is paid to the network.
|
||||
*
|
||||
* @section transaction_fees Fees
|
||||
*
|
||||
* Stealth transfers can have an arbitrarylly large size and therefore the transaction fee for
|
||||
* stealth transfers is based purley on the data size of the transaction.
|
||||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @ingroup stealth
|
||||
* This data is encrypted and stored in the
|
||||
* encrypted memo portion of the blind output.
|
||||
*/
|
||||
struct blind_memo
|
||||
{
|
||||
account_id_type from;
|
||||
share_type amount;
|
||||
string message;
|
||||
/** set to the first 4 bytes of the shared secret
|
||||
* used to encrypt the memo. Used to verify that
|
||||
* decryption was successful.
|
||||
*/
|
||||
uint32_t check= 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup stealth
|
||||
*/
|
||||
struct blind_input
|
||||
{
|
||||
fc::ecc::commitment_type commitment;
|
||||
/** provided to maintain the invariant that all authority
|
||||
* required by an operation is explicit in the operation. Must
|
||||
* match blinded_balance_id->owner
|
||||
*/
|
||||
static_variant<address,account_id_type> owner;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class blind_output
|
||||
* @brief Defines data required to create a new blind commitment
|
||||
* @ingroup stealth
|
||||
*
|
||||
* The blinded output that must be proven to be greater than 0
|
||||
*/
|
||||
struct blind_output
|
||||
{
|
||||
fc::ecc::commitment_type commitment;
|
||||
/** only required if there is more than one blind output */
|
||||
range_proof_type range_proof;
|
||||
static_variant<address,account_id_type> owner;
|
||||
public_key_type one_time_key;
|
||||
/** encrypted via aes with shared secret derived from
|
||||
* one_time_key and (owner or owner.memo_key)
|
||||
*/
|
||||
vector<char> encrypted_memo;
|
||||
};
|
||||
|
||||
/**
|
||||
* @class transfer_to_blind_operation
|
||||
* @ingroup stealth
|
||||
* @brief Converts public account balance to a blinded or stealth balance
|
||||
*/
|
||||
struct transfer_to_blind_operation
|
||||
{
|
||||
asset fee;
|
||||
asset amount;
|
||||
account_id_type from;
|
||||
vector<blind_output> outputs;
|
||||
|
||||
account_id_type fee_payer()const;
|
||||
void get_required_auth( flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& )const;
|
||||
void validate()const;
|
||||
share_type calculate_fee( const fee_schedule_type& k )const;
|
||||
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup stealth
|
||||
* @brief Converts blinded/stealth balance to a public account balance
|
||||
*/
|
||||
struct transfer_from_blind_operation
|
||||
{
|
||||
asset fee;
|
||||
asset amount;
|
||||
account_id_type to;
|
||||
vector<blind_input> inputs;
|
||||
|
||||
account_id_type fee_payer()const;
|
||||
void get_required_auth( flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& )const;
|
||||
void validate()const;
|
||||
share_type calculate_fee( const fee_schedule_type& k )const;
|
||||
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup stealth
|
||||
* @brief Transfers from blind to blind
|
||||
*
|
||||
* There are two ways to transfer value while maintaining privacy:
|
||||
* 1. account to account with amount kept secret
|
||||
* 2. stealth transfers with amount sender/receiver kept secret
|
||||
*
|
||||
* When doing account to account transfers, everyone with access to the
|
||||
* memo key can see the amounts, but they will not have access to the funds.
|
||||
*
|
||||
* When using stealth transfers the same key is used for control and reading
|
||||
* the memo.
|
||||
*
|
||||
* This operation is more expensive than a normal transfer and has
|
||||
* a fee proportional to the size of the operation.
|
||||
*
|
||||
* All assets in a blind transfer must be of the same type: fee.asset_id
|
||||
* The fee_payer is the temp account and can be funded from the blinded values.
|
||||
*
|
||||
* Using this operation you can transfer from an account and/or blinded balances
|
||||
* to an account and/or blinded balances.
|
||||
*
|
||||
* Stealth Transfers:
|
||||
*
|
||||
* Assuming Receiver has key pair R,r and has shared public key R with Sender
|
||||
* Assuming Sender has key pair S,s
|
||||
* Generate one time key pair O,o as s.child(nonce) where nonce can be inferred from transaction
|
||||
* Calculate secret V = o*R
|
||||
* blinding_factor = sha256(V)
|
||||
* memo is encrypted via aes of V
|
||||
* owner = R.child(sha256(blinding_factor))
|
||||
*
|
||||
* Sender gives Receiver output ID to complete the payment.
|
||||
*
|
||||
* This process can also be used to send money to a cold wallet without having to
|
||||
* pre-register any accounts.
|
||||
*
|
||||
* Outputs are assigned the same IDs as the inputs until no more input IDs are available,
|
||||
* in which case a the return value will be the *first* ID allocated for an output. Additional
|
||||
* output IDs are allocated sequentially thereafter. If there are fewer outputs than inputs
|
||||
* then the input IDs are freed and never used again.
|
||||
*/
|
||||
struct blind_transfer_operation
|
||||
{
|
||||
|
||||
asset fee;
|
||||
account_id_type fee_payer_id;
|
||||
vector<blind_input> inputs;
|
||||
vector<blind_output> outputs;
|
||||
|
||||
account_id_type fee_payer()const;
|
||||
void get_required_auth( flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& )const;
|
||||
void validate()const;
|
||||
share_type calculate_fee( const fee_schedule_type& k )const;
|
||||
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const;
|
||||
};
|
||||
///@} endgroup stealth
|
||||
|
||||
/**
|
||||
* @ingroup operations
|
||||
|
|
@ -2044,18 +1868,5 @@ FC_REFLECT( graphene::chain::worker_create_operation,
|
|||
FC_REFLECT( graphene::chain::custom_operation, (fee)(payer)(required_auths)(id)(data) )
|
||||
FC_REFLECT( graphene::chain::void_result, )
|
||||
|
||||
FC_REFLECT( graphene::chain::blind_memo,
|
||||
(from)(amount)(message)(check) )
|
||||
FC_REFLECT( graphene::chain::blind_input,
|
||||
(commitment)(owner) )
|
||||
FC_REFLECT( graphene::chain::blind_output,
|
||||
(commitment)(range_proof)(owner)(one_time_key)(encrypted_memo) )
|
||||
FC_REFLECT( graphene::chain::transfer_to_blind_operation,
|
||||
(fee)(amount)(from)(outputs) )
|
||||
FC_REFLECT( graphene::chain::transfer_from_blind_operation,
|
||||
(fee)(amount)(to)(inputs) )
|
||||
FC_REFLECT( graphene::chain::blind_transfer_operation,
|
||||
(fee)(fee_payer_id)(inputs)(outputs) )
|
||||
|
||||
FC_REFLECT_TYPENAME( graphene::chain::operation )
|
||||
FC_REFLECT_TYPENAME( fc::flat_set<graphene::chain::vote_id_type> )
|
||||
|
|
|
|||
|
|
@ -935,126 +935,4 @@ share_type account_upgrade_operation::calculate_fee(const fee_schedule_type& k)
|
|||
return k.membership_annual_fee;
|
||||
}
|
||||
|
||||
account_id_type transfer_to_blind_operation::fee_payer()const
|
||||
{
|
||||
// TODO
|
||||
return from;
|
||||
}
|
||||
|
||||
void transfer_to_blind_operation::get_required_auth( flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& )const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void transfer_to_blind_operation::validate()const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
share_type transfer_to_blind_operation::calculate_fee( const fee_schedule_type& k )const
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void transfer_to_blind_operation::get_balance_delta( balance_accumulator& acc, const operation_result& result )const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
account_id_type transfer_from_blind_operation::fee_payer()const
|
||||
{
|
||||
// TODO
|
||||
return to;
|
||||
}
|
||||
|
||||
void transfer_from_blind_operation::get_required_auth( flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& )const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void transfer_from_blind_operation::validate()const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
share_type transfer_from_blind_operation::calculate_fee( const fee_schedule_type& k )const
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void transfer_from_blind_operation::get_balance_delta( balance_accumulator& acc, const operation_result& result )const
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
// TODO
|
||||
return fee_payer_id;
|
||||
}
|
||||
|
||||
void blind_transfer_operation::get_required_auth( flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& )const
|
||||
{
|
||||
// TODO
|
||||
/*
|
||||
active_auth_set.insert( fee_payer_id );
|
||||
active_auth_set.insert( from_account );
|
||||
for( auto input : inputs )
|
||||
{
|
||||
if( input.owner.which() == static_variant<address,account_id_type>::tag<account_id_type>::value )
|
||||
active_auth_set.insert( input.owner.get<account_id_type>() );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* This method can be computationally intensive because it verifies that input commitments - output commitments add up to 0
|
||||
*/
|
||||
void blind_transfer_operation::validate()const
|
||||
{
|
||||
// TODO
|
||||
/*
|
||||
vector<commitment_type> in(inputs.size());
|
||||
vector<commitment_type> out(outputs.size());
|
||||
int64_t net_public = from_amount.value - to_amount.value;
|
||||
for( uint32_t i = 0; i < in.size(); ++i ) in[i] = inputs[i].commitment;
|
||||
for( uint32_t i = 0; i < out.size(); ++i ) out[i] = outputs[i].commitment;
|
||||
FC_ASSERT( in.size() + out.size() || net_public == 0 );
|
||||
if( fee_payer_id == GRAPHENE_TEMP_ACCOUNT ) net_public -= fee.amount.value;
|
||||
FC_ASSERT( fc::ecc::verify_sum( in, out, net_public ) );
|
||||
|
||||
if( outputs.size() > 1 )
|
||||
{
|
||||
for( auto out : outputs )
|
||||
{
|
||||
auto info = fc::ecc::range_get_info( out.range_proof );
|
||||
FC_ASSERT( info.min_value >= 0 );
|
||||
FC_ASSERT( info.max_value <= GRAPHENE_MAX_SHARE_SUPPLY );
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
share_type blind_transfer_operation::calculate_fee( const fee_schedule_type& k )const
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void blind_transfer_operation::get_balance_delta( balance_accumulator& acc, const operation_result& result)const
|
||||
{
|
||||
// TODO
|
||||
/*
|
||||
acc.adjust( fee_payer(), -fee );
|
||||
acc.adjust( from_account, asset(-from_amount,fee.asset_id) );
|
||||
acc.adjust( to_account, asset(to_amount,fee.asset_id) );
|
||||
*/
|
||||
}
|
||||
|
||||
} } // namespace graphene::chain
|
||||
|
|
|
|||
Loading…
Reference in a new issue