libbtc
bitcoinclibrary
tx.c
Go to the documentation of this file.
1 /*
2 
3  The MIT License (MIT)
4 
5  Copyright (c) 2015 Jonas Schnelli
6 
7  Permission is hereby granted, free of charge, to any person obtaining
8  a copy of this software and associated documentation files (the "Software"),
9  to deal in the Software without restriction, including without limitation
10  the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  and/or sell copies of the Software, and to permit persons to whom the
12  Software is furnished to do so, subject to the following conditions:
13 
14  The above copyright notice and this permission notice shall be included
15  in all copies or substantial portions of the Software.
16 
17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
21  OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  OTHER DEALINGS IN THE SOFTWARE.
24 
25 */
26 
27 #include <stdint.h>
28 #include <stddef.h>
29 #include <stdint.h>
30 #include <string.h>
31 
32 #include "btc/base58.h"
33 #include "btc/tx.h"
34 
35 #include "serialize.h"
36 #include "sha2.h"
37 #include "utils.h"
38 
40 {
41  if (!tx_in)
42  return;
43 
44  memset(&tx_in->prevout.hash, 0, 32);
45  tx_in->prevout.n = 0;
46 
47  if (tx_in->script_sig) {
48  cstr_free(tx_in->script_sig, true);
49  tx_in->script_sig = NULL;
50  }
51 }
52 
53 //callback for vector free function
54 void btc_tx_in_free_cb(void* data)
55 {
56  if (!data)
57  return;
58 
59  btc_tx_in* tx_in = data;
60  btc_tx_in_free(tx_in);
61 
62  memset(tx_in, 0, sizeof(*tx_in));
63  free(tx_in);
64 }
65 
66 
68 {
69  btc_tx_in* tx_in;
70  tx_in = calloc(1, sizeof(*tx_in));
71  memset(&tx_in->prevout, 0, sizeof(tx_in->prevout));
72  tx_in->sequence = UINT32_MAX;
73  return tx_in;
74 }
75 
76 
78 {
79  if (!tx_out)
80  return;
81  tx_out->value = 0;
82 
83  if (tx_out->script_pubkey) {
84  cstr_free(tx_out->script_pubkey, true);
85  tx_out->script_pubkey = NULL;
86  }
87 }
88 
89 
90 void btc_tx_out_free_cb(void* data)
91 {
92  if (!data)
93  return;
94 
95  btc_tx_out* tx_out = data;
96  btc_tx_out_free(tx_out);
97 
98  memset(tx_out, 0, sizeof(*tx_out));
99  free(tx_out);
100 }
101 
102 
104 {
105  btc_tx_out* tx_out;
106  tx_out = calloc(1, sizeof(*tx_out));
107 
108  return tx_out;
109 }
110 
111 
113 {
114  if (tx->vin)
115  vector_free(tx->vin, true);
116 
117  if (tx->vout)
118  vector_free(tx->vout, true);
119 
120  free(tx);
121 }
122 
123 
125 {
126  btc_tx* tx;
127  tx = calloc(1, sizeof(*tx));
128  tx->vin = vector_new(8, btc_tx_in_free_cb);
130  tx->version = 1;
131  tx->locktime = 0;
132  return tx;
133 }
134 
135 
137 {
138  deser_u256(tx_in->prevout.hash, buf);
139  if (!deser_u32(&tx_in->prevout.n, buf))
140  return false;
141  if (!deser_varstr(&tx_in->script_sig, buf))
142  return false;
143  if (!deser_u32(&tx_in->sequence, buf))
144  return false;
145  return true;
146 }
147 
149 {
150  if (!deser_s64(&tx_out->value, buf))
151  return false;
152  if (!deser_varstr(&tx_out->script_pubkey, buf))
153  return false;
154  return true;
155 }
156 
157 int btc_tx_deserialize(const unsigned char* tx_serialized, size_t inlen, btc_tx* tx)
158 {
159  struct const_buffer buf = {tx_serialized, inlen};
160 
161  //tx needs to be initialized
162  deser_u32(&tx->version, &buf);
163  uint32_t vlen;
164  if (!deser_varlen(&vlen, &buf))
165  return false;
166 
167  unsigned int i;
168  for (i = 0; i < vlen; i++) {
169  btc_tx_in* tx_in = btc_tx_in_new();
170 
171  if (!btc_tx_in_deserialize(tx_in, &buf)) {
172  free(tx_in);
173  }
174 
175  vector_add(tx->vin, tx_in);
176  }
177 
178  if (!deser_varlen(&vlen, &buf))
179  return false;
180  for (i = 0; i < vlen; i++) {
181  btc_tx_out* tx_out = btc_tx_out_new();
182 
183  if (!btc_tx_out_deserialize(tx_out, &buf)) {
184  free(tx_out);
185  }
186 
187  vector_add(tx->vout, tx_out);
188  }
189 
190  if (!deser_u32(&tx->locktime, &buf))
191  return false;
192 
193  return true;
194 }
195 
196 void btc_tx_in_serialize(cstring* s, const btc_tx_in* tx_in)
197 {
198  ser_u256(s, tx_in->prevout.hash);
199  ser_u32(s, tx_in->prevout.n);
200  ser_varstr(s, tx_in->script_sig);
201  ser_u32(s, tx_in->sequence);
202 }
203 
204 void btc_tx_out_serialize(cstring* s, const btc_tx_out* tx_out)
205 {
206  ser_s64(s, tx_out->value);
207  ser_varstr(s, tx_out->script_pubkey);
208 }
209 
210 void btc_tx_serialize(cstring* s, const btc_tx* tx)
211 {
212  ser_u32(s, tx->version);
213 
214  ser_varlen(s, tx->vin ? tx->vin->len : 0);
215 
216  unsigned int i;
217  if (tx->vin) {
218  for (i = 0; i < tx->vin->len; i++) {
219  btc_tx_in* tx_in;
220 
221  tx_in = vector_idx(tx->vin, i);
222  btc_tx_in_serialize(s, tx_in);
223  }
224  }
225 
226  ser_varlen(s, tx->vout ? tx->vout->len : 0);
227 
228  if (tx->vout) {
229  for (i = 0; i < tx->vout->len; i++) {
230  btc_tx_out* tx_out;
231 
232  tx_out = vector_idx(tx->vout, i);
233  btc_tx_out_serialize(s, tx_out);
234  }
235  }
236 
237  ser_u32(s, tx->locktime);
238 }
239 
240 void btc_tx_hash(const btc_tx* tx, uint8_t *hashout)
241 {
242  cstring *txser = cstr_new_sz(1024);
243  btc_tx_serialize(txser, tx);
244 
245 
246  sha256_Raw((const uint8_t*)txser->str, txser->len, hashout);
247  sha256_Raw(hashout, 32, hashout);
248  cstr_free(txser, true);
249 }
250 
251 
252 void btc_tx_in_copy(btc_tx_in* dest, const btc_tx_in* src)
253 {
254  memcpy(&dest->prevout, &src->prevout, sizeof(dest->prevout));
255  dest->sequence = src->sequence;
256 
257  if (!src->script_sig)
258  dest->script_sig = NULL;
259  else {
260  dest->script_sig = cstr_new_sz(src->script_sig->len);
262  src->script_sig->str,
263  src->script_sig->len);
264  }
265 }
266 
267 
268 void btc_tx_out_copy(btc_tx_out* dest, const btc_tx_out* src)
269 {
270  dest->value = src->value;
271 
272  if (!src->script_pubkey)
273  dest->script_pubkey = NULL;
274  else {
277  src->script_pubkey->str,
278  src->script_pubkey->len);
279  }
280 }
281 
282 
283 void btc_tx_copy(btc_tx* dest, const btc_tx* src)
284 {
285  dest->version = src->version;
286  dest->locktime = src->locktime;
287 
288  if (!src->vin)
289  dest->vin = NULL;
290  else {
291  unsigned int i;
292 
293  if (dest->vin)
294  vector_free(dest->vin, true);
295 
296  dest->vin = vector_new(src->vin->len, btc_tx_in_free_cb);
297 
298  for (i = 0; i < src->vin->len; i++) {
299  btc_tx_in* tx_in_old, *tx_in_new;
300 
301  tx_in_old = vector_idx(src->vin, i);
302  tx_in_new = malloc(sizeof(*tx_in_new));
303  btc_tx_in_copy(tx_in_new, tx_in_old);
304  vector_add(dest->vin, tx_in_new);
305  }
306  }
307 
308  if (!src->vout)
309  dest->vout = NULL;
310  else {
311  unsigned int i;
312 
313  if (dest->vout)
314  vector_free(dest->vout, true);
315 
316  dest->vout = vector_new(src->vout->len,
318 
319  for (i = 0; i < src->vout->len; i++) {
320  btc_tx_out* tx_out_old, *tx_out_new;
321 
322  tx_out_old = vector_idx(src->vout, i);
323  tx_out_new = malloc(sizeof(*tx_out_new));
324  btc_tx_out_copy(tx_out_new, tx_out_old);
325  vector_add(dest->vout, tx_out_new);
326  }
327  }
328 }
329 
330 btc_bool btc_tx_sighash(const btc_tx* tx_to, const cstring* fromPubKey, unsigned int in_num, int hashtype, uint8_t* hash)
331 {
332  if (in_num >= tx_to->vin->len)
333  return false;
334 
335  btc_bool ret = true;
336 
337  btc_tx* tx_tmp = btc_tx_new();
338  btc_tx_copy(tx_tmp, tx_to);
339 
340  cstring* new_script = cstr_new_sz(fromPubKey->len);
341  btc_script_copy_without_op_codeseperator(fromPubKey, new_script);
342 
343  unsigned int i;
344  btc_tx_in* tx_in;
345  for (i = 0; i < tx_tmp->vin->len; i++) {
346  tx_in = vector_idx(tx_tmp->vin, i);
347  cstr_resize(tx_in->script_sig, 0);
348 
349  if (i == in_num)
351  new_script->str,
352  new_script->len);
353  }
354  cstr_free(new_script, true);
355  /* Blank out some of the outputs */
356  if ((hashtype & 0x1f) == SIGHASH_NONE) {
357  /* Wildcard payee */
358  if (tx_tmp->vout)
359  vector_free(tx_tmp->vout, true);
360 
361  tx_tmp->vout = vector_new(1, btc_tx_out_free_cb);
362 
363  /* Let the others update at will */
364  for (i = 0; i < tx_tmp->vin->len; i++) {
365  tx_in = vector_idx(tx_tmp->vin, i);
366  if (i != in_num)
367  tx_in->sequence = 0;
368  }
369  }
370 
371  else if ((hashtype & 0x1f) == SIGHASH_SINGLE) {
372  /* Only lock-in the txout payee at same index as txin */
373  unsigned int n_out = in_num;
374  if (n_out >= tx_tmp->vout->len) {
375  //TODO: set error code
376  ret = false;
377  goto out;
378  }
379 
380  vector_resize(tx_tmp->vout, n_out + 1);
381 
382  for (i = 0; i < n_out; i++) {
383  btc_tx_out* tx_out;
384 
385  tx_out = vector_idx(tx_tmp->vout, i);
386  tx_out->value = -1;
387  if (tx_out->script_pubkey) {
388  cstr_free(tx_out->script_pubkey, true);
389  tx_out->script_pubkey = NULL;
390  }
391  }
392 
393  /* Let the others update at will */
394  for (i = 0; i < tx_tmp->vin->len; i++) {
395  tx_in = vector_idx(tx_tmp->vin, i);
396  if (i != in_num)
397  tx_in->sequence = 0;
398  }
399  }
400 
401  /* Blank out other inputs completely;
402  not recommended for open transactions */
403  if (hashtype & SIGHASH_ANYONECANPAY) {
404  if (in_num > 0)
405  vector_remove_range(tx_tmp->vin, 0, in_num);
406  vector_resize(tx_tmp->vin, 1);
407  }
408 
409  cstring* s = cstr_new_sz(512);
410  btc_tx_serialize(s, tx_tmp);
411  char hextest[4096];
412  ser_s32(s, hashtype);
413 
414  sha256_Raw((const uint8_t*)s->str, s->len, hash);
415  sha256_Raw(hash, 32, hash);
416 
417  cstr_free(s, true);
418 
419 out:
420  btc_tx_free(tx_tmp);
421 
422  return ret;
423 }
424 
425 
426 btc_bool btc_tx_add_address_out(btc_tx* tx, const btc_chain* chain, int64_t amount, const char *address)
427 {
428 
429  uint8_t buf[strlen(address)*2];
430  int r = btc_base58_decode_check(address, buf, sizeof(buf));
431  if (r <= 0)
432  return false;
433 
434  if (buf[0] == chain->b58prefix_pubkey_address)
435  {
436  btc_tx_add_p2pkh_hash160_out(tx, amount, &buf[1]);
437  }
438  else if (buf[0] == chain->b58prefix_script_address)
439  {
440  btc_tx_add_p2sh_hash160_out(tx, amount, &buf[1]);
441  }
442 
443  return true;
444 }
445 
446 
447 btc_bool btc_tx_add_p2pkh_hash160_out(btc_tx* tx, int64_t amount, uint8_t *hash160)
448 {
449  btc_tx_out* tx_out = btc_tx_out_new();
450 
451  tx_out->script_pubkey = cstr_new_sz(1024);
452  btc_script_build_p2pkh(tx_out->script_pubkey, hash160);
453 
454  tx_out->value = amount;
455 
456  vector_add(tx->vout, tx_out);
457 
458  return true;
459 }
460 
461 btc_bool btc_tx_add_p2sh_hash160_out(btc_tx* tx, int64_t amount, uint8_t *hash160)
462 {
463  btc_tx_out* tx_out = btc_tx_out_new();
464 
465  tx_out->script_pubkey = cstr_new_sz(1024);
466  btc_script_build_p2sh(tx_out->script_pubkey, hash160);
467 
468  tx_out->value = amount;
469 
470  vector_add(tx->vout, tx_out);
471 
472  return true;
473 }
474 
475 btc_bool btc_tx_add_p2pkh_out(btc_tx* tx, int64_t amount, const btc_pubkey *pubkey)
476 {
477 
478  uint8_t hash160[20];
479  btc_pubkey_get_hash160(pubkey, hash160);
480  return btc_tx_add_p2pkh_hash160_out(tx, amount, hash160);
481 }
vector * vector_new(size_t res, void(*free_f)(void *))
Definition: vector.c:31
uint8_t btc_bool
Definition: btc.h:34
Definition: tx.h:68
void btc_tx_copy(btc_tx *dest, const btc_tx *src)
Definition: tx.c:283
char * str
Definition: cstr.h:43
void btc_tx_out_serialize(cstring *s, const btc_tx_out *tx_out)
Definition: tx.c:204
btc_tx_out * btc_tx_out_new()
create a new tx output
Definition: tx.c:103
void btc_tx_in_free_cb(void *data)
Definition: tx.c:54
btc_bool btc_tx_in_deserialize(btc_tx_in *tx_in, struct const_buffer *buf)
Definition: tx.c:136
void vector_remove_range(vector *vec, size_t pos, size_t len)
Definition: vector.c:124
btc_bool btc_script_build_p2sh(cstring *script_in, const uint8_t *hash160)
Definition: script.c:338
uint32_t sequence
Definition: tx.h:65
static void ser_s32(cstring *s, int32_t v_)
Definition: serialize.h:53
void btc_tx_free(btc_tx *tx)
Definition: tx.c:112
void ser_u32(cstring *s, uint32_t v_)
Definition: serialize.c:24
void sha256_Raw(const sha2_byte *data, size_t len, uint8_t digest[SHA256_DIGEST_LENGTH])
Definition: sha2.c:652
static void ser_s64(cstring *s, int64_t v_)
Definition: serialize.h:58
btc_bool btc_tx_add_p2sh_hash160_out(btc_tx *tx, int64_t amount, uint8_t *hash160)
Definition: tx.c:461
btc_tx_in * btc_tx_in_new()
create a new tx input
Definition: tx.c:67
static void ser_u256(cstring *s, const unsigned char *v_)
Definition: serialize.h:44
Definition: tx.h:61
cstring * cstr_new_sz(size_t sz)
Definition: cstr.c:33
btc_tx * btc_tx_new()
create a new tx input
Definition: tx.c:124
void btc_tx_hash(const btc_tx *tx, uint8_t *hashout)
Definition: tx.c:240
void ser_varlen(cstring *s, uint32_t vlen)
Definition: serialize.c:36
btc_tx_outpoint prevout
Definition: tx.h:63
void ser_varstr(cstring *s, cstring *s_in)
Definition: serialize.c:68
int btc_base58_decode_check(const char *str, uint8_t *data, size_t datalen)
Definition: base58.c:219
cstring * script_sig
Definition: tx.h:64
void btc_tx_in_serialize(cstring *s, const btc_tx_in *tx_in)
Definition: tx.c:196
btc_bool deser_u32(uint32_t *vo, struct const_buffer *buf)
Definition: serialize.c:126
btc_bool deser_varlen(uint32_t *lo, struct const_buffer *buf)
Definition: serialize.c:148
void btc_tx_serialize(cstring *s, const btc_tx *tx)
serialize a lbc bitcoin data structure into a p2p serialized buffer
Definition: tx.c:210
uint32_t locktime
Definition: tx.h:79
btc_bool cstr_resize(cstring *s, size_t new_sz)
Definition: cstr.c:81
btc_bool vector_add(vector *vec, void *data)
Definition: vector.c:113
int btc_tx_deserialize(const unsigned char *tx_serialized, size_t inlen, btc_tx *tx)
deserialize/parse a p2p serialized bitcoin transaction
Definition: tx.c:157
uint32_t n
Definition: tx.h:58
cstring * script_pubkey
Definition: tx.h:71
btc_bool btc_tx_add_p2pkh_hash160_out(btc_tx *tx, int64_t amount, uint8_t *hash160)
Definition: tx.c:447
#define vector_idx(vec, idx)
Definition: vector.h:59
btc_bool btc_tx_add_address_out(btc_tx *tx, const btc_chain *chain, int64_t amount, const char *address)
Definition: tx.c:426
vector * vin
Definition: tx.h:77
size_t len
Definition: cstr.h:44
btc_bool deser_varstr(cstring **so, struct const_buffer *buf)
Definition: serialize.c:205
void btc_tx_out_copy(btc_tx_out *dest, const btc_tx_out *src)
Definition: tx.c:268
btc_bool btc_tx_add_p2pkh_out(btc_tx *tx, int64_t amount, const btc_pubkey *pubkey)
Definition: tx.c:475
static btc_bool deser_s64(int64_t *vo, struct const_buffer *buf)
Definition: serialize.h:80
uint256 hash
Definition: tx.h:57
size_t len
Definition: vector.h:42
void btc_tx_in_copy(btc_tx_in *dest, const btc_tx_in *src)
Definition: tx.c:252
void vector_free(vector *vec, btc_bool free_array)
Definition: vector.c:71
uint32_t version
Definition: tx.h:76
uint8_t b58prefix_pubkey_address
Definition: chain.h:42
int64_t value
Definition: tx.h:70
void btc_tx_out_free_cb(void *data)
Definition: tx.c:90
btc_bool btc_script_build_p2pkh(cstring *script_in, const uint8_t *hash160)
Definition: script.c:323
btc_bool vector_resize(vector *vec, size_t newsz)
Definition: vector.c:154
uint8_t b58prefix_script_address
Definition: chain.h:43
void btc_pubkey_get_hash160(const btc_pubkey *pubkey, uint8_t *hash160)
Definition: ecc_key.c:112
btc_bool btc_tx_sighash(const btc_tx *tx_to, const cstring *fromPubKey, unsigned int in_num, int hashtype, uint8_t *hash)
Definition: tx.c:330
void btc_tx_out_free(btc_tx_out *tx_out)
Definition: tx.c:77
btc_bool btc_script_copy_without_op_codeseperator(const cstring *script_in, cstring *script_out)
Definition: script.c:36
btc_bool btc_tx_out_deserialize(btc_tx_out *tx_out, struct const_buffer *buf)
Definition: tx.c:148
void cstr_free(cstring *s, btc_bool free_buf)
Definition: cstr.c:69
Definition: tx.h:74
btc_bool cstr_append_buf(cstring *s, const void *buf, size_t sz)
Definition: cstr.c:106
Definition: cstr.h:41
static btc_bool deser_u256(uint8_t *vo, struct const_buffer *buf)
Definition: serialize.h:71
void btc_tx_in_free(btc_tx_in *tx_in)
Definition: tx.c:39
vector * vout
Definition: tx.h:78