diff --git a/CMakeLists.txt b/CMakeLists.txt index 7604d16..6a4635f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -208,12 +208,13 @@ set(kth_sources src/wallet/transaction_functions.cpp src/wallet/wallet.cpp src/wallet/ec_compressed_list.cpp + src/wallet/wallet_data.cpp + src/wallet/wallet_manager.cpp src/libconfig/libconfig.cpp src/node/settings.cpp - src/vm/interpreter.cpp src/vm/program.cpp @@ -258,7 +259,7 @@ set(kth_sources src/chain/point_list.cpp src/chain/mempool_transaction.cpp - # src/chain/token_data.cpp + src/chain/token_data.cpp src/config/authority.cpp src/config/blockchain_settings.cpp @@ -269,7 +270,6 @@ set(kth_sources src/config/node_settings.cpp src/config/settings.cpp - src/node/settings.cpp src/vm/program.cpp @@ -331,6 +331,8 @@ set(kth_headers include/kth/capi/wallet/wallet.h include/kth/capi/wallet/raw_output.h include/kth/capi/wallet/ec_compressed_list.h + include/kth/capi/wallet/wallet_data.h + include/kth/capi/wallet/wallet_manager.h include/kth/capi/primitives.h include/kth/capi/hash_list.h @@ -378,6 +380,8 @@ set(kth_headers include/kth/capi/chain/block_list.h include/kth/capi/chain/mempool_transaction_list.h include/kth/capi/chain/compact_block.h + include/kth/capi/chain/token_capability.h + include/kth/capi/chain/token_kind.h include/kth/capi/chain/token_data.h include/kth/capi/chain/input.h include/kth/capi/chain/block_indexes.h @@ -402,6 +406,7 @@ set(kth_headers include/kth/capi/chain/mempool_transaction.h include/kth/capi/chain/rule_fork.h include/kth/capi/chain/script_version.h + include/kth/capi/chain/script_pattern.h include/kth/capi/chain/get_headers.h include/kth/capi/chain/double_spend_proof.h include/kth/capi/chain/input_list.h @@ -473,7 +478,9 @@ if (WITH_CONSOLE_CAPI) set(_test_console_sources # console/test_wallet.cpp # console/test_wallet.c - console/test_wallet2.c + # console/test_wallet2.c + console/test_wallet_manager.c + # console/test_header_hash.cpp # console/main.cpp # console/main.c diff --git a/conan.lock b/conan.lock index 6eab3ae..6cbb24a 100644 --- a/conan.lock +++ b/conan.lock @@ -2,28 +2,27 @@ "version": "0.5", "requires": [ "zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1736442063.163", + "tiny-aes-c/1.0.0#4ce574c8eae2dede7a94806b3adff526%1666613955.37", "spdlog/1.15.0#da21f74dd84627fa68601c4e3b9c3f00%1731353167.297", "secp256k1/0.21.0#ed9709c61dfdb38ac8181f876503dca6%1732364020.326", - "openssl/3.3.2#db38a6d356d27869fd90496897aedaf2%1736255835.422", + "openssl/3.3.2#90b3fc29e196eb631636c25d3516cd93%1741868603.502", "node/0.52.0#dd2fd028ad3363ba0a7ac27ba0f9ee97%1738534558.954", - "network/0.50.0#ac5d05429feed27feb2bcf3886fbeb99%1738533256.580533", - "lmdb/0.9.32#a9b704c2cb978c03eea680da55f26f8e%1715166447.685", - "libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1725632951.012", - "infrastructure/0.40.0#d3ebe4b063a768322e56d48eacecce0f%1738532851.2589662", + "lmdb/0.9.32#062e23b9624da8798d818cf697a2d6ba%1741857861.053", + "infrastructure/0.40.0#4a43a8836765a0b944b7f8c00e62f5e1%1742572044.359745", "gmp/6.3.0#df20ffb6d21c34d67704305bcd1dea9e%1716966936.742", "fmt/11.0.2#b4a24d70b93466b9b508ddb7b014643b%1735899162.196", "expected-lite/0.8.0#f87b3ec27a4f46894950b70f8d08af24%1717770563.402", - "domain/0.42.0#058df3e66d4ffd545d6a89e41f398843%1738533121.4168613", - "database/0.48.0#422a9f08fc0722cbb80bdb037213469b%1738533270.7408235", - "ctre/3.9.0#318a83b26476a59466795daac928f3ec%1716966898.508", - "consensus/0.35.0#0f3e3b29328263bebbb8dc48de242e5e%1738532864.604166", - "bzip2/1.0.8#d00dac990f08d991998d624be81a9526%1725632951.439", + "domain/0.42.0#58d654b7baa8ee6261b3ba6c66ac5559%1742572977.060045", + "database/0.48.0#422a9f08fc0722cbb80bdb037213469b%1738530526.086", + "ctre/3.9.0#318a83b26476a59466795daac928f3ec%1715925273.754", + "consensus/0.35.0#0f3e3b29328263bebbb8dc48de242e5e%1738529636.419", "boost/1.86.0#ce76e7477e466d7d8cbcf738c5d64175%1736442226.917", "blockchain/0.46.0#daa4d45e87890f17b6a17d4366484fdc%1738533774.007" ], "build_requires": [ + "nodejs/18.15.0#2e468fc390ccdb9595ea1a5bbb74d59f%1699800364.91", "m4/1.4.19#b38ced39a01e31fef5435bc634461fd2%1700758725.451", - "b2/5.2.1#91bc73931a0acb655947a81569ed8b80%1718416612.241" + "emsdk/3.1.66#dbe775f114c0ec093539734107e2ab5e%1733138978.7973351" ], "python_requires": [], "config_requires": [] diff --git a/console/test_wallet2.c b/console/test_wallet2.c index f1295da..dfdd027 100644 --- a/console/test_wallet2.c +++ b/console/test_wallet2.c @@ -43,7 +43,7 @@ void print_hex(uint8_t const* data, size_t n) { int main(int argc, char* argv[]) { // m/44'/145'/0' - char const* m44h145h0h_xpub_str = "xpub6CAemD8S648fre9X1e1YwQwWnumAjaXX7t7BxrN7mJRNFm6cwFusodAeyM6GaZXMVbALsYj7m6yf4SGHnoW6NojroW9MxspnUpNEeA6wWPV"; + char const* m44h145h0h_xpub_str = "xpub..."; kth_hd_public_t m44h145h0h = kth_wallet_hd_public_construct_string(m44h145h0h_xpub_str); kth_hd_public_t m44h145h0h0 = kth_wallet_hd_public_derive_public(m44h145h0h, 0); @@ -60,27 +60,5 @@ int main(int argc, char* argv[]) { printf("%s\n", kth_wallet_payment_address_encoded_cashaddr(pa, 0)); } - // bitcoincash:qr9sawzzmstkluq9nqefsu7eqya4zk2w7udune2pmf - // bitcoincash:qpvmwrhxcdyyq64ar6kz46rejp0r2tjcwg8d462hum - // bitcoincash:qqftgwpz0wm45z3sumncfrzm0s3n7x5rcqq9350gd6 - // bitcoincash:qrwelh5dw56rjnr3nnttfc45j0p0yv2a3vtuwu9nlt - // bitcoincash:qpawyf7fp6lhvhld5gtz74smm969fx2j2546uj60l0 - // bitcoincash:qqzhz2m6cg6au7r3hntjraqj4aj8akg3gvakarc69v - // bitcoincash:qpzf4kuq03js0tnug5z6e5q7zcfse6guagmhktuzcd - // bitcoincash:qr6jhutnh6jk7aphlyu9sq5f6zu2epj8uqpynlacwk - // bitcoincash:qrlfnn7f03n020yyvgyfqtq9fcu35wussq4ev4glfv - // bitcoincash:qrmn9ss3dsu79rws6j4jwa9qhdxrr4rqcqxxxvlnwx - // bitcoincash:qqnwp4ja6435s3v22hzhr5d5x6l7v80leyk7uf9z42 - // bitcoincash:qqyy3hnlt5z6xrxg57a74xt6tsce9hgrxqz7cz8tue - // bitcoincash:qpz2w7k0khnekpetayza9mq3uy47qkmgcvw46r0yga - // bitcoincash:qq3evlrgcdsgef6ut7l33qe2nguefnhvzgymup7pqk - // bitcoincash:qr3mpurdzyf0qkxq6qgue7ym98fsej4fwqsxq4u5j0 - // bitcoincash:qz5m8qceta5cckhs8k77lrzjzpwpe9y26ufvkl8gq7 - // bitcoincash:qzjnd7pykzsyt4z93j7mcphjxf8fk8unyym7et8x2z - // bitcoincash:qr2klzr2vllfq70a0ccd7zxpeaj2x8ma85wfrnp0tv - // bitcoincash:qq38t4jlhsz7gn9z9lrqptklpdm3n9z6eqn3hhqgme - // bitcoincash:qp9h0sjhe0m2pedjn3qr7x78c6utlpje9ulu40nej8 - - printf("\n"); } diff --git a/console/test_wallet_manager.c b/console/test_wallet_manager.c new file mode 100644 index 0000000..c328d45 --- /dev/null +++ b/console/test_wallet_manager.c @@ -0,0 +1,76 @@ +// Copyright (c) 2016-2024 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void print_hex(uint8_t const* data, size_t n) { + while (n != 0) { + printf("%02x", *data); + ++data; + --n; + } + printf("\n"); +} + +int main(int argc, char* argv[]) { + kth_wallet_data_t wallet_data; + kth_error_code_t code = kth_wallet_create_wallet( + "12345678", + "", + &wallet_data); + + printf("code: %d\n", code); + // printf("wallet_data: %s\n", kth_wallet_wallet_data_encoded(wallet_data)); + + kth_string_list_t mnemonics = kth_wallet_wallet_data_mnemonics(wallet_data); + + kth_size_t count = kth_core_string_list_count(mnemonics); + printf("count: %d\n", count); + + for (kth_size_t i = 0; i < count; i++) { + char const* mnemonic = kth_core_string_list_nth(mnemonics, i); + printf("mnemonic: %s\n", mnemonic); + } + + kth_encrypted_seed_t seed = kth_wallet_wallet_data_encrypted_seed(wallet_data); + print_hex(seed.hash, KTH_BITCOIN_ENCRYPTED_SEED_SIZE); + + + // ------------------------------------------------------------------------- + + kth_longhash_t decrypted_seed; + kth_error_code_t code2 = kth_wallet_decrypt_seed( + "12345678", + &seed, + &decrypted_seed); + + printf("code2: %d\n", code2); + print_hex(decrypted_seed.hash, KTH_BITCOIN_LONG_HASH_SIZE); +} diff --git a/include/kth/capi/chain/block.h b/include/kth/capi/chain/block.h index 0114bb0..6825a44 100644 --- a/include/kth/capi/chain/block.h +++ b/include/kth/capi/chain/block.h @@ -21,7 +21,7 @@ KTH_EXPORT kth_block_t kth_chain_block_construct(kth_header_t header, kth_transaction_list_t transactions); KTH_EXPORT -kth_block_t kth_chain_block_factory_from_data(uint32_t version, uint8_t* data, kth_size_t n); +kth_block_t kth_chain_block_factory_from_data(uint8_t* data, kth_size_t n); KTH_EXPORT void kth_chain_block_destruct(kth_block_t block); @@ -45,7 +45,7 @@ KTH_EXPORT kth_transaction_list_t kth_chain_block_transactions(kth_block_t block); KTH_EXPORT -kth_size_t kth_chain_block_serialized_size(kth_block_t block, uint32_t version); +kth_size_t kth_chain_block_serialized_size(kth_block_t block); /*static*/ KTH_EXPORT diff --git a/include/kth/capi/chain/header.h b/include/kth/capi/chain/header.h index ef8f088..1fa7969 100644 --- a/include/kth/capi/chain/header.h +++ b/include/kth/capi/chain/header.h @@ -16,19 +16,19 @@ extern "C" { #endif KTH_EXPORT -kth_header_t kth_chain_header_factory_from_data(uint32_t version, uint8_t* data, kth_size_t n); +kth_header_t kth_chain_header_factory_from_data(uint8_t* data, kth_size_t n); KTH_EXPORT -kth_size_t kth_chain_header_satoshi_fixed_size(uint32_t version); +kth_size_t kth_chain_header_satoshi_fixed_size(); KTH_EXPORT void kth_chain_header_reset(kth_header_t header); KTH_EXPORT -kth_size_t kth_chain_header_serialized_size(kth_header_t header, uint32_t version); +kth_size_t kth_chain_header_serialized_size(kth_header_t header); KTH_EXPORT -uint8_t const* kth_chain_header_to_data(kth_header_t header, uint32_t version, kth_size_t* out_size); +uint8_t const* kth_chain_header_to_data(kth_header_t header, kth_size_t* out_size); KTH_EXPORT kth_header_t kth_chain_header_construct_default(void); diff --git a/include/kth/capi/chain/output.h b/include/kth/capi/chain/output.h index fdc46d8..31bcfba 100644 --- a/include/kth/capi/chain/output.h +++ b/include/kth/capi/chain/output.h @@ -10,6 +10,8 @@ #include #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -18,9 +20,20 @@ KTH_EXPORT kth_output_t kth_chain_output_construct_default(void); KTH_EXPORT -// kth_output_t kth_chain_output_construct(uint64_t value, kth_script_t script, kth_token_data_t token_data); kth_output_t kth_chain_output_construct(uint64_t value, kth_script_t script); +KTH_EXPORT +kth_output_t kth_chain_output_construct_with_token_fungible(uint64_t value, kth_script_t script, kth_hash_t const* token_category, int64_t token_amount); + +KTH_EXPORT +kth_output_t kth_chain_output_construct_with_token_non_fungible(uint64_t value, kth_script_t script, kth_hash_t const* token_category, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n); + +KTH_EXPORT +kth_output_t kth_chain_output_construct_with_token_both(uint64_t value, kth_script_t script, kth_hash_t const* token_category, int64_t token_amount, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n); + +KTH_EXPORT +kth_output_t kth_chain_output_construct_with_token_data(uint64_t value, kth_script_t script, kth_token_data_t token_data); + KTH_EXPORT void kth_chain_output_destruct(kth_output_t output); @@ -50,6 +63,13 @@ uint8_t const* kth_chain_output_to_data(kth_output_t output, kth_bool_t wire, kt //uint32_t kth_chain_output_get_index(kth_output_t output); +// Cash Tokens --------------------------------------------------------------- +KTH_EXPORT +kth_bool_t kth_chain_output_has_token_data(kth_output_t output); + +KTH_EXPORT +kth_token_data_t kth_chain_output_token_data(kth_output_t output); + #ifdef __cplusplus } // extern "C" #endif diff --git a/include/kth/capi/chain/rule_fork.h b/include/kth/capi/chain/rule_fork.h index 8b569f1..0253195 100644 --- a/include/kth/capi/chain/rule_fork.h +++ b/include/kth/capi/chain/rule_fork.h @@ -51,21 +51,21 @@ typedef enum { kth_rule_fork_bip113_rule = 1U << 10, #if defined(KTH_CURRENCY_BCH) - kth_rule_fork_bch_uahf = 1U << 11, //2017-Aug Hardfork - Bitcoin Cash UAHF (1501590000) - kth_rule_fork_bch_daa_cw144 = 1U << 12, //2017-Nov Hardfork - DAA/cw-144 - (1510600000) - kth_rule_fork_bch_pythagoras = 1U << 13, //2018-May Hardfork - pythagoras - (1526400000) - kth_rule_fork_bch_euclid = 1U << 14, //2018-Nov Hardfork - euclid - (1542300000) - kth_rule_fork_bch_pisano = 1U << 15, //2019-May Hardfork - pisano - (1557921600) - kth_rule_fork_bch_mersenne = 1U << 16, //2019-Nov Hardfork - mersenne - (1573819200) - kth_rule_fork_bch_fermat = 1U << 17, //2020-May Hardfork - fermat - (1589544000) - kth_rule_fork_bch_euler = 1U << 18, //2020-Nov Hardfork - euler - (1605441600) - //2021-May NO-Hardfork - (1621080000) - kth_rule_fork_bch_gauss = 1U << 19, //2022-May Hardfork - gauss - (1652616000) - kth_rule_fork_bch_descartes = 1U << 20, //2023-May Hardfork - descartes - (1684152000) - kth_rule_fork_bch_lobachevski = 1U << 21, //2024-May Hardfork - lobachevski - (1715774400) - kth_rule_fork_bch_galois = 1U << 22, //2025-May Hardfork - galois - (1747310400) - kth_rule_fork_bch_leibniz = 1U << 23, //2025-May Hardfork - leibniz - (1778846400) - // kth_rule_fork_bch_unnamed = 1U << 24, //2026-May Hardfork - unnamed - (9999999999) + kth_rule_fork_bch_uahf = 1U << 11, //2017-Aug Upgrade - Bitcoin Cash UAHF (1501590000) + kth_rule_fork_bch_daa_cw144 = 1U << 12, //2017-Nov Upgrade - DAA/cw-144 - (1510600000) + kth_rule_fork_bch_pythagoras = 1U << 13, //2018-May Upgrade - pythagoras - (1526400000) + kth_rule_fork_bch_euclid = 1U << 14, //2018-Nov Upgrade - euclid - (1542300000) + kth_rule_fork_bch_pisano = 1U << 15, //2019-May Upgrade - pisano - (1557921600) + kth_rule_fork_bch_mersenne = 1U << 16, //2019-Nov Upgrade - mersenne - (1573819200) + kth_rule_fork_bch_fermat = 1U << 17, //2020-May Upgrade - fermat - (1589544000) + kth_rule_fork_bch_euler = 1U << 18, //2020-Nov Upgrade - euler - (1605441600) + //2021-May NO-Upgrade - (1621080000) + kth_rule_fork_bch_gauss = 1U << 19, //2022-May Upgrade - gauss - (1652616000) + kth_rule_fork_bch_descartes = 1U << 20, //2023-May Upgrade - descartes - (1684152000) + kth_rule_fork_bch_lobachevski = 1U << 21, //2024-May Upgrade - lobachevski - (1715774400) + kth_rule_fork_bch_galois = 1U << 22, //2025-May Upgrade - galois - (1747310400) + kth_rule_fork_bch_leibniz = 1U << 23, //2026-May Upgrade - leibniz - (1778846400) + // kth_rule_fork_bch_unnamed = 1U << 24, //2027-May Upgrade - unnamed - (9999999999) #else // Just for segwit coins /// Segregated witness consensus layer (soft fork, feature). diff --git a/include/kth/capi/chain/script.h b/include/kth/capi/chain/script.h index b780f38..e5b7f3f 100644 --- a/include/kth/capi/chain/script.h +++ b/include/kth/capi/chain/script.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -53,8 +54,8 @@ char const* kth_chain_script_type(kth_script_t script); KTH_EXPORT uint8_t const* kth_chain_script_to_data(kth_script_t script, kth_bool_t prefix, kth_size_t* out_size); -KTH_EXPORT -kth_size_t kth_chain_script_sigops(kth_script_t script, kth_bool_t embedded); +// KTH_EXPORT +// kth_size_t kth_chain_script_sigops(kth_script_t script, kth_bool_t embedded); KTH_EXPORT kth_operation_list_const_t kth_chain_script_operations(kth_script_t script); @@ -89,11 +90,14 @@ KTH_EXPORT kth_bool_t kth_chain_script_is_pay_public_key_pattern(kth_operation_list_t ops); KTH_EXPORT -kth_bool_t kth_chain_script_is_pay_key_hash_pattern(kth_operation_list_t ops); +kth_bool_t kth_chain_script_is_pay_public_key_hash_pattern(kth_operation_list_t ops); KTH_EXPORT kth_bool_t kth_chain_script_is_pay_script_hash_pattern(kth_operation_list_t ops); +KTH_EXPORT +kth_bool_t kth_chain_script_is_pay_script_hash_32_pattern(kth_operation_list_t ops); + /// Common input patterns (skh is also consensus). KTH_EXPORT kth_bool_t kth_chain_script_is_sign_multisig_pattern(kth_operation_list_t ops); @@ -102,7 +106,7 @@ KTH_EXPORT kth_bool_t kth_chain_script_is_sign_public_key_pattern(kth_operation_list_t ops); KTH_EXPORT -kth_bool_t kth_chain_script_is_sign_key_hash_pattern(kth_operation_list_t ops); +kth_bool_t kth_chain_script_is_sign_public_key_hash_pattern(kth_operation_list_t ops); KTH_EXPORT kth_bool_t kth_chain_script_is_sign_script_hash_pattern(kth_operation_list_t ops); @@ -115,11 +119,14 @@ KTH_EXPORT kth_operation_list_const_t kth_chain_script_to_pay_public_key_pattern(uint8_t const* point, kth_size_t n); KTH_EXPORT -kth_operation_list_const_t kth_chain_script_to_pay_key_hash_pattern(kth_shorthash_t const* chash); +kth_operation_list_const_t kth_chain_script_to_pay_public_key_hash_pattern(kth_shorthash_t const* chash); KTH_EXPORT kth_operation_list_const_t kth_chain_script_to_pay_script_hash_pattern(kth_shorthash_t const* hash); +KTH_EXPORT +kth_operation_list_const_t kth_chain_script_to_pay_script_hash_32_pattern(kth_hash_t const* hash); + KTH_EXPORT kth_operation_list_const_t kth_chain_script_to_pay_multisig_pattern(uint8_t signatures, kth_ec_compressed_list_t points); @@ -128,6 +135,31 @@ kth_operation_list_const_t kth_chain_script_to_pay_multisig_pattern(uint8_t sign // kth_operation_list_const_t kth_chain_script_to_pay_multisig_pattern(uint8_t signatures, data_stack const& points); +// Utilities (non-static). +//------------------------------------------------------------------------- + +/// Common pattern detection. + +KTH_EXPORT +kth_script_pattern_t kth_chain_script_pattern(kth_script_t script); + +KTH_EXPORT +kth_script_pattern_t kth_chain_script_output_pattern(kth_script_t script); + +KTH_EXPORT +kth_script_pattern_t kth_chain_script_input_pattern(kth_script_t script); + +/// Consensus computations. +KTH_EXPORT +kth_size_t kth_chain_script_sigops(kth_script_t script, kth_bool_t accurate); + +KTH_EXPORT +kth_bool_t kth_chain_script_is_unspendable(kth_script_t script); + +KTH_EXPORT +void kth_chain_script_reset(kth_script_t script); + + // Signing. //------------------------------------------------------------------------- @@ -137,7 +169,10 @@ kth_hash_t generate_signature_hash( uint32_t input_index, kth_script_t script_code, uint8_t sighash_type, + uint32_t active_forks, +#if ! defined(KTH_CURRENCY_BCH) kth_script_version_t version, +#endif // ! KTH_CURRENCY_BCH uint64_t value, kth_size_t* out_hashed_bytes ); @@ -151,15 +186,29 @@ kth_bool_t check_signature( kth_script_t script_code, kth_transaction_t tx, uint32_t input_index, + uint32_t active_forks, +#if ! defined(KTH_CURRENCY_BCH) kth_script_version_t version, +#endif // ! KTH_CURRENCY_BCH uint64_t value, kth_size_t* out_hashed_bytes ); -//TODO: implement this, we need endorsement type first -// static -// bool create_endorsement(endorsement& out, ec_secret const& secret, script const& prevout_script, transaction const& tx, uint32_t input_index, uint8_t sighash_type, script_version version = script_version::unversioned, uint64_t value = max_uint64); - +KTH_EXPORT +uint8_t const* kth_chain_script_create_endorsement( + kth_ec_secret_t const* secret, + kth_script_t prevout_script, + kth_transaction_t tx, + uint32_t input_index, + uint8_t sighash_type, + uint32_t active_forks, +#if ! defined(KTH_CURRENCY_BCH) + kth_script_version_t version, +#endif // ! KTH_CURRENCY_BCH + uint64_t value, + kth_endorsement_type_t type, + kth_size_t* out_size +); // Validation. //----------------------------------------------------------------------------- diff --git a/include/kth/capi/chain/script_pattern.h b/include/kth/capi/chain/script_pattern.h new file mode 100644 index 0000000..7b63e81 --- /dev/null +++ b/include/kth/capi/chain/script_pattern.h @@ -0,0 +1,75 @@ +// Copyright (c) 2016-2024 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_CAPI_CHAIN_SCRIPT_PATTERN_H_ +#define KTH_CAPI_CHAIN_SCRIPT_PATTERN_H_ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + /// Null Data + /// Pubkey Script: OP_RETURN <0 to 80 bytes of data> (formerly 40 bytes) + /// Null data scripts cannot be spent, so there's no signature script. + kth_script_pattern_null_data, + + /// Pay to Multisig [BIP11] + /// Pubkey script: [B pubkey][C pubkey...] OP_CHECKMULTISIG + /// Signature script: OP_0 [B sig][C sig...] + kth_script_pattern_pay_multisig, + + /// Pay to Public Key (obsolete) + kth_script_pattern_pay_public_key, + + /// Pay to Public Key Hash [P2PKH] + /// Pubkey script: OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG + /// Signature script: + kth_script_pattern_pay_public_key_hash, + + /// Pay to Script Hash [P2SH/BIP16] + /// The redeem script may be any pay type, but only multisig makes sense. + /// Pubkey script: OP_HASH160 OP_EQUAL + /// Signature script: [sig][sig...] + kth_script_pattern_pay_script_hash, + + /// Pay to Script Hash 32 + /// The redeem script may be any pay type, but only multisig makes sense. + /// Pubkey script: OP_HASH256 OP_EQUAL + /// Signature script: [sig][sig...] + kth_script_pattern_pay_script_hash_32, + + /// Sign Multisig script [BIP11] + kth_script_pattern_sign_multisig, + + /// Sign Public Key (obsolete) + kth_script_pattern_sign_public_key, + + /// Sign Public Key Hash [P2PKH] + kth_script_pattern_sign_public_key_hash, + + /// Sign Script Hash [P2SH/BIP16] + kth_script_pattern_sign_script_hash, + + /// Witness coinbase reserved value [BIP141]. + kth_script_pattern_witness_reservation, + + /// The script may be valid but does not conform to the common templates. + /// Such scripts are always accepted if they are mined into blocks, but + /// transactions with uncommon scripts may not be forwarded by peers. + kth_script_pattern_non_standard + +} kth_script_pattern_t; + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* KTH_CAPI_CHAIN_SCRIPT_PATTERN_H_ */ diff --git a/include/kth/capi/chain/script_version.h b/include/kth/capi/chain/script_version.h index ec90f88..8ff452a 100644 --- a/include/kth/capi/chain/script_version.h +++ b/include/kth/capi/chain/script_version.h @@ -15,6 +15,8 @@ extern "C" { #endif + +#if ! defined(KTH_CURRENCY_BCH) typedef enum { /// Defined by bip141. kth_script_version_zero, @@ -25,6 +27,8 @@ typedef enum { kth_script_version_unversioned } kth_script_version_t; +#endif // ! KTH_CURRENCY_BCH + #ifdef __cplusplus } // extern "C" diff --git a/include/kth/capi/chain/sighash_algorithm.h b/include/kth/capi/chain/sighash_algorithm.h new file mode 100644 index 0000000..c59414d --- /dev/null +++ b/include/kth/capi/chain/sighash_algorithm.h @@ -0,0 +1,96 @@ +// Copyright (c) 2016-2024 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_CAPI_CHAIN_SIGHASH_ALGORITHM_H_ +#define KTH_CAPI_CHAIN_SIGHASH_ALGORITHM_H_ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + /// The default, signs all the inputs and outputs, protecting everything + /// except the signature scripts against modification. + kth_sighash_algorithm_all = 0x01, + + /// Signs all of the inputs but none of the outputs, allowing anyone to + /// change where the satoshis are going unless other signatures using + /// other signature hash flags protect the outputs. + kth_sighash_algorithm_none = 0x02, + + /// The only output signed is the one corresponding to this input (the + /// output with the same output index number as this input), ensuring + /// nobody can change your part of the transaction but allowing other + /// signers to change their part of the transaction. The corresponding + /// output must exist or the value '1' will be signed, breaking the + /// security scheme. This input, as well as other inputs, are included + /// in the signature. The sequence numbers of other inputs are not + /// included in the signature, and can be updated. + kth_sighash_algorithm_single = 0x03, + + +#if defined(KTH_CURRENCY_BCH) + ///< New in Descartes/Upgrade9 (2023-May), must only be accepted if flags & SCRIPT_ENABLE_TOKENS + kth_sighash_algorithm_utxos = 0x20, + kth_sighash_algorithm_utxos_all = kth_sighash_algorithm_all | kth_sighash_algorithm_utxos, + kth_sighash_algorithm_utxos_none = kth_sighash_algorithm_none | kth_sighash_algorithm_utxos, + kth_sighash_algorithm_utxos_single = kth_sighash_algorithm_single | kth_sighash_algorithm_utxos, + + kth_sighash_algorithm_forkid = 0x40, + kth_sighash_algorithm_forkid_all = kth_sighash_algorithm_all | kth_sighash_algorithm_forkid, + kth_sighash_algorithm_forkid_none = kth_sighash_algorithm_none | kth_sighash_algorithm_forkid, + kth_sighash_algorithm_forkid_single = kth_sighash_algorithm_single | kth_sighash_algorithm_forkid, +#endif + + /// The above types can be modified with this flag, creating three new + /// combined types. + kth_sighash_algorithm_anyone_can_pay = 0x80, + + /// Signs all of the outputs but only this one input, and it also allows + /// anyone to add or remove other inputs, so anyone can contribute + /// additional satoshis but they cannot change how many satoshis are + /// sent nor where they go. + kth_sighash_algorithm_anyone_can_pay_all = kth_sighash_algorithm_all | kth_sighash_algorithm_anyone_can_pay, + + /// Signs only this one input and allows anyone to add or remove other + /// inputs or outputs, so anyone who gets a copy of this input can spend + /// it however they'd like. + kth_sighash_algorithm_anyone_can_pay_none = kth_sighash_algorithm_none | kth_sighash_algorithm_anyone_can_pay, + + /// Signs this one input and its corresponding output. Allows anyone to + /// add or remove other inputs. + kth_sighash_algorithm_anyone_can_pay_single = kth_sighash_algorithm_single | kth_sighash_algorithm_anyone_can_pay, + + /// Used to mask unused bits in the signature hash byte. + kth_sighash_algorithm_mask = 0x1f + +} kth_sighash_algorithm_t; + + +/// Convert the opcode to a mnemonic string. +KTH_EXPORT +char const* kth_chain_opcode_to_string(kth_opcode_t value, uint32_t active_forks); + +/// Convert a string to an opcode. +KTH_EXPORT +kth_bool_t kth_chain_opcode_from_string(kth_opcode_t* out_code, char const* value); + +/// Convert any opcode to a string hexadecimal representation. +KTH_EXPORT +char const* kth_chain_opcode_to_hexadecimal(kth_opcode_t code); + +// Convert any hexadecimal byte to an opcode. +KTH_EXPORT +kth_bool_t kth_chain_opcode_from_hexadecimal(kth_opcode_t* out_code, char const* value); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* KTH_CAPI_CHAIN_SIGHASH_ALGORITHM_H_ */ \ No newline at end of file diff --git a/include/kth/capi/chain/token_capability.h b/include/kth/capi/chain/token_capability.h new file mode 100644 index 0000000..6cb6dff --- /dev/null +++ b/include/kth/capi/chain/token_capability.h @@ -0,0 +1,27 @@ +// Copyright (c) 2016-2024 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_CAPI_CHAIN_TOKEN_CAPABILITY_H_ +#define KTH_CAPI_CHAIN_TOKEN_CAPABILITY_H_ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + kth_token_capability_none = 0x00, // The token lacks any capability or permission and is either a pure-fungible token or an immutable non-fungible token. + kth_token_capability_mut = 0x01, // If the mutable capability is present, it means that the encoded token is a non-fungible token that can be altered. + kth_token_capability_minting = 0x02, // If the minting capability is present, it indicates that the encoded token is a non-fungible token used for minting. +} kth_token_capability_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // KTH_CAPI_CHAIN_TOKEN_CAPABILITY_H_ diff --git a/include/kth/capi/chain/token_data.h b/include/kth/capi/chain/token_data.h index e383385..ff5f0fc 100644 --- a/include/kth/capi/chain/token_data.h +++ b/include/kth/capi/chain/token_data.h @@ -10,6 +10,9 @@ #include #include +#include +#include + #ifdef __cplusplus extern "C" { #endif @@ -17,8 +20,14 @@ extern "C" { KTH_EXPORT kth_token_data_t kth_chain_token_data_construct_default(void); -// KTH_EXPORT -// kth_token_data_t kth_chain_token_data_construct(); +KTH_EXPORT +kth_token_data_t kth_chain_token_data_construct_fungible(kth_hash_t const* token_category, int64_t token_amount); + +KTH_EXPORT +kth_token_data_t kth_chain_token_data_construct_non_fungible(kth_hash_t const* token_category, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n); + +KTH_EXPORT +kth_token_data_t kth_chain_token_data_construct_both(kth_hash_t const* token_category, int64_t token_amount, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n); KTH_EXPORT void kth_chain_token_data_destruct(kth_token_data_t token_data); @@ -32,6 +41,24 @@ kth_size_t kth_chain_token_data_serialized_size(kth_token_data_t token_data); KTH_EXPORT uint8_t const* kth_chain_token_data_to_data(kth_token_data_t token_data, kth_size_t* out_size); +KTH_EXPORT +kth_token_kind_t kth_chain_token_data_kind(kth_token_data_t token_data); + +KTH_EXPORT +kth_hash_t kth_chain_token_data_category(kth_token_data_t token_data); + +KTH_EXPORT +void kth_chain_token_data_category_out(kth_token_data_t token_data, kth_hash_t* out_category); + +KTH_EXPORT +int64_t kth_chain_token_data_fungible_amount(kth_token_data_t token_data); + +KTH_EXPORT +kth_token_capability_t kth_chain_token_data_non_fungible_capability(kth_token_data_t token_data); + +KTH_EXPORT +uint8_t const* kth_chain_token_data_non_fungible_commitment(kth_token_data_t token_data, kth_size_t* out_size); + #ifdef __cplusplus } // extern "C" #endif diff --git a/include/kth/capi/chain/token_kind.h b/include/kth/capi/chain/token_kind.h new file mode 100644 index 0000000..67a6cf7 --- /dev/null +++ b/include/kth/capi/chain/token_kind.h @@ -0,0 +1,28 @@ +// Copyright (c) 2016-2024 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_CAPI_CHAIN_TOKEN_KIND_H_ +#define KTH_CAPI_CHAIN_TOKEN_KIND_H_ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + kth_token_kind_none = 0x00, + kth_token_kind_fungible = 0x01, + kth_token_kind_non_fungible = 0x02, + kth_token_kind_both = 0x03, +} kth_token_kind_t; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // KTH_CAPI_CHAIN_TOKEN_KIND_H_ diff --git a/include/kth/capi/chain/transaction.h b/include/kth/capi/chain/transaction.h index fdabe64..987e9e8 100644 --- a/include/kth/capi/chain/transaction.h +++ b/include/kth/capi/chain/transaction.h @@ -16,7 +16,7 @@ extern "C" { #endif KTH_EXPORT -kth_transaction_t kth_chain_transaction_factory_from_data(uint32_t version, uint8_t* data, kth_size_t n); +kth_transaction_t kth_chain_transaction_factory_from_data(uint8_t* data, kth_size_t n); KTH_EXPORT kth_transaction_t kth_chain_transaction_construct_default(void); diff --git a/include/kth/capi/chain/utxo.h b/include/kth/capi/chain/utxo.h index 4fb1363..1be18b8 100644 --- a/include/kth/capi/chain/utxo.h +++ b/include/kth/capi/chain/utxo.h @@ -10,6 +10,9 @@ #include #include +#include +#include + #ifdef __cplusplus extern "C" { #endif @@ -21,34 +24,78 @@ KTH_EXPORT kth_utxo_t kth_chain_utxo_construct_from_hash_index_amount(kth_hash_t const* hash, uint32_t index, uint64_t amount); KTH_EXPORT -void kth_chain_utxo_destruct(kth_utxo_t op); +kth_utxo_t kth_chain_utxo_construct_from_hash_index_amount_fungible(kth_hash_t const* hash, uint32_t index, uint64_t amount, kth_hash_t const* token_category, uint64_t token_amount); + +KTH_EXPORT +kth_utxo_t kth_chain_utxo_construct_from_hash_index_amount_non_fungible(kth_hash_t const* hash, uint32_t index, uint64_t amount, kth_hash_t const* token_category, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n); + +KTH_EXPORT +kth_utxo_t kth_chain_utxo_construct_from_hash_index_amount_both(kth_hash_t const* hash, uint32_t index, uint64_t amount, kth_hash_t const* token_category, uint64_t token_amount, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n); + +KTH_EXPORT +void kth_chain_utxo_destruct(kth_utxo_t utxo); + +// Getters +KTH_EXPORT +kth_hash_t kth_chain_utxo_get_hash(kth_utxo_t utxo); + +KTH_EXPORT +void kth_chain_utxo_get_hash_out(kth_utxo_t utxo, kth_hash_t* out_hash); + +KTH_EXPORT +uint32_t kth_chain_utxo_get_index(kth_utxo_t utxo); + +KTH_EXPORT +uint64_t kth_chain_utxo_get_amount(kth_utxo_t utxo); + +KTH_EXPORT +kth_output_t kth_chain_utxo_get_cached_output(kth_utxo_t utxo); + +KTH_EXPORT +kth_bool_t kth_chain_utxo_has_token_data(kth_utxo_t utxo); + +KTH_EXPORT +kth_token_data_t kth_chain_utxo_get_token_data(kth_utxo_t utxo); + +KTH_EXPORT +kth_hash_t kth_chain_utxo_get_token_category(kth_utxo_t utxo); + +KTH_EXPORT +void kth_chain_utxo_get_token_category_out(kth_utxo_t utxo, kth_hash_t* out_token_category); + +KTH_EXPORT +uint64_t kth_chain_utxo_get_token_amount(kth_utxo_t utxo); + +KTH_EXPORT +kth_token_capability_t kth_chain_utxo_get_token_capability(kth_utxo_t utxo); KTH_EXPORT -kth_hash_t kth_chain_utxo_get_hash(kth_utxo_t op); +uint8_t const* kth_chain_utxo_get_token_commitment(kth_utxo_t utxo, kth_size_t* out_size); +// Setters KTH_EXPORT -void kth_chain_utxo_get_hash_out(kth_utxo_t op, kth_hash_t* out_hash); +void kth_chain_utxo_set_hash(kth_utxo_t utxo, kth_hash_t const* hash); KTH_EXPORT -uint32_t kth_chain_utxo_get_index(kth_utxo_t op); +void kth_chain_utxo_set_index(kth_utxo_t utxo, uint32_t index); KTH_EXPORT -uint64_t kth_chain_utxo_get_amount(kth_utxo_t op); +void kth_chain_utxo_set_amount(kth_utxo_t utxo, uint64_t amount); KTH_EXPORT -kth_output_t kth_chain_utxo_get_cached_output(kth_utxo_t op); +void kth_chain_utxo_set_cached_output(kth_utxo_t utxo, kth_output_t output); KTH_EXPORT -void kth_chain_utxo_set_hash(kth_utxo_t op, kth_hash_t const* hash); +void kth_chain_utxo_set_token_data(kth_utxo_t utxo, kth_token_data_t token_data); KTH_EXPORT -void kth_chain_utxo_set_index(kth_utxo_t op, uint32_t index); +void kth_chain_utxo_set_fungible_token_data(kth_utxo_t utxo, kth_hash_t const* token_category, int64_t token_amount); KTH_EXPORT -void kth_chain_utxo_set_amount(kth_utxo_t op, uint64_t amount); +void kth_chain_utxo_set_token_category(kth_utxo_t utxo, kth_hash_t const* token_category); KTH_EXPORT -void kth_chain_utxo_set_cached_output(kth_utxo_t op, kth_output_t output); +void kth_chain_utxo_set_token_amount(kth_utxo_t utxo, int64_t token_amount); #ifdef __cplusplus } // extern "C" diff --git a/include/kth/capi/config/blockchain_settings.h b/include/kth/capi/config/blockchain_settings.h index 7180bac..796737a 100644 --- a/include/kth/capi/config/blockchain_settings.h +++ b/include/kth/capi/config/blockchain_settings.h @@ -66,7 +66,7 @@ typedef struct { // //2024-May-15 hard fork, defaults to 1715774400: May 15, 2024 12:00:00 UTC protocol upgrade // uint64_t lobachevski_activation_time; - //2025-May-15 hard fork, defaults to 1747310400: May 15, 2025 12:00:00 UTC protocol upgrade + // 2025-May-15 hard fork, defaults to 1747310400: May 15, 2025 12:00:00 UTC protocol upgrade uint64_t galois_activation_time; // 2026-May-15 hard fork, defaults to 1778846400: May 15, 2026 12:00:00 UTC protocol upgrade diff --git a/include/kth/capi/conversions.hpp b/include/kth/capi/conversions.hpp index 6c41d82..e22e3f8 100644 --- a/include/kth/capi/conversions.hpp +++ b/include/kth/capi/conversions.hpp @@ -17,26 +17,29 @@ #include #include #include -#include -#include -#include +#include +#include +#include // #include #include +#include // #ifndef __EMSCRIPTEN__ #include // #endif -KTH_CONV_DECLARE(chain, kth_block_t, kth::domain::message::block, block) -KTH_CONV_DECLARE(chain, kth_header_t, kth::domain::message::header, header) +KTH_CONV_DECLARE(chain, kth_block_t, kth::domain::chain::block, block) +KTH_CONV_DECLARE(chain, kth_header_t, kth::domain::chain::header, header) KTH_CONV_DECLARE(chain, kth_input_t, kth::domain::chain::input, input) KTH_CONV_DECLARE(chain, kth_output_t, kth::domain::chain::output, output) KTH_CONV_DECLARE(chain, kth_outputpoint_t, kth::domain::chain::output_point, output_point) KTH_CONV_DECLARE(chain, kth_script_t, kth::domain::chain::script, script) -KTH_CONV_DECLARE(chain, kth_transaction_t, kth::domain::message::transaction, transaction) +KTH_CONV_DECLARE(chain, kth_transaction_t, kth::domain::chain::transaction, transaction) // KTH_CONV_DECLARE(chain, kth_transaction_t, kth::domain::chain::transaction, transaction) KTH_CONV_DECLARE(chain, kth_point_t, kth::domain::chain::point, point) KTH_CONV_DECLARE(chain, kth_utxo_t, kth::domain::chain::utxo, utxo) +KTH_CONV_DECLARE(chain, kth_token_data_t, kth::domain::chain::token_data_t, token_data) + // #ifndef __EMSCRIPTEN__ KTH_CONV_DECLARE(chain, kth_mempool_transaction_t, kth::blockchain::mempool_transaction_summary, mempool_transaction) // #endif @@ -49,21 +52,21 @@ KTH_CONV_DECLARE(chain, kth_stealth_compact_t, kth::domain::chain::stealth_compa KTH_CONV_DECLARE(chain, kth_operation_t, kth::domain::machine::operation, operation) //Note: kth_block_list_t created with this function has not have to destruct it... -// KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(chain, kth_block_list_t, kth::domain::message::block, block_list) +// KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(chain, kth_block_list_t, kth::domain::chain::block, block_list) KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(chain, kth_input_list_t, kth::domain::chain::input, input_list) KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(chain, kth_output_list_t, kth::domain::chain::output, output_list) KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(chain, kth_utxo_list_t, kth::domain::chain::utxo, utxo_list) -// KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(chain, kth_transaction_list_t, kth::domain::message::transaction, transaction_list) +// KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(chain, kth_transaction_list_t, kth::domain::chain::transaction, transaction_list) KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(chain, kth_transaction_list_t, kth::domain::chain::transaction, transaction_list) KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(core, kth_hash_list_t, kth::hash_digest, hash_list) KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP_CONST(chain, kth_operation_list_t, kth::domain::machine::operation, operation_list) -KTH_LIST_DECLARE_CONVERTERS(chain, kth_block_list_t, kth::domain::message::block, block_list) +KTH_LIST_DECLARE_CONVERTERS(chain, kth_block_list_t, kth::domain::chain::block, block_list) KTH_LIST_DECLARE_CONVERTERS(chain, kth_point_list_t, kth::domain::chain::point, point_list) KTH_LIST_DECLARE_CONVERTERS(chain, kth_input_list_t, kth::domain::chain::input, input_list) KTH_LIST_DECLARE_CONVERTERS(chain, kth_output_list_t, kth::domain::chain::output, output_list) KTH_LIST_DECLARE_CONVERTERS(chain, kth_utxo_list_t, kth::domain::chain::utxo, utxo_list) -// KTH_LIST_DECLARE_CONVERTERS(chain, kth_transaction_list_t, kth::domain::message::transaction, transaction_list) +// KTH_LIST_DECLARE_CONVERTERS(chain, kth_transaction_list_t, kth::domain::chain::transaction, transaction_list) KTH_LIST_DECLARE_CONVERTERS(chain, kth_transaction_list_t, kth::domain::chain::transaction, transaction_list) KTH_LIST_DECLARE_CONVERTERS(core, kth_hash_list_t, kth::hash_digest, hash_list) KTH_LIST_DECLARE_CONVERTERS(chain, kth_block_indexes_t, kth_size_t, block_indexes) @@ -76,10 +79,11 @@ KTH_CONV_DECLARE(wallet, kth_raw_output_t, kth::domain::wallet::raw_output, raw_ KTH_CONV_DECLARE(wallet, kth_payment_address_t, kth::domain::wallet::payment_address, payment_address) KTH_CONV_DECLARE(wallet, kth_ec_private_t, kth::domain::wallet::ec_private, ec_private) KTH_CONV_DECLARE(wallet, kth_ec_public_t, kth::domain::wallet::ec_public, ec_public) +KTH_CONV_DECLARE(wallet, kth_wallet_data_t, kth::domain::wallet::wallet_data, wallet_data) KTH_LIST_DECLARE_CONVERTERS(wallet, kth_raw_output_list_t, kth::domain::wallet::raw_output, raw_output_list) -KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(wallet, kth_payment_address_list_t, kth::domain::wallet::payment_address, payment_address_list) +KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP_BOTH(wallet, kth_payment_address_list_t, kth::domain::wallet::payment_address, payment_address_list) KTH_LIST_DECLARE_CONVERTERS(wallet, kth_payment_address_list_t, kth::domain::wallet::payment_address, payment_address_list) // Core. @@ -88,6 +92,8 @@ KTH_LIST_DECLARE_CONVERTERS(wallet, kth_payment_address_list_t, kth::domain::wal KTH_LIST_DECLARE_CONVERTERS(core, kth_double_list_t, double, double_list) KTH_LIST_DECLARE_CONVERTERS(core, kth_u32_list_t, uint32_t, u32_list) KTH_LIST_DECLARE_CONVERTERS(core, kth_u64_list_t, uint64_t, u64_list) +KTH_LIST_DECLARE_CONVERTERS(core, kth_string_list_t, std::string, string_list) +KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(core, kth_string_list_t, std::string, string_list) // VM. diff --git a/include/kth/capi/hash.h b/include/kth/capi/hash.h index 1c731de..f6d76bf 100644 --- a/include/kth/capi/hash.h +++ b/include/kth/capi/hash.h @@ -7,6 +7,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -45,6 +46,18 @@ void kth_longhash_set(kth_longhash_t* longhash, uint8_t const* data); KTH_EXPORT void kth_longhash_destruct(kth_longhash_t* longhash); +KTH_EXPORT +void kth_encrypted_seed_set(kth_encrypted_seed_t* seed, uint8_t const* data); + +KTH_EXPORT +void kth_encrypted_seed_destruct(kth_encrypted_seed_t* seed); + +KTH_EXPORT +void kth_ec_secret_set(kth_ec_secret_t* secret, uint8_t const* data); + +KTH_EXPORT +void kth_ec_secret_destruct(kth_ec_secret_t* secret); + #ifdef __cplusplus } // extern "C" #endif diff --git a/include/kth/capi/helpers.hpp b/include/kth/capi/helpers.hpp index 03212a0..a757ff7 100644 --- a/include/kth/capi/helpers.hpp +++ b/include/kth/capi/helpers.hpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -21,7 +22,9 @@ #include #include #include +#include #include +#include // #ifndef __EMSCRIPTEN__ #include @@ -81,6 +84,28 @@ std::array, 32> to_array(T (&x)[32]) { x[24], x[25], x[26], x[27], x[28], x[29], x[30], x[31]}}; } +template +constexpr +std::array, 96> to_array(T (&x)[96]) { + // return detail::to_array_impl(x, std::make_index_sequence{}); + // return std::array, 32> {{ + + return {{ + x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], + x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15], + x[16], x[17], x[18], x[19], x[20], x[21], x[22], x[23], + x[24], x[25], x[26], x[27], x[28], x[29], x[30], x[31], + x[32], x[33], x[34], x[35], x[36], x[37], x[38], x[39], + x[40], x[41], x[42], x[43], x[44], x[45], x[46], x[47], + x[48], x[49], x[50], x[51], x[52], x[53], x[54], x[55], + x[56], x[57], x[58], x[59], x[60], x[61], x[62], x[63], + x[64], x[65], x[66], x[67], x[68], x[69], x[70], x[71], + x[72], x[73], x[74], x[75], x[76], x[77], x[78], x[79], + x[80], x[81], x[82], x[83], x[84], x[85], x[86], x[87], + x[88], x[89], x[90], x[91], x[92], x[93], x[94], x[95] + }}; +} + inline kth_hash_t to_hash_t(kth::hash_digest const& x) { // return to_c_array(x); @@ -113,6 +138,22 @@ kth_longhash_t to_longhash_t(kth::long_hash const& x) { } +inline +kth_encrypted_seed_t to_encrypted_seed_t(kth::domain::wallet::encrypted_seed_t const& x) { + return { {x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], + x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15], + x[16], x[17], x[18], x[19], x[20], x[21], x[22], x[23], + x[24], x[25], x[26], x[27], x[28], x[29], x[30], x[31], + x[32], x[33], x[34], x[35], x[36], x[37], x[38], x[39], + x[40], x[41], x[42], x[43], x[44], x[45], x[46], x[47], + x[48], x[49], x[50], x[51], x[52], x[53], x[54], x[55], + x[56], x[57], x[58], x[59], x[60], x[61], x[62], x[63], + x[64], x[65], x[66], x[67], x[68], x[69], x[70], x[71], + x[72], x[73], x[74], x[75], x[76], x[77], x[78], x[79], + x[80], x[81], x[82], x[83], x[84], x[85], x[86], x[87], + x[88], x[89], x[90], x[91], x[92], x[93], x[94], x[95]} }; +} + // inline // kth_ec_secret_t to_ec_secret_t(kth::hash_digest const& x) { // return { {x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], @@ -265,8 +306,21 @@ kth::domain::machine::rule_fork rule_fork_to_cpp(kth_rule_fork_t fork) { return static_cast(fork); } +// Script Pattern ----------------------------------------------------- + +inline +kth_script_pattern_t script_pattern_to_c(kth::infrastructure::machine::script_pattern pattern) { + return static_cast(pattern); +} + +inline +kth::infrastructure::machine::script_pattern script_pattern_to_cpp(kth_script_pattern_t pattern) { + return static_cast(pattern); +} + // Script Version ----------------------------------------------------- +#if ! defined(KTH_CURRENCY_BCH) inline kth::infrastructure::machine::script_version script_version_to_cpp(kth_script_version_t version) { return static_cast(version); @@ -276,7 +330,7 @@ inline kth_script_version_t script_version_to_c(kth::infrastructure::machine::script_version version) { return static_cast(version); } - +#endif // ! KTH_CURRENCY_BCH // Coin Selection ----------------------------------------------------- inline @@ -289,6 +343,32 @@ kth_coin_selection_algorithm_t coin_selection_algorithm_to_c(kth::domain::chain: return static_cast(algo); } +// Cash Tokens ----------------------------------------------------- + +inline +kth::domain::chain::capability_t token_capability_to_cpp(kth_token_capability_t capability) { + return static_cast(capability); +} + +inline +kth_token_capability_t token_capability_to_c(kth::domain::chain::capability_t capability) { + return static_cast(capability); +} + + +// Endorsement ------------------------------------------------------------- + +inline +kth::domain::chain::endorsement_type endorsement_type_to_cpp(kth_endorsement_type_t type) { + return static_cast(type); +} + +inline +kth_endorsement_type_t endorsement_type_to_c(kth::domain::chain::endorsement_type type) { + return static_cast(type); +} + + // Other ------------------------------------------------------------- inline diff --git a/include/kth/capi/list_creator.h b/include/kth/capi/list_creator.h index c8812c1..e096006 100644 --- a/include/kth/capi/list_creator.h +++ b/include/kth/capi/list_creator.h @@ -38,6 +38,18 @@ void const* kth_##api##_##list_name##_construct_from_cpp(std::vector return &l; \ } +#define KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP_BOTH(api, list_t, cpp_elem_t, list_name) \ +KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP(api, list_t, cpp_elem_t, list_name) \ +KTH_LIST_DECLARE_CONSTRUCT_FROM_CPP_CONST(api, list_t, cpp_elem_t, list_name) \ +void const* kth_##api##_##list_name##_construct_from_cpp_const(std::vector const& l); + +#define KTH_LIST_DEFINE_CONSTRUCT_FROM_CPP_BOTH(api, list_t, cpp_elem_t, list_name) \ +KTH_LIST_DEFINE_CONSTRUCT_FROM_CPP(api, list_t, cpp_elem_t, list_name) \ +KTH_LIST_DEFINE_CONSTRUCT_FROM_CPP_CONST(api, list_t, cpp_elem_t, list_name) \ +void const* kth_##api##_##list_name##_construct_from_cpp_const(std::vector const& l) { \ + return &l; \ +} + #define KTH_LIST_DECLARE(api, list_t, elem_t, list_name) \ KTH_EXPORT \ list_t kth_##api##_##list_name##_construct_default(void); \ diff --git a/include/kth/capi/primitives.h b/include/kth/capi/primitives.h index d2e29bb..44cd7dc 100644 --- a/include/kth/capi/primitives.h +++ b/include/kth/capi/primitives.h @@ -17,6 +17,7 @@ extern "C" { #define KTH_BITCOIN_SHORT_HASH_SIZE 20 #define KTH_BITCOIN_HASH_SIZE 32 #define KTH_BITCOIN_LONG_HASH_SIZE 64 +#define KTH_BITCOIN_ENCRYPTED_SEED_SIZE 96 #define KTH_BITCOIN_MINIMUM_SEED_BITS 128 #define KTH_BITCOIN_BYTE_BITS 8 @@ -71,6 +72,7 @@ typedef void* kth_inputpoint_t; typedef void* kth_merkleblock_t; typedef void* kth_script_t; typedef void* kth_token_data_t; +typedef void const* kth_token_data_const_t; typedef void* kth_operation_list_t; typedef void const* kth_operation_list_const_t; @@ -94,6 +96,7 @@ typedef void* kth_get_headers_t; typedef void* kth_get_headers_ptr_t; typedef void* kth_payment_address_t; typedef void* kth_payment_address_list_t; +typedef void const* kth_payment_address_list_const_t; typedef void* kth_binary_t; typedef void* kth_stealth_compact_t; typedef void* kth_stealth_compact_list_t; @@ -105,6 +108,7 @@ typedef void* kth_double_list_t; typedef void* kth_u32_list_t; typedef void* kth_u64_list_t; +typedef void* kth_wallet_data_t; typedef void* kth_ec_compressed_list_t; @@ -130,6 +134,11 @@ typedef struct kth_longhash_t { uint8_t hash[KTH_BITCOIN_LONG_HASH_SIZE]; //kth::long_hash_size } kth_longhash_t; +typedef struct kth_encrypted_seed_t { + uint8_t hash[KTH_BITCOIN_ENCRYPTED_SEED_SIZE]; +} kth_encrypted_seed_t; + + // Currencies -------------------------------------------------------- @@ -168,6 +177,13 @@ typedef enum { } kth_db_mode_t; +// Endorsement type ---------------------------------------------------- +typedef enum { + kth_endorsement_type_ecdsa = 0, + kth_endorsement_type_schnorr = 1 +} kth_endorsement_type_t; + + // Callback signatures ------------------------------------------------ typedef void (*kth_run_handler_t)(kth_node_t, void*, kth_error_code_t); typedef void (*kth_stealth_fetch_handler_t)(kth_chain_t, void*, kth_error_code_t, kth_stealth_compact_list_t); diff --git a/include/kth/capi/string_list.h b/include/kth/capi/string_list.h index 17654a9..637466f 100644 --- a/include/kth/capi/string_list.h +++ b/include/kth/capi/string_list.h @@ -23,6 +23,13 @@ void kth_core_string_list_push_back(kth_string_list_t string_list, char const* s KTH_EXPORT void kth_core_string_list_destruct(kth_string_list_t string_list); +KTH_EXPORT +char const* kth_core_string_list_nth(kth_string_list_t string_list, kth_size_t index); + +KTH_EXPORT +kth_size_t kth_core_string_list_count(kth_string_list_t string_list); + + #ifdef __cplusplus } // extern "C" #endif diff --git a/include/kth/capi/wallet/payment_address.h b/include/kth/capi/wallet/payment_address.h index d85af5e..2562baa 100644 --- a/include/kth/capi/wallet/payment_address.h +++ b/include/kth/capi/wallet/payment_address.h @@ -22,15 +22,17 @@ kth_payment_address_t kth_wallet_payment_address_construct_from_string(char cons KTH_EXPORT kth_payment_address_t kth_wallet_payment_address_construct_from_short_hash(kth_shorthash_t const* hash, uint8_t version); +KTH_EXPORT +kth_payment_address_t kth_wallet_payment_address_construct_from_hash(kth_hash_t const* hash, uint8_t version); + KTH_EXPORT kth_payment_address_t kth_wallet_payment_address_construct_from_public(kth_ec_public_t point, uint8_t version); KTH_EXPORT kth_payment_address_t kth_wallet_payment_address_construct_from_script(kth_script_t script, uint8_t version); -// payment_address payment_address::from_pay_key_hash_script(chain::script const& script, uint8_t version) { KTH_EXPORT -kth_payment_address_t kth_wallet_payment_address_from_pay_key_hash_script(kth_script_t script, uint8_t version); +kth_payment_address_t kth_wallet_payment_address_from_pay_public_key_hash_script(kth_script_t script, uint8_t version); KTH_EXPORT void kth_wallet_payment_address_destruct(kth_payment_address_t payment_address); @@ -60,14 +62,14 @@ uint8_t kth_wallet_payment_address_version(kth_payment_address_t payment_address KTH_EXPORT kth_bool_t kth_wallet_payment_address_is_valid(kth_payment_address_t payment_address); -// KTH_EXPORT -// kth_payment_address_list_t kth_wallet_payment_address_extract(kth_script_t script, uint8_t p2kh_version, uint8_t p2sh_version); +KTH_EXPORT +kth_payment_address_list_const_t kth_wallet_payment_address_extract(kth_script_t script, uint8_t p2kh_version, uint8_t p2sh_version); -// KTH_EXPORT -// kth_payment_address_list_t kth_wallet_payment_address_extract_input(kth_script_t script, uint8_t p2kh_version, uint8_t p2sh_version); +KTH_EXPORT +kth_payment_address_list_const_t kth_wallet_payment_address_extract_input(kth_script_t script, uint8_t p2kh_version, uint8_t p2sh_version); -// KTH_EXPORT -// kth_payment_address_list_t kth_wallet_payment_address_extract_output(kth_script_t script, uint8_t p2kh_version, uint8_t p2sh_version); +KTH_EXPORT +kth_payment_address_list_const_t kth_wallet_payment_address_extract_output(kth_script_t script, uint8_t p2kh_version, uint8_t p2sh_version); #ifdef __cplusplus } // extern "C" diff --git a/include/kth/capi/wallet/wallet.h b/include/kth/capi/wallet/wallet.h index a15a92b..e3cf5a1 100644 --- a/include/kth/capi/wallet/wallet.h +++ b/include/kth/capi/wallet/wallet.h @@ -20,6 +20,12 @@ kth_longhash_t kth_wallet_mnemonics_to_seed(kth_string_list_t mnemonics); KTH_EXPORT void kth_wallet_mnemonics_to_seed_out(kth_string_list_t mnemonics, kth_longhash_t* out_hash); +KTH_EXPORT +kth_longhash_t kth_wallet_mnemonics_to_seed_normalized_passphrase(kth_string_list_t mnemonics, char const* normalized_passphrase); + +KTH_EXPORT +void kth_wallet_mnemonics_to_seed_normalized_passphrase_out(kth_string_list_t mnemonics, char const* normalized_passphrase, kth_longhash_t* out_hash); + KTH_EXPORT kth_hd_private_t kth_wallet_hd_new(kth_longhash_t seed, uint32_t version /* = 76066276*/); diff --git a/include/kth/capi/wallet/wallet_data.h b/include/kth/capi/wallet/wallet_data.h new file mode 100644 index 0000000..9b5ddae --- /dev/null +++ b/include/kth/capi/wallet/wallet_data.h @@ -0,0 +1,36 @@ +// Copyright (c) 2016-2024 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_CAPI_WALLET_WALLET_DATA_H_ +#define KTH_CAPI_WALLET_WALLET_DATA_H_ + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +KTH_EXPORT +void kth_wallet_wallet_data_destruct(kth_wallet_data_t wallet_data); + +KTH_EXPORT +kth_string_list_t kth_wallet_wallet_data_mnemonics(kth_wallet_data_t wallet_data); + +KTH_EXPORT +kth_hd_public_t kth_wallet_wallet_data_xpub(kth_wallet_data_t wallet_data); + +KTH_EXPORT +kth_encrypted_seed_t kth_wallet_wallet_data_encrypted_seed(kth_wallet_data_t wallet_data); + +KTH_EXPORT +void kth_wallet_wallet_data_encrypted_seed_out(kth_wallet_data_t wallet_data, kth_encrypted_seed_t* out_encrypted_seed); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* KTH_CAPI_WALLET_WALLET_DATA_H_ */ diff --git a/include/kth/capi/wallet/wallet_manager.h b/include/kth/capi/wallet/wallet_manager.h new file mode 100644 index 0000000..6a493c1 --- /dev/null +++ b/include/kth/capi/wallet/wallet_manager.h @@ -0,0 +1,33 @@ +// Copyright (c) 2016-2024 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef KTH_CAPI_WALLET_WALLET_MANAGER_H_ +#define KTH_CAPI_WALLET_WALLET_MANAGER_H_ + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +KTH_EXPORT +kth_error_code_t kth_wallet_create_wallet( + char const* password, + char const* normalized_passphrase, + kth_wallet_data_t* out_wallet_data); + +KTH_EXPORT +kth_error_code_t kth_wallet_decrypt_seed( + char const* password, + kth_encrypted_seed_t const* encrypted_seed, + kth_longhash_t** out_decrypted_seed); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* KTH_CAPI_WALLET_WALLET_MANAGER_H_ */ diff --git a/src/chain/block.cpp b/src/chain/block.cpp index 9ef6503..74b56b7 100644 --- a/src/chain/block.cpp +++ b/src/chain/block.cpp @@ -7,27 +7,27 @@ #include #include -#include +#include -KTH_CONV_DEFINE(chain, kth_block_t, kth::domain::message::block, block) +KTH_CONV_DEFINE(chain, kth_block_t, kth::domain::chain::block, block) // --------------------------------------------------------------------------- extern "C" { kth_block_t kth_chain_block_construct_default() { - return new kth::domain::message::block(); + return new kth::domain::chain::block(); } kth_block_t kth_chain_block_construct(kth_header_t header, kth_transaction_list_t transactions) { auto const& header_cpp = kth_chain_header_const_cpp(header); // auto const& txs_cpp = *static_cast(transactions); auto const& txs_cpp = kth_chain_transaction_list_const_cpp(transactions); - return new kth::domain::message::block(header_cpp, txs_cpp); + return new kth::domain::chain::block(header_cpp, txs_cpp); } -kth_block_t kth_chain_block_factory_from_data(uint32_t version, uint8_t* data, kth_size_t n) { +kth_block_t kth_chain_block_factory_from_data(uint8_t* data, kth_size_t n) { kth::data_chunk data_cpp(data, std::next(data, n)); - auto block = kth::domain::create(version, data_cpp); + auto block = kth::domain::create(data_cpp); return kth::move_or_copy_and_leak(std::move(block)); } @@ -65,21 +65,18 @@ kth_transaction_list_t kth_chain_block_transactions(kth_block_t block) { // ----------------------- -kth_size_t kth_chain_block_serialized_size(kth_block_t block, uint32_t version) { - return kth_chain_block_const_cpp(block).serialized_size(version); +kth_size_t kth_chain_block_serialized_size(kth_block_t block) { + return kth_chain_block_const_cpp(block).serialized_size(); } /*static*/ uint64_t kth_chain_block_subsidy(kth_size_t height) { - return kth::domain::message::block::subsidy(height); + return kth::domain::chain::block::subsidy(height); } //static uint256_t kth_chain_block_proof(uint32_t bits) {} ///*static*/ -//uint256_t kth_chain_block_proof(kth_size_t height) { -// return kth::domain::message::block::proof(height); -//} uint64_t kth_chain_block_fees(kth_block_t block) { return kth_chain_block_const_cpp(block).fees(); @@ -160,7 +157,7 @@ kth_bool_t kth_chain_block_is_valid_merkle_root(kth_block_t block) { } uint8_t const* kth_chain_block_to_data(kth_block_t block, kth_bool_t wire, kth_size_t* out_size) { - auto block_data = kth_chain_block_const_cpp(block).to_data(wire); + auto block_data = kth_chain_block_const_cpp(block).to_data(kth::int_to_bool(wire)); return kth::create_c_array(block_data, *out_size); } diff --git a/src/chain/block_list.cpp b/src/chain/block_list.cpp index 511db8d..0e7fd79 100644 --- a/src/chain/block_list.cpp +++ b/src/chain/block_list.cpp @@ -8,11 +8,11 @@ #include -KTH_LIST_DEFINE_CONVERTERS(chain, kth_block_list_t, kth::domain::message::block, block_list) -KTH_LIST_DEFINE_CONSTRUCT_FROM_CPP(chain, kth_block_list_t, kth::domain::message::block, block_list) +KTH_LIST_DEFINE_CONVERTERS(chain, kth_block_list_t, kth::domain::chain::block, block_list) +KTH_LIST_DEFINE_CONSTRUCT_FROM_CPP(chain, kth_block_list_t, kth::domain::chain::block, block_list) extern "C" { -KTH_LIST_DEFINE(chain, kth_block_list_t, kth_block_t, block_list, kth::domain::message::block, kth_chain_block_const_cpp) +KTH_LIST_DEFINE(chain, kth_block_list_t, kth_block_t, block_list, kth::domain::chain::block, kth_chain_block_const_cpp) } // extern "C" diff --git a/src/chain/chain_async.cpp b/src/chain/chain_async.cpp index ef56186..5cd52dc 100644 --- a/src/chain/chain_async.cpp +++ b/src/chain/chain_async.cpp @@ -9,10 +9,10 @@ // #include -#include -#include +#include +#include #include -#include +#include #include #include @@ -28,7 +28,7 @@ kth::blockchain::safe_chain& safe_chain(kth_chain_t chain) { inline kth::domain::message::transaction::const_ptr tx_shared(kth_transaction_t tx) { - auto const& tx_ref = *static_cast(tx); + auto const& tx_ref = *static_cast(tx); auto* tx_new = new kth::domain::message::transaction(tx_ref); return kth::domain::message::transaction::const_ptr(tx_new); } @@ -42,7 +42,7 @@ kth::domain::message::transaction::const_ptr tx_shared(kth_transaction_t tx) { inline kth::domain::message::block::const_ptr block_shared(kth_block_t block) { - auto const& block_ref = *static_cast(block); + auto const& block_ref = *static_cast(block); auto* block_new = new kth::domain::message::block(block_ref); return kth::domain::message::block::const_ptr(block_new); } @@ -67,14 +67,14 @@ void kth_chain_async_block_height(kth_chain_t chain, void* ctx, kth_hash_t hash, } void kth_chain_async_block_header_by_height(kth_chain_t chain, void* ctx, kth_size_t height, kth_block_header_fetch_handler_t handler) { - safe_chain(chain).fetch_block_header(height, [chain, ctx, handler](std::error_code const& ec, kth::domain::message::header::ptr header, size_t h) { + safe_chain(chain).fetch_block_header(height, [chain, ctx, handler](std::error_code const& ec, kth::domain::chain::header::ptr header, size_t h) { handler(chain, ctx, kth::to_c_err(ec), kth::leak_if_success(header, ec), h); }); } void kth_chain_async_block_header_by_hash(kth_chain_t chain, void* ctx, kth_hash_t hash, kth_block_header_fetch_handler_t handler) { auto hash_cpp = kth::to_array(hash.hash); - safe_chain(chain).fetch_block_header(hash_cpp, [chain, ctx, handler](std::error_code const& ec, kth::domain::message::header::ptr header, size_t h) { + safe_chain(chain).fetch_block_header(hash_cpp, [chain, ctx, handler](std::error_code const& ec, kth::domain::chain::header::ptr header, size_t h) { handler(chain, ctx, kth::to_c_err(ec), kth::leak_if_success(header, ec), h); }); } diff --git a/src/chain/chain_other.cpp b/src/chain/chain_other.cpp index c527954..971e3f8 100644 --- a/src/chain/chain_other.cpp +++ b/src/chain/chain_other.cpp @@ -9,10 +9,10 @@ // #include -#include -#include +#include +#include #include -#include +#include #include #include @@ -28,7 +28,7 @@ kth::blockchain::safe_chain& safe_chain(kth_chain_t chain) { inline kth::domain::message::transaction::const_ptr tx_shared(kth_transaction_t tx) { - auto const& tx_ref = *static_cast(tx); + auto const& tx_ref = *static_cast(tx); auto* tx_new = new kth::domain::message::transaction(tx_ref); return kth::domain::message::transaction::const_ptr(tx_new); } @@ -42,14 +42,14 @@ kth::domain::message::transaction::const_ptr tx_shared(kth_transaction_t tx) { inline kth::domain::message::block::const_ptr block_shared(kth_block_t block) { - auto const& block_ref = *static_cast(block); + auto const& block_ref = *static_cast(block); auto* block_new = new kth::domain::message::block(block_ref); return kth::domain::message::block::const_ptr(block_new); } inline -kth_block_t cast_block(kth::domain::message::block const& x) { - return const_cast(&x); +kth_block_t cast_block(kth::domain::chain::block const& x) { + return const_cast(&x); } } /* end of anonymous namespace */ @@ -72,7 +72,7 @@ void kth_chain_subscribe_blockchain(kth_node_t exec, kth_chain_t chain, void* ct if (incoming) { incoming_cpp = kth_chain_block_list_construct_default(); for (auto&& x : *incoming) { - // auto new_block = new kth::domain::message::block(*x); + // auto new_block = new kth::domain::chain::block(*x); // kth_chain_block_list_push_back(incoming_cpp, new_block); kth_chain_block_list_push_back(incoming_cpp, cast_block(*x)); } @@ -82,7 +82,7 @@ void kth_chain_subscribe_blockchain(kth_node_t exec, kth_chain_t chain, void* ct if (replaced_blocks) { replaced_blocks_cpp = kth_chain_block_list_construct_default(); for (auto&& x : *replaced_blocks) { - // auto new_block = new kth::domain::message::block(*x); + // auto new_block = new kth::domain::chain::block(*x); // kth_chain_block_list_push_back(replaced_blocks_cpp, new_block); // kth_chain_block_list_push_back_const(replaced_blocks_cpp, x.get()); kth_chain_block_list_push_back(replaced_blocks_cpp, cast_block(*x)); @@ -158,10 +158,10 @@ kth_bool_t kth_chain_is_stale(kth_chain_t chain) { // kth_transaction_t kth_chain_hex_to_tx(char const* tx_hex) { // -// static auto const version = kth::domain::message::version::level::canonical; +// static auto const version = kth::domain::chain::version::level::canonical; // -//// auto const tx = std::make_shared(); -// auto* tx = new kth::domain::message::transaction; +//// auto const tx = std::make_shared(); +// auto* tx = new kth::domain::chain::transaction; // // std::string tx_hex_cpp(tx_hex); // std::vector data(tx_hex_cpp.size() / 2); // (tx_hex_cpp.begin(), tx_hex_cpp.end()); @@ -189,7 +189,7 @@ kth_bool_t kth_chain_is_stale(kth_chain_t chain) { // // safe_chain(chain).fetch_block_locator(heights_cpp, [chain, ctx, handler](std::error_code const& ec, kth::get_headers_ptr headers) { // //TODO: check if the pointer is set, before dereferencing -// auto* new_headers = new kth::domain::message::get_headers(*headers); +// auto* new_headers = new kth::domain::chain::get_headers(*headers); // handler(chain, ctx, kth::to_c_err(ec), new_headers); // }); //} @@ -203,7 +203,7 @@ kth_bool_t kth_chain_is_stale(kth_chain_t chain) { // // safe_chain(chain).fetch_block_locator(heights_cpp, [&](std::error_code const& ec, kth::get_headers_ptr headers) { // //TODO: check if the pointer is set, before dereferencing -// *out_headers = new kth::domain::message::get_headers(*headers); +// *out_headers = new kth::domain::chain::get_headers(*headers); // res = kth::to_c_err(ec); // latch.count_down(); // }); @@ -235,9 +235,9 @@ kth_bool_t kth_chain_is_stale(kth_chain_t chain) { //// Filters. ////------------------------------------------------------------------------- // -//virtual void filter_blocks(get_data_ptr message, result_handler handler) const = 0; +//virtual void filter_blocks(get_data_ptr chain, result_handler handler) const = 0; -//void kth_chain_filter_blocks(kth_chain_t chain, void* ctx, get_data_ptr message, result_handler handler) { +//void kth_chain_filter_blocks(kth_chain_t chain, void* ctx, get_data_ptr chain, result_handler handler) { //} diff --git a/src/chain/chain_sync.cpp b/src/chain/chain_sync.cpp index 7e9a115..632a53b 100644 --- a/src/chain/chain_sync.cpp +++ b/src/chain/chain_sync.cpp @@ -9,10 +9,10 @@ // #include -#include -#include +#include +#include #include -#include +#include #include #include @@ -29,7 +29,7 @@ kth::blockchain::safe_chain& safe_chain(kth_chain_t chain) { inline kth::domain::message::transaction::const_ptr tx_shared(kth_transaction_t tx) { - auto const& tx_ref = *static_cast(tx); + auto const& tx_ref = *static_cast(tx); auto* tx_new = new kth::domain::message::transaction(tx_ref); return kth::domain::message::transaction::const_ptr(tx_new); } @@ -43,7 +43,7 @@ kth::domain::message::transaction::const_ptr tx_shared(kth_transaction_t tx) { inline kth::domain::message::block::const_ptr block_shared(kth_block_t block) { - auto const& block_ref = *static_cast(block); + auto const& block_ref = *static_cast(block); auto* block_new = new kth::domain::message::block(block_ref); return kth::domain::message::block::const_ptr(block_new); } @@ -88,7 +88,7 @@ kth_error_code_t kth_chain_sync_block_header_by_height(kth_chain_t chain, kth_si std::latch latch(1); //Note: workaround to fix an error on some versions of Boost.Threads kth_error_code_t res; - safe_chain(chain).fetch_block_header(height, [&](std::error_code const& ec, kth::domain::message::header::ptr header, size_t h) { + safe_chain(chain).fetch_block_header(height, [&](std::error_code const& ec, kth::domain::chain::header::ptr header, size_t h) { *out_header = kth::leak_if_success(header, ec); *out_height = h; res = kth::to_c_err(ec); @@ -105,7 +105,7 @@ kth_error_code_t kth_chain_sync_block_header_by_hash(kth_chain_t chain, kth_hash auto hash_cpp = kth::to_array(hash.hash); - safe_chain(chain).fetch_block_header(hash_cpp, [&](std::error_code const& ec, kth::domain::message::header::ptr header, size_t h) { + safe_chain(chain).fetch_block_header(hash_cpp, [&](std::error_code const& ec, kth::domain::chain::header::ptr header, size_t h) { *out_header = kth::leak_if_success(header, ec); *out_height = h; res = kth::to_c_err(ec); diff --git a/src/chain/header.cpp b/src/chain/header.cpp index 27c5b93..f902b11 100644 --- a/src/chain/header.cpp +++ b/src/chain/header.cpp @@ -7,24 +7,24 @@ #include #include -KTH_CONV_DEFINE(chain, kth_header_t, kth::domain::message::header, header) +KTH_CONV_DEFINE(chain, kth_header_t, kth::domain::chain::header, header) extern "C" { -kth_header_t kth_chain_header_factory_from_data(uint32_t version, uint8_t* data, kth_size_t n) { +kth_header_t kth_chain_header_factory_from_data(uint8_t* data, kth_size_t n) { kth::data_chunk data_cpp(data, std::next(data, n)); - auto header = kth::domain::create(version, data_cpp); + auto header = kth::domain::create(data_cpp); return kth::move_or_copy_and_leak(std::move(header)); } -kth_size_t kth_chain_header_satoshi_fixed_size(uint32_t version) { - return kth::domain::message::header::satoshi_fixed_size(version); +kth_size_t kth_chain_header_satoshi_fixed_size() { + return kth::domain::chain::header::satoshi_fixed_size(); } //Note: It is the responsability of the user to release/destruct the array -uint8_t const* kth_chain_header_to_data(kth_header_t header, uint32_t version, kth_size_t* out_size) { +uint8_t const* kth_chain_header_to_data(kth_header_t header, kth_size_t* out_size) { auto const& header_cpp = kth_chain_header_const_cpp(header); - auto data = header_cpp.to_data(version); + auto data = header_cpp.to_data(); return kth::create_c_array(data, *out_size); } @@ -32,12 +32,12 @@ void kth_chain_header_reset(kth_header_t header) { return kth_chain_header_cpp(header).reset(); } -kth_size_t kth_chain_header_serialized_size(kth_header_t header, uint32_t version) { - return kth_chain_header_const_cpp(header).serialized_size(version); +kth_size_t kth_chain_header_serialized_size(kth_header_t header) { + return kth_chain_header_const_cpp(header).serialized_size(); } kth_header_t kth_chain_header_construct_default() { - return new kth::domain::message::header(); + return new kth::domain::chain::header(); } kth_header_t kth_chain_header_construct(uint32_t version, uint8_t* previous_block_hash, uint8_t* merkle, uint32_t timestamp, uint32_t bits, uint32_t nonce) { @@ -46,7 +46,7 @@ kth_header_t kth_chain_header_construct(uint32_t version, uint8_t* previous_bloc auto previous_block_hash_cpp = kth::hash_to_cpp(previous_block_hash); auto merkle_cpp = kth::hash_to_cpp(merkle); - return new kth::domain::message::header(version, previous_block_hash_cpp, merkle_cpp, timestamp, bits, nonce); + return new kth::domain::chain::header(version, previous_block_hash_cpp, merkle_cpp, timestamp, bits, nonce); } void kth_chain_header_destruct(kth_header_t header) { diff --git a/src/chain/output.cpp b/src/chain/output.cpp index fd098c7..9778377 100644 --- a/src/chain/output.cpp +++ b/src/chain/output.cpp @@ -23,6 +23,75 @@ kth_output_t kth_chain_output_construct(uint64_t value, kth_script_t script) { return new kth::domain::chain::output(value, kth_chain_script_const_cpp(script), std::nullopt); } +kth_output_t kth_chain_output_construct_with_token_fungible(uint64_t value, kth_script_t script, kth_hash_t const* token_category, int64_t token_amount) { + using kth::domain::chain::amount_t; + + auto token_category_cpp = kth::to_array(token_category->hash); + + kth::domain::chain::token_data_t token_data = { + token_category_cpp, + kth::domain::chain::fungible{amount_t{token_amount}} + }; + + return new kth::domain::chain::output( + value, + kth_chain_script_const_cpp(script), + std::move(token_data) + ); +} + +kth_output_t kth_chain_output_construct_with_token_non_fungible(uint64_t value, kth_script_t script, kth_hash_t const* token_category, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n) { + auto token_category_cpp = kth::to_array(token_category->hash); + auto capability_cpp = kth::token_capability_to_cpp(capability); + kth::data_chunk commitment_cpp(commitment_data, std::next(commitment_data, commitment_n)); + + kth::domain::chain::token_data_t token_data = { + token_category_cpp, + kth::domain::chain::non_fungible{capability_cpp, std::move(commitment_cpp)} + }; + + return new kth::domain::chain::output( + value, + kth_chain_script_const_cpp(script), + std::move(token_data) + ); +} + +kth_output_t kth_chain_output_construct_with_token_both(uint64_t value, kth_script_t script, kth_hash_t const* token_category, int64_t token_amount, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n) { + using kth::domain::chain::amount_t; + + auto token_category_cpp = kth::to_array(token_category->hash); + auto capability_cpp = kth::token_capability_to_cpp(capability); + kth::data_chunk commitment_cpp(commitment_data, std::next(commitment_data, commitment_n)); + + kth::domain::chain::token_data_t token_data = { + token_category_cpp, + kth::domain::chain::both_kinds{ + kth::domain::chain::fungible{ + amount_t{token_amount} + }, + kth::domain::chain::non_fungible{ + capability_cpp, + std::move(commitment_cpp) + } + } + }; + + return new kth::domain::chain::output( + value, + kth_chain_script_const_cpp(script), + std::move(token_data) + ); +} + +kth_output_t kth_chain_output_construct_with_token_data(uint64_t value, kth_script_t script, kth_token_data_t token_data) { + return new kth::domain::chain::output( + value, + kth_chain_script_const_cpp(script), + kth_chain_token_data_const_cpp(token_data) + ); +} + void kth_chain_output_destruct(kth_output_t output) { delete &kth_chain_output_cpp(output); } @@ -68,4 +137,17 @@ uint8_t const* kth_chain_output_to_data(kth_output_t output, kth_bool_t wire, kt return kth::create_c_array(output_data, *out_size); } +// Cash Tokens --------------------------------------------------------------- + +kth_bool_t kth_chain_output_has_token_data(kth_output_t output) { + return kth::bool_to_int(kth_chain_output_const_cpp(output).token_data().has_value()); +} + +kth_token_data_t kth_chain_output_token_data(kth_output_t output) { + if ( ! kth_chain_output_cpp(output).token_data().has_value()) { + return nullptr; + } + return &kth_chain_output_cpp(output).token_data().value(); +} + } // extern "C" diff --git a/src/chain/script.cpp b/src/chain/script.cpp index eff1f18..c9583e6 100644 --- a/src/chain/script.cpp +++ b/src/chain/script.cpp @@ -70,11 +70,12 @@ char const* kth_chain_script_type(kth_script_t script) { case kth::infrastructure::machine::script_pattern::null_data: type = "nulldata"; break; case kth::infrastructure::machine::script_pattern::pay_multisig: type = "pay_multisig"; break; case kth::infrastructure::machine::script_pattern::pay_public_key: type = "pay_public_key"; break; - case kth::infrastructure::machine::script_pattern::pay_key_hash: type = "pay_key_hash"; break; + case kth::infrastructure::machine::script_pattern::pay_public_key_hash: type = "pay_public_key_hash"; break; case kth::infrastructure::machine::script_pattern::pay_script_hash: type = "pay_script_hash"; break; + case kth::infrastructure::machine::script_pattern::pay_script_hash_32: type = "pay_script_hash_32"; break; case kth::infrastructure::machine::script_pattern::sign_multisig: type = "sign_multisig"; break; case kth::infrastructure::machine::script_pattern::sign_public_key: type = "sign_public_key"; break; - case kth::infrastructure::machine::script_pattern::sign_key_hash: type = "sign_key_hash"; break; + case kth::infrastructure::machine::script_pattern::sign_public_key_hash: type = "sign_public_key_hash"; break; case kth::infrastructure::machine::script_pattern::sign_script_hash: type = "sign_script_hash"; break; default: type = "non_standard"; break; } @@ -87,9 +88,9 @@ uint8_t const* kth_chain_script_to_data(kth_script_t script, kth_bool_t prefix, return kth::create_c_array(script_data, *out_size); } -kth_size_t kth_chain_script_sigops(kth_script_t script, kth_bool_t embedded) { - return kth_chain_script_const_cpp(script).sigops(kth::int_to_bool(embedded)); -} +// kth_size_t kth_chain_script_sigops(kth_script_t script, kth_bool_t embedded) { +// return kth_chain_script_const_cpp(script).sigops(kth::int_to_bool(embedded)); +// } kth_operation_list_const_t kth_chain_script_operations(kth_script_t script) { auto& script_cpp = kth_chain_script_cpp(script); @@ -136,9 +137,9 @@ kth_bool_t kth_chain_script_is_pay_public_key_pattern(kth_operation_list_t ops) return kth::bool_to_int(kth::domain::chain::script::is_pay_public_key_pattern(ops_cpp)); } -kth_bool_t kth_chain_script_is_pay_key_hash_pattern(kth_operation_list_t ops) { +kth_bool_t kth_chain_script_is_pay_public_key_hash_pattern(kth_operation_list_t ops) { auto const& ops_cpp = kth_chain_operation_list_const_cpp(ops); - return kth::bool_to_int(kth::domain::chain::script::is_pay_key_hash_pattern(ops_cpp)); + return kth::bool_to_int(kth::domain::chain::script::is_pay_public_key_hash_pattern(ops_cpp)); } kth_bool_t kth_chain_script_is_pay_script_hash_pattern(kth_operation_list_t ops) { @@ -146,6 +147,11 @@ kth_bool_t kth_chain_script_is_pay_script_hash_pattern(kth_operation_list_t ops return kth::bool_to_int(kth::domain::chain::script::is_pay_script_hash_pattern(ops_cpp)); } +kth_bool_t kth_chain_script_is_pay_script_hash_32_pattern(kth_operation_list_t ops) { + auto const& ops_cpp = kth_chain_operation_list_const_cpp(ops); + return kth::bool_to_int(kth::domain::chain::script::is_pay_script_hash_32_pattern(ops_cpp)); +} + kth_bool_t kth_chain_script_is_sign_multisig_pattern(kth_operation_list_t ops) { auto const& ops_cpp = kth_chain_operation_list_const_cpp(ops); return kth::bool_to_int(kth::domain::chain::script::is_sign_multisig_pattern(ops_cpp)); @@ -156,9 +162,9 @@ kth_bool_t kth_chain_script_is_sign_public_key_pattern(kth_operation_list_t ops return kth::bool_to_int(kth::domain::chain::script::is_sign_public_key_pattern(ops_cpp)); } -kth_bool_t kth_chain_script_is_sign_key_hash_pattern(kth_operation_list_t ops) { +kth_bool_t kth_chain_script_is_sign_public_key_hash_pattern(kth_operation_list_t ops) { auto const& ops_cpp = kth_chain_operation_list_const_cpp(ops); - return kth::bool_to_int(kth::domain::chain::script::is_sign_key_hash_pattern(ops_cpp)); + return kth::bool_to_int(kth::domain::chain::script::is_sign_public_key_hash_pattern(ops_cpp)); } kth_bool_t kth_chain_script_is_sign_script_hash_pattern(kth_operation_list_t ops) { @@ -179,9 +185,9 @@ kth_operation_list_const_t kth_chain_script_to_pay_public_key_pattern(uint8_t co return kth::move_or_copy_and_leak(std::move(res)); } -kth_operation_list_const_t kth_chain_script_to_pay_key_hash_pattern(kth_shorthash_t const* hash) { +kth_operation_list_const_t kth_chain_script_to_pay_public_key_hash_pattern(kth_shorthash_t const* hash) { auto const hash_cpp = kth::short_hash_to_cpp(hash->hash); - auto res = kth::domain::chain::script::to_pay_key_hash_pattern(hash_cpp); + auto res = kth::domain::chain::script::to_pay_public_key_hash_pattern(hash_cpp); return kth::move_or_copy_and_leak(std::move(res)); } @@ -191,6 +197,12 @@ kth_operation_list_const_t kth_chain_script_to_pay_script_hash_pattern(kth_short return kth::move_or_copy_and_leak(std::move(res)); } +kth_operation_list_const_t kth_chain_script_to_pay_script_hash_32_pattern(kth_hash_t const* hash) { + auto const hash_cpp = kth::hash_to_cpp(hash->hash); + auto res = kth::domain::chain::script::to_pay_script_hash_32_pattern(hash_cpp); + return kth::move_or_copy_and_leak(std::move(res)); +} + kth_operation_list_const_t kth_chain_script_to_pay_multisig_pattern(uint8_t signatures, kth_ec_compressed_list_t points) { auto const& points_cpp = kth_wallet_ec_compressed_list_const_cpp(points); auto res = kth::domain::chain::script::to_pay_multisig_pattern(signatures, points_cpp); @@ -220,11 +232,47 @@ kth_bool_t kth_chain_script_is_pay_witness_script_hash_pattern(kth_operation_li } #endif +// Utilities (non-static). +//------------------------------------------------------------------------- + +/// Common pattern detection. + + +kth_script_pattern_t kth_chain_script_pattern(kth_script_t script) { + auto const& script_cpp = kth_chain_script_const_cpp(script); + return kth::script_pattern_to_c(script_cpp.pattern()); +} + +kth_script_pattern_t kth_chain_script_output_pattern(kth_script_t script) { + auto const& script_cpp = kth_chain_script_const_cpp(script); + return kth::script_pattern_to_c(script_cpp.output_pattern()); +} + +kth_script_pattern_t kth_chain_script_input_pattern(kth_script_t script) { + auto const& script_cpp = kth_chain_script_const_cpp(script); + return kth::script_pattern_to_c(script_cpp.input_pattern()); +} + +/// Consensus computations. +kth_size_t kth_chain_script_sigops(kth_script_t script, kth_bool_t accurate) { + auto const& script_cpp = kth_chain_script_const_cpp(script); + return script_cpp.sigops(kth::int_to_bool(accurate)); +} + +kth_bool_t kth_chain_script_is_unspendable(kth_script_t script) { + auto const& script_cpp = kth_chain_script_const_cpp(script); + return kth::bool_to_int(script_cpp.is_unspendable()); +} + +void kth_chain_script_reset(kth_script_t script) { + auto& script_cpp = kth_chain_script_cpp(script); + script_cpp.reset(); +} + // Signing. //------------------------------------------------------------------------- - // static // std::pair generate_signature_hash(transaction const& tx, // uint32_t input_index, @@ -256,14 +304,32 @@ kth_hash_t generate_signature_hash( uint32_t input_index, kth_script_t script_code, uint8_t sighash_type, + uint32_t active_forks, +#if ! defined(KTH_CURRENCY_BCH) kth_script_version_t version, +#endif // ! KTH_CURRENCY_BCH uint64_t value, kth_size_t* out_hashed_bytes ) { auto const& tx_cpp = kth_chain_transaction_const_cpp(tx); auto const& script_code_cpp = kth_chain_script_const_cpp(script_code); +#if ! defined(KTH_CURRENCY_BCH) auto const& version_cpp = kth::script_version_to_cpp(version); - auto res = kth::domain::chain::script::generate_signature_hash(tx_cpp, input_index, script_code_cpp, sighash_type, version_cpp, value); +#endif // ! KTH_CURRENCY_BCH + + auto res = kth::domain::chain::script::generate_signature_hash( + tx_cpp, + input_index, + script_code_cpp, + sighash_type, + active_forks, + +#if ! defined(KTH_CURRENCY_BCH) + version_cpp, +#endif // ! KTH_CURRENCY_BCH + value + ); + *out_hashed_bytes = res.second; return kth::to_hash_t(res.first); } @@ -276,7 +342,10 @@ kth_bool_t check_signature( kth_script_t script_code, kth_transaction_t tx, uint32_t input_index, + uint32_t active_forks, +#if ! defined(KTH_CURRENCY_BCH) kth_script_version_t version, +#endif // ! KTH_CURRENCY_BCH uint64_t value, kth_size_t* out_hashed_bytes ) { @@ -284,12 +353,71 @@ kth_bool_t check_signature( auto const& public_key_cpp = kth::data_chunk(public_key, public_key + public_key_size); auto const& script_code_cpp = kth_chain_script_const_cpp(script_code); auto const& tx_cpp = kth_chain_transaction_const_cpp(tx); + +#if ! defined(KTH_CURRENCY_BCH) auto const& version_cpp = kth::script_version_to_cpp(version); - auto res = kth::domain::chain::script::check_signature(signature_cpp, sighash_type, public_key_cpp, script_code_cpp, tx_cpp, input_index, version_cpp, value); +#endif // ! KTH_CURRENCY_BCH + auto res = kth::domain::chain::script::check_signature( + signature_cpp, + sighash_type, + public_key_cpp, + script_code_cpp, + tx_cpp, + input_index, + active_forks, +#if ! defined(KTH_CURRENCY_BCH) + version_cpp, +#endif // ! KTH_CURRENCY_BCH + value + ); *out_hashed_bytes = res.second; return kth::bool_to_int(res.first); } +uint8_t const* kth_chain_script_create_endorsement( + kth_ec_secret_t const* secret, + kth_script_t prevout_script, + kth_transaction_t tx, + uint32_t input_index, + uint8_t sighash_type, + uint32_t active_forks, +#if ! defined(KTH_CURRENCY_BCH) + kth_script_version_t version, +#endif // ! KTH_CURRENCY_BCH + uint64_t value, + kth_endorsement_type_t type, + kth_size_t* out_size +) { + + auto const& secret_cpp = detail::from_ec_secret_t(*secret); + auto const& prevout_script_cpp = kth_chain_script_const_cpp(prevout_script); + auto const& tx_cpp = kth_chain_transaction_const_cpp(tx); +#if ! defined(KTH_CURRENCY_BCH) + auto const version_cpp = kth::script_version_to_cpp(version); +#endif // ! KTH_CURRENCY_BCH + auto const endorsement_type_cpp = kth::endorsement_type_to_cpp(type); + + auto res = kth::domain::chain::script::create_endorsement( + secret_cpp, + prevout_script_cpp, + tx_cpp, + input_index, + sighash_type, + active_forks, +#if ! defined(KTH_CURRENCY_BCH) + version_cpp, +#endif // ! KTH_CURRENCY_BCH + value, + endorsement_type_cpp + ); + + if ( ! res) { + *out_size = 0; + return nullptr; + } + return kth::create_c_array(res.value(), *out_size); +} + // Validation. //----------------------------------------------------------------------------- diff --git a/src/chain/token_data.cpp b/src/chain/token_data.cpp index 6781845..ac7bef0 100644 --- a/src/chain/token_data.cpp +++ b/src/chain/token_data.cpp @@ -7,20 +7,60 @@ #include #include -KTH_CONV_DEFINE(chain, kth_token_data_t, kth::domain::chain::token_data, token_data) +#include + +#include + +KTH_CONV_DEFINE(chain, kth_token_data_t, kth::domain::chain::token_data_t, token_data) // --------------------------------------------------------------------------- extern "C" { kth_token_data_t kth_chain_token_data_construct_default() { - return new kth::domain::chain::token_data(); + return new kth::domain::chain::token_data_t(); +} + +kth_token_data_t kth_chain_token_data_construct_fungible(kth_hash_t const* token_category, int64_t token_amount) { + using kth::domain::chain::amount_t; + + auto token_category_cpp = kth::to_array(token_category->hash); + return new kth::domain::chain::token_data_t { + token_category_cpp, + kth::domain::chain::fungible{amount_t{token_amount}} + }; +} + +kth_token_data_t kth_chain_token_data_construct_non_fungible(kth_hash_t const* token_category, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n) { + auto token_category_cpp = kth::to_array(token_category->hash); + auto capability_cpp = kth::token_capability_to_cpp(capability); + kth::data_chunk commitment_cpp(commitment_data, std::next(commitment_data, commitment_n)); + + return new kth::domain::chain::token_data_t { + token_category_cpp, + kth::domain::chain::non_fungible{capability_cpp, std::move(commitment_cpp)} + }; } -// // token_data::token_data(const data_chunk& encoded, bool prefix) -// kth_token_data_t kth_chain_token_data_construct() { -// kth::data_chunk encoded_cpp(encoded, std::next(encoded, n)); -// return new kth::domain::chain::token_data(encoded_cpp, kth::int_to_bool(prefix)); -// } +kth_token_data_t kth_chain_token_data_construct_both(kth_hash_t const* token_category, int64_t token_amount, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n) { + using kth::domain::chain::amount_t; + + auto token_category_cpp = kth::to_array(token_category->hash); + auto capability_cpp = kth::token_capability_to_cpp(capability); + kth::data_chunk commitment_cpp(commitment_data, std::next(commitment_data, commitment_n)); + + return new kth::domain::chain::token_data_t { + token_category_cpp, + kth::domain::chain::both_kinds{ + kth::domain::chain::fungible{ + amount_t{token_amount} + }, + kth::domain::chain::non_fungible{ + capability_cpp, + std::move(commitment_cpp) + } + } + }; +} void kth_chain_token_data_destruct(kth_token_data_t token_data) { delete &kth_chain_token_data_cpp(token_data); @@ -45,4 +85,72 @@ uint8_t const* kth_chain_token_data_to_data(kth_token_data_t token_data, kth_siz return kth::create_c_array(token_data_data, *out_size); } +kth_token_kind_t kth_chain_token_data_kind(kth_token_data_t token_data) { + auto const& token_data_cpp = kth_chain_token_data_const_cpp(token_data); + if (std::holds_alternative(token_data_cpp.data)) { + return kth_token_kind_fungible; + } + if (std::holds_alternative(token_data_cpp.data)) { + return kth_token_kind_non_fungible; + } + if (std::holds_alternative(token_data_cpp.data)) { + return kth_token_kind_both; + } + return kth_token_kind_none; +} + +kth_hash_t kth_chain_token_data_category(kth_token_data_t token_data) { + auto const& category_cpp = kth_chain_token_data_const_cpp(token_data).id; + return kth::to_hash_t(category_cpp); +} + +void kth_chain_token_data_category_out(kth_token_data_t token_data, kth_hash_t* out_category) { + auto const& category_cpp = kth_chain_token_data_const_cpp(token_data).id; + kth::copy_c_hash(category_cpp, out_category); +} + +int64_t kth_chain_token_data_fungible_amount(kth_token_data_t token_data) { + auto const& token_data_cpp = kth_chain_token_data_const_cpp(token_data); + if (std::holds_alternative(token_data_cpp.data)) { + auto const& fungible_cpp = std::get(token_data_cpp.data); + return std::to_underlying(fungible_cpp.amount); + } + if (std::holds_alternative(token_data_cpp.data)) { + auto const& both_kinds_cpp = std::get(token_data_cpp.data); + auto const& fungible_cpp = both_kinds_cpp.first; + return std::to_underlying(fungible_cpp.amount); + } + return std::numeric_limits::max(); +} + +kth_token_capability_t kth_chain_token_data_non_fungible_capability(kth_token_data_t token_data) { + auto const& token_data_cpp = kth_chain_token_data_const_cpp(token_data); + if (std::holds_alternative(token_data_cpp.data)) { + auto const& non_fungible_cpp = std::get(token_data_cpp.data); + return kth::token_capability_to_c(non_fungible_cpp.capability); + } + if (std::holds_alternative(token_data_cpp.data)) { + auto const& both_kinds_cpp = std::get(token_data_cpp.data); + auto const& non_fungible_cpp = both_kinds_cpp.second; + return kth::token_capability_to_c(non_fungible_cpp.capability); + } + return kth_token_capability_none; // TODO: this is not a good way to signal an error +} + +uint8_t const* kth_chain_token_data_non_fungible_commitment(kth_token_data_t token_data, kth_size_t* out_size) { + auto const& token_data_cpp = kth_chain_token_data_const_cpp(token_data); + if (std::holds_alternative(token_data_cpp.data)) { + auto const& non_fungible_cpp = std::get(token_data_cpp.data); + return kth::create_c_array(non_fungible_cpp.commitment, *out_size); + } + if (std::holds_alternative(token_data_cpp.data)) { + auto const& both_kinds_cpp = std::get(token_data_cpp.data); + auto const& non_fungible_cpp = both_kinds_cpp.second; + return kth::create_c_array(non_fungible_cpp.commitment, *out_size); + } + + *out_size = 0; + return nullptr; +} + } // extern "C" diff --git a/src/chain/transaction.cpp b/src/chain/transaction.cpp index 2f1ae43..cdc6e81 100644 --- a/src/chain/transaction.cpp +++ b/src/chain/transaction.cpp @@ -11,23 +11,23 @@ #include -KTH_CONV_DEFINE(chain, kth_transaction_t, kth::domain::message::transaction, transaction) +KTH_CONV_DEFINE(chain, kth_transaction_t, kth::domain::chain::transaction, transaction) // --------------------------------------------------------------------------- extern "C" { - kth_transaction_t kth_chain_transaction_factory_from_data(uint32_t version, uint8_t* data, kth_size_t n) { +kth_transaction_t kth_chain_transaction_factory_from_data(uint8_t* data, kth_size_t n) { kth::data_chunk data_cpp(data, std::next(data, n)); - auto tx = kth::domain::create(version, data_cpp); + auto tx = kth::domain::create(data_cpp); return kth::move_or_copy_and_leak(std::move(tx)); } - kth_transaction_t kth_chain_transaction_construct_default() { - return new kth::domain::message::transaction(); +kth_transaction_t kth_chain_transaction_construct_default() { + return new kth::domain::chain::transaction(); } - kth_transaction_t kth_chain_transaction_construct(uint32_t version, uint32_t locktime, kth_input_list_t inputs, kth_output_list_t outputs) { - return new kth::domain::message::transaction(version, locktime, +kth_transaction_t kth_chain_transaction_construct(uint32_t version, uint32_t locktime, kth_input_list_t inputs, kth_output_list_t outputs) { + return new kth::domain::chain::transaction(version, locktime, kth_chain_input_list_const_cpp(inputs), kth_chain_output_list_const_cpp(outputs)); } @@ -45,7 +45,7 @@ uint32_t kth_chain_transaction_version(kth_transaction_t transaction) { } void kth_chain_transaction_set_version(kth_transaction_t transaction, uint32_t version) { - return static_cast(transaction)->set_version(version); + return static_cast(transaction)->set_version(version); } kth_hash_t kth_chain_transaction_hash(kth_transaction_t transaction) { @@ -148,7 +148,7 @@ kth_input_list_t kth_chain_transaction_inputs(kth_transaction_t transaction) { } uint8_t const* kth_chain_transaction_to_data(kth_transaction_t transaction, kth_bool_t wire, kth_size_t* out_size) { - auto tx_data = kth_chain_transaction_const_cpp(transaction).to_data(wire); + auto tx_data = kth_chain_transaction_const_cpp(transaction).to_data(kth::int_to_bool(wire)); return kth::create_c_array(tx_data, *out_size); } diff --git a/src/chain/transaction_list.cpp b/src/chain/transaction_list.cpp index aa805ee..6273e6b 100644 --- a/src/chain/transaction_list.cpp +++ b/src/chain/transaction_list.cpp @@ -17,11 +17,11 @@ KTH_LIST_DEFINE(chain, kth_transaction_list_t, kth_transaction_t, transaction_li } // extern "C" -// KTH_LIST_DEFINE_CONVERTERS(chain, kth_transaction_list_t, kth::domain::message::transaction, transaction_list) -// KTH_LIST_DEFINE_CONSTRUCT_FROM_CPP(chain, kth_transaction_list_t, kth::domain::message::transaction, transaction_list) +// KTH_LIST_DEFINE_CONVERTERS(chain, kth_transaction_list_t, kth::domain::chain::transaction, transaction_list) +// KTH_LIST_DEFINE_CONSTRUCT_FROM_CPP(chain, kth_transaction_list_t, kth::domain::chain::transaction, transaction_list) // extern "C" { -// KTH_LIST_DEFINE(chain, kth_transaction_list_t, kth_transaction_t, transaction_list, kth::domain::message::transaction, kth_chain_transaction_const_cpp) +// KTH_LIST_DEFINE(chain, kth_transaction_list_t, kth_transaction_t, transaction_list, kth::domain::chain::transaction, kth_chain_transaction_const_cpp) // } // extern "C" diff --git a/src/chain/utxo.cpp b/src/chain/utxo.cpp index 80d8949..e283e97 100644 --- a/src/chain/utxo.cpp +++ b/src/chain/utxo.cpp @@ -17,60 +17,257 @@ kth_utxo_t kth_chain_utxo_construct() { return new kth::domain::chain::utxo; } - kth_utxo_t kth_chain_utxo_construct_from_hash_index_amount(kth_hash_t const* hash, uint32_t index, uint64_t amount) { auto hash_cpp = kth::to_array(hash->hash); - auto ret = new kth::domain::chain::utxo(kth::domain::chain::output_point(hash_cpp, index), amount); + auto ret = new kth::domain::chain::utxo(kth::domain::chain::output_point(hash_cpp, index), amount, std::nullopt); + return ret; +} + +kth_utxo_t kth_chain_utxo_construct_from_hash_index_amount_fungible(kth_hash_t const* hash, uint32_t index, uint64_t amount, kth_hash_t const* token_category, uint64_t token_amount) { + auto hash_cpp = kth::to_array(hash->hash); + auto token_category_cpp = kth::to_array(token_category->hash); + + kth::domain::chain::token_data_t token_data { + .id = token_category_cpp, + .data = kth::domain::chain::fungible { + .amount = kth::domain::chain::amount_t{int64_t(token_amount)} + } + }; + auto ret = new kth::domain::chain::utxo( + kth::domain::chain::output_point(hash_cpp, index), + amount, + token_data); return ret; } -void kth_chain_utxo_destruct(kth_utxo_t op) { - delete &kth_chain_utxo_cpp(op); +kth_utxo_t kth_chain_utxo_construct_from_hash_index_amount_non_fungible(kth_hash_t const* hash, uint32_t index, uint64_t amount, kth_hash_t const* token_category, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n) { + auto hash_cpp = kth::to_array(hash->hash); + auto token_category_cpp = kth::to_array(token_category->hash); + auto capability_cpp = kth::token_capability_to_cpp(capability); + kth::data_chunk commitment_cpp(commitment_data, std::next(commitment_data, commitment_n)); + + kth::domain::chain::token_data_t token_data { + token_category_cpp, + kth::domain::chain::non_fungible{capability_cpp, std::move(commitment_cpp)} + }; + + auto ret = new kth::domain::chain::utxo( + kth::domain::chain::output_point(hash_cpp, index), + amount, + token_data); + return ret; } -//kth_hash_t kth_chain_utxo_get_hash(kth_utxo_t op) { -// auto const& hash_cpp = kth_chain_utxo_const_cpp(op).hash(); -// return hash_cpp.data(); -//} +kth_utxo_t kth_chain_utxo_construct_from_hash_index_amount_both(kth_hash_t const* hash, uint32_t index, uint64_t amount, kth_hash_t const* token_category, uint64_t token_amount, kth_token_capability_t capability, uint8_t* commitment_data, kth_size_t commitment_n) { + auto hash_cpp = kth::to_array(hash->hash); + auto token_category_cpp = kth::to_array(token_category->hash); + auto capability_cpp = kth::token_capability_to_cpp(capability); + kth::data_chunk commitment_cpp(commitment_data, std::next(commitment_data, commitment_n)); + -kth_hash_t kth_chain_utxo_get_hash(kth_utxo_t op) { - auto const& hash_cpp = kth_chain_utxo_const_cpp(op).point().hash(); + kth::domain::chain::token_data_t token_data { + token_category_cpp, + kth::domain::chain::both_kinds{ + kth::domain::chain::fungible{ + kth::domain::chain::amount_t{int64_t(token_amount)} + }, + kth::domain::chain::non_fungible{ + capability_cpp, + std::move(commitment_cpp) + } + } + }; + + auto ret = new kth::domain::chain::utxo( + kth::domain::chain::output_point(hash_cpp, index), + amount, + token_data); + return ret; +} + + + +void kth_chain_utxo_destruct(kth_utxo_t utxo) { + delete &kth_chain_utxo_cpp(utxo); +} + +// Getters + +kth_hash_t kth_chain_utxo_get_hash(kth_utxo_t utxo) { + auto const& hash_cpp = kth_chain_utxo_const_cpp(utxo).point().hash(); return kth::to_hash_t(hash_cpp); } -void kth_chain_utxo_get_hash_out(kth_utxo_t op, kth_hash_t* out_hash) { - auto const& hash_cpp = kth_chain_utxo_const_cpp(op).point().hash(); +void kth_chain_utxo_get_hash_out(kth_utxo_t utxo, kth_hash_t* out_hash) { + auto const& hash_cpp = kth_chain_utxo_const_cpp(utxo).point().hash(); kth::copy_c_hash(hash_cpp, out_hash); } -uint32_t kth_chain_utxo_get_index(kth_utxo_t op) { - return kth_chain_utxo_const_cpp(op).point().index(); +uint32_t kth_chain_utxo_get_index(kth_utxo_t utxo) { + return kth_chain_utxo_const_cpp(utxo).point().index(); } -uint64_t kth_chain_utxo_get_amount(kth_utxo_t op) { - return kth_chain_utxo_const_cpp(op).amount(); +uint64_t kth_chain_utxo_get_amount(kth_utxo_t utxo) { + return kth_chain_utxo_const_cpp(utxo).amount(); } -kth_output_t kth_chain_utxo_get_cached_output(kth_utxo_t op) { - auto& output = kth_chain_utxo_const_cpp(op).point().validation.cache; +kth_output_t kth_chain_utxo_get_cached_output(kth_utxo_t utxo) { + auto& output = kth_chain_utxo_const_cpp(utxo).point().validation.cache; return &output; } -void kth_chain_utxo_set_hash(kth_utxo_t op, kth_hash_t const* hash) { +kth_bool_t kth_chain_utxo_has_token_data(kth_utxo_t utxo) { + return kth_chain_utxo_const_cpp(utxo).token_data() ? + kth::bool_to_int(true) : + kth::bool_to_int(false); +} + +kth_token_data_t kth_chain_utxo_get_token_data(kth_utxo_t utxo) { + auto& utxo_cpp = kth_chain_utxo_cpp(utxo); + if ( ! utxo_cpp.token_data()) { + return nullptr; + } + return &utxo_cpp.token_data().value(); +} + +kth_hash_t kth_chain_utxo_get_token_category(kth_utxo_t utxo) { + auto const& token_data = kth_chain_utxo_const_cpp(utxo).token_data(); + if ( ! token_data) { + return kth::to_hash_t(kth::null_hash); + } + auto const& token_category_cpp = token_data->id; + return kth::to_hash_t(token_category_cpp); +} + +void kth_chain_utxo_get_token_category_out(kth_utxo_t utxo, kth_hash_t* out_token_category) { + auto const& token_data = kth_chain_utxo_const_cpp(utxo).token_data(); + if ( ! token_data) { + kth::copy_c_hash(kth::null_hash, out_token_category); + return; + } + auto const& token_category_cpp = token_data->id; + kth::copy_c_hash(token_category_cpp, out_token_category); +} + +uint64_t kth_chain_utxo_get_token_amount(kth_utxo_t utxo) { + auto const& token_data = kth_chain_utxo_const_cpp(utxo).token_data(); + if ( ! token_data) { + return kth::max_uint64; + } + if (std::holds_alternative(token_data->data)) { + return uint64_t(std::get(token_data->data).amount); + } + if (std::holds_alternative(token_data->data)) { + return uint64_t(std::get(token_data->data).first.amount); + } + return kth::max_uint64; +} + +kth_token_capability_t kth_chain_utxo_get_token_capability(kth_utxo_t utxo) { + auto const& token_data_opt = kth_chain_utxo_const_cpp(utxo).token_data(); + if ( ! token_data_opt) { + return kth_token_capability_none; + } + auto const& token_data = *token_data_opt; + if (std::holds_alternative(token_data.data)) { + auto const& non_fungible_cpp = std::get(token_data.data); + return kth::token_capability_to_c(non_fungible_cpp.capability); + } + if (std::holds_alternative(token_data.data)) { + auto const& both_kinds_cpp = std::get(token_data.data); + auto const& non_fungible_cpp = both_kinds_cpp.second; + return kth::token_capability_to_c(non_fungible_cpp.capability); + } + return kth_token_capability_none; // TODO: this is not a good way to signal an error +} + +uint8_t const* kth_chain_utxo_get_token_commitment(kth_utxo_t utxo, kth_size_t* out_size) { + auto const& token_data_opt = kth_chain_utxo_const_cpp(utxo).token_data(); + if ( ! token_data_opt) { + *out_size = 0; + return nullptr; + } + auto const& token_data = *token_data_opt; + if (std::holds_alternative(token_data.data)) { + auto const& non_fungible_cpp = std::get(token_data.data); + return kth::create_c_array(non_fungible_cpp.commitment, *out_size); + } + if (std::holds_alternative(token_data.data)) { + auto const& both_kinds_cpp = std::get(token_data.data); + auto const& non_fungible_cpp = both_kinds_cpp.second; + return kth::create_c_array(non_fungible_cpp.commitment, *out_size); + } + + *out_size = 0; + return nullptr; +} + +// Setters + +void kth_chain_utxo_set_hash(kth_utxo_t utxo, kth_hash_t const* hash) { auto hash_cpp = kth::to_array(hash->hash); - kth_chain_utxo_cpp(op).point().set_hash(hash_cpp); + kth_chain_utxo_cpp(utxo).point().set_hash(hash_cpp); +} + +void kth_chain_utxo_set_index(kth_utxo_t utxo, uint32_t index) { + kth_chain_utxo_cpp(utxo).point().set_index(index); +} + +void kth_chain_utxo_set_amount(kth_utxo_t utxo, uint64_t amount) { + kth_chain_utxo_cpp(utxo).set_amount(amount); } -void kth_chain_utxo_set_index(kth_utxo_t op, uint32_t index) { - kth_chain_utxo_cpp(op).point().set_index(index); +void kth_chain_utxo_set_cached_output(kth_utxo_t utxo, kth_output_t output) { + kth_chain_utxo_cpp(utxo).point().validation.cache = kth_chain_output_const_cpp(output); +} + +void kth_chain_utxo_set_token_data(kth_utxo_t utxo, kth_token_data_t token_data) { + auto const& token_data_cpp = kth_chain_token_data_const_cpp(token_data); + kth_chain_utxo_cpp(utxo).set_token_data(token_data_cpp); +} + +void kth_chain_utxo_set_fungible_token_data(kth_utxo_t utxo, kth_hash_t const* token_category, int64_t token_amount) { + auto token_category_cpp = kth::to_array(token_category->hash); + + kth::domain::chain::token_data_t token_data { + .id = token_category_cpp, + .data = kth::domain::chain::fungible { + .amount = kth::domain::chain::amount_t{int64_t(token_amount)} + } + }; + kth_chain_utxo_cpp(utxo).set_token_data(token_data); } -void kth_chain_utxo_set_amount(kth_utxo_t op, uint64_t amount) { - kth_chain_utxo_cpp(op).set_amount(amount); +void kth_chain_utxo_set_token_category(kth_utxo_t utxo, kth_hash_t const* token_category) { + auto token_category_cpp = kth::to_array(token_category->hash); + auto& utxo_cpp = kth_chain_utxo_cpp(utxo); + if (utxo_cpp.token_data()) { + utxo_cpp.token_data()->id = token_category_cpp; + } else { + kth::domain::chain::token_data_t token_data { + .id = token_category_cpp, + }; + utxo_cpp.set_token_data(token_data); + } } -void kth_chain_utxo_set_cached_output(kth_utxo_t op, kth_output_t output) { - kth_chain_utxo_cpp(op).point().validation.cache = kth_chain_output_const_cpp(output); +void kth_chain_utxo_set_token_amount(kth_utxo_t utxo, int64_t token_amount) { + auto& utxo_cpp = kth_chain_utxo_cpp(utxo); + if (utxo_cpp.token_data()) { + if (std::holds_alternative(utxo_cpp.token_data()->data)) { + std::get(utxo_cpp.token_data()->data).amount = kth::domain::chain::amount_t{int64_t(token_amount)}; + } else if (std::holds_alternative(utxo_cpp.token_data()->data)) { + std::get(utxo_cpp.token_data()->data).first.amount = kth::domain::chain::amount_t{int64_t(token_amount)}; + } + } else { + kth::domain::chain::token_data_t token_data { + .id = kth::null_hash, + .data = kth::domain::chain::fungible { + .amount = kth::domain::chain::amount_t{int64_t(token_amount)} + } + }; + utxo_cpp.set_token_data(token_data); + } } } // extern "C" diff --git a/src/hash.cpp b/src/hash.cpp index f38a389..a365b98 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -111,6 +111,23 @@ void kth_longhash_destruct(kth_longhash_t* longhash) { delete longhash; } +void kth_encrypted_seed_set(kth_encrypted_seed_t* seed, uint8_t const* data) { + memcpy(seed->hash, data, KTH_BITCOIN_ENCRYPTED_SEED_SIZE); +} + +void kth_encrypted_seed_destruct(kth_encrypted_seed_t* seed) { + delete seed; +} + +void kth_ec_secret_set(kth_ec_secret_t* secret, uint8_t const* data) { + memcpy(secret->hash, data, KTH_BITCOIN_EC_SECRET_SIZE); +} + +void kth_ec_secret_destruct(kth_ec_secret_t* secret) { + delete secret; +} + + // void print_hex(uint8_t const* data, size_t n) { // while (n != 0) { // printf("%2x", *data); diff --git a/src/string_list.cpp b/src/string_list.cpp index eea2110..7e8523c 100644 --- a/src/string_list.cpp +++ b/src/string_list.cpp @@ -7,9 +7,11 @@ #include #include +#include #include KTH_LIST_DEFINE_CONVERTERS(core, kth_string_list_t, std::string, string_list) +KTH_LIST_DEFINE_CONSTRUCT_FROM_CPP(core, kth_string_list_t, std::string, string_list) // --------------------------------------------------------------------------- extern "C" { @@ -26,4 +28,13 @@ void kth_core_string_list_push_back(kth_string_list_t string_list, char const* s kth_core_string_list_cpp(string_list).emplace_back(std::string(string)); } +char const* kth_core_string_list_nth(kth_string_list_t string_list, kth_size_t index) { + auto str = kth_core_string_list_cpp(string_list)[index]; + return kth::create_c_str(str); +} + +kth_size_t kth_core_string_list_count(kth_string_list_t string_list) { + return kth_core_string_list_cpp(string_list).size(); +} + } // extern "C" \ No newline at end of file diff --git a/src/wallet/payment_address.cpp b/src/wallet/payment_address.cpp index 3285f0c..3781613 100644 --- a/src/wallet/payment_address.cpp +++ b/src/wallet/payment_address.cpp @@ -26,6 +26,11 @@ kth_payment_address_t kth_wallet_payment_address_construct_from_short_hash(kth_s return new kth::domain::wallet::payment_address(hash_cpp, version); } +kth_payment_address_t kth_wallet_payment_address_construct_from_hash(kth_hash_t const* hash, uint8_t version) { + auto const hash_cpp = kth::hash_to_cpp(hash->hash); + return new kth::domain::wallet::payment_address(hash_cpp, version); +} + kth_payment_address_t kth_wallet_payment_address_construct_from_point(kth_ec_public_t point, uint8_t version) { auto const point_cpp = kth_wallet_ec_public_const_cpp(point); return new kth::domain::wallet::payment_address(point_cpp, version); @@ -36,10 +41,9 @@ kth_payment_address_t kth_wallet_payment_address_construct_from_script(kth_scrip return new kth::domain::wallet::payment_address(script_cpp, version); } -// payment_address payment_address::from_pay_key_hash_script(chain::script const& script, uint8_t version) { -kth_payment_address_t kth_wallet_payment_address_from_pay_key_hash_script(kth_script_t script, uint8_t version) { +kth_payment_address_t kth_wallet_payment_address_from_pay_public_key_hash_script(kth_script_t script, uint8_t version) { auto script_cpp = kth_chain_script_const_cpp(script); - auto pa = kth::domain::wallet::payment_address::from_pay_key_hash_script(script_cpp, version); + auto pa = kth::domain::wallet::payment_address::from_pay_public_key_hash_script(script_cpp, version); return kth::move_or_copy_and_leak(std::move(pa)); } @@ -97,22 +101,22 @@ kth_bool_t kth_wallet_payment_address_is_valid(kth_payment_address_t payment_add return kth::bool_to_int(static_cast(kth_wallet_payment_address_const_cpp(payment_address))); } -// payment_address_list_t kth_wallet_payment_address_extract(chain::script_t const* script, uint8_t p2kh_version, uint8_t p2sh_version) { -// kth::chain::script kth_script = kth_chain_script_const_cpp(script); -// auto list = kth::domain::wallet::payment_address::extract(kth_script, p2kh_version, p2sh_version); -// return kth_wallet_payment_address_list_to_capi(new std::vector(list)); -// } +kth_payment_address_list_const_t kth_wallet_payment_address_extract(kth_script_t script, uint8_t p2kh_version, uint8_t p2sh_version) { + auto const& script_cpp = kth_chain_script_const_cpp(script); + auto addrs = kth::domain::wallet::payment_address::extract(script_cpp, p2kh_version, p2sh_version); + return kth::move_or_copy_and_leak(std::move(addrs)); +} -// payment_address_list_t kth_wallet_payment_address_extract_input(chain::script_t const* script, uint8_t p2kh_version, uint8_t p2sh_version) { -// kth::chain::script kth_script = kth_chain_script_const_cpp(script); -// auto list = kth::domain::wallet::payment_address::extract_input(kth_script, p2kh_version, p2sh_version); -// return kth_wallet_payment_address_list_to_capi(new std::vector(list)); -// } +kth_payment_address_list_const_t kth_wallet_payment_address_extract_input(kth_script_t script, uint8_t p2kh_version, uint8_t p2sh_version) { + auto const& script_cpp = kth_chain_script_const_cpp(script); + auto addrs = kth::domain::wallet::payment_address::extract_input(script_cpp, p2kh_version, p2sh_version); + return kth::move_or_copy_and_leak(std::move(addrs)); +} -// payment_address_list_t kth_wallet_payment_address_extract_output(chain::script_t const* script, uint8_t p2kh_version, uint8_t p2sh_version) { -// kth::chain::script kth_script = kth_chain_script_const_cpp(script); -// auto list = kth::domain::wallet::payment_address::extract_output(kth_script, p2kh_version, p2sh_version); -// return kth_wallet_payment_address_list_to_capi(new std::vector(list)); -// } +kth_payment_address_list_const_t kth_wallet_payment_address_extract_output(kth_script_t script, uint8_t p2kh_version, uint8_t p2sh_version) { + auto const& script_cpp = kth_chain_script_const_cpp(script); + auto addrs = kth::domain::wallet::payment_address::extract_output(script_cpp, p2kh_version, p2sh_version); + return kth::move_or_copy_and_leak(std::move(addrs)); +} } // extern "C" diff --git a/src/wallet/payment_address_list.cpp b/src/wallet/payment_address_list.cpp index c4038fe..0f1dc8f 100644 --- a/src/wallet/payment_address_list.cpp +++ b/src/wallet/payment_address_list.cpp @@ -12,7 +12,7 @@ #include KTH_LIST_DEFINE_CONVERTERS(wallet, kth_payment_address_list_t, kth::domain::wallet::payment_address, payment_address_list) -KTH_LIST_DEFINE_CONSTRUCT_FROM_CPP(wallet, kth_payment_address_list_t, kth::domain::wallet::payment_address, payment_address_list) +KTH_LIST_DEFINE_CONSTRUCT_FROM_CPP_BOTH(wallet, kth_payment_address_list_t, kth::domain::wallet::payment_address, payment_address_list) extern "C" { KTH_LIST_DEFINE(wallet, kth_payment_address_list_t, kth_payment_address_t, payment_address_list, kth::domain::wallet::payment_address, kth_wallet_payment_address_const_cpp) diff --git a/src/wallet/transaction_functions.cpp b/src/wallet/transaction_functions.cpp index 56d4482..4d9b487 100644 --- a/src/wallet/transaction_functions.cpp +++ b/src/wallet/transaction_functions.cpp @@ -34,7 +34,7 @@ // ); // if (p.first == kth::error::success) { -// *out_transaction = new kth::domain::message::transaction(std::move(p.second)); +// *out_transaction = new kth::domain::chain::transaction(std::move(p.second)); // } else { // *out_transaction = nullptr; // } @@ -59,7 +59,7 @@ // ); // if (p.first == kth::error::success) { -// *out_transaction = new kth::domain::message::transaction(std::move(p.second)); +// *out_transaction = new kth::domain::chain::transaction(std::move(p.second)); // } else { // *out_transaction = nullptr; // } @@ -171,7 +171,7 @@ // ); // if (p.first == kth::error::success) { -// *out_transaction = new kth::domain::message::transaction(std::move(p.second)); +// *out_transaction = new kth::domain::chain::transaction(std::move(p.second)); // } else { // *out_transaction = nullptr; // } @@ -197,7 +197,7 @@ // // ); // // if (p.first == kth::error::success) { -// // *out_transaction = new kth::domain::message::transaction(std::move(p.second)); +// // *out_transaction = new kth::domain::chain::transaction(std::move(p.second)); // // } else { // // *out_transaction = nullptr; // // } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 049c1ad..faf7b15 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -39,6 +39,18 @@ void kth_wallet_mnemonics_to_seed_out(kth_string_list_t mnemonics, kth_longhash_ kth::copy_c_hash(hash_cpp, out_hash); } +kth_longhash_t kth_wallet_mnemonics_to_seed_normalized_passphrase(kth_string_list_t mnemonics, char const* normalized_passphrase) { + auto const& mnemonics_cpp = *static_cast const*>(mnemonics); + auto hash_cpp = kth::infrastructure::wallet::decode_mnemonic_normalized_passphrase(mnemonics_cpp, std::string(normalized_passphrase)); + return kth::to_longhash_t(hash_cpp); +} + +void kth_wallet_mnemonics_to_seed_normalized_passphrase_out(kth_string_list_t mnemonics, char const* normalized_passphrase, kth_longhash_t* out_hash) { + auto const& mnemonics_cpp = *static_cast const*>(mnemonics); + auto hash_cpp = kth::infrastructure::wallet::decode_mnemonic_normalized_passphrase(mnemonics_cpp, std::string(normalized_passphrase)); + kth::copy_c_hash(hash_cpp, out_hash); +} + //TODO(fernando): return error code and use output parameters kth_hd_private_t kth_wallet_hd_new(kth_longhash_t seed, uint32_t version /* = 76066276*/) { kth::data_chunk seed_cpp(seed.hash, std::next(seed.hash, KTH_BITCOIN_LONG_HASH_SIZE)); diff --git a/src/wallet/wallet_data.cpp b/src/wallet/wallet_data.cpp new file mode 100644 index 0000000..ebd3f40 --- /dev/null +++ b/src/wallet/wallet_data.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2016-2024 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +#include + +#include +#include +#include + +#include + + +KTH_CONV_DEFINE(wallet, kth_wallet_data_t, kth::domain::wallet::wallet_data, wallet_data) + +// --------------------------------------------------------------------------- +extern "C" { + + +void kth_wallet_wallet_data_destruct(kth_wallet_data_t wallet_data) { + delete &kth_wallet_wallet_data_cpp(wallet_data); +} + +kth_string_list_t kth_wallet_wallet_data_mnemonics(kth_wallet_data_t wallet_data) { + auto& mnemonics_cpp = kth_wallet_wallet_data_cpp(wallet_data).mnemonics; + return kth_core_string_list_construct_from_cpp(mnemonics_cpp); +} + +kth_hd_public_t kth_wallet_wallet_data_xpub(kth_wallet_data_t wallet_data) { + auto const& xpub_cpp = kth_wallet_wallet_data_cpp(wallet_data).xpub; + return kth::move_or_copy_and_leak(std::move(xpub_cpp)); +} + +kth_encrypted_seed_t kth_wallet_wallet_data_encrypted_seed(kth_wallet_data_t wallet_data) { + auto const& encrypted_seed_cpp = kth_wallet_wallet_data_cpp(wallet_data).encrypted_seed; + return kth::to_encrypted_seed_t(encrypted_seed_cpp); +} + +void kth_wallet_wallet_data_encrypted_seed_out(kth_wallet_data_t wallet_data, kth_encrypted_seed_t* out_encrypted_seed) { + auto const& encrypted_seed_cpp = kth_wallet_wallet_data_cpp(wallet_data).encrypted_seed; + kth::copy_c_hash(encrypted_seed_cpp, out_encrypted_seed); +} + +} // extern "C" diff --git a/src/wallet/wallet_manager.cpp b/src/wallet/wallet_manager.cpp new file mode 100644 index 0000000..259a879 --- /dev/null +++ b/src/wallet/wallet_manager.cpp @@ -0,0 +1,55 @@ +// Copyright (c) 2016-2024 Knuth Project developers. +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +#include + +#include +#include + +// --------------------------------------------------------------------------- +extern "C" { + +kth_error_code_t kth_wallet_create_wallet( + char const* password, + char const* normalized_passphrase, + kth_wallet_data_t* out_wallet_data) { + + auto res = kth::domain::wallet::create_wallet( + std::string(password), + std::string(normalized_passphrase) + // lexicon + ); + + if ( ! res) { + return kth::to_c_err(res.error()); + } + + *out_wallet_data = kth::move_or_copy_and_leak(std::move(res.value())); + return kth_ec_success; +} + +kth_error_code_t kth_wallet_decrypt_seed( + char const* password, + kth_encrypted_seed_t const* encrypted_seed, + kth_longhash_t** out_decrypted_seed) { + + auto seed_cpp = kth::to_array(encrypted_seed->hash); + + auto res = kth::domain::wallet::decrypt_seed( + std::string(password), + seed_cpp + ); + + if ( ! res) { + return kth::to_c_err(res.error()); + } + + *out_decrypted_seed = new kth_longhash_t; + kth::copy_c_hash(res.value(), *out_decrypted_seed); + + return kth_ec_success; +} + +} // extern "C"