diff --git a/.github/workflows/create_release-and-upload.yml b/.github/workflows/create_release-and-upload.yml
index fe078d8..cbe1029 100644
--- a/.github/workflows/create_release-and-upload.yml
+++ b/.github/workflows/create_release-and-upload.yml
@@ -171,6 +171,10 @@ jobs:
name: upload-object-alpine
needs: create_releases
runs-on: ubuntu-18.04
+ strategy:
+ fail-fast: false
+ matrix:
+ alpine: ['3.10', '3.12', '3.13']
steps:
- name: checkout
@@ -180,10 +184,21 @@ jobs:
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
- name: list
run: ls -a $GITHUB_WORKSPACE
- - name: docker setup
+ - name: docker setup 3.10
+ if: matrix.alpine == '3.10'
uses: docker://alpine:3.10
with:
entrypoint: /github/workspace/.github/workflows/docker/alpine_build_entrypoint.sh
+ - name: docker setup 3.12
+ if: matrix.alpine == '3.12'
+ uses: docker://alpine:3.12
+ with:
+ entrypoint: /github/workspace/.github/workflows/docker/alpine_build_entrypoint.sh
+ - name: docker setup 3.13
+ if: matrix.alpine == '3.13'
+ uses: docker://alpine:3.13
+ with:
+ entrypoint: /github/workspace/.github/workflows/docker/alpine_build_entrypoint.sh
- name: create archive file
run: |
echo "---- dump output data ----"
@@ -211,7 +226,7 @@ jobs:
with:
upload_url: ${{ steps.get_url.outputs.upload_url }}
asset_path: /tmp/cfd/cfd.zip
- asset_name: cfd-sys-${{ steps.get_version.outputs.VERSION }}-alpine_x86_64.zip
+ asset_name: cfd-sys-${{ steps.get_version.outputs.VERSION }}-alpine${{ matrix.alpine }}_x86_64.zip
asset_content_type: application/zip
upload-object-macos:
@@ -221,7 +236,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- xcode: [10.3, 11.6]
+ xcode: [10.3, 11.7, 12.4]
shared: [on, off]
include:
- shared: on
diff --git a/Cargo.toml b/Cargo.toml
index f9818b8..a16770e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cfd-rust"
-version = "0.2.2"
+version = "0.3.0"
license = "MIT"
readme = "README.md"
keywords = ["build-dependencies"]
@@ -15,12 +15,12 @@ name = "cfd_rust"
path = "src/lib.rs"
[dependencies]
-libc = "0.2.74"
+libc = "0.2.83"
hex = "0.4.2"
cfd_sys = { path = "./cfd-sys" }
[dev-dependencies]
-sha2 = "0.9.1"
+sha2 = "0.9.2"
[[example]]
name = "create_pubkey_address"
diff --git a/README.md b/README.md
index 8b2b663..c72848a 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,51 @@
# Crypto Finance Development Kit for Rust (CFD-RUST)
+CFD library for Rust.
+
+## 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
+
+- Bitcoin
+ - Bitcoin Script (builder, viewer)
+ - Transaction
+ - Create, Parse, Decode
+ - Simple pubkey-hash sign / verify
+ - Estimate Fee
+ - Coin Selection (FundRawTransaction)
+ - 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
+ - Reissuance
+ - Confidential Address
+
+### Libraries for each language
+
+- Rust : cfd-rust
+ - C/C++ : cfd
+ - Extend the cfd-core library. Defines the C language API and extension classes.
+ - C++ : cfd-core
+ - Core library. Definition base class.
+- other language:
+ - JavaScript : cfd-js
+ - WebAssembly : cfd-js-wasm
+ - Python : cfd-python
+ - C# : cfd-csharp
+ - Go : cfd-go
+
## Dependencies
- Rust
@@ -7,9 +53,10 @@
- can compile c++11
- CMake (3.14.3 or higher)
-### Windows
+### Windows
download and install files.
+
- [Rustup](https://rustup.rs/)
- [CMake](https://cmake.org/) (3.14.3 or higher)
- MSVC
@@ -38,7 +85,7 @@ curl https://sh.rustup.rs -sSf | sh (select is 1)
```
cmake version 3.14.2 or lower, download from website and install cmake.
-(https://cmake.org/download/)
+([https://cmake.org/download/](https://cmake.org/download/))
---
@@ -58,9 +105,10 @@ Using pkg-config, build is quickly.
```Shell
# The described version is an example. If you use it, please rewrite it to an appropriate version.
-wget https://github.com/cryptogarageinc/cfd-rust/releases/download/v0.0.1/cfd-sys-v0.0.1-osx-xcode9.4-static_x86_64.zip
+wget https://github.com/p2pderivatives/cfd-rust/releases/download/v0.3.0/cfd-sys-v0.3.0-osx-xcode12.4-static-x86_64.zip
+
# decompress
-sudo unzip -d / cfd-sys-v0.0.1-osx-xcode9.4-static_x86_64.zip
+sudo unzip -d / cfd-sys-v0.3.0-osx-xcode12.4-static-x86_64.zip
# build
cargo build
```
@@ -68,7 +116,8 @@ cargo build
### Prepare cfd native library from releases asset (Windows)
Using cmake find_package.
-1. get releases asset. (ex. https://github.com/cryptogarageinc/cfd/releases/download/v0.1.12/cfd-v0.1.12-win-vs2019-x86_64.zip )
+
+1. get releases asset. (ex. [https://github.com/p2pderivatives/cfd-rust/releases/download/v0.3.0/cfd-sys-v0.3.0-win-vs2019-x86_64.zip](https://github.com/p2pderivatives/cfd-rust/releases/download/v0.3.0/cfd-sys-v0.3.0-win-vs2019-x86_64.zip) )
2. Expand to PATH
---
@@ -77,13 +126,13 @@ Using cmake find_package.
### Test
-```
+```shell
cargo test
```
### Example
-```
+```shell
cargo run --example create_pubkey_address
```
@@ -109,7 +158,8 @@ cargo run --example create_pubkey_address
### document tool
- cargo
- ```
+
+ ```shell
cargo doc
```
@@ -123,26 +173,29 @@ cargo run --example create_pubkey_address
## Note
-### Git connection:
+### Git connection
Git repository connections default to HTTPS.
However, depending on the connection settings of GitHub, you may only be able to connect via SSH.
As a countermeasure, forcibly establish SSH connection by setting `CFD_CMAKE_GIT_SSH=1` in the environment variable.
- Windows: (On the command line. Or set from the system setting screen.)
-```
+
+```bat
set CFD_CMAKE_GIT_SSH=1
```
- MacOS & Linux(Ubuntu):
-```
+
+```shell
export CFD_CMAKE_GIT_SSH=1
```
-### Ignore git update for CMake External Project:
+### Ignore git update for CMake External Project
Depending on your git environment, you may get the following error when checking out external:
-```
+
+```log
Performing update step for 'libwally-core-download'
Current branch cmake_build is up to date.
No stash entries found.
@@ -161,11 +214,13 @@ This phenomenon is due to the `git update` related command.
Please set an environment variable that skips update processing.
- Windows: (On the command line. Or set from the system setting screen.)
-```
+
+```bat
set CFD_CMAKE_GIT_SKIP_UPDATE=1
```
- MacOS & Linux(Ubuntu):
-```
+
+```shell
export CFD_CMAKE_GIT_SKIP_UPDATE=1
```
diff --git a/cfd-sys/Cargo.toml b/cfd-sys/Cargo.toml
index 2b5b664..2b89ec5 100644
--- a/cfd-sys/Cargo.toml
+++ b/cfd-sys/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cfd_sys"
-version = "0.2.2"
+version = "0.3.0"
license = "MIT"
readme = "../README.md"
keywords = ["build-dependencies"]
@@ -17,11 +17,11 @@ features = [ "serde" ]
all-features = true
[dependencies]
-libc = "0.2.74"
+libc = "0.2.83"
[build-dependencies]
-cmake = "0.1.44"
-pkg-config = "0.3.18"
+cmake = "0.1.45"
+pkg-config = "0.3.19"
[features]
# When building from source, enable building optimized assembly routines. As
diff --git a/cfd-sys/cfd-cmake/cmake/CfdCommonOption.cmake b/cfd-sys/cfd-cmake/cmake/CfdCommonOption.cmake
index 73a61ce..848197f 100644
--- a/cfd-sys/cfd-cmake/cmake/CfdCommonOption.cmake
+++ b/cfd-sys/cfd-cmake/cmake/CfdCommonOption.cmake
@@ -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)
diff --git a/cfd-sys/cfd-cmake/cmake/CfdWallyOption.cmake b/cfd-sys/cfd-cmake/cmake/CfdWallyOption.cmake
index 63df95d..8dc2cad 100644
--- a/cfd-sys/cfd-cmake/cmake/CfdWallyOption.cmake
+++ b/cfd-sys/cfd-cmake/cmake/CfdWallyOption.cmake
@@ -6,4 +6,5 @@ option(ENABLE_JS_WRAPPER "enable the Javascript interface wrappers (ON or OFF. d
else()
set(ENABLE_JS_WRAPPER OFF)
endif()
-set(GENERATE_WALLY ON)
+option(GENERATE_WALLY "generate the wally.xxx library (ON or OFF. default:ON)" ON)
+option(EXCLUDE_WALLYCORE_LIB "exclude wallycore lib (ON or OFF. default:OFF)" OFF)
diff --git a/cfd-sys/cfd-cmake/cmake/Cpp11Setting.cmake b/cfd-sys/cfd-cmake/cmake/Cpp11Setting.cmake
index c6beeab..b92ed3e 100644
--- a/cfd-sys/cfd-cmake/cmake/Cpp11Setting.cmake
+++ b/cfd-sys/cfd-cmake/cmake/Cpp11Setting.cmake
@@ -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)
diff --git a/cfd-sys/cfd-cmake/external/CMakeLists.txt b/cfd-sys/cfd-cmake/external/CMakeLists.txt
index 4ebcc93..23b8e9f 100644
--- a/cfd-sys/cfd-cmake/external/CMakeLists.txt
+++ b/cfd-sys/cfd-cmake/external/CMakeLists.txt
@@ -43,7 +43,7 @@ if(CFD_TARGET_VERSION)
set(CFD_TARGET_TAG ${CFD_TARGET_VERSION})
message(STATUS "[external project local] cfd target=${CFD_TARGET_VERSION}")
else()
-set(CFD_TARGET_TAG v0.2.2)
+set(CFD_TARGET_TAG v0.3.0)
endif()
if(CFD_TARGET_URL)
set(CFD_TARGET_REP ${CFD_TARGET_URL})
diff --git a/cfd-sys/src/lib.rs b/cfd-sys/src/lib.rs
index 6a5c61b..0664873 100644
--- a/cfd-sys/src/lib.rs
+++ b/cfd-sys/src/lib.rs
@@ -5,7 +5,7 @@
extern crate libc;
-use self::libc::{c_char, c_double, c_int, c_longlong, c_uint, c_void};
+use self::libc::{c_char, c_double, c_int, c_longlong, c_uchar, c_uint, c_void};
pub const BLIND_OPT_MINIMUM_RANGE_VALUE: c_int = 1;
pub const BLIND_OPT_EXPONENT: c_int = 2;
@@ -29,6 +29,20 @@ pub const FEE_OPT_BLIND_MINIMUM_BITS: c_int = 2;
pub const DEFAULT_BLIND_MINIMUM_BITS: c_int = 52;
+pub const PSBT_RECORD_TYPE_GLOBAL: c_int = 1;
+pub const PSBT_RECORD_TYPE_INPUT: c_int = 2;
+pub const PSBT_RECORD_TYPE_OUTPUT: c_int = 3;
+
+pub const PSBT_RECORD_INPUT_SIGNATURE: c_int = 1;
+pub const PSBT_RECORD_INPUT_BIP32: c_int = 2;
+pub const PSBT_RECORD_OUTPUT_BIP32: c_int = 3;
+pub const PSBT_RECORD_GLOBAL_XPUB: c_int = 4;
+
+pub const PSBT_OPT_ESTIMATE_FEE_RATE: c_int = 1;
+pub const PSBT_OPT_DUST_FEE_RATE: c_int = 2;
+pub const PSBT_OPT_LONG_TERM_FEE_RATE: c_int = 3;
+pub const PSBT_OPT_KNAPSACK_MIN_CHANGE: c_int = 4;
+
// references: https://github.com/rust-lang/libz-sys
#[rustfmt::skip]
macro_rules! fns {
@@ -66,6 +80,26 @@ fns! {
ignore_version_info: bool,
value_hex: *mut *mut c_char,
) -> c_int;
+ pub fn CfdEncryptAES(
+ handle: *const c_void, key: *const c_char, cbc_iv: *const c_char, buffer: *const c_char,
+ output: *mut *mut c_char) -> c_int;
+ pub fn CfdDecryptAES(
+ handle: *const c_void, key: *const c_char, cbc_iv: *const c_char, buffer: *const c_char,
+ output: *mut *mut c_char) -> c_int;
+ pub fn CfdEncodeBase64(handle: *const c_void, buffer: *const c_char, output: *mut *mut c_char) -> c_int;
+ pub fn CfdDecodeBase64(handle: *const c_void, base64: *const c_char, output: *mut *mut c_char) -> c_int;
+ pub fn CfdEncodeBase58(
+ handle: *const c_void, buffer: *const c_char, use_checksum: bool, output: *mut *mut c_char) -> c_int;
+ pub fn CfdDecodeBase58(
+ handle: *const c_void, base58: *const c_char, use_checksum: bool, output: *mut *mut c_char) -> c_int;
+ pub fn CfdRipemd160(
+ handle: *const c_void, message: *const c_char, has_text: bool, output: *mut *mut c_char) -> c_int;
+ pub fn CfdSha256(
+ handle: *const c_void, message: *const c_char, has_text: bool, output: *mut *mut c_char) -> c_int;
+ pub fn CfdHash160(
+ handle: *const c_void, message: *const c_char, has_text: bool, output: *mut *mut c_char) -> c_int;
+ pub fn CfdHash256(
+ handle: *const c_void, message: *const c_char, has_text: bool, output: *mut *mut c_char) -> c_int;
pub fn CfdCreateConfidentialAddress(
handle: *const c_void,
address: *const i8,
@@ -137,7 +171,7 @@ fns! {
fingerprint: *const i8,
key: *const i8,
chain_code: *const i8,
- depth: u8,
+ depth: c_uchar,
child_number: u32,
extkey: *mut *mut c_char,
) -> c_int;
@@ -294,6 +328,11 @@ fns! {
is_compressed: bool,
pubkey: *mut *mut c_char,
) -> c_int;
+ pub fn CfdGetPubkeyFingerprint(
+ handle: *const c_void,
+ pubkey: *const c_char,
+ fingerprint: *mut *mut c_char,
+ ) -> c_int;
pub fn CfdCalculateEcSignature(
handle: *const c_void,
sighash: *const i8,
@@ -417,6 +456,19 @@ fns! {
nonce: *const i8,
signature: *mut *mut c_char,
) -> c_int;
+ pub fn CfdAddSighashTypeInSchnorrSignature(
+ handle: *const c_void,
+ signature: *const i8,
+ sighash_type: c_int,
+ anyone_can_pay: bool,
+ added_signature: *mut *mut c_char,
+ ) -> c_int;
+ pub fn CfdGetSighashTypeFromSchnorrSignature(
+ handle: *const c_void,
+ signature: *const i8,
+ sighash_type: *mut c_int,
+ anyone_can_pay: *mut bool,
+ ) -> c_int;
pub fn CfdComputeSchnorrSigPoint(
handle: *const c_void,
message: *const i8,
@@ -454,6 +506,109 @@ fns! {
script_item: *mut *mut c_char,
) -> c_int;
pub fn CfdFreeScriptItemHandle(handle: *const c_void, script_handle: *const c_void) -> c_int;
+ pub fn CfdInitializeTaprootScriptTree(
+ handle: *const c_void,
+ tree_handle: *mut *mut c_void,
+ ) -> c_int;
+ pub fn CfdSetInitialTapLeaf(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ tapscript: *const i8,
+ leaf_version: c_uchar,
+ ) -> c_int;
+ pub fn CfdSetInitialTapBranchByHash(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ hash: *const i8,
+ ) -> c_int;
+ pub fn CfdSetScriptTreeFromString(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ tree_string: *const i8,
+ tapscript: *const i8,
+ leaf_version: c_uchar,
+ control_nodes: *const i8,
+ ) -> c_int;
+ pub fn CfdSetTapScriptByWitnessStack(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ control_block: *const i8,
+ tapscript: *const i8,
+ internal_pubkey: *mut *mut i8,
+ ) -> c_int;
+ pub fn CfdAddTapBranchByHash(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ branch_hash: *const i8,
+ ) -> c_int;
+ pub fn CfdAddTapBranchByScriptTree(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ branch_tree: *const c_void,
+ ) -> c_int;
+ pub fn CfdAddTapBranchByScriptTreeString(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ tree_string: *const i8,
+ ) -> c_int;
+ pub fn CfdAddTapBranchByTapLeaf(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ tapscript: *const i8,
+ leaf_version: c_uchar,
+ ) -> c_int;
+ pub fn CfdGetBaseTapLeaf(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ leaf_version: *mut c_uchar,
+ tapscript: *mut *mut i8,
+ tap_leaf_hash: *mut *mut i8,
+ ) -> c_int;
+ pub fn CfdGetTapBranchCount(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ branch_count: *mut c_uint,
+ ) -> c_int;
+ pub fn CfdGetTapBranchData(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ index_from_leaf: c_uchar,
+ is_root_data: bool,
+ branch_hash: *mut *mut i8,
+ leaf_version: *mut c_uchar,
+ tapscript: *mut *mut i8,
+ depth_by_leaf_or_end: *mut c_uchar,
+ ) -> c_int;
+ pub fn CfdGetTapBranchHandle(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ index_from_leaf: c_uchar,
+ branch_hash: *mut *mut i8,
+ branch_tree_handle: *mut *mut c_void,
+ ) -> c_int;
+ pub fn CfdGetTaprootScriptTreeHash(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ internal_pubkey: *const i8,
+ hash: *mut *mut i8,
+ tap_leaf_hash: *mut *mut i8,
+ control_block: *mut *mut i8,
+ ) -> c_int;
+ pub fn CfdGetTaprootTweakedPrivkey(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ internal_privkey: *const i8,
+ tweaked_privkey: *mut *mut i8,
+ ) -> c_int;
+ pub fn CfdGetTaprootScriptTreeSrting(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ tree_string: *mut *mut i8,
+ ) -> c_int;
+ pub fn CfdFreeTaprootScriptTreeHandle(
+ handle: *const c_void,
+ tree_handle: *const c_void,
+ ) -> c_int;
pub fn CfdInitializeMultisigScript(
handle: *const c_void,
network_type: c_int,
@@ -541,6 +696,106 @@ fns! {
direct_locking_script: *const i8,
asset_string: *const i8,
) -> c_int;
+ pub fn CfdClearWitnessStack(
+ handle: *const c_void,
+ create_handle: *const c_void,
+ txid: *const i8,
+ vout: c_uint,
+ ) -> c_int;
+ pub fn CfdUpdateTxInScriptSig(
+ handle: *const c_void,
+ create_handle: *const c_void,
+ txid: *const i8,
+ vout: c_uint,
+ script_sig: *const i8,
+ ) -> c_int;
+ pub fn CfdSetTransactionUtxoData(
+ handle: *const c_void,
+ create_handle: *const c_void,
+ txid: *const i8,
+ vout: c_uint,
+ amount: c_longlong,
+ commitment: *const i8,
+ descriptor: *const i8,
+ address: *const i8,
+ asset: *const i8,
+ scriptsig_template: *const i8,
+ can_insert: bool,
+ ) -> c_int;
+ pub fn CfdCreateSighashByHandle(
+ handle: *const c_void,
+ create_handle: *const c_void,
+ txid: *const i8,
+ vout: c_uint,
+ sighash_type: c_int,
+ sighash_anyone_can_pay: bool,
+ pubkey: *const i8,
+ redeem_script: *const i8,
+ tapleaf_hash: *const i8,
+ code_separator_position: c_uint,
+ annex: *const i8,
+ sighash: *mut *mut i8,
+ ) -> c_int;
+ pub fn CfdAddSignWithPrivkeyByHandle(
+ handle: *const c_void,
+ create_handle: *const c_void,
+ txid: *const i8,
+ vout: c_uint,
+ privkey: *const i8,
+ sighash_type: c_int,
+ sighash_anyone_can_pay: bool,
+ has_grind_r: bool,
+ aux_rand: *const i8,
+ annex: *const i8,
+ ) -> c_int;
+ pub fn CfdVerifyTxSignByHandle(
+ handle: *const c_void,
+ create_handle: *const c_void,
+ txid: *const i8,
+ vout: c_uint,
+ ) -> c_int;
+ pub fn CfdAddTxSignByHandle(
+ handle: *const c_void,
+ create_handle: *const c_void,
+ txid: *const i8,
+ vout: c_uint,
+ hash_type: c_int,
+ sign_data_hex: *const i8,
+ use_der_encode: bool,
+ sighash_type: c_int,
+ sighash_anyone_can_pay: bool,
+ clear_stack: bool,
+ ) -> c_int;
+ pub fn CfdAddTaprootSignByHandle(
+ handle: *const c_void,
+ create_handle: *const c_void,
+ txid: *const i8,
+ vout: c_uint,
+ signature: *const i8,
+ tapscript: *const i8,
+ control_block: *const i8,
+ annex: *const i8,
+ ) -> c_int;
+ pub fn CfdAddPubkeyHashSignByHandle(
+ handle: *const c_void,
+ create_handle: *const c_void,
+ txid: *const i8,
+ vout: c_uint,
+ hash_type: c_int,
+ pubkey: *const i8,
+ signature: *const i8,
+ use_der_encode: bool,
+ sighash_type: c_int,
+ sighash_anyone_can_pay: bool,
+ ) -> c_int;
+ pub fn CfdAddScriptHashLastSignByHandle(
+ handle: *const c_void,
+ create_handle: *const c_void,
+ txid: *const i8,
+ vout: c_uint,
+ hash_type: c_int,
+ redeem_script: *const i8,
+ ) -> c_int;
pub fn CfdFinalizeTransaction(
handle: *const c_void,
create_handle: *const c_void,
@@ -991,12 +1246,10 @@ fns! {
direct_locking_script: *const c_char, index: *mut c_uint) -> c_int;
pub fn CfdInitializeConfidentialTx(
handle: *const c_void, version: c_uint, locktime: c_uint, tx_string: *mut *mut c_char) -> c_int;
- // Just in case
pub fn CfdAddConfidentialTxOut(
handle: *const c_void, tx_hex_string: *const c_char, asset_string: *const c_char,
value_satoshi: c_longlong, value_commitment: *const c_char, address: *const c_char,
direct_locking_script: *const c_char, nonce: *const c_char, tx_string: *mut *mut c_char) -> c_int;
- // Needed
pub fn CfdUpdateConfidentialTxOut(
handle: *const c_void, tx_hex_string: *const c_char, index: c_uint,
asset_string: *const c_char, value_satoshi: c_longlong,
@@ -1054,7 +1307,7 @@ fns! {
is_issuance_asset: *mut bool, is_issuance_token: *mut bool) -> c_int;
pub fn CfdFreeBlindHandle(handle: *const c_void, blind_handle: *const c_void) -> c_int;
pub fn CfdFinalizeElementsMultisigSign(
- handle: *const c_void, multi_sign_handle: *const c_void, tx_hex_string: *const c_char, txid: *const c_char, vout: c_uint, hash_type: c_int, witness_script: *const c_char, redeem_script: *const c_char, clear_stack: bool, tx_string: *mut *mut c_char) -> c_int;
+ handle: *const c_void, multi_sign_handle: *const c_void, tx_hex_string: *const c_char, txid: *const c_char, vout: c_uint, hash_type: c_int, witness_script: *const c_char, redeem_script: *const c_char, clear_stack: bool, tx_string: *mut *mut c_char) -> c_int;
pub fn CfdAddConfidentialTxSignWithPrivkeySimple(
handle: *const c_void, tx_hex_string: *const c_char, txid: *const c_char, vout: c_uint,
hash_type: c_int, pubkey: *const c_char, privkey: *const c_char,
@@ -1094,4 +1347,135 @@ fns! {
handle: *const c_void, create_handle: *const c_void, value_satoshi: c_longlong,
address: *const c_char, direct_locking_script: *const c_char,
asset_string: *const c_char, nonce: *const c_char) -> c_int;
+ pub fn CfdCreatePsbtHandle(
+ handle: *const c_void, net_type: c_int, psbt_string: *const c_char,
+ tx_hex_string: *const c_char, version: c_uint, locktime: c_uint,
+ psbt_handle: *mut *mut c_void) -> c_int;
+ pub fn CfdFreePsbtHandle(handle: *const c_void, psbt_handle: *const c_void) -> c_int;
+ pub fn CfdGetPsbtData(
+ handle: *const c_void, psbt_handle: *const c_void, psbt_base64: *mut *mut c_char, psbt_hex: *mut *mut c_char) -> c_int;
+ pub fn CfdGetPsbtGlobalData(
+ handle: *const c_void, psbt_handle: *const c_void, psbt_version: *mut c_uint, base_tx: *mut *mut c_char,
+ txin_count: *mut c_uint, txout_count: *mut c_uint) -> c_int;
+ pub fn CfdJoinPsbt(
+ handle: *const c_void, psbt_handle: *const c_void, psbt_join_base64: *const c_char) -> c_int;
+ pub fn CfdSignPsbt(
+ handle: *const c_void, psbt_handle: *const c_void, privkey: *const c_char, has_grind_r: bool) -> c_int;
+ pub fn CfdCombinePsbt(
+ handle: *const c_void, psbt_handle: *const c_void, psbt_combine_base64: *const c_char) -> c_int;
+ pub fn CfdFinalizePsbt(handle: *const c_void, psbt_handle: *const c_void) -> c_int;
+ pub fn CfdExtractPsbtTransaction(
+ handle: *const c_void, psbt_handle: *const c_void, transaction: *mut *mut c_char) -> c_int;
+ pub fn CfdIsFinalizedPsbt(handle: *const c_void, psbt_handle: *const c_void) -> c_int;
+ pub fn CfdIsFinalizedPsbtInput(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint) -> c_int;
+ pub fn CfdAddPsbtTxInWithPubkey(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ sequence: c_uint, amount: c_longlong, locking_script: *const c_char,
+ descriptor: *const c_char, full_tx_hex: *const c_char) -> c_int;
+ pub fn CfdAddPsbtTxInWithScript(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ sequence: c_uint, amount: c_longlong, locking_script: *const c_char,
+ redeem_script: *const c_char, descriptor: *const c_char,
+ full_tx_hex: *const c_char) -> c_int;
+ pub fn CfdSetPsbtTxInUtxo(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ amount: c_longlong, locking_script: *const c_char, full_tx_hex: *const c_char) -> c_int;
+ pub fn CfdSetPsbtTxInBip32Pubkey(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ pubkey: *const c_char, fingerprint: *const c_char, bip32_path: *const c_char) -> c_int;
+ pub fn CfdSetPsbtSignature(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ pubkey: *const c_char, der_signature: *const c_char) -> c_int;
+ pub fn CfdSetPsbtSighashType(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ sighash_type: c_int) -> c_int;
+ pub fn CfdSetPsbtFinalizeScript(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ scriptsig: *const c_char) -> c_int;
+ pub fn CfdClearPsbtSignData(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint) -> c_int;
+ pub fn CfdGetPsbtSighashType(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ sighash_type: *mut c_int) -> c_int;
+ pub fn CfdGetPsbtUtxoData(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ amount: *mut c_longlong, locking_script: *mut *mut c_char, redeem_script: *mut *mut c_char,
+ descriptor: *mut *mut c_char, full_tx_hex: *mut *mut c_char) -> c_int;
+ pub fn CfdGetPsbtUtxoDataByIndex(
+ handle: *const c_void, psbt_handle: *const c_void, index: c_uint, txid: *mut *mut c_char,
+ vout: *mut c_uint, amount: *mut c_longlong, locking_script: *mut *mut c_char,
+ redeem_script: *mut *mut c_char, descriptor: *mut *mut c_char, full_tx_hex: *mut *mut c_char) -> c_int;
+ pub fn CfdAddPsbtTxOutWithPubkey(
+ handle: *const c_void, psbt_handle: *const c_void, amount: c_longlong,
+ locking_script: *const c_char, descriptor: *const c_char, index: *mut c_uint) -> c_int;
+ pub fn CfdAddPsbtTxOutWithScript(
+ handle: *const c_void, psbt_handle: *const c_void, amount: c_longlong,
+ locking_script: *const c_char, redeem_script: *const c_char,
+ descriptor: *const c_char, index: *mut c_uint) -> c_int;
+ pub fn CfdSetPsbtTxOutBip32Pubkey(
+ handle: *const c_void, psbt_handle: *const c_void, index: c_uint, pubkey: *const c_char,
+ fingerprint: *const c_char, bip32_path: *const c_char) -> c_int;
+ pub fn CfdGetPsbtTxInIndex(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ index: *mut c_uint) -> c_int;
+ pub fn CfdGetPsbtPubkeyRecord(
+ handle: *const c_void, psbt_handle: *const c_void, record_kind: c_int, index: c_uint,
+ pubkey: *const c_char, value: *mut *mut c_char) -> c_int; // (txin:signature, key. txout:key)
+ pub fn CfdIsFindPsbtPubkeyRecord(
+ handle: *const c_void, psbt_handle: *const c_void, record_kind: c_int, index: c_uint,
+ pubkey: *const c_char) -> c_int;
+ pub fn CfdGetPsbtBip32Data(
+ handle: *const c_void, psbt_handle: *const c_void, record_kind: c_int, index: c_uint,
+ pubkey: *const c_char, fingerprint: *mut *mut c_char, bip32_path: *mut *mut c_char) -> c_int;
+ pub fn CfdGetPsbtPubkeyList(
+ handle: *const c_void, psbt_handle: *const c_void, record_kind: c_int, index: c_uint,
+ list_num: *mut c_uint, pubkey_list_handle: *mut *mut c_void) -> c_int;
+ pub fn CfdGetPsbtPubkeyListData(
+ handle: *const c_void, pubkey_list_handle: *const c_void, index: c_uint, pubkey: *mut *mut c_char,
+ pubkey_hex: *mut *mut c_char) -> c_int;
+ pub fn CfdGetPsbtPubkeyListBip32Data(
+ handle: *const c_void, pubkey_list_handle: *const c_void, index: c_uint, pubkey: *mut *mut c_char,
+ fingerprint: *mut *mut c_char, bip32_path: *mut *mut c_char) -> c_int;
+ pub fn CfdFreePsbtPubkeyList(handle: *const c_void, pubkey_list_handle: *const c_void) -> c_int;
+ pub fn CfdGetPsbtByteDataList(
+ handle: *const c_void, psbt_handle: *const c_void, record_kind: c_int, index: c_uint,
+ list_num: *mut c_uint, data_list_handle: *mut *mut c_void) -> c_int;
+ pub fn CfdGetPsbtByteDataItem(
+ handle: *const c_void, data_list_handle: *const c_void, index: c_uint, data: *mut *mut c_char) -> c_int;
+ pub fn CfdFreePsbtByteDataList(handle: *const c_void, data_list_handle: *const c_void) -> c_int;
+ pub fn CfdAddPsbtGlobalXpubkey(
+ handle: *const c_void, psbt_handle: *const c_void, xpubkey: *const c_char,
+ fingerprint: *const c_char, bip32_path: *const c_char) -> c_int;
+ pub fn CfdSetPsbtRedeemScript(
+ handle: *const c_void, psbt_handle: *const c_void, record_type: c_int, index: c_uint,
+ redeem_script: *const c_char) -> c_int;
+ pub fn CfdAddPsbtRecord(
+ handle: *const c_void, psbt_handle: *const c_void, record_type: c_int, index: c_uint,
+ key: *const c_char, value: *const c_char) -> c_int;
+ pub fn CfdGetPsbtRecord(
+ handle: *const c_void, psbt_handle: *const c_void, record_type: c_int, index: c_uint,
+ key: *const c_char, value: *mut *mut c_char) -> c_int;
+ pub fn CfdIsFindPsbtRecord(
+ handle: *const c_void, psbt_handle: *const c_void, record_type: c_int, index: c_uint,
+ key: *const c_char) -> c_int;
+ pub fn CfdVerifyPsbtTxIn(
+ handle: *const c_void, psbt_handle: *const c_void, txid: *const c_char, vout: c_uint) -> c_int;
+ pub fn CfdInitializeFundPsbt(handle: *const c_void, fund_handle: *mut *mut c_void) -> c_int;
+ pub fn CfdFundPsbtAddToUtxoList(
+ handle: *const c_void, fund_handle: *const c_void, txid: *const c_char, vout: c_uint,
+ amount: c_longlong, asset: *const c_char, descriptor: *const c_char,
+ scriptsig_template: *const c_char, full_utxo_tx: *const c_char) -> c_int;
+ pub fn CfdSetOptionFundPsbt(
+ handle: *const c_void, fund_handle: *const c_void, key: c_int, int64_value: c_longlong,
+ double_value: c_double, bool_value: bool) -> c_int;
+ pub fn CfdFinalizeFundPsbt(
+ handle: *const c_void, psbt_handle: *const c_void, fund_handle: *const c_void,
+ change_address_descriptor: *const c_char, tx_fee: *mut c_longlong,
+ used_utxo_count: *mut c_uint) -> c_int;
+ pub fn CfdGetFundPsbtUsedUtxo(
+ handle: *const c_void, fund_handle: *const c_void, index: c_uint, utxo_index: *mut c_uint,
+ txid: *mut *mut c_char, vout: *mut c_uint, amount: *mut c_longlong, asset: *mut *mut c_char,
+ descriptor: *mut *mut c_char, scriptsig_template: *mut *mut c_char) -> c_int;
+ pub fn CfdFreeFundPsbt(handle: *const c_void, fund_handle: *const c_void) -> c_int;
}
diff --git a/src/address.rs b/src/address.rs
index 3017c7d..257fb4a 100644
--- a/src/address.rs
+++ b/src/address.rs
@@ -3,10 +3,10 @@ extern crate libc;
use self::libc::{c_char, c_int, c_uint, c_void};
use crate::common::{
- alloc_c_string, collect_cstring_and_free, collect_multi_cstring_and_free, CfdError, ErrorHandle,
- Network,
+ alloc_c_string, collect_cstring_and_free, collect_multi_cstring_and_free, ByteData, CfdError,
+ ErrorHandle, Network,
};
-use crate::{key::Pubkey, script::Script};
+use crate::{key::Pubkey, schnorr::SchnorrPubkey, script::Script};
use std::fmt;
use std::ptr;
use std::result::Result::{Err, Ok};
@@ -32,6 +32,8 @@ pub enum HashType {
P2shP2wpkh,
/// p2sh-p2wsh
P2shP2wsh,
+ /// taproot
+ Taproot,
/// unknown type
Unknown,
}
@@ -45,6 +47,7 @@ impl HashType {
4 => HashType::P2wpkh,
5 => HashType::P2shP2wsh,
6 => HashType::P2shP2wpkh,
+ 7 => HashType::Taproot,
_ => HashType::Unknown,
}
}
@@ -57,7 +60,8 @@ impl HashType {
HashType::P2wpkh => 4,
HashType::P2shP2wsh => 5,
HashType::P2shP2wpkh => 6,
- HashType::Unknown => 0,
+ HashType::Taproot => 7,
+ HashType::Unknown => 0xff,
}
}
@@ -79,6 +83,7 @@ impl HashType {
HashType::P2wsh => AddressType::P2wshAddress,
HashType::P2shP2wpkh => AddressType::P2shP2wpkhAddress,
HashType::P2shP2wsh => AddressType::P2shP2wshAddress,
+ HashType::Taproot => AddressType::TaprootAddress,
HashType::Unknown => AddressType::Unknown,
}
}
@@ -107,6 +112,7 @@ impl fmt::Display for HashType {
HashType::P2wpkh => write!(f, "HashType:p2wpkh"),
HashType::P2shP2wsh => write!(f, "HashType:p2sh-p2wsh"),
HashType::P2shP2wpkh => write!(f, "HashType:p2sh-p2wpkh"),
+ HashType::Taproot => write!(f, "HashType:taproot"),
HashType::Unknown => write!(f, "HashType:unknown"),
}
}
@@ -127,6 +133,8 @@ pub enum AddressType {
P2shP2wpkhAddress,
/// p2sh-p2wsh address (p2sh-segwit)
P2shP2wshAddress,
+ /// taproot address
+ TaprootAddress,
/// unknown address
Unknown,
}
@@ -140,7 +148,8 @@ impl AddressType {
AddressType::P2wpkhAddress => 4,
AddressType::P2shP2wshAddress => 5,
AddressType::P2shP2wpkhAddress => 6,
- AddressType::Unknown => 0,
+ AddressType::TaprootAddress => 7,
+ AddressType::Unknown => 0xff,
}
}
@@ -166,6 +175,7 @@ impl AddressType {
AddressType::P2wshAddress => HashType::P2wsh,
AddressType::P2shP2wpkhAddress => HashType::P2shP2wpkh,
AddressType::P2shP2wshAddress => HashType::P2shP2wsh,
+ AddressType::TaprootAddress => HashType::Taproot,
AddressType::Unknown => HashType::Unknown,
}
}
@@ -182,6 +192,7 @@ impl AddressType {
/// ```
pub fn get_witness_version(&self) -> WitnessVersion {
match self {
+ AddressType::TaprootAddress => WitnessVersion::Version1,
AddressType::P2wpkhAddress => WitnessVersion::Version0,
AddressType::P2wshAddress => WitnessVersion::Version0,
AddressType::P2shP2wpkhAddress => WitnessVersion::Version0,
@@ -200,6 +211,7 @@ impl fmt::Display for AddressType {
AddressType::P2wpkhAddress => write!(f, "Address:p2wpkh"),
AddressType::P2shP2wshAddress => write!(f, "Address:p2sh-p2wsh"),
AddressType::P2shP2wpkhAddress => write!(f, "Address:p2sh-p2wpkh"),
+ AddressType::TaprootAddress => write!(f, "Address:taproot"),
AddressType::Unknown => write!(f, "Address:unknown"),
}
}
@@ -280,6 +292,7 @@ pub struct Address {
address_type: AddressType,
p2sh_wrapped_segwit_script: Script,
witness_version: WitnessVersion,
+ hash: ByteData,
}
impl Address {
@@ -297,7 +310,7 @@ impl Address {
/// ```
pub fn from_string(address: &str) -> Result
{
let addr = alloc_c_string(address)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut network_type_c: c_int = 0;
let mut hash_type_c: c_int = 0;
let mut witness_version_c: c_int = 0;
@@ -318,6 +331,7 @@ impl Address {
0 => {
let str_list = unsafe { collect_multi_cstring_and_free(&[locking_script, hash]) }?;
let script_obj = &str_list[0];
+ let hash_obj = ByteData::from_str(&str_list[1])?;
let script = Script::from_hex(script_obj)?;
let hash_type = HashType::from_c_value(hash_type_c);
Ok(Address {
@@ -325,8 +339,9 @@ impl Address {
locking_script: script,
network_type: Network::from_c_value(network_type_c),
address_type: hash_type.to_address_type(),
- p2sh_wrapped_segwit_script: Script::default(),
witness_version: hash_type.get_witness_version(),
+ hash: hash_obj,
+ ..Address::default()
})
}
_ => Err(handle.get_error(error_code)),
@@ -353,7 +368,7 @@ impl Address {
/// ```
pub fn from_locking_script(script: &Script, network_type: &Network) -> Result {
let hex = alloc_c_string(&script.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut address: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdGetAddressFromLockingScript(
@@ -440,6 +455,7 @@ impl Address {
) -> Result {
let script = Script::multisig(require_num, pubkey_list)?;
Address::get_address(
+ ptr::null(),
ptr::null(),
&script,
address_type.to_c_value(),
@@ -468,6 +484,7 @@ impl Address {
Address::get_address(
pubkey,
ptr::null(),
+ ptr::null(),
HashType::P2pkh.to_c_value(),
network_type.to_c_value(),
)
@@ -494,6 +511,7 @@ impl Address {
Address::get_address(
pubkey,
ptr::null(),
+ ptr::null(),
HashType::P2wpkh.to_c_value(),
network_type.to_c_value(),
)
@@ -520,6 +538,7 @@ impl Address {
Address::get_address(
pubkey,
ptr::null(),
+ ptr::null(),
HashType::P2shP2wpkh.to_c_value(),
network_type.to_c_value(),
)
@@ -544,6 +563,7 @@ impl Address {
/// ```
pub fn p2sh(script: &Script, network_type: &Network) -> Result {
Address::get_address(
+ ptr::null(),
ptr::null(),
script,
HashType::P2sh.to_c_value(),
@@ -570,6 +590,7 @@ impl Address {
/// ```
pub fn p2wsh(script: &Script, network_type: &Network) -> Result {
Address::get_address(
+ ptr::null(),
ptr::null(),
script,
HashType::P2wsh.to_c_value(),
@@ -596,6 +617,7 @@ impl Address {
/// ```
pub fn p2sh_p2wsh(script: &Script, network_type: &Network) -> Result {
Address::get_address(
+ ptr::null(),
ptr::null(),
script,
HashType::P2shP2wsh.to_c_value(),
@@ -627,6 +649,10 @@ impl Address {
self.witness_version
}
+ pub fn get_hash(&self) -> &ByteData {
+ &self.hash
+ }
+
/// Get p2wpkh or p2wsh locking script on p2sh-segwit.
///
/// # Example
@@ -651,6 +677,35 @@ impl Address {
}
}
+ /// Create taproot address.
+ ///
+ /// # Arguments
+ /// * `pubkey` - A schnorr public key.
+ /// * `network_type` - A target network.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use cfd_rust::Address;
+ /// use cfd_rust::Network;
+ /// use cfd_rust::Pubkey;
+ /// use cfd_rust::SchnorrPubkey;
+ /// use std::str::FromStr;
+ /// let key_str = "031d7463018f867de51a27db866f869ceaf52abab71827a6051bab8a0fd020f4c1";
+ /// let pk = Pubkey::from_str(&key_str).expect("fail");
+ /// let (key, parity) = SchnorrPubkey::from_pubkey(&pk).expect("fail");
+ /// let addr = Address::taproot(&key, &Network::Mainnet).expect("Fail");
+ /// ```
+ pub fn taproot(pubkey: &SchnorrPubkey, network_type: &Network) -> Result {
+ Address::get_address(
+ ptr::null(),
+ pubkey,
+ ptr::null(),
+ HashType::Taproot.to_c_value(),
+ network_type.to_c_value(),
+ )
+ }
+
/// Validate an address.
///
/// # Example
@@ -668,10 +723,8 @@ impl Address {
pub fn valid(&self) -> bool {
if self.address.is_empty() {
false
- } else if let Ok(_result) = Address::from_string(&self.address) {
- true
} else {
- false
+ matches!(Address::from_string(&self.address), Ok(_result))
}
}
@@ -699,7 +752,7 @@ impl Address {
network_type: &Network,
) -> Result, CfdError> {
let redeem_script = alloc_c_string(&multisig_script.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut max_key_num: c_uint = 0;
let mut addr_multisig_keys_handle: *mut c_void = ptr::null_mut();
let error_code = unsafe {
@@ -768,6 +821,7 @@ impl Address {
fn get_address(
pubkey: *const Pubkey,
+ schnorr_pubkey: *const SchnorrPubkey,
script: *const Script,
hash_type: c_int,
network_type: c_int,
@@ -775,7 +829,10 @@ impl Address {
let pubkey_hex = unsafe {
match pubkey.as_ref() {
Some(pubkey) => alloc_c_string(&pubkey.to_hex()),
- _ => alloc_c_string(""),
+ _ => match schnorr_pubkey.as_ref() {
+ Some(schnorr_pubkey) => alloc_c_string(&schnorr_pubkey.to_hex()),
+ _ => alloc_c_string(""),
+ },
}
}?;
let redeem_script = unsafe {
@@ -784,7 +841,7 @@ impl Address {
_ => alloc_c_string(""),
}
}?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut address: *mut c_char = ptr::null_mut();
let mut locking_script: *mut c_char = ptr::null_mut();
let mut p2sh_segwit_locking_script: *mut c_char = ptr::null_mut();
@@ -805,19 +862,26 @@ impl Address {
let str_list = unsafe {
collect_multi_cstring_and_free(&[address, locking_script, p2sh_segwit_locking_script])
}?;
- let addr_obj = &str_list[0];
+ let addr_str = &str_list[0];
let script_obj = &str_list[1];
let segwit_obj = &str_list[2];
+ let hash_obj = unsafe {
+ match schnorr_pubkey.as_ref() {
+ Some(schnorr_pubkey) => ByteData::from_str(&schnorr_pubkey.to_hex()),
+ _ => Ok(ByteData::default()),
+ }?
+ };
let addr_locking_script = Script::from_hex(script_obj)?;
let segwit_script = Script::from_hex(segwit_obj)?;
let hash_type_obj = HashType::from_c_value(hash_type);
Ok(Address {
- address: addr_obj.clone(),
+ address: addr_str.clone(),
locking_script: addr_locking_script,
network_type: Network::from_c_value(network_type),
address_type: hash_type_obj.to_address_type(),
p2sh_wrapped_segwit_script: segwit_script,
witness_version: hash_type_obj.get_witness_version(),
+ hash: hash_obj,
})
}
_ => Err(handle.get_error(error_code)),
@@ -849,6 +913,7 @@ impl Default for Address {
address_type: AddressType::Unknown,
p2sh_wrapped_segwit_script: Script::default(),
witness_version: WitnessVersion::None,
+ hash: ByteData::default(),
}
}
}
diff --git a/src/common.rs b/src/common.rs
index 712c08d..bfd6c89 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -38,6 +38,8 @@ pub enum CfdError {
DiskAccess(String),
/// Sign verification error.
SignVerification(String),
+ /// Not found error.
+ NotFound(String),
}
impl fmt::Display for CfdError {
@@ -53,6 +55,7 @@ impl fmt::Display for CfdError {
CfdError::Connection(ref a) => write!(f, "[Connection]: {}", a),
CfdError::DiskAccess(ref a) => write!(f, "[DiskAccess]: {}", a),
CfdError::SignVerification(ref a) => write!(f, "[SignVerification]: {}", a),
+ CfdError::NotFound(ref a) => write!(f, "[NotFound]: {}", a),
}
}
}
@@ -70,6 +73,7 @@ impl error::Error for CfdError {
CfdError::Connection(..) => "connection error",
CfdError::DiskAccess(..) => "disk access error",
CfdError::SignVerification(..) => "sign verification error",
+ CfdError::NotFound(..) => "Not found error",
}
}
}
@@ -272,6 +276,23 @@ impl ByteData {
self.data.is_empty()
}
+ /// Output fixed 32byte array into byte data.
+ /// If the size of the byte data is less than 32 bytes, it returns an array of all zeros.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use cfd_rust::ByteData;
+ /// use std::str::FromStr;
+ /// let data = ByteData::from_str(
+ /// "4691fbb1196f4675241c8958a7ab6378a63aa0cc008ed03d216fd038357f52fd",
+ /// ).expect("Fail");
+ /// let array = data.to_32byte_array();
+ /// ```
+ pub fn to_32byte_array(&self) -> [u8; 32] {
+ copy_array_32byte(&self.data)
+ }
+
/// Get serialized byte data.
///
/// # Example
@@ -286,7 +307,7 @@ impl ByteData {
/// ```
pub fn serialize(&self) -> Result {
let buffer = alloc_c_string(&hex_from_bytes(&self.data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut output: *mut c_char = ptr::null_mut();
let error_code =
unsafe { CfdSerializeByteData(handle.as_handle(), buffer.as_ptr(), &mut output) };
@@ -429,7 +450,7 @@ impl Amount {
/// // byte_data == "a086010000000000"
/// ```
pub fn as_byte(&self) -> Result, CfdError> {
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut output: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdGetConfidentialValueHex(handle.as_handle(), self.satoshi_amount, true, &mut output)
@@ -519,8 +540,9 @@ impl FromStr for ReverseContainer {
} else {
let byte_data = ByteData::from_slice_reverse(&bytes);
let reverse_bytes = byte_data.to_slice();
- let mut data = ReverseContainer::default();
- data.data = copy_array_32byte(&reverse_bytes);
+ let data = ReverseContainer {
+ data: copy_array_32byte(&reverse_bytes),
+ };
Ok(data)
}
}
@@ -541,7 +563,7 @@ impl Default for ReverseContainer {
pub fn request_json(request: &str, option: &str) -> Result {
let req_name = alloc_c_string(request)?;
let opt_data = alloc_c_string(option)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut output: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdRequestExecuteJson(
@@ -607,19 +629,17 @@ impl ErrorHandle {
}
// FIXME: I might use Drop and Rc.
- pub fn free_handle(&self) -> bool {
+ pub fn free_handle(&mut self) -> bool {
unsafe {
let mut result: bool = false;
- if self.handle.is_null() {
- // println!("CfdFreeHandle NG. null-ptr.");
- } else {
+ if !self.handle.is_null() {
let cfd_ret = CfdFreeHandle(self.handle);
if cfd_ret == 0 {
- // self.handle = ptr::null_mut();
result = true;
} else {
println!("CfdFreeHandle NG:{}", cfd_ret);
}
+ self.handle = ptr::null_mut();
}
result
}
@@ -638,6 +658,7 @@ impl ErrorHandle {
5 => CfdError::Connection(err_msg),
6 => CfdError::DiskAccess(err_msg),
7 => CfdError::SignVerification(err_msg),
+ 8 => CfdError::NotFound(err_msg),
_ => CfdError::Unknown(err_msg),
}
}
diff --git a/src/confidential_address.rs b/src/confidential_address.rs
index d50aede..dbde83f 100644
--- a/src/confidential_address.rs
+++ b/src/confidential_address.rs
@@ -49,7 +49,7 @@ impl ConfidentialAddress {
) -> Result {
let addr = alloc_c_string(address.to_str())?;
let ct_key = alloc_c_string(&confidential_key.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut confidential_address: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdCreateConfidentialAddress(
@@ -88,7 +88,7 @@ impl ConfidentialAddress {
/// ```
pub fn parse(confidential_address: &str) -> Result {
let ct_addr = alloc_c_string(confidential_address)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut network_type_c: c_int = 0;
let mut address: *mut c_char = ptr::null_mut();
let mut confidential_key: *mut c_char = ptr::null_mut();
diff --git a/src/confidential_transaction.rs b/src/confidential_transaction.rs
index 702e0bb..4951ead 100644
--- a/src/confidential_transaction.rs
+++ b/src/confidential_transaction.rs
@@ -10,7 +10,7 @@ use crate::common::{
use crate::transaction::{
set_fund_tx_option, FeeData, FeeOption, FundOptionValue, FundTargetOption, FundTransactionData,
HashTypeData, OutPoint, ScriptWitness, SigHashOption, TransactionOperation, TxData, TxDataHandle,
- TxInData, Txid, UtxoData, SEQUENCE_LOCK_TIME_DISABLE,
+ TxInData, Txid, UtxoData, SEQUENCE_LOCK_TIME_FINAL,
};
use crate::{
address::{Address, HashType},
@@ -203,15 +203,17 @@ impl ConfidentialAsset {
)),
},
32 => {
- let mut asset_obj = ConfidentialAsset::default();
- asset_obj.data = get_commitment_from_byte(data, 32).to_vec();
+ let asset_obj = ConfidentialAsset {
+ data: get_commitment_from_byte(data, 32).to_vec(),
+ };
Ok(asset_obj)
}
33 => match data[0] {
0 => Ok(ConfidentialAsset::default()),
1 | 10 | 11 => {
- let mut asset_obj = ConfidentialAsset::default();
- asset_obj.data = get_commitment_from_byte(data, 32).to_vec();
+ let asset_obj = ConfidentialAsset {
+ data: get_commitment_from_byte(data, 32).to_vec(),
+ };
Ok(asset_obj)
}
_ => Err(CfdError::IllegalArgument(
@@ -236,17 +238,11 @@ impl ConfidentialAsset {
}
pub fn is_blind(&self) -> bool {
- match self.data[0] {
- 10 | 11 => true,
- _ => false,
- }
+ matches!(self.data[0], 10 | 11)
}
pub fn is_empty(&self) -> bool {
- match self.data[0] {
- 0 => true,
- _ => false,
- }
+ matches!(self.data[0], 0)
}
pub fn as_bytes(&self) -> Vec {
@@ -288,7 +284,7 @@ impl ConfidentialAsset {
}
let asset_str = alloc_c_string(&self.to_hex())?;
let abf_str = alloc_c_string(&asset_blind_factor.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut output: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdGetAssetCommitment(
@@ -377,15 +373,17 @@ impl ConfidentialNonce {
)),
},
32 => {
- let mut nonce_obj = ConfidentialNonce::default();
- nonce_obj.data = get_commitment_from_byte(data, 32).to_vec();
+ let nonce_obj = ConfidentialNonce {
+ data: get_commitment_from_byte(data, 32).to_vec(),
+ };
Ok(nonce_obj)
}
33 => match data[0] {
0 => Ok(ConfidentialNonce::default()),
1 | 2 | 3 => {
- let mut nonce_obj = ConfidentialNonce::default();
- nonce_obj.data = get_commitment_from_byte(data, 32).to_vec();
+ let nonce_obj = ConfidentialNonce {
+ data: get_commitment_from_byte(data, 32).to_vec(),
+ };
Ok(nonce_obj)
}
_ => Err(CfdError::IllegalArgument(
@@ -427,17 +425,11 @@ impl ConfidentialNonce {
}
pub fn is_blind(&self) -> bool {
- match self.data[0] {
- 2 | 3 => true,
- _ => false,
- }
+ matches!(self.data[0], 2 | 3)
}
pub fn is_empty(&self) -> bool {
- match self.data[0] {
- 0 => true,
- _ => false,
- }
+ matches!(self.data[0], 0)
}
pub fn as_bytes(&self) -> Vec {
@@ -507,9 +499,10 @@ impl ConfidentialValue {
)),
},
8 => {
- let mut value_obj = ConfidentialValue::default();
- value_obj.data = get_commitment_from_byte(data, 8).to_vec();
- value_obj.amount = ConfidentialValue::get_amount(data);
+ let value_obj = ConfidentialValue {
+ data: get_commitment_from_byte(data, 8).to_vec(),
+ amount: ConfidentialValue::get_amount(data),
+ };
Ok(value_obj)
}
9 | 33 => match data[0] {
@@ -520,8 +513,10 @@ impl ConfidentialValue {
"Invalid value version format.".to_string(),
))
} else {
- let mut value_obj = ConfidentialValue::default();
- value_obj.data = get_commitment_from_byte(data, 8).to_vec();
+ let mut value_obj = ConfidentialValue {
+ data: get_commitment_from_byte(data, 8).to_vec(),
+ ..ConfidentialValue::default()
+ };
if data[0] == 1 {
let unblind_data = get_byte_from_commitment(&value_obj.data, 8);
value_obj.amount = ConfidentialValue::get_amount(&unblind_data);
@@ -561,7 +556,7 @@ impl ConfidentialValue {
/// ```
pub fn from_amount(amount: i64) -> Result {
let data = {
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut output: *mut c_char = ptr::null_mut();
let error_code =
unsafe { CfdGetConfidentialValueHex(handle.as_handle(), amount, true, &mut output) };
@@ -575,9 +570,10 @@ impl ConfidentialValue {
handle.free_handle();
result
}?;
- let mut value_obj = ConfidentialValue::default();
- value_obj.data = get_commitment_from_byte(&data, 8).to_vec();
- value_obj.amount = amount;
+ let value_obj = ConfidentialValue {
+ data: get_commitment_from_byte(&data, 8).to_vec(),
+ amount,
+ };
Ok(value_obj)
}
@@ -590,17 +586,11 @@ impl ConfidentialValue {
}
pub fn is_blind(&self) -> bool {
- match self.data[0] {
- 8 | 9 => true,
- _ => false,
- }
+ matches!(self.data[0], 8 | 9)
}
pub fn is_empty(&self) -> bool {
- match self.data[0] {
- 0 => true,
- _ => false,
- }
+ matches!(self.data[0], 0)
}
pub fn as_bytes(&self) -> Vec {
@@ -646,7 +636,7 @@ impl ConfidentialValue {
}
let asset_str = alloc_c_string(&asset_commitment.as_str())?;
let vbf_str = alloc_c_string(&amount_blind_factor.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut output: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdGetValueCommitment(
@@ -719,7 +709,7 @@ pub fn get_issuance_blinding_key(
) -> Result {
let privkey = alloc_c_string(&master_blinding_key.to_hex())?;
let txid = alloc_c_string(&outpoint.get_txid().to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut output: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdGetIssuanceBlindingKey(
@@ -763,7 +753,7 @@ pub fn get_default_blinding_key(
) -> Result {
let privkey = alloc_c_string(&master_blinding_key.to_hex())?;
let script = alloc_c_string(&locking_script.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut output: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdGetDefaultBlindingKey(
@@ -1212,11 +1202,12 @@ impl ConfidentialTxOutData {
asset: &ConfidentialAsset,
address: &Address,
) -> ConfidentialTxOutData {
- let mut data = ConfidentialTxOutData::default();
- data.amount = amount;
- data.address = address.clone();
- data.asset = asset.clone();
- data
+ ConfidentialTxOutData {
+ amount,
+ address: address.clone(),
+ asset: asset.clone(),
+ ..ConfidentialTxOutData::default()
+ }
}
pub fn from_confidential_address(
@@ -1224,12 +1215,13 @@ impl ConfidentialTxOutData {
asset: &ConfidentialAsset,
confidential_address: &ConfidentialAddress,
) -> ConfidentialTxOutData {
- let mut data = ConfidentialTxOutData::default();
- data.amount = amount;
- data.address = confidential_address.get_address().clone();
- data.confidential_address = confidential_address.clone();
- data.asset = asset.clone();
- data
+ ConfidentialTxOutData {
+ amount,
+ address: confidential_address.get_address().clone(),
+ confidential_address: confidential_address.clone(),
+ asset: asset.clone(),
+ ..ConfidentialTxOutData::default()
+ }
}
pub fn from_locking_script(
@@ -1238,29 +1230,33 @@ impl ConfidentialTxOutData {
locking_script: &Script,
nonce: &ConfidentialNonce,
) -> ConfidentialTxOutData {
- let mut data = ConfidentialTxOutData::default();
- data.amount = amount;
- data.locking_script = locking_script.clone();
- data.nonce = nonce.clone();
- data.asset = asset.clone();
- data
+ ConfidentialTxOutData {
+ amount,
+ locking_script: locking_script.clone(),
+ nonce: nonce.clone(),
+ asset: asset.clone(),
+ ..ConfidentialTxOutData::default()
+ }
}
pub fn from_fee(amount: i64, asset: &ConfidentialAsset) -> ConfidentialTxOutData {
- let mut data = ConfidentialTxOutData::default();
- data.amount = amount;
- data.asset = asset.clone();
- data
+ ConfidentialTxOutData {
+ amount,
+ asset: asset.clone(),
+ ..ConfidentialTxOutData::default()
+ }
}
pub fn from_destroy_amount(
amount: i64,
asset: &ConfidentialAsset,
) -> Result {
- let mut data = ConfidentialTxOutData::default();
- data.amount = amount;
- data.asset = asset.clone();
- data.locking_script = Script::from_slice(&[0x6a])?;
+ let data = ConfidentialTxOutData {
+ amount,
+ asset: asset.clone(),
+ locking_script: Script::from_slice(&[0x6a])?,
+ ..ConfidentialTxOutData::default()
+ };
Ok(data)
}
@@ -1276,9 +1272,11 @@ impl ConfidentialTxOutData {
asset: &ConfidentialAsset,
amount: i64,
) -> Result {
- let mut txout = ConfidentialTxOutData::default();
- txout.asset = asset.clone();
- txout.amount = amount;
+ let mut txout = ConfidentialTxOutData {
+ asset: asset.clone(),
+ amount,
+ ..ConfidentialTxOutData::default()
+ };
let ct_addr_ret = ConfidentialAddress::parse(address);
if let Ok(ct_addr) = ct_addr_ret {
txout.confidential_address = ct_addr;
@@ -1312,9 +1310,27 @@ pub struct ConfidentialTxData {
impl Default for ConfidentialTxData {
fn default() -> ConfidentialTxData {
+ // default txid: version=2, locktime=0
+ let txid_value =
+ match Txid::from_str("c7e8a6e4ebd4981c43ff919703d54e91b4b3cb2325caf102dfc384bcad455c6f") {
+ Ok(_txid) => _txid,
+ _ => Txid::default(),
+ };
+ let wit_hash =
+ match Txid::from_str("d8a93718eaf9feba4362d2c091d4e58ccabe9f779957336269b4b917be9856da") {
+ Ok(_txid) => _txid,
+ _ => Txid::default(),
+ };
ConfidentialTxData {
- tx_data: TxData::default(),
- wit_hash: Txid::default(),
+ tx_data: TxData {
+ txid: txid_value.clone(),
+ wtxid: txid_value,
+ size: 11,
+ vsize: 11,
+ weight: 44,
+ ..TxData::default()
+ },
+ wit_hash,
}
}
}
@@ -1501,7 +1517,7 @@ impl Default for ConfidentialTxIn {
fn default() -> ConfidentialTxIn {
ConfidentialTxIn {
outpoint: OutPoint::default(),
- sequence: SEQUENCE_LOCK_TIME_DISABLE,
+ sequence: SEQUENCE_LOCK_TIME_FINAL,
script_sig: Script::default(),
issuance: Issuance::default(),
script_witness: ScriptWitness::default(),
@@ -1531,8 +1547,10 @@ impl ConfidentialTxOut {
} else {
&item.locking_script
};
- let mut txout = ConfidentialTxOut::default();
- txout.locking_script = script.clone();
+ let mut txout = ConfidentialTxOut {
+ locking_script: script.clone(),
+ ..ConfidentialTxOut::default()
+ };
if let Ok(value) = ConfidentialValue::from_amount(item.amount) {
txout.value = value;
}
@@ -2031,6 +2049,7 @@ impl ConfidentialTransaction {
true => ByteData::default(),
_ => value.as_byte_data(),
},
+ ..SigHashOption::default()
};
ope.create_sighash(
&hex_from_bytes(&self.tx),
@@ -2085,6 +2104,7 @@ impl ConfidentialTransaction {
true => ByteData::default(),
_ => value.as_byte_data(),
},
+ ..SigHashOption::default()
};
ope.create_sighash(
&hex_from_bytes(&self.tx),
@@ -2204,6 +2224,7 @@ impl ConfidentialTransaction {
true => ByteData::default(),
_ => value.as_byte_data(),
},
+ ..SigHashOption::default()
};
let tx = ope.sign_with_privkey(&tx_hex, outpoint, hash_type, &key, &option, true)?;
let new_tx_hex = ope.get_last_tx();
@@ -2462,6 +2483,7 @@ impl ConfidentialTransaction {
true => ByteData::default(),
_ => value.as_byte_data(),
},
+ ..SigHashOption::default()
};
let key = HashTypeData::from_pubkey(pubkey);
ope.verify_signature(
@@ -2522,6 +2544,7 @@ impl ConfidentialTransaction {
true => ByteData::default(),
_ => value.as_byte_data(),
},
+ ..SigHashOption::default()
};
let key = HashTypeData::new(pubkey, redeem_script);
ope.verify_signature(
@@ -2577,6 +2600,7 @@ impl ConfidentialTransaction {
true => ByteData::default(),
_ => value.as_byte_data(),
},
+ ..SigHashOption::default()
};
ope.verify_sign(
&hex_from_bytes(&self.tx),
@@ -2633,6 +2657,7 @@ impl ConfidentialTransaction {
true => ByteData::default(),
_ => value.as_byte_data(),
},
+ ..SigHashOption::default()
};
ope.verify_sign(
&hex_from_bytes(&self.tx),
@@ -2751,14 +2776,11 @@ impl FromStr for ConfidentialTransaction {
impl Default for ConfidentialTransaction {
fn default() -> ConfidentialTransaction {
- match ConfidentialTransaction::new(2, 0) {
- Ok(tx) => tx,
- _ => ConfidentialTransaction {
- tx: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].to_vec(),
- data: ConfidentialTxData::default(),
- txin_list: vec![],
- txout_list: vec![],
- },
+ ConfidentialTransaction {
+ tx: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].to_vec(),
+ data: ConfidentialTxData::default(),
+ txin_list: vec![],
+ txout_list: vec![],
}
}
}
@@ -2816,7 +2838,7 @@ impl ConfidentialTxOperation {
// set_blind_tx_option
let tx_str = alloc_c_string(tx)?;
let empty_str = alloc_c_string("")?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut blind_handle: *mut c_void = ptr::null_mut();
let error_code = unsafe { CfdInitializeBlindTx(handle.as_handle(), &mut blind_handle) };
let result = match error_code {
@@ -3023,7 +3045,7 @@ impl ConfidentialTxOperation {
) -> Result {
let tx_str = alloc_c_string(tx)?;
let privkey = alloc_c_string(&blinding_key.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut asset_value: c_longlong = 0;
let mut asset: *mut c_char = ptr::null_mut();
let mut asset_abf: *mut c_char = ptr::null_mut();
@@ -3067,7 +3089,7 @@ impl ConfidentialTxOperation {
let tx_str = alloc_c_string(tx)?;
let asset_key = alloc_c_string(&asset_blinding_key.to_hex())?;
let token_key = alloc_c_string(&token_blinding_key.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut asset_value: c_longlong = 0;
let mut token_value: c_longlong = 0;
let mut asset: *mut c_char = ptr::null_mut();
@@ -3137,7 +3159,7 @@ impl ConfidentialTxOperation {
let entropy_hex = alloc_c_string(&entropy.to_hex())?;
let address = alloc_c_string(send_address)?;
let empty_str = alloc_c_string("")?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut asset: *mut c_char = ptr::null_mut();
let mut output: *mut c_char = ptr::null_mut();
let error_code = unsafe {
@@ -3194,7 +3216,7 @@ impl ConfidentialTxOperation {
amount: i64,
) -> Result, CfdError> {
let tx_str = alloc_c_string(tx)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut output: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdUpdateTxOutAmount(
@@ -3220,7 +3242,7 @@ impl ConfidentialTxOperation {
pub fn update_fee_amount(&mut self, tx: &str, amount: i64) -> Result, CfdError> {
let tx_str = alloc_c_string(tx)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let result = {
let index = {
let mut index: c_uint = 0;
@@ -3266,7 +3288,7 @@ impl ConfidentialTxOperation {
}
pub fn get_all_data(&mut self, tx: &str) -> Result {
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let result = {
let tx_handle = TxDataHandle::new(&handle, &self.network, tx)?;
let tx_result = {
@@ -3312,7 +3334,7 @@ impl ConfidentialTxOperation {
}
pub fn get_tx_data(&self, tx: &str) -> Result {
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let result = self.get_tx_data_internal(&handle, &TxDataHandle::empty(), tx);
handle.free_handle();
result
@@ -3370,7 +3392,7 @@ impl ConfidentialTxOperation {
tx: &str,
outpoint: &OutPoint,
) -> Result {
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let result = {
let tx_data_handle = TxDataHandle::new(&handle, &self.network, tx)?;
let list_result = {
@@ -3573,7 +3595,7 @@ impl ConfidentialTxOperation {
let value_commitment = alloc_c_string(&option.value_byte.to_hex())?;
let amount = option.amount;
let sighash_type = option.sighash_type;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut output: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdCreateConfidentialSighash(
@@ -3616,7 +3638,7 @@ impl ConfidentialTxOperation {
let pubkey_hex = alloc_c_string(&key.to_pubkey().to_hex())?;
let privkey_hex = alloc_c_string(&key.to_privkey().to_hex())?;
let value_hex = alloc_c_string(&option.value_byte.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let sighash_type = option.sighash_type;
let mut output: *mut c_char = ptr::null_mut();
let error_code = unsafe {
@@ -3657,7 +3679,7 @@ impl ConfidentialTxOperation {
) -> Result {
let tx_str = alloc_c_string(tx)?;
let fee_asset = alloc_c_string(&option.fee_asset.get_unblind_asset()?)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut fee_handle: *mut c_void = ptr::null_mut();
let error_code = unsafe {
CfdInitializeEstimateFee(
@@ -3748,7 +3770,7 @@ impl ConfidentialTxOperation {
fee_param: &FeeOption,
) -> Result {
let fee_asset = alloc_c_string(&fee_param.fee_asset.get_unblind_asset()?)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut coin_handle: *mut c_void = ptr::null_mut();
let error_code = unsafe {
CfdInitializeCoinSelection(
@@ -3921,7 +3943,7 @@ impl ConfidentialTxOperation {
};
let tx_hex = alloc_c_string(tx)?;
let fee_asset = alloc_c_string(&fee_param.fee_asset.get_unblind_asset()?)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut fund_handle: *mut c_void = ptr::null_mut();
let error_code = unsafe {
CfdInitializeFundRawTx(
@@ -4179,7 +4201,7 @@ impl ConfidentialTxOperation {
txout_list: &[ConfidentialTxOutData],
) -> Result, CfdError> {
let tx_str = alloc_c_string(tx)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut create_handle: *mut c_void = ptr::null_mut();
let error_code = unsafe {
CfdInitializeTransaction(
diff --git a/src/descriptor.rs b/src/descriptor.rs
index 3a69577..99faa0b 100644
--- a/src/descriptor.rs
+++ b/src/descriptor.rs
@@ -224,20 +224,22 @@ pub struct DescriptorScriptData {
impl DescriptorScriptData {
pub fn from_raw_script(depth: u32, redeem_script: &Script) -> DescriptorScriptData {
- let mut obj = DescriptorScriptData::default();
- obj.script_type = DescriptorScriptType::Raw;
- obj.depth = depth;
- obj.redeem_script = redeem_script.clone();
- obj
+ DescriptorScriptData {
+ script_type: DescriptorScriptType::Raw,
+ depth,
+ redeem_script: redeem_script.clone(),
+ ..DescriptorScriptData::default()
+ }
}
pub fn from_address(depth: u32, hash_type: &HashType, address: &Address) -> DescriptorScriptData {
- let mut obj = DescriptorScriptData::default();
- obj.script_type = DescriptorScriptType::Addr;
- obj.depth = depth;
- obj.hash_type = *hash_type;
- obj.address = address.clone();
- obj
+ DescriptorScriptData {
+ script_type: DescriptorScriptType::Addr,
+ depth,
+ hash_type: *hash_type,
+ address: address.clone(),
+ ..DescriptorScriptData::default()
+ }
}
pub fn from_pubkey(
@@ -247,13 +249,14 @@ impl DescriptorScriptData {
address: Address,
key_data: KeyData,
) -> DescriptorScriptData {
- let mut obj = DescriptorScriptData::default();
- obj.script_type = script_type;
- obj.depth = depth;
- obj.hash_type = hash_type;
- obj.address = address;
- obj.key_data = key_data;
- obj
+ DescriptorScriptData {
+ script_type,
+ depth,
+ hash_type,
+ address,
+ key_data,
+ ..DescriptorScriptData::default()
+ }
}
pub fn from_script(
@@ -263,13 +266,14 @@ impl DescriptorScriptData {
address: Address,
script: Script,
) -> DescriptorScriptData {
- let mut obj = DescriptorScriptData::default();
- obj.script_type = script_type;
- obj.depth = depth;
- obj.hash_type = hash_type;
- obj.address = address;
- obj.redeem_script = script;
- obj
+ DescriptorScriptData {
+ script_type,
+ depth,
+ hash_type,
+ address,
+ redeem_script: script,
+ ..DescriptorScriptData::default()
+ }
}
pub fn from_key_and_script(
@@ -656,7 +660,7 @@ impl Descriptor {
) -> Result {
let descriptor_str = alloc_c_string(descriptor)?;
let bip32_path_str = alloc_c_string(bip32_path)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut max_num: c_uint = 0;
let mut descriptor_handle: *mut c_void = ptr::null_mut();
let error_code = unsafe {
@@ -883,10 +887,12 @@ impl Descriptor {
/// ```
pub fn has_script_hash(&self) -> bool {
match self.root_data.script_type {
- DescriptorScriptType::Sh | DescriptorScriptType::Wsh => match self.root_data.hash_type {
- HashType::P2sh | HashType::P2wsh | HashType::P2shP2wsh => true,
- _ => false,
- },
+ DescriptorScriptType::Sh | DescriptorScriptType::Wsh => {
+ matches!(
+ self.root_data.hash_type,
+ HashType::P2sh | HashType::P2wsh | HashType::P2shP2wsh
+ )
+ }
_ => false,
}
}
@@ -917,10 +923,12 @@ impl Descriptor {
DescriptorScriptType::Sh
| DescriptorScriptType::Pkh
| DescriptorScriptType::Wpkh
- | DescriptorScriptType::Combo => match self.root_data.hash_type {
- HashType::P2pkh | HashType::P2wpkh | HashType::P2shP2wpkh => true,
- _ => false,
- },
+ | DescriptorScriptType::Combo => {
+ matches!(
+ self.root_data.hash_type,
+ HashType::P2pkh | HashType::P2wpkh | HashType::P2shP2wpkh
+ )
+ }
_ => false,
}
}
@@ -965,7 +973,7 @@ impl Descriptor {
fn append_checksum(descriptor: &str, network_type: &Network) -> Result {
let descriptor_str = alloc_c_string(descriptor)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut desc_added_checksum: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdGetDescriptorChecksum(
diff --git a/src/hdwallet.rs b/src/hdwallet.rs
index d516dec..a5acff1 100644
--- a/src/hdwallet.rs
+++ b/src/hdwallet.rs
@@ -67,7 +67,7 @@ pub struct ExtKey {
fn generate_pubkey(extkey: &str, network_type: Network) -> Result {
let extkey_str = alloc_c_string(extkey)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut pubkey_hex: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdGetPubkeyFromExtkey(
@@ -90,7 +90,7 @@ fn generate_pubkey(extkey: &str, network_type: Network) -> Result Result {
let extkey_str = alloc_c_string(extkey)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut privkey_hex: *mut c_char = ptr::null_mut();
let mut wif: *mut c_char = ptr::null_mut();
let error_code = unsafe {
@@ -117,7 +117,7 @@ fn generate_privkey(extkey: &str, network_type: Network) -> Result Result {
let extkey_str = alloc_c_string(extkey)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut version: *mut c_char = ptr::null_mut();
let mut fingerprint: *mut c_char = ptr::null_mut();
let mut chain_code: *mut c_char = ptr::null_mut();
@@ -176,7 +176,7 @@ impl ExtKey {
key_type: &ExtKeyType,
) -> Result {
let extkey_str = alloc_c_string(&self.extkey)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut extkey_hex: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdCreateExtkeyFromParent(
@@ -222,7 +222,7 @@ impl ExtKey {
) -> Result {
let extkey_str = alloc_c_string(&self.extkey)?;
let path_str = alloc_c_string(path)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut extkey_hex: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdCreateExtkeyFromParentPath(
@@ -324,7 +324,7 @@ impl ExtPrivkey {
/// ```
pub fn from_seed(seed: &[u8], network_type: &Network) -> Result {
let seed_str = alloc_c_string(&hex_from_bytes(seed))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut extkey_hex: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdCreateExtkeyFromSeed(
@@ -448,7 +448,7 @@ impl ExtPrivkey {
/// ```
pub fn get_ext_pubkey(&self) -> Result {
let extkey_str = alloc_c_string(&self.extkey.to_str())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut ext_pubkey_hex: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdCreateExtPubkey(
@@ -739,7 +739,7 @@ impl ExtPubkey {
}?;
let pubkey_hex = alloc_c_string(&pubkey.to_hex())?;
let chain_code_hex = alloc_c_string(&chain_code.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut extkey: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdCreateExtkey(
@@ -975,7 +975,7 @@ impl HDWallet {
/// ```
pub fn mnemonic_word_list(lang: MnemonicLanguage) -> Result, CfdError> {
let language = alloc_c_string(&lang.to_str())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut max_num: c_uint = 0;
let mut mnemonic_handle: *mut c_void = ptr::null_mut();
let error_code = unsafe {
@@ -1047,7 +1047,7 @@ impl HDWallet {
pub fn mnemonic_from_entropy(entropy: &[u8], lang: MnemonicLanguage) -> Result {
let entropy_hex = alloc_c_string(&hex_from_bytes(&entropy))?;
let language = alloc_c_string(&lang.to_str())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut mnemonic: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdConvertEntropyToMnemonic(
@@ -1088,7 +1088,7 @@ impl HDWallet {
let passphrase = alloc_c_string("")?;
let language = alloc_c_string(&lang.to_str())?;
let mnemonic_str = alloc_c_string(&tmp_mnemonic)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut seed: *mut c_char = ptr::null_mut();
let mut entropy: *mut c_char = ptr::null_mut();
let error_code = unsafe {
@@ -1160,7 +1160,7 @@ impl HDWallet {
let passphrase = alloc_c_string(passphrase)?;
let language = alloc_c_string(&lang.to_str())?;
let mnemonic_str = alloc_c_string(&tmp_mnemonic)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut seed: *mut c_char = ptr::null_mut();
let mut entropy: *mut c_char = ptr::null_mut();
let error_code = unsafe {
diff --git a/src/key.rs b/src/key.rs
index 77c917f..dab46fc 100644
--- a/src/key.rs
+++ b/src/key.rs
@@ -13,9 +13,9 @@ use std::result::Result::{Err, Ok};
use std::str::FromStr;
use self::cfd_sys::{
- CfdAddCombinePubkey, CfdCalculateEcSignature, CfdCompressPubkey, CfdCreateKeyPair,
- CfdDecodeSignatureFromDer, CfdEncodeSignatureByDer, CfdFinalizeCombinePubkey,
- CfdFreeCombinePubkeyHandle, CfdGetPrivkeyWif, CfdGetPubkeyFromPrivkey,
+ CfdAddCombinePubkey, CfdAddSighashTypeInSchnorrSignature, CfdCalculateEcSignature,
+ CfdCompressPubkey, CfdCreateKeyPair, CfdDecodeSignatureFromDer, CfdEncodeSignatureByDer,
+ CfdFinalizeCombinePubkey, CfdFreeCombinePubkeyHandle, CfdGetPrivkeyWif, CfdGetPubkeyFromPrivkey,
CfdInitializeCombinePubkey, CfdNegatePrivkey, CfdNegatePubkey, CfdNormalizeSignature,
CfdParsePrivkeyWif, CfdPrivkeyTweakAdd, CfdPrivkeyTweakMul, CfdPubkeyTweakAdd, CfdPubkeyTweakMul,
CfdUncompressPubkey, CfdVerifyEcSignature,
@@ -100,7 +100,7 @@ impl Privkey {
/// ```
pub fn from_wif(wif: &str) -> Result {
let wif_str = alloc_c_string(wif)?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut privkey_hex: *mut c_char = ptr::null_mut();
let mut is_compressed = true;
let mut network_type: c_int = 0;
@@ -142,7 +142,7 @@ impl Privkey {
/// let key = Privkey::generate(&Network::Mainnet, true).expect("Fail");
/// ```
pub fn generate(network_type: &Network, is_compressed: bool) -> Result {
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut pubkey_hex: *mut c_char = ptr::null_mut();
let mut privkey_hex: *mut c_char = ptr::null_mut();
let mut wif: *mut c_char = ptr::null_mut();
@@ -191,7 +191,7 @@ impl Privkey {
pub fn tweak_add(&self, data: &[u8]) -> Result {
let privkey = alloc_c_string(&hex_from_bytes(&self.key))?;
let tweak = alloc_c_string(&hex_from_bytes(data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut tweak_privkey: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdPrivkeyTweakAdd(
@@ -230,7 +230,7 @@ impl Privkey {
pub fn tweak_mul(&self, data: &[u8]) -> Result {
let privkey = alloc_c_string(&hex_from_bytes(&self.key))?;
let tweak = alloc_c_string(&hex_from_bytes(data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut tweak_privkey: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdPrivkeyTweakMul(
@@ -264,7 +264,7 @@ impl Privkey {
/// ```
pub fn negate(&self) -> Result {
let privkey = alloc_c_string(&hex_from_bytes(&self.key))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut negate_privkey: *mut c_char = ptr::null_mut();
let error_code =
unsafe { CfdNegatePrivkey(handle.as_handle(), privkey.as_ptr(), &mut negate_privkey) };
@@ -362,7 +362,7 @@ impl Privkey {
return Ok(self.to_wif().to_string());
}
let privkey = alloc_c_string(&self.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut wif: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdGetPrivkeyWif(
@@ -410,7 +410,7 @@ impl Privkey {
/// ```
pub fn generate_pubkey(key: &[u8], is_compressed: bool) -> Result {
let privkey = alloc_c_string(&hex_from_bytes(key))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let wif: *const i8 = ptr::null();
let mut pubkey: *mut c_char = ptr::null_mut();
let error_code = unsafe {
@@ -455,7 +455,7 @@ impl Privkey {
) -> Result {
let signature_hash = alloc_c_string(&hex_from_bytes(sighash))?;
let privkey = alloc_c_string(&hex_from_bytes(&self.key))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let wif: *const i8 = ptr::null();
let network_type: c_int = 0;
let mut signature_hex: *mut c_char = ptr::null_mut();
@@ -641,7 +641,7 @@ impl Pubkey {
/// ```
pub fn compress(&self) -> Result {
let pubkey = alloc_c_string(&self.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut compressed_pubkey: *mut c_char = ptr::null_mut();
let error_code =
unsafe { CfdCompressPubkey(handle.as_handle(), pubkey.as_ptr(), &mut compressed_pubkey) };
@@ -671,7 +671,7 @@ impl Pubkey {
/// ```
pub fn uncompress(&self) -> Result {
let pubkey = alloc_c_string(&self.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut decompressed_pubkey: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdUncompressPubkey(
@@ -711,7 +711,7 @@ impl Pubkey {
pub fn tweak_add(&self, data: &[u8]) -> Result {
let pubkey = alloc_c_string(&hex_from_bytes(&self.key))?;
let tweak = alloc_c_string(&hex_from_bytes(data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut tweak_pubkey: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdPubkeyTweakAdd(
@@ -750,7 +750,7 @@ impl Pubkey {
pub fn tweak_mul(&self, data: &[u8]) -> Result {
let pubkey = alloc_c_string(&hex_from_bytes(&self.key))?;
let tweak = alloc_c_string(&hex_from_bytes(data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut tweak_pubkey: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdPubkeyTweakMul(
@@ -784,7 +784,7 @@ impl Pubkey {
/// ```
pub fn negate(&self) -> Result {
let pubkey = alloc_c_string(&hex_from_bytes(&self.key))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut negate_pubkey: *mut c_char = ptr::null_mut();
let error_code =
unsafe { CfdNegatePubkey(handle.as_handle(), pubkey.as_ptr(), &mut negate_pubkey) };
@@ -824,7 +824,7 @@ impl Pubkey {
return Ok(pubkey_list[0].clone());
}
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut combine_handle: *mut c_void = ptr::null_mut();
let error_code: i32 =
unsafe { CfdInitializeCombinePubkey(handle.as_handle(), &mut combine_handle) };
@@ -887,7 +887,7 @@ impl Pubkey {
let pubkey = alloc_c_string(&self.to_hex())?;
let sighash_hex = alloc_c_string(&hex_from_bytes(sighash))?;
let signature_hex = alloc_c_string(&hex_from_bytes(signature))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let error_code = unsafe {
CfdVerifyEcSignature(
handle.as_handle(),
@@ -938,10 +938,7 @@ impl Pubkey {
/// ```
#[inline]
pub fn valid(&self) -> bool {
- match self.compress() {
- Ok(_result) => true,
- _ => false,
- }
+ matches!(self.compress(), Ok(_result))
}
}
@@ -1020,6 +1017,8 @@ impl Default for KeyPair {
/// An enumeration definition of signature hash type.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum SigHashType {
+ /// SigHashType::Default
+ Default,
/// SigHashType::All
All,
/// SigHashType::None
@@ -1056,12 +1055,14 @@ impl SigHashType {
SigHashType::Single | SigHashType::SinglePlusAnyoneCanPay => {
SigHashType::SinglePlusAnyoneCanPay
}
+ SigHashType::Default => SigHashType::Default,
}
} else {
match sighash_type {
SigHashType::All | SigHashType::AllPlusAnyoneCanPay => SigHashType::All,
SigHashType::None | SigHashType::NonePlusAnyoneCanPay => SigHashType::None,
SigHashType::Single | SigHashType::SinglePlusAnyoneCanPay => SigHashType::Single,
+ SigHashType::Default => SigHashType::Default,
}
}
}
@@ -1081,12 +1082,13 @@ impl SigHashType {
SigHashType::AllPlusAnyoneCanPay
| SigHashType::NonePlusAnyoneCanPay
| SigHashType::SinglePlusAnyoneCanPay => true,
- SigHashType::All | SigHashType::None | SigHashType::Single => false,
+ SigHashType::All | SigHashType::None | SigHashType::Single | SigHashType::Default => false,
}
}
pub(in crate) fn from_c_value(sighash_type: c_int) -> SigHashType {
match sighash_type {
+ 0 => SigHashType::Default,
1 => SigHashType::All,
2 => SigHashType::None,
3 => SigHashType::Single,
@@ -1096,6 +1098,7 @@ impl SigHashType {
pub(in crate) fn to_c_value(&self) -> c_int {
match self {
+ SigHashType::Default => 0,
SigHashType::All | SigHashType::AllPlusAnyoneCanPay => 1,
SigHashType::None | SigHashType::NonePlusAnyoneCanPay => 2,
SigHashType::Single | SigHashType::SinglePlusAnyoneCanPay => 3,
@@ -1106,6 +1109,7 @@ impl SigHashType {
impl fmt::Display for SigHashType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let _ = match *self {
+ SigHashType::Default => write!(f, "sighashType:Default"),
SigHashType::All | SigHashType::AllPlusAnyoneCanPay => write!(f, "sighashType:All"),
SigHashType::None | SigHashType::NonePlusAnyoneCanPay => write!(f, "sighashType:None"),
SigHashType::Single | SigHashType::SinglePlusAnyoneCanPay => write!(f, "sighashType:Single"),
@@ -1143,7 +1147,7 @@ impl SignParameter {
pub fn from_slice(data: &[u8]) -> SignParameter {
SignParameter {
data: data.to_vec(),
- sighash_type: SigHashType::All,
+ sighash_type: SigHashType::Default,
pubkey: Pubkey::default(),
use_der_encode: false,
}
@@ -1287,7 +1291,7 @@ impl SignParameter {
/// ```
pub fn normalize(&self) -> Result {
let signature_hex = alloc_c_string(&hex_from_bytes(&self.data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut normalize_signature: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdNormalizeSignature(
@@ -1318,15 +1322,19 @@ impl SignParameter {
/// let der_encoded_sig = signature.to_der_encode().expect("Fail");
/// ```
pub fn to_der_encode(&self) -> Result {
+ let sighashtype = match self.sighash_type {
+ SigHashType::Default => SigHashType::All,
+ _ => self.sighash_type,
+ };
let signature_hex = alloc_c_string(&hex_from_bytes(&self.data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut der_signature: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdEncodeSignatureByDer(
handle.as_handle(),
signature_hex.as_ptr(),
- self.sighash_type.to_c_value(),
- self.sighash_type.is_anyone_can_pay(),
+ sighashtype.to_c_value(),
+ sighashtype.is_anyone_can_pay(),
&mut der_signature,
)
};
@@ -1334,7 +1342,7 @@ impl SignParameter {
0 => {
let der_encoded = unsafe { collect_cstring_and_free(der_signature) }?;
let mut sig = SignParameter::from_vec(byte_from_hex_unsafe(&der_encoded));
- sig.sighash_type = self.sighash_type;
+ sig.sighash_type = sighashtype;
Ok(sig)
}
_ => Err(handle.get_error(error_code)),
@@ -1355,7 +1363,7 @@ impl SignParameter {
/// ```
pub fn to_der_decode(&self) -> Result {
let signature_hex = alloc_c_string(&hex_from_bytes(&self.data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut signature: *mut c_char = ptr::null_mut();
let mut sighash_type_value: c_int = 0;
let mut is_anyone_can_pay = false;
@@ -1380,6 +1388,36 @@ impl SignParameter {
handle.free_handle();
result
}
+
+ pub fn append_taproot_sighash_type(&self) -> Result {
+ if self.data.len() != 64 || self.sighash_type == SigHashType::Default {
+ Ok(self.clone())
+ } else {
+ let signature_hex = alloc_c_string(&hex_from_bytes(&self.data))?;
+ let mut handle = ErrorHandle::new()?;
+ let mut added_signature: *mut c_char = ptr::null_mut();
+ let error_code = unsafe {
+ CfdAddSighashTypeInSchnorrSignature(
+ handle.as_handle(),
+ signature_hex.as_ptr(),
+ self.sighash_type.to_c_value(),
+ self.sighash_type.is_anyone_can_pay(),
+ &mut added_signature,
+ )
+ };
+ let result = match error_code {
+ 0 => {
+ let sig = unsafe { collect_cstring_and_free(added_signature) }?;
+ let mut sig = SignParameter::from_vec(byte_from_hex_unsafe(&sig));
+ sig.sighash_type = self.sighash_type;
+ Ok(sig)
+ }
+ _ => Err(handle.get_error(error_code)),
+ };
+ handle.free_handle();
+ result
+ }
+ }
}
impl fmt::Display for SignParameter {
diff --git a/src/lib.rs b/src/lib.rs
index 57af338..0006ffd 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -82,6 +82,10 @@ pub use schnorr::SCHNORR_NONCE_SIZE;
pub use schnorr::SCHNORR_SIGNATURE_SIZE;
pub use script::Script;
+pub use script::TapBranch;
+pub use script::TAPROOT_HASH_SIZE;
+pub use script::TAPSCRIPT_LEAF_VERSION;
+
pub use transaction::CoinSelectionData;
pub use transaction::FeeData;
pub use transaction::FeeOption;
@@ -97,5 +101,7 @@ pub use transaction::TxOut;
pub use transaction::TxOutData;
pub use transaction::Txid;
pub use transaction::UtxoData;
-pub use transaction::SEQUENCE_LOCK_TIME_DISABLE;
+pub use transaction::CODE_SEPARATOR_POSITION_FINAL;
pub use transaction::SEQUENCE_LOCK_TIME_ENABLE_MAX;
+pub use transaction::SEQUENCE_LOCK_TIME_FINAL;
+pub use transaction::TXID_SIZE;
diff --git a/src/schnorr.rs b/src/schnorr.rs
index 04ebe2e..f1aff1f 100644
--- a/src/schnorr.rs
+++ b/src/schnorr.rs
@@ -6,7 +6,7 @@ use crate::common::{
alloc_c_string, byte_from_hex, collect_cstring_and_free, collect_multi_cstring_and_free,
copy_array_32byte, hex_from_bytes, ByteData, CfdError, ErrorHandle,
};
-use crate::key::{Privkey, Pubkey};
+use crate::key::{Privkey, Pubkey, SigHashType, SignParameter};
use std::fmt;
use std::ptr;
use std::result::Result::{Err, Ok};
@@ -235,7 +235,7 @@ impl EcdsaAdaptorUtil {
let msg_hex = alloc_c_string(&msg.to_hex())?;
let sk_hex = alloc_c_string(&secret_key.to_hex())?;
let adaptor_hex = alloc_c_string(&adaptor.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut signature: *mut c_char = ptr::null_mut();
let mut proof: *mut c_char = ptr::null_mut();
let error_code = unsafe {
@@ -287,7 +287,7 @@ impl EcdsaAdaptorUtil {
) -> Result {
let sig_hex = alloc_c_string(&adaptor_signature.to_hex())?;
let sk_hex = alloc_c_string(&adaptor_secret.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut signature: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdAdaptEcdsaAdaptor(
@@ -335,7 +335,7 @@ impl EcdsaAdaptorUtil {
let adaptor_sig_hex = alloc_c_string(&adaptor_signature.to_hex())?;
let sig_hex = alloc_c_string(&signature.to_hex())?;
let adaptor_hex = alloc_c_string(&adaptor.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut secret: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdExtractEcdsaAdaptorSecret(
@@ -392,7 +392,7 @@ impl EcdsaAdaptorUtil {
let adaptor_hex = alloc_c_string(&adaptor.to_hex())?;
let msg_hex = alloc_c_string(&msg.to_hex())?;
let pubkey_hex = alloc_c_string(&pubkey.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let error_code = unsafe {
CfdVerifyEcdsaAdaptor(
handle.as_handle(),
@@ -463,7 +463,7 @@ impl SchnorrSignature {
));
}
let signature_hex = alloc_c_string(&hex_from_bytes(&data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut nonce_hex: *mut c_char = ptr::null_mut();
let mut key_hex: *mut c_char = ptr::null_mut();
let error_code = unsafe {
@@ -511,6 +511,23 @@ impl SchnorrSignature {
pub fn as_key(&self) -> &Privkey {
&self.key
}
+
+ /// Get sign parameter.
+ ///
+ /// # Arguments
+ /// * `sighash_type` - A signature hash type.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use cfd_rust::{SchnorrSignature, SigHashType};
+ /// let bytes = [2; 64];
+ /// let sig = SchnorrSignature::from_vec(bytes.to_vec()).expect("Fail");
+ /// let sign_param = sig.get_sign_parameter(&SigHashType::All);
+ /// ```
+ pub fn get_sign_parameter(&self, sighash_type: &SigHashType) -> SignParameter {
+ SignParameter::from_slice(&self.data).set_signature_hash(sighash_type)
+ }
}
impl fmt::Display for SchnorrSignature {
@@ -596,7 +613,7 @@ impl SchnorrPubkey {
/// ```
pub fn from_privkey(key: &Privkey) -> Result<(SchnorrPubkey, bool), CfdError> {
let key_hex = alloc_c_string(&key.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut pubkey_hex: *mut c_char = ptr::null_mut();
let mut parity = false;
let error_code = unsafe {
@@ -635,7 +652,7 @@ impl SchnorrPubkey {
/// ```
pub fn from_pubkey(key: &Pubkey) -> Result<(SchnorrPubkey, bool), CfdError> {
let key_hex = alloc_c_string(&key.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut pubkey_hex: *mut c_char = ptr::null_mut();
let mut parity = false;
let error_code = unsafe {
@@ -680,7 +697,7 @@ impl SchnorrPubkey {
) -> Result<(SchnorrPubkey, bool, Privkey), CfdError> {
let key_hex = alloc_c_string(&key.to_hex())?;
let tweak_hex = alloc_c_string(&hex_from_bytes(data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut pubkey_hex: *mut c_char = ptr::null_mut();
let mut privkey_hex: *mut c_char = ptr::null_mut();
let mut parity = false;
@@ -744,7 +761,7 @@ impl SchnorrPubkey {
pub fn tweak_add(&self, data: &[u8]) -> Result<(SchnorrPubkey, bool), CfdError> {
let key_hex = alloc_c_string(&self.to_hex())?;
let tweak_hex = alloc_c_string(&hex_from_bytes(data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut pubkey_hex: *mut c_char = ptr::null_mut();
let mut parity = false;
let error_code = unsafe {
@@ -792,7 +809,7 @@ impl SchnorrPubkey {
let key_hex = alloc_c_string(&self.to_hex())?;
let base_key_hex = alloc_c_string(&base_pubkey.to_hex())?;
let tweak_hex = alloc_c_string(&hex_from_bytes(data))?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let error_code = unsafe {
CfdCheckTweakAddFromSchnorrPubkey(
handle.as_handle(),
@@ -873,7 +890,7 @@ impl SchnorrUtil {
let msg_hex = alloc_c_string(&msg.to_hex())?;
let sk_hex = alloc_c_string(&secret_key.to_hex())?;
let rand_hex = alloc_c_string(&aux_rand.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut signature: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdSignSchnorr(
@@ -922,7 +939,7 @@ impl SchnorrUtil {
let msg_hex = alloc_c_string(&msg.to_hex())?;
let sk_hex = alloc_c_string(&secret_key.to_hex())?;
let nonce_hex = alloc_c_string(&nonce.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut signature: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdSignSchnorrWithNonce(
@@ -971,7 +988,7 @@ impl SchnorrUtil {
let msg_hex = alloc_c_string(&msg.to_hex())?;
let nonce_hex = alloc_c_string(&nonce.to_hex())?;
let pubkey_hex = alloc_c_string(&pubkey.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let mut sig_point: *mut c_char = ptr::null_mut();
let error_code = unsafe {
CfdComputeSchnorrSigPoint(
@@ -1020,7 +1037,7 @@ impl SchnorrUtil {
let sig_hex = alloc_c_string(&signature.to_hex())?;
let msg_hex = alloc_c_string(&msg.to_hex())?;
let pubkey_hex = alloc_c_string(&pubkey.to_hex())?;
- let handle = ErrorHandle::new()?;
+ let mut handle = ErrorHandle::new()?;
let error_code = unsafe {
CfdVerifySchnorr(
handle.as_handle(),
diff --git a/src/script.rs b/src/script.rs
index ae13784..2d16a69 100644
--- a/src/script.rs
+++ b/src/script.rs
@@ -1,25 +1,37 @@
extern crate cfd_sys;
extern crate libc;
-use self::libc::{c_char, c_int, c_uint, c_void};
+use self::libc::{c_char, c_int, c_uchar, c_uint, c_void};
use crate::common::{
alloc_c_string, byte_from_hex, byte_from_hex_unsafe, collect_cstring_and_free,
- collect_multi_cstring_and_free, hex_from_bytes, ErrorHandle,
+ collect_multi_cstring_and_free, copy_array_32byte, hex_from_bytes, ErrorHandle,
};
use crate::{
- common::{ByteData, CfdError},
- key::Pubkey,
+ address::Address,
+ common::{ByteData, CfdError, Network},
+ key::{Privkey, Pubkey},
+ schnorr::SchnorrPubkey,
};
use std::fmt;
use std::ptr;
use std::result::Result::{Err, Ok};
+use std::str::FromStr;
use self::cfd_sys::{
- CfdAddMultisigScriptData, CfdConvertScriptAsmToHex, CfdFinalizeMultisigScript,
- CfdFreeMultisigScriptHandle, CfdFreeScriptItemHandle, CfdGetScriptItem,
- CfdInitializeMultisigScript, CfdParseScript,
+ CfdAddMultisigScriptData, CfdAddTapBranchByScriptTreeString, CfdConvertScriptAsmToHex,
+ CfdFinalizeMultisigScript, CfdFreeMultisigScriptHandle, CfdFreeScriptItemHandle,
+ CfdFreeTaprootScriptTreeHandle, CfdGetBaseTapLeaf, CfdGetScriptItem, CfdGetTapBranchCount,
+ CfdGetTapBranchData, CfdGetTapBranchHandle, CfdGetTaprootScriptTreeHash,
+ CfdGetTaprootScriptTreeSrting, CfdGetTaprootTweakedPrivkey, CfdInitializeMultisigScript,
+ CfdInitializeTaprootScriptTree, CfdParseScript, CfdSetScriptTreeFromString,
+ CfdSetTapScriptByWitnessStack,
};
+/// taproot hash size.
+pub const TAPROOT_HASH_SIZE: usize = 32;
+/// tapscript leaf version
+pub const TAPSCRIPT_LEAF_VERSION: u8 = 0xc0;
+
/// A container that stores a bitcoin script.
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Script {
@@ -43,7 +55,7 @@ impl Script {
#[inline]
pub fn from_slice(data: &[u8]) -> Result