diff --git a/src/key_io.cpp b/src/key_io.cpp index cd41a9354994c..1bf36b52345dd 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -56,6 +56,14 @@ class DestinationEncoder : public boost::static_visitor return bech32::Encode(m_params.Bech32HRP(), data); } + std::string operator()(const WitnessV1Point& id) const + { + std::vector data = {1}; + data.reserve(53); + ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.begin(), id.end()); + return bech32::Encode(m_params.Bech32HRP(), data); + } + std::string operator()(const WitnessUnknown& id) const { if (id.version < 1 || id.version > 16 || id.length < 2 || id.length > 40) { diff --git a/src/pubkey.cpp b/src/pubkey.cpp index 5bb0d1a527e13..b441484ec47d6 100644 --- a/src/pubkey.cpp +++ b/src/pubkey.cpp @@ -295,6 +295,20 @@ bool CPubKey::CheckPayToContract(const CPubKey& base, const uint256& hash) const return memcmp(out, vch, COMPRESSED_PUBLIC_KEY_SIZE) == 0; } +bool CPubKey::CreatePayToContract(CPubKey& res, const uint256& hash) const +{ + if (!IsCompressed()) return false; + secp256k1_pubkey base_point; + if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &base_point, vch, size())) return false; + if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &base_point, hash.begin())) return false; + + size_t tweaked_len = COMPRESSED_PUBLIC_KEY_SIZE; + unsigned char tweaked[tweaked_len]; + secp256k1_ec_pubkey_serialize(secp256k1_context_verify, tweaked, &tweaked_len, &base_point, SECP256K1_EC_COMPRESSED); + res.Set(tweaked, tweaked + tweaked_len); + return true; +} + /* static */ bool CPubKey::CheckLowS(const std::vector& vchSig) { secp256k1_ecdsa_signature sig; if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) { diff --git a/src/pubkey.h b/src/pubkey.h index d102e5be8ec7e..38698f2374c32 100644 --- a/src/pubkey.h +++ b/src/pubkey.h @@ -209,6 +209,8 @@ class CPubKey //! Verify a P2C derivation. Hash must be a cryptographic hash that commits to base. bool CheckPayToContract(const CPubKey& base, const uint256& hash) const; + + bool CreatePayToContract(CPubKey& res, const uint256& hash) const; }; struct CExtPubKey { diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index 22d67c34daee9..53ae80fd2be7f 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -233,6 +233,16 @@ class DescribeAddressVisitor : public boost::static_visitor return obj; } + UniValue operator()(const WitnessV1Point& id) const + { + //TODO: What other data should be here? + UniValue obj(UniValue::VOBJ); + obj.pushKV("iswitness", true); + obj.pushKV("witness_version", 1); + obj.pushKV("witness_program", HexStr(id.begin(), id.end())); + return obj; + } + UniValue operator()(const WitnessUnknown& id) const { UniValue obj(UniValue::VOBJ); diff --git a/src/script/binarytree.h b/src/script/binarytree.h new file mode 100644 index 0000000000000..4bc5d696bea66 --- /dev/null +++ b/src/script/binarytree.h @@ -0,0 +1,110 @@ +// Copyright (c) 2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +#ifndef BITCOIN_BINARYTREE_H +#define BITCOIN_BINARYTREE_H + + +#include