Skip to content

Commit

Permalink
Merge pull request #280 from cryptogarageinc/features/sprint67
Browse files Browse the repository at this point in the history
feat: taproot support
  • Loading branch information
k-matsuzawa authored Mar 15, 2021
2 parents 701bfc8 + 3fbd342 commit 80d84b2
Show file tree
Hide file tree
Showing 55 changed files with 5,365 additions and 744 deletions.
52 changes: 47 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,53 @@
# Crypto Finance Development Kit (CFD)

cfd library in C/C++

<!-- TODO: Write Summary and Overview
CFD library for C/C++.

## Overview

-->
This library is development kit for crypto finance application.
Useful when developing applications for cryptocurrencies.

### Target Network

- Bitcoin
- Liquid Network

### Support function by cfd

- Estimate Fee
- Coin Selection (FundRawTransaction)
- Simple pubkey-hash sign / verify
- C language API (for reference from other languages)
- from cfd-core function:
- Bitcoin
- Bitcoin Script (builder, viewer)
- Transaction
- PSBT (v0)
- ECDSA Pubkey/Privkey (TweakAdd/Mul, Negate, Sign, Verify)
- BIP32, BIP39
- Output Descriptor (contains miniscript parser)
- Schnorr/Taproot
- Bitcoin Address (Segwit-v0, Segwit-v1, P2PKH/P2SH)
- Liquid Network
- Confidential Transaction
- Blind, Unblind
- Issuance, Reissuance
- PegIn, PegOut
- Confidential Address

### Libraries for each language

- C++ : cfd-core
- Core library. Definition base class.
- C/C++ : cfd
- Extend the cfd-core library. Defines the C language API and extension classes.
- Libraries to link cfd library:
- JavaScript : cfd-js
- WebAssembly : cfd-js-wasm
- Python : cfd-python
- C# : cfd-csharp
- Go : cfd-go
- Rust : cfd-rust

## Dependencies

Expand All @@ -20,7 +61,8 @@ cfd library in C/C++

### Windows

download and install files.
download and install files:

