mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Change Proprietary types to use the method specified in BIP 174
This commit is contained in:
parent
ed03bfc899
commit
3fa355c767
1 changed files with 178 additions and 136 deletions
314
src/psbt.h
314
src/psbt.h
|
|
@ -13,9 +13,11 @@
|
|||
|
||||
// Magic bytes
|
||||
static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff};
|
||||
static constexpr uint8_t PSBT_ELEMENTS_MAGIC_BYTES[5] = {'p', 's', 'e', 't', 0xff};
|
||||
|
||||
// Global types
|
||||
static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00;
|
||||
static constexpr uint8_t PSBT_GLOBAL_PROPRIETARY = 0xFC;
|
||||
|
||||
// Input types
|
||||
static constexpr uint8_t PSBT_IN_NON_WITNESS_UTXO = 0x00;
|
||||
|
|
@ -27,26 +29,30 @@ static constexpr uint8_t PSBT_IN_WITNESSSCRIPT = 0x05;
|
|||
static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06;
|
||||
static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07;
|
||||
static constexpr uint8_t PSBT_IN_SCRIPTWITNESS = 0x08;
|
||||
static constexpr uint8_t PSBT_IN_PROPRIETARY = 0xFC;
|
||||
// Confidential Assets stuff (private use area)
|
||||
static constexpr uint8_t PSBT_IN_VALUE = 0xf0;
|
||||
static constexpr uint8_t PSBT_IN_VALUE_BLINDER = 0xf1;
|
||||
static constexpr uint8_t PSBT_IN_ASSET = 0xf2;
|
||||
static constexpr uint8_t PSBT_IN_ASSET_BLINDER = 0xf3;
|
||||
static constexpr uint8_t PSBT_IN_VALUE = 0x00;
|
||||
static constexpr uint8_t PSBT_IN_VALUE_BLINDER = 0x01;
|
||||
static constexpr uint8_t PSBT_IN_ASSET = 0x02;
|
||||
static constexpr uint8_t PSBT_IN_ASSET_BLINDER = 0x03;
|
||||
|
||||
// Output types
|
||||
static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00;
|
||||
static constexpr uint8_t PSBT_OUT_WITNESSSCRIPT = 0x01;
|
||||
static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02;
|
||||
static constexpr uint8_t PSBT_OUT_PROPRIETARY = 0xFC;
|
||||
// Confidential Assets stuff (private use area)
|
||||
static constexpr uint8_t PSBT_OUT_VALUE_COMMITMENT = 0xf0;
|
||||
static constexpr uint8_t PSBT_OUT_VALUE_BLINDER = 0xf1;
|
||||
static constexpr uint8_t PSBT_OUT_ASSET_COMMITMENT = 0xf2;
|
||||
static constexpr uint8_t PSBT_OUT_ASSET_BLINDER = 0xf3;
|
||||
static constexpr uint8_t PSBT_OUT_RANGE_PROOF = 0xf4;
|
||||
static constexpr uint8_t PSBT_OUT_SURJECTION_PROOF = 0xf5;
|
||||
static constexpr uint8_t PSBT_OUT_BLINDING_PUBKEY = 0xf6;
|
||||
static constexpr uint8_t PSBT_OUT_NONCE_COMMITMENT = 0xf7;
|
||||
static constexpr uint8_t PSBT_OUT_VALUE_COMMITMENT = 0x00;
|
||||
static constexpr uint8_t PSBT_OUT_VALUE_BLINDER = 0x01;
|
||||
static constexpr uint8_t PSBT_OUT_ASSET_COMMITMENT = 0x02;
|
||||
static constexpr uint8_t PSBT_OUT_ASSET_BLINDER = 0x03;
|
||||
static constexpr uint8_t PSBT_OUT_RANGE_PROOF = 0x04;
|
||||
static constexpr uint8_t PSBT_OUT_SURJECTION_PROOF = 0x05;
|
||||
static constexpr uint8_t PSBT_OUT_BLINDING_PUBKEY = 0x06;
|
||||
static constexpr uint8_t PSBT_OUT_NONCE_COMMITMENT = 0x07;
|
||||
|
||||
// Proprietary type identifer string
|
||||
static const std::string PSBT_ELEMENTS_ID("elements");
|
||||
|
||||
// The separator is 0x00. Reading this in means that the unserializer can interpret it
|
||||
// as a 0 length key which indicates that this is the separator. The separator has no value.
|
||||
|
|
@ -122,22 +128,22 @@ struct PSBTInput
|
|||
|
||||
// Write the Confidential Assets blinding data
|
||||
if (value) {
|
||||
SerializeToVector(s, PSBT_IN_VALUE);
|
||||
SerializeToVector(s, PSBT_IN_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_IN_VALUE);
|
||||
SerializeToVector(s, *value);
|
||||
}
|
||||
|
||||
if (!value_blinding_factor.IsNull()) {
|
||||
SerializeToVector(s, PSBT_IN_VALUE_BLINDER);
|
||||
SerializeToVector(s, PSBT_IN_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_IN_VALUE_BLINDER);
|
||||
SerializeToVector(s, value_blinding_factor);
|
||||
}
|
||||
|
||||
if (!asset.IsNull()) {
|
||||
SerializeToVector(s, PSBT_IN_ASSET);
|
||||
SerializeToVector(s, PSBT_IN_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_IN_ASSET);
|
||||
SerializeToVector(s, asset);
|
||||
}
|
||||
|
||||
if (!asset_blinding_factor.IsNull()) {
|
||||
SerializeToVector(s, PSBT_IN_ASSET_BLINDER);
|
||||
SerializeToVector(s, PSBT_IN_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_IN_ASSET_BLINDER);
|
||||
SerializeToVector(s, asset_blinding_factor);
|
||||
}
|
||||
|
||||
|
|
@ -279,46 +285,64 @@ struct PSBTInput
|
|||
UnserializeFromVector(s, final_script_witness.stack);
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_VALUE:
|
||||
case PSBT_IN_PROPRIETARY:
|
||||
{
|
||||
if (value != boost::none) {
|
||||
throw std::ios_base::failure("Duplicate Key, input value already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Final value key is more than one byte type");
|
||||
VectorReader skey(s.GetType(), s.GetVersion(), key, 1);
|
||||
std::string identifier;
|
||||
skey >> identifier;
|
||||
|
||||
if (identifier != PSBT_ELEMENTS_ID) {
|
||||
// This is not our proprietary type, skip it
|
||||
continue;
|
||||
}
|
||||
CAmount amt;
|
||||
UnserializeFromVector(s, amt);
|
||||
value = amt;
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_VALUE_BLINDER:
|
||||
{
|
||||
if (!value_blinding_factor.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, input value_blinding_factor already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Final value_blinding_factor key is more than one byte type");
|
||||
|
||||
size_t subkey_len = skey.size();
|
||||
uint64_t subtype = ReadCompactSize(skey);
|
||||
|
||||
switch(subtype) {
|
||||
case PSBT_IN_VALUE:
|
||||
{
|
||||
if (value != boost::none) {
|
||||
throw std::ios_base::failure("Duplicate Key, input value already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Final value key is more than one byte type");
|
||||
}
|
||||
CAmount amt;
|
||||
UnserializeFromVector(s, amt);
|
||||
value = amt;
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_VALUE_BLINDER:
|
||||
{
|
||||
if (!value_blinding_factor.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, input value_blinding_factor already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Final value_blinding_factor key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, value_blinding_factor);
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_ASSET:
|
||||
{
|
||||
if (!asset.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, input asset already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Final asset key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, asset);
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_ASSET_BLINDER:
|
||||
{
|
||||
if (!asset_blinding_factor.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, input asset_blinding_factor already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Final asset_blinding_factor key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, asset_blinding_factor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
UnserializeFromVector(s, value_blinding_factor);
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_ASSET:
|
||||
{
|
||||
if (!asset.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, input asset already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Final asset key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, asset);
|
||||
break;
|
||||
}
|
||||
case PSBT_IN_ASSET_BLINDER:
|
||||
{
|
||||
if (!asset_blinding_factor.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, input asset_blinding_factor already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Final asset_blinding_factor key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, asset_blinding_factor);
|
||||
break;
|
||||
}
|
||||
// Unknown stuff
|
||||
|
|
@ -390,42 +414,42 @@ struct PSBTOutput
|
|||
if (g_con_elementsmode) {
|
||||
// Write the Confidential Assets blinding data
|
||||
if (!value_commitment.IsNull()) {
|
||||
SerializeToVector(s, PSBT_OUT_VALUE_COMMITMENT);
|
||||
SerializeToVector(s, PSBT_OUT_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_OUT_VALUE_COMMITMENT);
|
||||
SerializeToVector(s, value_commitment);
|
||||
}
|
||||
|
||||
if (!value_blinding_factor.IsNull()) {
|
||||
SerializeToVector(s, PSBT_OUT_VALUE_BLINDER);
|
||||
SerializeToVector(s, PSBT_OUT_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_OUT_VALUE_BLINDER);
|
||||
SerializeToVector(s, value_blinding_factor);
|
||||
}
|
||||
|
||||
if (!asset_commitment.IsNull()) {
|
||||
SerializeToVector(s, PSBT_OUT_ASSET_COMMITMENT);
|
||||
SerializeToVector(s, PSBT_OUT_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_OUT_ASSET_COMMITMENT);
|
||||
SerializeToVector(s, asset_commitment);
|
||||
}
|
||||
|
||||
if (!asset_blinding_factor.IsNull()) {
|
||||
SerializeToVector(s, PSBT_OUT_ASSET_BLINDER);
|
||||
SerializeToVector(s, PSBT_OUT_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_OUT_ASSET_BLINDER);
|
||||
SerializeToVector(s, asset_blinding_factor);
|
||||
}
|
||||
|
||||
if (!nonce_commitment.IsNull()) {
|
||||
SerializeToVector(s, PSBT_OUT_NONCE_COMMITMENT);
|
||||
SerializeToVector(s, PSBT_OUT_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_OUT_NONCE_COMMITMENT);
|
||||
SerializeToVector(s, nonce_commitment);
|
||||
}
|
||||
|
||||
if (!range_proof.empty()) {
|
||||
SerializeToVector(s, PSBT_OUT_RANGE_PROOF);
|
||||
SerializeToVector(s, PSBT_OUT_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_OUT_RANGE_PROOF);
|
||||
s << range_proof;
|
||||
}
|
||||
|
||||
if (!surjection_proof.empty()) {
|
||||
SerializeToVector(s, PSBT_OUT_SURJECTION_PROOF);
|
||||
SerializeToVector(s, PSBT_OUT_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_OUT_SURJECTION_PROOF);
|
||||
s << surjection_proof;
|
||||
}
|
||||
|
||||
if (blinding_pubkey.IsValid()) {
|
||||
SerializeToVector(s, PSBT_OUT_BLINDING_PUBKEY);
|
||||
SerializeToVector(s, PSBT_OUT_PROPRIETARY, PSBT_ELEMENTS_ID, PSBT_OUT_BLINDING_PUBKEY);
|
||||
s << blinding_pubkey;
|
||||
}
|
||||
}
|
||||
|
|
@ -486,84 +510,102 @@ struct PSBTOutput
|
|||
DeserializeHDKeypaths(s, key, hd_keypaths);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_VALUE_COMMITMENT:
|
||||
case PSBT_OUT_PROPRIETARY:
|
||||
{
|
||||
if (!value_commitment.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output value_commitment already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output value_commitment key is more than one byte type");
|
||||
VectorReader skey(s.GetType(), s.GetVersion(), key, 1);
|
||||
std::string identifier;
|
||||
skey >> identifier;
|
||||
|
||||
if (identifier != PSBT_ELEMENTS_ID) {
|
||||
// This is not our proprietary type, skip it
|
||||
continue;
|
||||
}
|
||||
UnserializeFromVector(s, value_commitment);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_VALUE_BLINDER:
|
||||
{
|
||||
if (!value_blinding_factor.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output value_blinding_factor already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output value_blinding_factor key is more than one byte type");
|
||||
|
||||
size_t subkey_len = skey.size();
|
||||
uint64_t subtype = ReadCompactSize(skey);
|
||||
|
||||
switch(subtype) {
|
||||
case PSBT_OUT_VALUE_COMMITMENT:
|
||||
{
|
||||
if (!value_commitment.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output value_commitment already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Output value_commitment key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, value_commitment);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_VALUE_BLINDER:
|
||||
{
|
||||
if (!value_blinding_factor.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output value_blinding_factor already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Output value_blinding_factor key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, value_blinding_factor);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_ASSET_COMMITMENT:
|
||||
{
|
||||
if (!asset_commitment.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output asset_commitment already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Output asset_commitment key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, asset_commitment);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_ASSET_BLINDER:
|
||||
{
|
||||
if (!asset_blinding_factor.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output asset_blinding_factor already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Output asset_blinding_factor key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, asset_blinding_factor);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_NONCE_COMMITMENT:
|
||||
{
|
||||
if (!nonce_commitment.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output nonce_commitment already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Output nonce_commitment key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, nonce_commitment);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_RANGE_PROOF:
|
||||
{
|
||||
if (!range_proof.empty()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output range_proof already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Output range_proof key is more than one byte type");
|
||||
}
|
||||
s >> range_proof;
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_SURJECTION_PROOF:
|
||||
{
|
||||
if (!surjection_proof.empty()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output surjection_proof already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Output surjection_proof key is more than one byte type");
|
||||
}
|
||||
s >> surjection_proof;
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_BLINDING_PUBKEY:
|
||||
{
|
||||
if (blinding_pubkey.IsValid()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output blinding_pubkey already provided");
|
||||
} else if (subkey_len != 1) {
|
||||
throw std::ios_base::failure("Output blinding_pubkey key is more than one byte type");
|
||||
}
|
||||
s >> blinding_pubkey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
UnserializeFromVector(s, value_blinding_factor);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_ASSET_COMMITMENT:
|
||||
{
|
||||
if (!asset_commitment.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output asset_commitment already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output asset_commitment key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, asset_commitment);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_ASSET_BLINDER:
|
||||
{
|
||||
if (!asset_blinding_factor.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output asset_blinding_factor already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output asset_blinding_factor key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, asset_blinding_factor);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_NONCE_COMMITMENT:
|
||||
{
|
||||
if (!nonce_commitment.IsNull()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output nonce_commitment already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output nonce_commitment key is more than one byte type");
|
||||
}
|
||||
UnserializeFromVector(s, nonce_commitment);
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_RANGE_PROOF:
|
||||
{
|
||||
if (!range_proof.empty()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output range_proof already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output range_proof key is more than one byte type");
|
||||
}
|
||||
s >> range_proof;
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_SURJECTION_PROOF:
|
||||
{
|
||||
if (!surjection_proof.empty()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output surjection_proof already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output surjection_proof key is more than one byte type");
|
||||
}
|
||||
s >> surjection_proof;
|
||||
break;
|
||||
}
|
||||
case PSBT_OUT_BLINDING_PUBKEY:
|
||||
{
|
||||
if (blinding_pubkey.IsValid()) {
|
||||
throw std::ios_base::failure("Duplicate Key, output blinding_pubkey already provided");
|
||||
} else if (key.size() != 1) {
|
||||
throw std::ios_base::failure("Output blinding_pubkey key is more than one byte type");
|
||||
}
|
||||
s >> blinding_pubkey;
|
||||
break;
|
||||
}
|
||||
// Unknown stuff
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue