diff --git a/src/common/crypto_serialization.h b/src/common/crypto_serialization.h index dd988a68..9ac2ac90 100644 --- a/src/common/crypto_serialization.h +++ b/src/common/crypto_serialization.h @@ -21,6 +21,7 @@ #include "crypto/clsag.h" #include "crypto/zarcanum.h" #include "crypto/one_out_of_many_proofs.h" +#include "crypto/eth_signature.h" #include "boost_serialization_maps.h" #include "serialization/keyvalue_enable_POD_serialize_as_string.h" // @@ -230,6 +231,8 @@ BLOB_SERIALIZER(crypto::key_image); BLOB_SERIALIZER(crypto::signature); BLOB_SERIALIZER(crypto::scalar_t); BLOB_SERIALIZER(crypto::point_t); +BLOB_SERIALIZER(crypto::eth_public_key); +BLOB_SERIALIZER(crypto::eth_signature); VARIANT_TAG(debug_archive, crypto::hash, "hash"); VARIANT_TAG(debug_archive, crypto::public_key, "public_key"); @@ -245,6 +248,8 @@ VARIANT_TAG(debug_archive, crypto::signature, "signature"); KV_ENABLE_POD_SERIALIZATION_AS_HEX(crypto::scalar_t); KV_ENABLE_POD_SERIALIZATION_AS_HEX(crypto::hash); +KV_ENABLE_POD_SERIALIZATION_AS_HEX(crypto::eth_public_key); +KV_ENABLE_POD_SERIALIZATION_AS_HEX(crypto::eth_signature); // // Boost serialization @@ -296,5 +301,15 @@ namespace boost { a & reinterpret_cast(x); } + template + inline void serialize(Archive &a, crypto::eth_public_key &x, const boost::serialization::version_type ver) + { + a & reinterpret_cast(x); + } + template + inline void serialize(Archive &a, crypto::eth_signature &x, const boost::serialization::version_type ver) + { + a & reinterpret_cast(x); + } } // namespace serialization } // namespace boost diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 419cdd1c..44d80862 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -4105,14 +4105,24 @@ bool blockchain_storage::pop_asset_info(const crypto::public_key& asset_id) //------------------------------------------------------------------ bool validate_ado_ownership(asset_op_verification_context& avc) { + bool r = false; + CHECK_AND_ASSERT_MES(avc.asset_op_history->size() != 0, false, "asset with id " << avc.asset_id << " has empty history record"); + const asset_descriptor_operation& last_ado = avc.asset_op_history->back(); + + if (last_ado.descriptor.owner_eth_pub_key.has_value()) + { + asset_operation_ownership_proof_eth aoop_eth{}; + r = get_type_in_variant_container(avc.tx.proofs, aoop_eth); + CHECK_AND_ASSERT_MES(r, false, "Ownership validation failed - missing signature (asset_operation_ownership_proof)"); + return crypto::verify_eth_signature(avc.tx_id, last_ado.descriptor.owner_eth_pub_key.value(), aoop_eth.eth_sig); + } + + // owner_eth_pub_key has no value -- falback to default asset_operation_ownership_proof aoop = AUTO_VAL_INIT(aoop); - bool r = get_type_in_variant_container(avc.tx.proofs, aoop); + r = get_type_in_variant_container(avc.tx.proofs, aoop); CHECK_AND_ASSERT_MES(r, false, "Ownership validation failed - missing signature (asset_operation_ownership_proof)"); - CHECK_AND_ASSERT_MES(avc.asset_op_history->size() != 0, false, "asset with id " << avc.asset_id << " has invalid history size() == 0"); - - crypto::public_key owner_key = avc.asset_op_history->back().descriptor.owner; - return crypto::verify_schnorr_sig(avc.tx_id, owner_key, aoop.gss); + return crypto::verify_schnorr_sig(avc.tx_id, last_ado.descriptor.owner, aoop.gss); } //------------------------------------------------------------------ bool blockchain_storage::validate_asset_operation_against_current_blochain_state(asset_op_verification_context& avc) const diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index 0d3e5891..e7052146 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -40,6 +40,7 @@ #include "crypto/hash.h" #include "crypto/range_proofs.h" #include "crypto/zarcanum.h" +#include "crypto/eth_signature.h" #include "misc_language.h" #include "block_flags.h" #include "etc_custom_serialization.h" @@ -695,6 +696,7 @@ namespace currency } }; +#define ASSET_DESCRIPTOR_BASE_STRUCTURE_VER 1 struct asset_descriptor_base { @@ -706,9 +708,11 @@ namespace currency std::string meta_info; crypto::public_key owner = currency::null_pkey; // consider premultipling by 1/8 bool hidden_supply = false; - uint8_t version = 0; + std::optional owner_eth_pub_key; - BEGIN_VERSIONED_SERIALIZE(0, version) + uint8_t version = ASSET_DESCRIPTOR_BASE_STRUCTURE_VER; + + BEGIN_VERSIONED_SERIALIZE(ASSET_DESCRIPTOR_BASE_STRUCTURE_VER, version) FIELD(total_max_supply) FIELD(current_supply) FIELD(decimal_point) @@ -717,9 +721,10 @@ namespace currency FIELD(meta_info) FIELD(owner) FIELD(hidden_supply) + END_VERSION_UNDER(1) + FIELD(owner_eth_pub_key) END_SERIALIZE() - BEGIN_BOOST_SERIALIZATION() BOOST_SERIALIZE(total_max_supply) BOOST_SERIALIZE(current_supply) @@ -729,17 +734,20 @@ namespace currency BOOST_SERIALIZE(meta_info) BOOST_SERIALIZE(owner) BOOST_SERIALIZE(hidden_supply) + BOOST_END_VERSION_UNDER(1) + BOOST_SERIALIZE(owner_eth_pub_key) END_BOOST_SERIALIZATION() BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(total_max_supply) DOC_DSCR("Maximum possible supply for given asset, can't be changed after deployment") DOC_EXMP(1000000000000000000) DOC_END - KV_SERIALIZE(current_supply) DOC_DSCR("Currently emitted supply for given asset (ignored for REGISTER operation)") DOC_EXMP(500000000000000000) DOC_END - KV_SERIALIZE(decimal_point) DOC_DSCR("Decimal point") DOC_EXMP(12) DOC_END - KV_SERIALIZE(ticker) DOC_DSCR("Ticker associated with asset") DOC_EXMP("ZUSD") DOC_END - KV_SERIALIZE(full_name) DOC_DSCR("Full name of the asset") DOC_EXMP("Zano wrapped USD") DOC_END - KV_SERIALIZE(meta_info) DOC_DSCR("Any other information assetiaded with asset in a free form") DOC_EXMP("Stable and private") DOC_END - KV_SERIALIZE_POD_AS_HEX_STRING(owner) DOC_DSCR("Owner's key, used only for EMIT and UPDATE validation, could be changed by transferring asset ownership") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END - KV_SERIALIZE(hidden_supply) DOC_DSCR("This one reserved for future use, will be documented later") DOC_END + KV_SERIALIZE(total_max_supply) DOC_DSCR("Maximum possible supply for a given asset, cannot be changed after deployment.") DOC_EXMP(1000000000000000000) DOC_END + KV_SERIALIZE(current_supply) DOC_DSCR("Currently emitted supply for the given asset (ignored for REGISTER operation).") DOC_EXMP(500000000000000000) DOC_END + KV_SERIALIZE(decimal_point) DOC_DSCR("Decimal point.") DOC_EXMP(12) DOC_END + KV_SERIALIZE(ticker) DOC_DSCR("Ticker associated with the asset.") DOC_EXMP("ZABC") DOC_END + KV_SERIALIZE(full_name) DOC_DSCR("Full name of the asset.") DOC_EXMP("Zano wrapped ABC") DOC_END + KV_SERIALIZE(meta_info) DOC_DSCR("Any other information associated with the asset in free form.") DOC_EXMP("Stable and private") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(owner) DOC_DSCR("Owner's key, used only for EMIT and UPDATE validation, can be changed by transferring asset ownership.") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END + KV_SERIALIZE(hidden_supply) DOC_DSCR("This field is reserved for future use and will be documented later.") DOC_END + KV_SERIALIZE(owner_eth_pub_key) DOC_DSCR("[Optional] Owner's key in the case when ETH signature is used.") DOC_END END_KV_SERIALIZE_MAP() }; @@ -833,6 +841,21 @@ namespace currency }; + struct asset_operation_ownership_proof_eth + { + crypto::eth_signature eth_sig; + uint8_t version = 0; + + BEGIN_VERSIONED_SERIALIZE(0, version) + FIELD(eth_sig) + END_SERIALIZE() + + BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(eth_sig) + BOOST_SERIALIZE(version) + END_BOOST_SERIALIZATION() + }; + struct extra_padding { std::vector buff; //stub @@ -936,7 +959,7 @@ namespace currency typedef boost::variant signature_v; - typedef boost::variant proof_v; + typedef boost::variant proof_v; //include backward compatibility defintions @@ -1195,6 +1218,10 @@ SET_VARIANT_TAGS(currency::zc_balance_proof, 48, "zc_balance_proof"); SET_VARIANT_TAGS(currency::asset_descriptor_operation, 49, "asset_descriptor_base"); SET_VARIANT_TAGS(currency::asset_operation_proof, 50, "asset_operation_proof"); SET_VARIANT_TAGS(currency::asset_operation_ownership_proof, 51, "asset_operation_ownership_proof"); +SET_VARIANT_TAGS(currency::asset_operation_ownership_proof_eth, 52, "asset_operation_ownership_proof_eth"); + +SET_VARIANT_TAGS(crypto::eth_public_key, 60, "eth_public_key"); +//SET_VARIANT_TAGS(crypto::eth_signature, 61, "eth_signature");s