- [CMake](https://cmake.org/) (3.14.3 or higher)
- Compiler or development environment (One of the following)
- MSVC
Expand Down
1 change: 1 addition & 0 deletions cmake/CfdCommonOption.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ endif()
option(ENABLE_ELEMENTS "enable elements code (ON or OFF. default:ON)" ON)
option(ENABLE_TESTS "enable code tests (ON or OFF. default:ON)" ON)
option(ENABLE_EMSCRIPTEN "enable EMSCRIPTEN (ON or OFF. default:OFF)" OFF)
option(STD_CPP_VERSION "c++ version (11/14/17. default:11)" "11")

# use "cmake -DCMAKE_BUILD_TYPE=Debug" or "cmake-js -D"
# option(ENABLE_DEBUG "enable debugging (ON or OFF. default:OFF)" OFF)
Expand Down
5 changes: 5 additions & 0 deletions cmake/Cpp11Setting.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ if(${USE_EMSCRIPTEN})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0")
endif()

if(${STD_CPP_VERSION})
set(CMAKE_CXX_STANDARD ${STD_CPP_VERSION})
message(STATUS "[STD_CPP_VERSION] ${STD_CPP_VERSION}")
else()
set(CMAKE_CXX_STANDARD 11)
endif()
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
171 changes: 141 additions & 30 deletions include/cfd/cfd_address.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/**
* @file cfd_address.h
*
* @brief Address操作の関連クラス定義
* @brief Related class definition for Address operation
*/
#ifndef CFD_INCLUDE_CFD_CFD_ADDRESS_H_
#define CFD_INCLUDE_CFD_CFD_ADDRESS_H_
Expand All @@ -13,8 +13,11 @@
#include "cfd/cfd_common.h"
#include "cfdcore/cfdcore_address.h"
#include "cfdcore/cfdcore_bytedata.h"
#include "cfdcore/cfdcore_descriptor.h"
#include "cfdcore/cfdcore_key.h"
#include "cfdcore/cfdcore_schnorrsig.h"
#include "cfdcore/cfdcore_script.h"
#include "cfdcore/cfdcore_taproot.h"

namespace cfd {

Expand All @@ -23,36 +26,65 @@ using cfd::core::AddressFormatData;
using cfd::core::AddressType;
using cfd::core::ByteData;
using cfd::core::ByteData160;
using cfd::core::ByteData256;
using cfd::core::DescriptorKeyType;
using cfd::core::DescriptorScriptType;
using cfd::core::KeyData;
using cfd::core::NetType;
using cfd::core::Pubkey;
using cfd::core::SchnorrPubkey;
using cfd::core::Script;
using cfd::core::TaprootScriptTree;
using cfd::core::WitnessVersion;

/**
* @brief Addressを生成するFactoryクラス
* @brief Descriptor Script information structure
*/
struct DescriptorScriptData {
DescriptorScriptType type; //!< script type
Script locking_script; //!< locking script
uint32_t depth; //!< depth
Address address; //!< address
AddressType address_type; //!< address type
Script redeem_script; //!< redeem script
DescriptorKeyType key_type; //!< key type
std::string key; //!< key string
uint32_t multisig_req_sig_num; //!< multisig num of require signatures
};

/**
* @brief Descriptor Key information structure
*/
struct DescriptorKeyData {
DescriptorKeyType type; //!< key type
std::string key; //!< key string
};

/**
* @brief Factory class that generates Address
*/
class CFD_EXPORT AddressFactory {
public:
/**
* @brief コンストラクタ.
* @brief Constructor.
*/
AddressFactory();

/**
* @brief コンストラクタ.
* @brief Constructor.
* @param[in] type network type
*/
explicit AddressFactory(NetType type);

/**
* @brief コンストラクタ.
* @brief Constructor.
* @param[in] type network type
* @param[in] wit_ver witness version
*/
explicit AddressFactory(NetType type, WitnessVersion wit_ver);

/**
* @brief コンストラクタ.
* @brief Constructor.
* @param[in] type network type
* @param[in] wit_ver witness version
* @param[in] prefix_list address prefix list
Expand All @@ -62,44 +94,44 @@ class CFD_EXPORT AddressFactory {
const std::vector<AddressFormatData>& prefix_list);

/**
* @brief コンストラクタ.
* @brief Constructor.
* @param[in] type network type
* @param[in] prefix_list address prefix list
*/
explicit AddressFactory(
NetType type, const std::vector<AddressFormatData>& prefix_list);

/**
* @brief デストラクタ.
* @brief Destructor.
*/
virtual ~AddressFactory() {
// do nothing
}

/**
* @brief アドレスを作成する
* @param[in] address_string address文字列
* @brief Create an address
* @param[in] address_string address string
* @return address
*/
Address GetAddress(const std::string& address_string) const;

/**
* @brief LockingScriptからアドレスを作成する
* @brief Create an address from locking script
* @param[in] locking_script locking script
* @return address
*/
Address GetAddressByLockingScript(const Script& locking_script) const;

/**
* @brief Hash情報からアドレスを作成する
* @brief Create an address from hash data
* @param[in] address_type address type
* @param[in] hash hash data
* @return address
*/
Address GetAddressByHash(
AddressType address_type, const ByteData& hash) const;
/**
* @brief Hash情報からアドレスを作成する
* @brief Create an address from hash data
* @param[in] address_type address type
* @param[in] hash hash data
* @return address
Expand All @@ -108,49 +140,82 @@ class CFD_EXPORT AddressFactory {
AddressType address_type, const ByteData160& hash) const;

/**
* @brief Hash情報から segwit native アドレスを作成する
* @brief Create a segwit native address from hash data.
* @param[in] hash hash data
* @return address
*/
Address GetSegwitAddressByHash(const ByteData& hash) const;

/**
* @brief P2PKHアドレスを生成する.
* @param[in] pubkey Pubkeyインスタンス
* @return P2PKHアドレスのAddressインスタンス
* @brief Create a segwit native address from hash data.
* @param[in] hash hash data
* @param[in] version witness version
* @return address
*/
Address GetSegwitAddressByHash(
const ByteData& hash, WitnessVersion version) const;

/**
* @brief Create a P2PKH address.
* @param[in] pubkey Pubkey
* @return address
*/
Address CreateP2pkhAddress(const Pubkey& pubkey) const;

/**
* @brief P2SHのアドレスを生成する.
* @param[in] script Scriptインスタンス
* @return P2SHアドレスのAddressインスタンス
* @brief Create a P2SH address.
* @param[in] script Redeem script
* @return address
*/
Address CreateP2shAddress(const Script& script) const;

/**
* @brief P2WPKHのアドレスを生成する.
* @param[in] pubkey Pubkeyインスタンス
* @return P2WPKHのAddressインスタンス
* @brief Create a P2WPKH address.
* @param[in] pubkey Pubkey
* @return address
*/
Address CreateP2wpkhAddress(const Pubkey& pubkey) const;

/**
* @brief P2WSHのアドレスを生成する.
* @param[in] script Scriptインスタンス
* @return P2WSHのAddressインスタンス
* @brief Create a P2WSH address.
* @param[in] script Redeem script
* @return address
*/
Address CreateP2wshAddress(const Script& script) const;

/**
* @brief P2WSHのMultisig(n of m)アドレスを生成する.
* @param[in] require_num signature要求数(n)
* @param[in] pubkeys Pubkeyリスト(m)
* @return P2WSH MultisigのAddressインスタンス
* @brief Create a P2WSH Multisig (n of m) address.
* @param[in] require_num signature require num(n)
* @param[in] pubkeys Pubkey list(m)
* @return address
*/
Address CreateP2wshMultisigAddress(
uint32_t require_num, const std::vector<Pubkey>& pubkeys) const;

/**
* @brief Create taproot address by schnorr pubkey.
* @param[in] pubkey schnorr pubkey
* @return Address by taproot
*/
Address CreateTaprootAddress(const SchnorrPubkey& pubkey) const;

/**
* @brief Create taproot address by tapscript.
* @param[in] tree merkle tree
* @param[in] internal_pubkey internal schnorr pubkey
* @return Address by taproot
*/
Address CreateTaprootAddress(
const TaprootScriptTree& tree,
const SchnorrPubkey& internal_pubkey) const;

/**
* @brief Create taproot address by hash.
* @param[in] hash hash
* @return Address by taproot
*/
Address CreateTaprootAddress(const ByteData256& hash) const;

/**
* @brief check address's network type is valid.
* @param[in] address address which is checked network type
Expand All @@ -159,6 +224,52 @@ class CFD_EXPORT AddressFactory {
*/
bool CheckAddressNetType(const Address& address, NetType net_type) const;

/**
* @brief Create address.
* @param[in] address_type address type
* @param[in] pubkey public key (default: nullptr)
* @param[in] script script (default: nullptr)
* @param[out] locking_script locking script
* @param[out] redeem_script redeem script
* @return Address
*/
Address CreateAddress(
AddressType address_type, const Pubkey* pubkey, const Script* script,
Script* locking_script = nullptr, Script* redeem_script = nullptr) const;

/**
* @brief Create a Pubkey Address list from Multisig Script.
* @param[in] address_type address type
* @param[in] redeem_script multisig script
* @param[out] pubkey_list pubkey list
* @return pubkey address list
*/
std::vector<Address> GetAddressesFromMultisig(
AddressType address_type, const Script& redeem_script,
std::vector<Pubkey>* pubkey_list = nullptr) const;

/**
* @brief Extract information from Output descriptor.
* @param[in] descriptor output descriptor
* @param[in] bip32_derivation_path bip32 derivation path
* @param[out] script_list descriptor script list
* @param[out] multisig_key_list descriptor multisig key list
* @param[out] key_list key data list
* @return descriptor script data (top level or high security)
*/
DescriptorScriptData ParseOutputDescriptor(
const std::string& descriptor,
const std::string& bip32_derivation_path = "",
std::vector<DescriptorScriptData>* script_list = nullptr,
std::vector<DescriptorKeyData>* multisig_key_list = nullptr,
std::vector<KeyData>* key_list = nullptr) const;

/**
* @brief Get current address prefix list.
* @return address prefix list.
*/
std::vector<AddressFormatData> GetPrefixList() const;

protected:
NetType type_; //!< network type
WitnessVersion wit_ver_; //!< witness version
Expand Down
Loading

0 comments on commit 80d84b2

Please sign in to comment.