Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 27 additions & 19 deletions include/btc/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,26 @@ typedef struct btc_wallet {

/* use binary trees for in-memory mapping for wtxs, keys */
void* wtxes_rbtree;
vector *vec_wtxes;
void* hdkeys_rbtree;
void* waddr_rbtree;
vector *waddr_vector; //points to the addr objects managed by the waddr_rbtree [in order]
void* spends_rbtree;
} btc_wallet;

typedef struct btc_wtx_ {
uint256 tx_hash_cache;
uint256 blockhash;
uint32_t height;
btc_tx* tx;
btc_bool ignore; //if set, transaction will be ignored (soft-delete)
} btc_wtx;

typedef struct btc_wallet_hdnode_ {
typedef struct btc_wallet_addr_{
uint160 pubkeyhash;
btc_hdnode *hdnode;
} btc_wallet_hdnode;
uint8_t type;
uint32_t childindex;
} btc_wallet_addr;

typedef struct btc_output_ {
uint32_t i;
Expand All @@ -77,13 +84,7 @@ LIBBTC_API btc_wtx* btc_wallet_wtx_new();
LIBBTC_API void btc_wallet_wtx_free(btc_wtx* wtx);
LIBBTC_API void btc_wallet_wtx_serialize(cstring* s, const btc_wtx* wtx);
LIBBTC_API btc_bool btc_wallet_wtx_deserialize(btc_wtx* wtx, struct const_buffer* buf);
/** ------------------------------------ */

/** wallet hdnode (wallet_hdnode) functions */
LIBBTC_API btc_wallet_hdnode* btc_wallet_hdnode_new();
LIBBTC_API void btc_wallet_hdnode_free(btc_wallet_hdnode* whdnode);
LIBBTC_API void btc_wallet_hdnode_serialize(cstring* s, const btc_chainparams *params, const btc_wallet_hdnode* whdnode);
LIBBTC_API btc_bool btc_wallet_hdnode_deserialize(btc_wallet_hdnode* whdnode, const btc_chainparams *params, struct const_buffer* buf);
LIBBTC_API void btc_wallet_addr_free(btc_wallet_addr* waddr);
/** ------------------------------------ */

/** wallet outputs (prev wtx + n) functions */
Expand All @@ -102,42 +103,49 @@ LIBBTC_API btc_bool btc_wallet_flush(btc_wallet* wallet);

/** set the master key of new created wallet
consuming app needs to ensure that we don't override exiting masterkeys */
LIBBTC_API void btc_wallet_set_master_key_copy(btc_wallet* wallet, btc_hdnode* masterkey);
LIBBTC_API void btc_wallet_set_master_key_copy(btc_wallet* wallet, const btc_hdnode* master_xpub);

/** derives the next child hdnode (memory is owned by the wallet) */
LIBBTC_API btc_wallet_hdnode* btc_wallet_next_key(btc_wallet* wallet);
/** derives the next child hdnode and derives an address (memory is owned by the wallet) */
LIBBTC_API btc_wallet_addr* btc_wallet_next_addr(btc_wallet* wallet);

/** writes all available addresses (P2PKH) to the addr_out vector */
LIBBTC_API void btc_wallet_get_addresses(btc_wallet* wallet, vector* addr_out);

/** searches after a hdnode by given P2PKH (base58(hash160)) address */
LIBBTC_API btc_wallet_hdnode* btc_wallet_find_hdnode_byaddr(btc_wallet* wallet, const char* search_addr);
/** finds wallet address object based on pure addresses (base58/bech32) */
LIBBTC_API btc_wallet_addr* btc_wallet_find_waddr_byaddr(btc_wallet* wallet, const char* search_addr);

/** adds transaction to the wallet (hands over memory management) */
LIBBTC_API btc_bool btc_wallet_add_wtx_move(btc_wallet* wallet, btc_wtx* wtx);

/** looks if a key with the hash160 (SHA256/RIPEMD) exists */
LIBBTC_API btc_bool btc_wallet_have_key(btc_wallet* wallet, uint160 hash160);

/** gets credit from given transaction */
LIBBTC_API int64_t btc_wallet_get_balance(btc_wallet* wallet);

/** gets credit from given transaction */
LIBBTC_API int64_t btc_wallet_wtx_get_credit(btc_wallet* wallet, btc_wtx* wtx);

LIBBTC_API int64_t btc_wallet_get_debit_tx(btc_wallet *wallet, const btc_tx *tx);
LIBBTC_API int64_t btc_wallet_wtx_get_available_credit(btc_wallet* wallet, btc_wtx* wtx);

/** checks if a transaction outpoint is owned by the wallet */
LIBBTC_API btc_bool btc_wallet_txout_is_mine(btc_wallet* wallet, btc_tx_out* tx_out);

/** checks if a transaction outpoint is owned by the wallet */
LIBBTC_API void btc_wallet_add_to_spent(btc_wallet* wallet, btc_wtx* wtx);
LIBBTC_API void btc_wallet_add_to_spent(btc_wallet* wallet, const btc_wtx* wtx);
LIBBTC_API btc_bool btc_wallet_is_spent(btc_wallet* wallet, uint256 hash, uint32_t n);
LIBBTC_API btc_bool btc_wallet_get_unspent(btc_wallet* wallet, vector* unspents);

/** checks a transaction or relevance to the wallet */
LIBBTC_API void btc_wallet_check_transaction(void *ctx, btc_tx *tx, unsigned int pos, btc_blockindex *pindex);

/** returns wtx based on given hash
* may return NULL if transaction could not be found
* memory is managed by the transaction tree
*/
LIBBTC_API btc_wtx * btc_wallet_get_wtx(btc_wallet* wallet, const uint256 hash);

#ifdef __cplusplus
}
#endif


