text: /*
   * 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.
   */
  #pragma once
  #include <graphene/chain/protocol/base.hpp>
  #include <graphene/chain/protocol/memo.hpp>
  
  #include <uvm/uvm_lib.h>
  
  namespace graphene { namespace chain {
  
     /**
      * @ingroup operations
      *
      * @brief Transfers an amount of one asset from one account to another
      *
      *  Fees are paid by the "from" account
      *
      *  @pre amount.amount > 0
      *  @pre fee.amount >= 0
      *  @pre from != to
      *  @post from account's balance will be reduced by fee and amount
      *  @post to account's balance will be increased by amount
      *  @return n/a
      */
     struct transfer_operation : public base_operation
     {
        struct fee_parameters_type {
           uint64_t fee       = 0.001 * GRAPHENE_HBCHAIN_PRECISION;
           uint32_t price_per_kbyte = 10 * GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos.
        };
  
        asset            fee;
  	  optional<guarantee_object_id_type> guarantee_id;
        /// Account to transfer asset from
        account_id_type  from;
        /// Account to transfer asset to
        account_id_type  to;
  	  ///addr to transfer asset from
  	  address from_addr;
  	  /// addr to transfer asset to
  	  address to_addr;
  
        /// The amount of asset to transfer from @ref from to @ref to
        asset            amount;
  
        /// User provided data encrypted to the memo key of the "to" account
        optional<memo_data> memo;
        extensions_type   extensions;
  
        address fee_payer()const { return from_addr; }
        void            validate()const;
        share_type      calculate_fee(const fee_parameters_type& k)const;
  	  void get_required_authorities(vector<authority>& a)const
  	  {
  		  a.push_back(authority(1, from_addr, 1));
  	  }
  	  optional<guarantee_object_id_type> get_guarantee_id()const { return guarantee_id; }
     };
  
     /**
      *  @class override_transfer_operation
      *  @brief Allows the issuer of an asset to transfer an asset from any account to any account if they have override_authority
      *  @ingroup operations
      *
      *  @pre amount.asset_id->issuer == issuer
      *  @pre issuer != from  because this is pointless, use a normal transfer operation
      */
     struct override_transfer_operation : public base_operation
     {
        struct fee_parameters_type {
           uint64_t fee       = 0.001 * GRAPHENE_HBCHAIN_PRECISION;
           uint32_t price_per_kbyte = 10; /// only required for large memos.
        };
  
        asset           fee;
        account_id_type issuer;
        /// Account to transfer asset from
        account_id_type from;
        /// Account to transfer asset to
        account_id_type to;
        /// The amount of asset to transfer from @ref from to @ref to
        asset amount;
  
        /// User provided data encrypted to the memo key of the "to" account
        optional<memo_data> memo;
        extensions_type   extensions;
  
        account_id_type fee_payer()const { return issuer; }
        void            validate()const;
        share_type      calculate_fee(const fee_parameters_type& k)const;
     };
  
     struct asset_transfer_from_cold_to_hot_operation :public base_operation
     {
  	   struct fee_parameters_type {
  		   uint64_t fee = 0.001 * GRAPHENE_HBCHAIN_PRECISION;
  	   };
  	   asset fee;
  	   address addr;
  	   string chain_type;
  	   fc::variant_object trx;
  	   address fee_payer()const { return addr; }
  	   void            validate()const;
  	   share_type      calculate_fee(const fee_parameters_type& k)const;
  	   void get_required_authorities(vector<authority>& a)const
  	   {
  		   a.push_back(authority(1, addr, 1));
  	   }
  
     };
  
     struct sign_multisig_asset_operation :public base_operation
     {
  	   struct fee_parameters_type {
  		   uint64_t fee = 0.001 * GRAPHENE_HBCHAIN_PRECISION;
  	   };
  	   asset fee;
  	   address addr;
  	   multisig_asset_transfer_id_type multisig_trx_id;
  	   string signature;
  	   address fee_payer()const { return addr; }
  	   void            validate()const;
  	   share_type      calculate_fee(const fee_parameters_type& k)const;
  	   void get_required_authorities(vector<authority>& a)const
  	   {
  		   a.push_back(authority(1, addr, 1));
  	   }
     };
  }} // graphene::chain
  
  FC_REFLECT(graphene::chain::transfer_operation::fee_parameters_type, (fee)(price_per_kbyte))
  FC_REFLECT(graphene::chain::override_transfer_operation::fee_parameters_type, (fee)(price_per_kbyte))
  
  FC_REFLECT(graphene::chain::override_transfer_operation, (fee)(issuer)(from)(to)(amount)(memo)(extensions))
  FC_REFLECT(graphene::chain::transfer_operation, (fee)(guarantee_id)(from)(to)(from_addr)(to_addr)(amount)(memo)(extensions))
  
  FC_REFLECT(graphene::chain::asset_transfer_from_cold_to_hot_operation::fee_parameters_type, (fee))
  FC_REFLECT(graphene::chain::asset_transfer_from_cold_to_hot_operation, (fee)(addr)(chain_type)(trx))
  
  FC_REFLECT(graphene::chain::sign_multisig_asset_operation::fee_parameters_type, (fee))
  FC_REFLECT(graphene::chain::sign_multisig_asset_operation, (fee)(addr)(multisig_trx_id)(signature))
  
  