cstring *ser_wallet(const struct wallet *wlt) { struct bp_key *key; cstring *rs = cstr_new_sz(20 * 1024); /* * ser "root" record */ { cstring *s_root = ser_wallet_root(wlt); cstring *recdata = message_str(wlt->chain->netmagic, "root", s_root->str, s_root->len); cstr_append_buf(rs, recdata->str, recdata->len); cstr_free(recdata, true); cstr_free(s_root, true); } /* ser "privkey" records */ wallet_for_each_key(wlt, key) { void *privkey = NULL; size_t pk_len = 0; bp_privkey_get(key, &privkey, &pk_len); cstring *recdata = message_str(wlt->chain->netmagic, "privkey", privkey, pk_len); free(privkey); cstr_append_buf(rs, recdata->str, recdata->len); cstr_free(recdata, true); }
cstring *message_str(const unsigned char netmagic[4], const char *command_, const void *data, uint32_t data_len) { cstring *s = cstr_new_sz(P2P_HDR_SZ + data_len); /* network identifier (magic number) */ cstr_append_buf(s, netmagic, 4); /* command string */ char command[12] = {}; strncpy(command, command_, 12); cstr_append_buf(s, command, 12); /* data length */ uint32_t data_len_le = htole32(data_len); cstr_append_buf(s, &data_len_le, 4); /* data checksum */ unsigned char md32[4]; bu_Hash4(md32, data, data_len); cstr_append_buf(s, &md32[0], 4); /* data payload */ if (data_len > 0) cstr_append_buf(s, data, data_len); return s; }
void logdb_record_set(logdb_record* rec, struct buffer *key, struct buffer *val) { if (key == NULL) return; cstr_append_buf(rec->key, key->p, key->len); if (val) { cstr_append_buf(rec->value, val->p, val->len); rec->mode = RECORD_TYPE_WRITE; } else rec->mode = RECORD_TYPE_ERASE; }
static void test_privkey_valid_dec(const char *base58_str, cstring *payload, bool compress, bool is_testnet) { assert(payload != NULL); cstring *pl = cstr_new_sz(payload->len + 1); cstr_append_buf(pl, payload->str, payload->len); if (compress) cstr_append_c(pl, 1); unsigned char addrtype; cstring *dec = base58_decode_check(&addrtype, base58_str); assert(dec != NULL); if (is_testnet) assert(addrtype == PRIVKEY_ADDRESS_TEST); else assert(addrtype == PRIVKEY_ADDRESS); if (compress) { assert(dec->len == 33); assert(dec->str[32] == 1); } else assert(dec->len == 32); assert(dec->len == pl->len); assert(memcmp(dec->str, pl->str, pl->len) == 0); cstr_free(dec, true); cstr_free(pl, true); cstr_free(payload, true); }
static void test_privkey_valid_enc(const char *base58_str, cstring *payload, bool compress, bool is_testnet) { assert(payload != NULL); cstring *pl = cstr_new_sz(payload->len + 1); cstr_append_buf(pl, payload->str, payload->len); if (compress) cstr_append_c(pl, 1); cstring *b58 = base58_encode_check( is_testnet ? PRIVKEY_ADDRESS_TEST : PRIVKEY_ADDRESS, true, pl->str, pl->len); assert(b58 != NULL); if (strcmp(b58->str, base58_str)) { fprintf(stderr, "base58: have %s, expected %s\n", b58->str, base58_str); assert(!strcmp(b58->str, base58_str)); } cstr_free(b58, true); cstr_free(pl, true); cstr_free(payload, true); }
cstring *base58_encode_check(unsigned char addrtype, bool have_addrtype, const void *data, size_t data_len) { cstring *s = cstr_new_sz(data_len + 1 + 4); if (have_addrtype) cstr_append_c(s, addrtype); cstr_append_buf(s, data, data_len); unsigned char md32[4]; bu_Hash4(md32, s->str, s->len); cstr_append_buf(s, md32, 4); cstring *s_enc = base58_encode(s->str, s->len); cstr_free(s, true); return s_enc; }
void btc_tx_out_copy(btc_tx_out* dest, const btc_tx_out* src) { dest->value = src->value; if (!src->script_pubkey) dest->script_pubkey = NULL; else { dest->script_pubkey = cstr_new_sz(src->script_pubkey->len); cstr_append_buf(dest->script_pubkey, src->script_pubkey->str, src->script_pubkey->len); } }
void btc_tx_in_copy(btc_tx_in* dest, const btc_tx_in* src) { memcpy(&dest->prevout, &src->prevout, sizeof(dest->prevout)); dest->sequence = src->sequence; if (!src->script_sig) dest->script_sig = NULL; else { dest->script_sig = cstr_new_sz(src->script_sig->len); cstr_append_buf(dest->script_sig, src->script_sig->str, src->script_sig->len); } }
wallet_for_each_mkey(wlt, hdkey) { struct hd_extended_key_serialized hdraw; bool rc = write_ek_ser_prv(&hdraw, hdkey); assert(rc == true); cstring *recdata = message_str(wlt->chain->netmagic, "hdmaster", hdraw.data, sizeof(hdraw.data) - 1); assert(recdata != NULL); cstr_append_buf(rs, recdata->str, recdata->len); cstr_free(recdata, true); }
void test_cstr() { cstring* s1 = cstr_new("foo"); cstring* s2 = cstr_new("foo"); cstring* s3 = cstr_new("bar"); cstring* s4 = cstr_new("bar1"); cstring* s = cstr_new("foo"); assert(s != NULL); assert(s->len == 3); assert(strcmp(s->str, "foo") == 0); cstr_free(s, true); s = cstr_new_sz(200); assert(s != NULL); assert(s->alloc > 200); assert(s->len == 0); cstr_free(s, true); s = cstr_new_buf("foo", 2); assert(s != NULL); assert(s->len == 2); assert(strcmp(s->str, "fo") == 0); cstr_free(s, true); s = cstr_new(NULL); assert(s != NULL); cstr_append_buf(s, "f", 1); cstr_append_buf(s, "o", 1); cstr_append_buf(s, "o", 1); assert(s->len == 3); assert(strcmp(s->str, "foo") == 0); cstr_free(s, true); s = cstr_new("foo"); assert(s != NULL); cstr_resize(s, 2); cstr_resize(s, 2); cstr_alloc_minsize(s, 2); cstr_alloc_minsize(s, 1); assert(s->len == 2); assert(strcmp(s->str, "fo") == 0); cstr_resize(s, 4); assert(s->len == 4); assert(s->alloc > 4); memcpy(s->str, "food", 4); assert(strcmp(s->str, "food") == 0); cstr_free(s, true); assert(cstr_compare(s1, s2) == 0); assert(cstr_compare(s1, s3) == 1); assert(cstr_compare(s3, s1) == -1); assert(cstr_compare(s3, s4) == -1); assert(cstr_compare(s4, s3) == 1); assert(cstr_equal(s1, s2) == true); assert(cstr_equal(s1, s3) == false); assert(cstr_equal(s1, NULL) == false); assert(cstr_equal(s2, s3) == false); assert(cstr_equal(s3, s3) == true); assert(cstr_equal(s3, s4) == false); cstr_erase(s4, 0, 3); cstr_erase(s4, 110, 3); cstr_erase(s4, s4->len, 0); cstr_erase(s4, 0, 100); assert(strcmp(s4->str, "1") == 0); cstr_free(s1, true); cstr_free(s2, true); cstr_free(s3, true); cstr_free(s4, true); }
void test_logdb(logdb_log_db* (*new_func)()) { logdb_log_db *db; enum logdb_error error = 0; cstring *key;// key= {"key0", 4}; cstring *value;// = {"val0", 4}; cstring *key1; cstring *value1; cstring *outtest; cstring *value_test; unsigned char testbin[4] = {0x00, 0x10, 0x20, 0x30}; cstring *value0;// = {"dumb", 4}; cstring *key2;// = {"pkey", 4}; cstring *value2; cstring *smp_value; cstring *smp_key; uint8_t txbin[10240]; uint8_t txbin_rev[10240]; char hexrev[98]; int outlenrev; long fsize; char *buf; char *wrk_buf; FILE *f; unsigned int i; char bufs[300][65]; rb_red_blk_node *nodetest; unsigned int cnt = 0; logdb_record* rec; key = cstr_new("key0"); value = cstr_new("val0"); value0 = cstr_new("dumb"); value1 = cstr_new_sz(10); value2 = cstr_new_sz(10); key1 = cstr_new_sz(10); key2 = cstr_new("key2"); cstr_append_buf(value2, testbin, sizeof(testbin)); cstr_append_buf(value2, testbin, sizeof(testbin)); cstr_append_buf(key1, key1str, strlen(key1str)); cstr_append_buf(value1, value1str, strlen(value1str)); unlink(dbtmpfile); db = new_func(); u_assert_int_eq(logdb_load(db, "file_that_should_not_exists.dat", false, NULL), false); u_assert_int_eq(logdb_load(db, dbtmpfile, true, NULL), true); logdb_append(db, NULL, key, value); logdb_append(db, NULL, key1, value1); u_assert_int_eq(logdb_cache_size(db), 2); outtest = logdb_find_cache(db, key1); u_assert_int_eq(strcmp(outtest->str, value1str),0); logdb_flush(db); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); u_assert_int_eq(logdb_count_keys(db), 2); value_test = logdb_find(db, key1); u_assert_int_eq(strcmp(value_test->str, value1str), 0); value_test = logdb_find(db, key); u_assert_int_eq(memcmp(value_test->str, value->str, value->len), 0); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); logdb_append(db, NULL, key2, value2); logdb_flush(db); logdb_free(db); /* check if private key is available */ db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); value_test = logdb_find(db, key2); u_assert_int_eq(memcmp(value_test->str, value2->str, value2->len), 0); value_test = logdb_find(db, key); u_assert_int_eq(memcmp(value_test->str, value->str, value->len), 0); /* delete a record */ logdb_delete(db, NULL, key2); logdb_flush(db); logdb_free(db); /* find and check the deleted record */ db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); value_test = logdb_find(db, key); u_assert_int_eq(memcmp(value_test->str, value->str, value->len), 0); value_test = logdb_find(db, key2); u_assert_int_eq((int)value_test, 0); /* should be null */ /* overwrite a key */ logdb_append(db, NULL, key, value0); value_test = logdb_find(db, key); u_assert_int_eq(memcmp(value_test->str, value0->str, value0->len), 0); logdb_flush(db); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); value_test = logdb_find(db, key); u_assert_int_eq(memcmp(value_test->str, value0->str, value0->len), 0); logdb_flush(db); logdb_free(db); /* simulate corruption */ f = fopen(dbtmpfile, "rb"); fseek(f, 0, SEEK_END); fsize = ftell(f); fseek(f, 0, SEEK_SET); buf = malloc(fsize + 1); fread(buf, fsize, 1, f); fclose(f); /* ---------------------------------------------------- */ wrk_buf = safe_malloc(fsize + 1); memcpy(wrk_buf, buf, fsize); wrk_buf[0] = 0x88; /* wrong header */ unlink(dbtmpfile); f = fopen(dbtmpfile, "wb"); fwrite(wrk_buf, 1, fsize, f); fclose(f); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), false); u_assert_int_eq(error, LOGDB_ERROR_WRONG_FILE_FORMAT); logdb_free(db); /* ---------------------------------------------------- */ memcpy(wrk_buf, buf, fsize); wrk_buf[66] = 0x00; /* wrong checksum hash */ unlink(dbtmpfile); f = fopen(dbtmpfile, "wb"); fwrite(wrk_buf, 1, fsize, f); fclose(f); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), false); u_assert_int_eq(error, LOGDB_ERROR_CHECKSUM); logdb_free(db); /* ---------------------------------------------------- */ memcpy(wrk_buf, buf, fsize); wrk_buf[42] = 0xFF; /* wrong value length */ unlink(dbtmpfile); f = fopen(dbtmpfile, "wb"); fwrite(wrk_buf, 1, fsize, f); fclose(f); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), false); u_assert_int_eq(error, LOGDB_ERROR_DATASTREAM_ERROR); logdb_free(db); free(buf); free(wrk_buf); /* --- large db test */ unlink(dbtmpfile); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, true, NULL), true); smp_key = cstr_new_sz(100); smp_value = cstr_new_sz(100); for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); cstr_erase(smp_value, 0, smp_value->len); cstr_append_buf(smp_value, txbin, outlen); logdb_append(db, NULL, smp_key, smp_value); } u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); /* check all records */ for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); outtest = logdb_find(db, smp_key); outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); u_assert_int_eq(outlen, outtest->len); } logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); /* check all records */ for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); memcpy(hexrev, tx->txhash, sizeof(tx->txhash)); utils_reverse_hex(hexrev, strlen(tx->txhash)); outlenrev = sizeof(tx->txhash) / 2; utils_hex_to_bin(hexrev, txbin_rev, strlen(hexrev), &outlenrev); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); outtest = logdb_find(db, smp_key); outlen = strlen(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); u_assert_int_eq(outlen, outtest->len); /* hash transaction data and check hashes */ if (strlen(tx->hextx) > 2) { uint8_t tx_hash_check[SHA256_DIGEST_LENGTH]; sha256_Raw(txbin, outlen, tx_hash_check); sha256_Raw(tx_hash_check, 32, tx_hash_check); u_assert_int_eq(memcmp(tx_hash_check, txbin_rev, SHA256_DIGEST_LENGTH), 0); } } /* check all records */ for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); logdb_delete(db, NULL, smp_key); } u_assert_int_eq(logdb_count_keys(db), 0); logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(error, LOGDB_SUCCESS); u_assert_int_eq(logdb_count_keys(db), 0); for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); cstr_erase(smp_value, 0, smp_value->len); cstr_append_buf(smp_value, txbin, outlen); logdb_append(db, NULL, smp_key, smp_value); } logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(error, LOGDB_SUCCESS); u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); logdb_flush(db); logdb_free(db); db = new_func(); error = 0; u_assert_int_eq(logdb_load(db, dbtmpfile, false, &error), true); u_assert_int_eq(error, LOGDB_SUCCESS); u_assert_int_eq(logdb_count_keys(db), (sizeof(sampledata) / sizeof(sampledata[0]))); if(new_func == logdb_rbtree_new) { logdb_rbtree_db* handle = (logdb_rbtree_db *)db->cb_ctx; size_t size = rbtree_count(handle->tree); nodetest = NULL; while ((nodetest = rbtree_enumerate_next(handle->tree))) { rec = (logdb_record *)nodetest->info; utils_bin_to_hex((unsigned char *)rec->key->str, rec->key->len, bufs[cnt]); for(i = 0; i < cnt; i++) { u_assert_int_eq(strcmp(bufs[i], bufs[cnt]) != 0, 1); } cnt++; } u_assert_int_eq(size, cnt); } for (i = 0; i < (sizeof(sampledata) / sizeof(sampledata[0])); i++) { const struct txtest *tx = &sampledata[i]; uint8_t hashbin[sizeof(tx->txhash) / 2]; int outlen = sizeof(tx->txhash) / 2; utils_hex_to_bin(tx->txhash, hashbin, strlen(tx->txhash), &outlen); cstr_erase(smp_key, 0, smp_key->len); cstr_append_buf(smp_key, hashbin, outlen); outlen = sizeof(tx->hextx) / 2; utils_hex_to_bin(tx->hextx, txbin, strlen(tx->hextx), &outlen); cstr_erase(smp_value, 0, smp_value->len); cstr_append_buf(smp_value, txbin, outlen); logdb_append(db, NULL, smp_key, smp_value); } logdb_flush(db); logdb_free(db); /* test switch mem mapper after initialitaion. */ db = logdb_new(); logdb_set_memmapper(db, &logdb_rbtree_mapper, NULL); logdb_flush(db); logdb_free(db); unlink(dbtmpfile); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, true, NULL), true); // create transaction, don't store logdb_txn* txn = logdb_txn_new(); logdb_append(db, txn, key, value); logdb_append(db, txn, key1, value1); u_assert_int_eq(logdb_cache_size(db), 0); logdb_txn_free(txn); logdb_flush(db); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); // db should still be empty u_assert_int_eq(logdb_count_keys(db), 0); // create transaction, store it this time txn = logdb_txn_new(); logdb_append(db, txn, key, value); logdb_append(db, txn, key1, value1); logdb_txn_commit(db, txn); u_assert_int_eq(logdb_cache_size(db), 2); logdb_txn_free(txn); logdb_flush(db); logdb_free(db); db = new_func(); u_assert_int_eq(logdb_load(db, dbtmpfile, false, NULL), true); // now we should have the two persisted items from the txn u_assert_int_eq(logdb_count_keys(db), 2); logdb_flush(db); logdb_free(db); cstr_free(key, true); cstr_free(value, true); cstr_free(value0, true); cstr_free(value1, true); cstr_free(value2, true); cstr_free(key1, true); cstr_free(key2, true); cstr_free(smp_key, true); cstr_free(smp_value, true); }
static void test_basic(void) { cstring *s = cstr_new("foo"); assert(s != NULL); assert(s->len == 3); assert(strcmp(s->str, "foo") == 0); cstr_free(s, true); s = cstr_new_sz(200); assert(s != NULL); assert(s->alloc > 200); assert(s->len == 0); cstr_free(s, true); s = cstr_new_buf("foo", 2); assert(s != NULL); assert(s->len == 2); assert(strcmp(s->str, "fo") == 0); cstr_free(s, true); s = cstr_new(NULL); assert(s != NULL); cstr_append_buf(s, "f", 1); cstr_append_buf(s, "o", 1); cstr_append_buf(s, "o", 1); assert(s->len == 3); assert(strcmp(s->str, "foo") == 0); cstr_free(s, true); s = cstr_new("foo"); assert(s != NULL); cstr_resize(s, 2); assert(s->len == 2); assert(strcmp(s->str, "fo") == 0); cstr_resize(s, 4); assert(s->len == 4); assert(s->alloc > 4); memcpy(s->str, "food", 4); assert(strcmp(s->str, "food") == 0); cstr_free(s, true); cstring *s1 = cstr_new("foo"); cstring *s2 = cstr_new("foo"); cstring *s3 = cstr_new("bar"); assert(cstr_equal(s1, s2) == true); assert(cstr_equal(s1, s3) == false); assert(cstr_equal(s2, s3) == false); assert(cstr_equal(s3, s3) == true); cstr_free(s1, true); cstr_free(s2, true); cstr_free(s3, true); }
btc_bool btc_tx_sighash(const btc_tx* tx_to, const cstring* fromPubKey, unsigned int in_num, int hashtype, uint8_t* hash) { if (in_num >= tx_to->vin->len) return false; btc_bool ret = true; btc_tx* tx_tmp = btc_tx_new(); btc_tx_copy(tx_tmp, tx_to); cstring* new_script = cstr_new_sz(fromPubKey->len); btc_script_copy_without_op_codeseperator(fromPubKey, new_script); unsigned int i; btc_tx_in* tx_in; for (i = 0; i < tx_tmp->vin->len; i++) { tx_in = vector_idx(tx_tmp->vin, i); cstr_resize(tx_in->script_sig, 0); if (i == in_num) cstr_append_buf(tx_in->script_sig, new_script->str, new_script->len); } cstr_free(new_script, true); /* Blank out some of the outputs */ if ((hashtype & 0x1f) == SIGHASH_NONE) { /* Wildcard payee */ if (tx_tmp->vout) vector_free(tx_tmp->vout, true); tx_tmp->vout = vector_new(1, btc_tx_out_free_cb); /* Let the others update at will */ for (i = 0; i < tx_tmp->vin->len; i++) { tx_in = vector_idx(tx_tmp->vin, i); if (i != in_num) tx_in->sequence = 0; } } else if ((hashtype & 0x1f) == SIGHASH_SINGLE) { /* Only lock-in the txout payee at same index as txin */ unsigned int n_out = in_num; if (n_out >= tx_tmp->vout->len) { //TODO: set error code ret = false; goto out; } vector_resize(tx_tmp->vout, n_out + 1); for (i = 0; i < n_out; i++) { btc_tx_out* tx_out; tx_out = vector_idx(tx_tmp->vout, i); tx_out->value = -1; if (tx_out->script_pubkey) { cstr_free(tx_out->script_pubkey, true); tx_out->script_pubkey = NULL; } } /* Let the others update at will */ for (i = 0; i < tx_tmp->vin->len; i++) { tx_in = vector_idx(tx_tmp->vin, i); if (i != in_num) tx_in->sequence = 0; } } /* Blank out other inputs completely; not recommended for open transactions */ if (hashtype & SIGHASH_ANYONECANPAY) { if (in_num > 0) vector_remove_range(tx_tmp->vin, 0, in_num); vector_resize(tx_tmp->vin, 1); } cstring* s = cstr_new_sz(512); btc_tx_serialize(s, tx_tmp); ser_s32(s, hashtype); sha256_Raw((const uint8_t*)s->str, s->len, hash); sha256_Raw(hash, 32, hash); cstr_free(s, true); out: btc_tx_free(tx_tmp); return ret; }
int cstr_append_c(cstring* s, char ch) { return cstr_append_buf(s, &ch, 1); }
int cstr_append_cstr(cstring* s, cstring *append) { return cstr_append_buf(s, append->str, append->len); }