#endif //__LIBBTC_WALLET_H__
58 changes: 58 additions & 0 deletions src/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,64 @@ btc_bool btc_script_build_p2wpkh(cstring* script_in, const uint160 hash160)
return true;
}

//btc_bool btc_script_get_script_from_address(const char *addr, cstring *script_out)
//{
// std::vector<unsigned char> data;
// uint160 hash;
// if (DecodeBase58Check(str, data)) {
// // base58-encoded Bitcoin addresses.
// // Public-key-hash-addresses have version 0 (or 111 testnet).
// // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
// const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
// if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
// std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
// return CKeyID(hash);
// }
// // Script-hash-addresses have version 5 (or 196 testnet).
// // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
// const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
// if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
// std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
// return CScriptID(hash);
// }
// }
// data.clear();
// auto bech = bech32::Decode(str);
// if (bech.second.size() > 0 && bech.first == params.Bech32HRP()) {
// // Bech32 decoding
// int version = bech.second[0]; // The first 5 bit symbol is the witness version (0-16)
// // The rest of the symbols are converted witness program bytes.
// if (ConvertBits<5, 8, false>(data, bech.second.begin() + 1, bech.second.end())) {
// if (version == 0) {
// {
// WitnessV0KeyHash keyid;
// if (data.size() == keyid.size()) {
// std::copy(data.begin(), data.end(), keyid.begin());
// return keyid;
// }
// }
// {
// WitnessV0ScriptHash scriptid;
// if (data.size() == scriptid.size()) {
// std::copy(data.begin(), data.end(), scriptid.begin());
// return scriptid;
// }
// }
// return CNoDestination();
// }
// if (version > 16 || data.size() < 2 || data.size() > 40) {
// return CNoDestination();
// }
// WitnessUnknown unk;
// unk.version = version;
// std::copy(data.begin(), data.end(), unk.program);
// unk.length = data.size();
// return unk;
// }
// }
// return CNoDestination();
//}

btc_bool btc_script_build_p2sh(cstring* script_in, const uint160 hash160)
{
cstr_resize(script_in, 0); //clear script
Expand Down
7 changes: 4 additions & 3 deletions src/tools/bitcoin-spv.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "libbtc-config.h"

#include <btc/chainparams.h>
#include <btc/base58.h>
#include <btc/ecc.h>
#include <btc/net.h>
#include <btc/netspv.h>
Expand Down Expand Up @@ -185,11 +186,11 @@ int main(int argc, char* argv[])
// TODO
}

btc_wallet_hdnode* node = btc_wallet_next_key(wallet);
btc_wallet_addr* waddr = btc_wallet_next_addr(wallet);
size_t strsize = 128;
char str[strsize];
btc_hdnode_get_p2pkh_address(node->hdnode, chain, str, strsize);
printf("Wallet addr: %s (child %d)\n", str, node->hdnode->child_num);
btc_p2wpkh_addr_from_hash160(waddr->pubkeyhash, wallet->chain, str);
printf("Wallet addr: %s (child %d)\n", str, waddr->childindex);

vector *addrs = vector_new(1, free);
btc_wallet_get_addresses(wallet, addrs);
Expand Down
Loading