|
|
|
@ -37,6 +37,10 @@ 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_RIPEMD160 = 0x0A;
|
|
|
|
|
static constexpr uint8_t PSBT_IN_SHA256 = 0x0B;
|
|
|
|
|
static constexpr uint8_t PSBT_IN_HASH160 = 0x0C;
|
|
|
|
|
static constexpr uint8_t PSBT_IN_HASH256 = 0x0D;
|
|
|
|
|
static constexpr uint8_t PSBT_IN_PROPRIETARY = 0xFC;
|
|
|
|
|
|
|
|
|
|
// Output types
|
|
|
|
@ -171,6 +175,10 @@ struct PSBTInput
|
|
|
|
|
CScriptWitness final_script_witness;
|
|
|
|
|
std::map<CPubKey, KeyOriginInfo> hd_keypaths;
|
|
|
|
|
std::map<CKeyID, SigPair> partial_sigs;
|
|
|
|
|
std::map<uint160, std::vector<unsigned char>> ripemd160_preimages;
|
|
|
|
|
std::map<uint256, std::vector<unsigned char>> sha256_preimages;
|
|
|
|
|
std::map<uint160, std::vector<unsigned char>> hash160_preimages;
|
|
|
|
|
std::map<uint256, std::vector<unsigned char>> hash256_preimages;
|
|
|
|
|
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
|
|
|
|
|
std::set<PSBTProprietary> m_proprietary;
|
|
|
|
|
std::optional<int> sighash_type;
|
|
|
|
@ -221,6 +229,30 @@ struct PSBTInput
|
|
|
|
|
|
|
|
|
|
// Write any hd keypaths
|
|
|
|
|
SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_IN_BIP32_DERIVATION));
|
|
|
|
|
|
|
|
|
|
// Write any ripemd160 preimage
|
|
|
|
|
for (const auto& [hash, preimage] : ripemd160_preimages) {
|
|
|
|
|
SerializeToVector(s, CompactSizeWriter(PSBT_IN_RIPEMD160), Span{hash});
|
|
|
|
|
s << preimage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write any sha256 preimage
|
|
|
|
|
for (const auto& [hash, preimage] : sha256_preimages) {
|
|
|
|
|
SerializeToVector(s, CompactSizeWriter(PSBT_IN_SHA256), Span{hash});
|
|
|
|
|
s << preimage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write any hash160 preimage
|
|
|
|
|
for (const auto& [hash, preimage] : hash160_preimages) {
|
|
|
|
|
SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH160), Span{hash});
|
|
|
|
|
s << preimage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write any hash256 preimage
|
|
|
|
|
for (const auto& [hash, preimage] : hash256_preimages) {
|
|
|
|
|
SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH256), Span{hash});
|
|
|
|
|
s << preimage;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write script sig
|
|
|
|
@ -373,6 +405,90 @@ struct PSBTInput
|
|
|
|
|
UnserializeFromVector(s, final_script_witness.stack);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PSBT_IN_RIPEMD160:
|
|
|
|
|
{
|
|
|
|
|
// Make sure that the key is the size of a ripemd160 hash + 1
|
|
|
|
|
if (key.size() != CRIPEMD160::OUTPUT_SIZE + 1) {
|
|
|
|
|
throw std::ios_base::failure("Size of key was not the expected size for the type ripemd160 preimage");
|
|
|
|
|
}
|
|
|
|
|
// Read in the hash from key
|
|
|
|
|
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
|
|
|
|
|
uint160 hash(hash_vec);
|
|
|
|
|
if (ripemd160_preimages.count(hash) > 0) {
|
|
|
|
|
throw std::ios_base::failure("Duplicate Key, input ripemd160 preimage already provided");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read in the preimage from value
|
|
|
|
|
std::vector<unsigned char> preimage;
|
|
|
|
|
s >> preimage;
|
|
|
|
|
|
|
|
|
|
// Add to preimages list
|
|
|
|
|
ripemd160_preimages.emplace(hash, std::move(preimage));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PSBT_IN_SHA256:
|
|
|
|
|
{
|
|
|
|
|
// Make sure that the key is the size of a sha256 hash + 1
|
|
|
|
|
if (key.size() != CSHA256::OUTPUT_SIZE + 1) {
|
|
|
|
|
throw std::ios_base::failure("Size of key was not the expected size for the type sha256 preimage");
|
|
|
|
|
}
|
|
|
|
|
// Read in the hash from key
|
|
|
|
|
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
|
|
|
|
|
uint256 hash(hash_vec);
|
|
|
|
|
if (sha256_preimages.count(hash) > 0) {
|
|
|
|
|
throw std::ios_base::failure("Duplicate Key, input sha256 preimage already provided");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read in the preimage from value
|
|
|
|
|
std::vector<unsigned char> preimage;
|
|
|
|
|
s >> preimage;
|
|
|
|
|
|
|
|
|
|
// Add to preimages list
|
|
|
|
|
sha256_preimages.emplace(hash, std::move(preimage));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PSBT_IN_HASH160:
|
|
|
|
|
{
|
|
|
|
|
// Make sure that the key is the size of a hash160 hash + 1
|
|
|
|
|
if (key.size() != CHash160::OUTPUT_SIZE + 1) {
|
|
|
|
|
throw std::ios_base::failure("Size of key was not the expected size for the type hash160 preimage");
|
|
|
|
|
}
|
|
|
|
|
// Read in the hash from key
|
|
|
|
|
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
|
|
|
|
|
uint160 hash(hash_vec);
|
|
|
|
|
if (hash160_preimages.count(hash) > 0) {
|
|
|
|
|
throw std::ios_base::failure("Duplicate Key, input hash160 preimage already provided");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read in the preimage from value
|
|
|
|
|
std::vector<unsigned char> preimage;
|
|
|
|
|
s >> preimage;
|
|
|
|
|
|
|
|
|
|
// Add to preimages list
|
|
|
|
|
hash160_preimages.emplace(hash, std::move(preimage));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PSBT_IN_HASH256:
|
|
|
|
|
{
|
|
|
|
|
// Make sure that the key is the size of a hash256 hash + 1
|
|
|
|
|
if (key.size() != CHash256::OUTPUT_SIZE + 1) {
|
|
|
|
|
throw std::ios_base::failure("Size of key was not the expected size for the type hash256 preimage");
|
|
|
|
|
}
|
|
|
|
|
// Read in the hash from key
|
|
|
|
|
std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
|
|
|
|
|
uint256 hash(hash_vec);
|
|
|
|
|
if (hash256_preimages.count(hash) > 0) {
|
|
|
|
|
throw std::ios_base::failure("Duplicate Key, input hash256 preimage already provided");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read in the preimage from value
|
|
|
|
|
std::vector<unsigned char> preimage;
|
|
|
|
|
s >> preimage;
|
|
|
|
|
|
|
|
|
|
// Add to preimages list
|
|
|
|
|
hash256_preimages.emplace(hash, std::move(preimage));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PSBT_IN_PROPRIETARY:
|
|
|
|
|
{
|
|
|
|
|
PSBTProprietary this_prop;
|
|
|
|
|