btc_bool btc_tx_in_deserialize(btc_tx_in* tx_in, struct const_buffer* buf) { deser_u256(tx_in->prevout.hash, buf); if (!deser_u32(&tx_in->prevout.n, buf)) return false; if (!deser_varstr(&tx_in->script_sig, buf)) return false; if (!deser_u32(&tx_in->sequence, buf)) return false; return true; }
bool deser_peer(unsigned int protover, struct peer *peer, struct const_buffer *buf) { peer_free(peer); if (!deser_bp_addr(protover, &peer->addr, buf)) return false; if (!deser_s64(&peer->last_ok, buf)) return false; if (!deser_u32(&peer->n_ok, buf)) return false; if (!deser_s64(&peer->last_fail, buf)) return false; if (!deser_u32(&peer->n_fail, buf)) return false; return true; }
static bool deser_wallet_account(struct wallet *wlt, struct const_buffer *buf) { struct wallet_account *acct; acct = calloc(1, sizeof(*acct)); if (!acct) return false; if (!deser_varstr(&acct->name, buf) || !deser_u32(&acct->acct_idx, buf) || !deser_u32(&acct->next_key_idx, buf)) goto err_out; parr_add(wlt->accounts, acct); return true; err_out: account_free(acct); return false; }
bool deser_msg_version(struct msg_version *mv, struct const_buffer *buf) { memset(mv, 0, sizeof(*mv)); if (!deser_u32(&mv->nVersion, buf)) return false; if (mv->nVersion == 10300) mv->nVersion = 300; if (!deser_u64(&mv->nServices, buf)) return false; if (!deser_s64(&mv->nTime, buf)) return false; if (!deser_bp_addr(MIN_PROTO_VERSION, &mv->addrTo, buf)) return false; if (mv->nVersion >= 106) { if (!deser_bp_addr(MIN_PROTO_VERSION, &mv->addrFrom, buf)) return false; if (!deser_u64(&mv->nonce, buf)) return false; if (!deser_str(mv->strSubVer, buf, sizeof(mv->strSubVer))) return false; if (mv->nVersion >= 209) if (!deser_u32(&mv->nStartingHeight, buf)) return false; } return true; }
bool bsp_getop(struct bscript_op *op, struct bscript_parser *bp) { if (bp->buf->len == 0) return false; /* EOF */ unsigned char opcode; if (!deser_bytes(&opcode, bp->buf, 1)) goto err_out; op->op = opcode; uint32_t data_len; if (opcode < OP_PUSHDATA1) data_len = opcode; else if (opcode == OP_PUSHDATA1) { uint8_t v8; if (!deser_bytes(&v8, bp->buf, 1)) goto err_out; data_len = v8; } else if (opcode == OP_PUSHDATA2) { uint16_t v16; if (!deser_u16(&v16, bp->buf)) goto err_out; data_len = v16; } else if (opcode == OP_PUSHDATA4) { uint32_t v32; if (!deser_u32(&v32, bp->buf)) goto err_out; data_len = v32; } else { assert(!is_bsp_pushdata(opcode)); op->data.p = NULL; op->data.len = 0; return true; } op->data.p = bp->buf->p; op->data.len = data_len; if (!deser_skip(bp->buf, data_len)) goto err_out; return true; err_out: bp->error = true; return false; }
int btc_tx_deserialize(const unsigned char* tx_serialized, size_t inlen, btc_tx* tx) { struct const_buffer buf = {tx_serialized, inlen}; //tx needs to be initialized deser_s32(&tx->version, &buf); uint32_t vlen; if (!deser_varlen(&vlen, &buf)) return false; unsigned int i; for (i = 0; i < vlen; i++) { btc_tx_in* tx_in = btc_tx_in_new(); if (!btc_tx_in_deserialize(tx_in, &buf)) { free(tx_in); } vector_add(tx->vin, tx_in); } if (!deser_varlen(&vlen, &buf)) return false; for (i = 0; i < vlen; i++) { btc_tx_out* tx_out = btc_tx_out_new(); if (!btc_tx_out_deserialize(tx_out, &buf)) { free(tx_out); } vector_add(tx->vout, tx_out); } if (!deser_u32(&tx->locktime, &buf)) return false; return true; }
void test_serialize() { char hex0[] = "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1"; char hex1[] = "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c2"; char hex2[] = "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c3"; uint8_t* hash0 = malloc(32); uint8_t* hash1 = malloc(32); uint8_t* hash2 = malloc(32); memcpy(hash0, utils_hex_to_uint8(hex0), 32); memcpy(hash1, utils_hex_to_uint8(hex1), 32); memcpy(hash2, utils_hex_to_uint8(hex2), 32); vector* vec = vector_new(5, free); vector_add(vec, hash0); vector_add(vec, hash1); vector_add(vec, hash2); cstring* s = cstr_new_sz(200); ser_u256_vector(s, vec); vector_free(vec, true); vector* vec2 = vector_new(0, NULL); struct const_buffer buf = {s->str, s->len}; deser_u256_vector(&vec2, &buf); vector_free(vec2, true); cstr_free(s, true); cstring* s2 = cstr_new_sz(200); ser_u16(s2, 0xAAFF); ser_u32(s2, 0xDDBBAAFF); ser_u64(s2, 0x99FF99FFDDBBAAFF); ser_varlen(s2, 10); ser_varlen(s2, 1000); ser_varlen(s2, 100000000); ser_str(s2, "test", 4); cstring* s3 = cstr_new("foo"); ser_varstr(s2, s3); cstr_free(s3, true); // ser_varlen(s2, (uint64_t)0x9999999999999999); // uint64 varlen is not supported right now struct const_buffer buf2 = {s2->str, s2->len}; uint16_t num0; deser_u16(&num0, &buf2); assert(num0 == 43775); //0xAAFF uint32_t num1; deser_u32(&num1, &buf2); assert(num1 == 3720063743); //0xDDBBAAFF uint64_t num2; deser_u64(&num2, &buf2); assert(num2 == 0x99FF99FFDDBBAAFF); //0x99FF99FFDDBBAAFF uint32_t num3; deser_varlen(&num3, &buf2); assert(num3 == 10); deser_varlen(&num3, &buf2); assert(num3 == 1000); deser_varlen(&num3, &buf2); assert(num3 == 100000000); char strbuf[255]; deser_str(strbuf, &buf2, 255); assert(strncmp(strbuf, "test", 4) == 0); cstring* deser_test = cstr_new_sz(0); deser_varstr(&deser_test, &buf2); assert(strncmp(deser_test->str, "foo", 3) == 0); cstr_free(deser_test, true); cstr_free(s2, true); }