libbtc
bitcoinclibrary
script.c
Go to the documentation of this file.
1 /*
2 
3  The MIT License (MIT)
4 
5  Copyright 2012 exMULTI, Inc.
6  Copyright (c) 2015 Jonas Schnelli
7 
8  Permission is hereby granted, free of charge, to any person obtaining
9  a copy of this software and associated documentation files (the "Software"),
10  to deal in the Software without restriction, including without limitation
11  the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  and/or sell copies of the Software, and to permit persons to whom the
13  Software is furnished to do so, subject to the following conditions:
14 
15  The above copyright notice and this permission notice shall be included
16  in all copies or substantial portions of the Software.
17 
18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
22  OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24  OTHER DEALINGS IN THE SOFTWARE.
25 
26 */
27 
28 #include <btc/script.h>
29 
30 #include <assert.h>
31 #include <string.h>
32 
33 #include "buffer.h"
34 #include "serialize.h"
35 
37 {
38  if (script_in->len == 0)
39  return false; /* EOF */
40 
41  struct const_buffer buf = {script_in->str, script_in->len};
42  unsigned char opcode;
43  while (buf.len > 0) {
44  if (!deser_bytes(&opcode, &buf, 1))
45  goto err_out;
46 
47  uint32_t data_len;
48 
49  if (opcode == OP_CODESEPARATOR)
50  continue;
51 
52  else if (opcode == OP_PUSHDATA1) {
53  uint8_t v8;
54  if (!deser_bytes(&v8, &buf, 1))
55  goto err_out;
56  data_len = v8;
57  } else if (opcode == OP_PUSHDATA2) {
58  uint16_t v16;
59  if (!deser_u16(&v16, &buf))
60  goto err_out;
61  data_len = v16;
62  } else if (opcode == OP_PUSHDATA4) {
63  uint32_t v32;
64  if (!deser_u32(&v32, &buf))
65  goto err_out;
66  data_len = v32;
67  } else {
68  cstr_append_buf(script_out, &opcode, 1);
69  continue;
70  }
71 
72  cstr_append_buf(script_out, buf.p, data_len);
73  if (!deser_skip(&buf, data_len))
74  goto err_out;
75  }
76 
77 err_out:
78  return false;
79 }
80 
82 {
83  btc_script_op* script_op;
84  script_op = calloc(1, sizeof(*script_op));
85 
86  return script_op;
87 }
88 
89 
91 {
92  if (script_op->data) {
93  free(script_op->data);
94  script_op->data = NULL;
95  }
96  script_op->datalen = 0;
97  script_op->op = OP_0;
98 }
99 
100 void btc_script_op_free_cb(void* data)
101 {
102  btc_script_op* script_op = data;
103  btc_script_op_free(script_op);
104 
105  free(script_op);
106 }
107 
108 btc_bool btc_script_get_ops(const cstring* script_in, vector* ops_out)
109 {
110  if (script_in->len == 0)
111  return false; /* EOF */
112 
113  struct const_buffer buf = {script_in->str, script_in->len};
114  unsigned char opcode;
115 
116  btc_script_op* op = NULL;
117  while (buf.len > 0) {
118  op = btc_script_op_new();
119 
120  if (!deser_bytes(&opcode, &buf, 1))
121  goto err_out;
122 
123  op->op = opcode;
124 
125  uint32_t data_len;
126 
127  if (opcode < OP_PUSHDATA1) {
128  data_len = opcode;
129  } else if (opcode == OP_PUSHDATA1) {
130  uint8_t v8;
131  if (!deser_bytes(&v8, &buf, 1))
132  goto err_out;
133  data_len = v8;
134  } else if (opcode == OP_PUSHDATA2) {
135  uint16_t v16;
136  if (!deser_u16(&v16, &buf))
137  goto err_out;
138  data_len = v16;
139  } else if (opcode == OP_PUSHDATA4) {
140  uint32_t v32;
141  if (!deser_u32(&v32, &buf))
142  goto err_out;
143  data_len = v32;
144  } else {
145  vector_add(ops_out, op);
146  continue;
147  }
148 
149  op->data = calloc(1, data_len);
150  memcpy(op->data, &buf.p, data_len);
151  op->datalen = data_len;
152 
153  vector_add(ops_out, op);
154 
155  if (!deser_skip(&buf, data_len))
156  goto err_out;
157  }
158 
159  return true;
160 err_out:
161  btc_script_op_free(op);
162  return false;
163 }
164 
166 {
167  return (op <= OP_PUSHDATA4);
168 }
169 
170 static btc_bool btc_script_is_op(const btc_script_op* op, enum opcodetype opcode)
171 {
172  return (op->op == opcode);
173 }
174 
176 {
177  if (!btc_script_is_pushdata(op->op))
178  return false;
179  if (op->datalen < 33 || op->datalen > 120)
180  return false;
181  return true;
182 }
183 
185 {
186  if (!btc_script_is_pushdata(op->op))
187  return false;
188  if (op->datalen != 20)
189  return false;
190  return true;
191 }
192 
193 // OP_PUBKEY, OP_CHECKSIG
195 {
196  return ((ops->len == 2) &&
199 }
200 
201 // OP_DUP, OP_HASH160, OP_PUBKEYHASH, OP_EQUALVERIFY, OP_CHECKSIG,
203 {
204  return ((ops->len == 5) &&
205  btc_script_is_op(vector_idx(ops, 0), OP_DUP) &&
210 }
211 
212 // OP_HASH160, OP_PUBKEYHASH, OP_EQUAL
214 {
215  return ((ops->len == 3) &&
219 }
220 
222 {
223  return ((op->op == OP_0) ||
224  (op->op >= OP_1 && op->op <= OP_16));
225 }
226 
228 {
229  if ((ops->len < 3) || (ops->len > (16 + 3)) ||
231  !btc_script_is_op_smallint(vector_idx(ops, ops->len - 2)) ||
233  return false;
234 
235  unsigned int i;
236  for (i = 1; i < (ops->len - 2); i++)
237  if (!btc_script_is_op_pubkey(vector_idx(ops, i)))
238  return false;
239 
240  return true;
241 }
242 
244 {
245  if (btc_script_is_pubkeyhash(ops))
246  return BTC_TX_PUBKEYHASH;
247  if (btc_script_is_scripthash(ops))
248  return BTC_TX_SCRIPTHASH;
249  if (btc_script_is_pubkey(ops))
250  return BTC_TX_PUBKEY;
251  if (btc_script_is_multisig(ops))
252  return BTC_TX_MULTISIG;
253 
254  return BTC_TX_NONSTANDARD;
255 }
256 
257 static enum opcodetype btc_encode_op_n(int n)
258 {
259  assert(n >= 0 && n <= 16);
260  if (n == 0)
261  return OP_0;
262  return (enum opcodetype)(OP_1+n-1);
263 }
264 
265 
266 static void btc_script_append_op(cstring* script_in, enum opcodetype op)
267 {
268  cstr_append_buf(script_in, &op, 1);
269 }
270 
271 
272 static void btc_script_append_pushdata(cstring* script_in, unsigned char *data, size_t datalen)
273 {
274  if (datalen < OP_PUSHDATA1)
275  {
276  cstr_append_buf(script_in, (unsigned char *)&datalen, 1);
277  }
278  else if (datalen <= 0xff)
279  {
281  cstr_append_buf(script_in, (unsigned char *)&datalen, 1);
282  }
283  else if (datalen <= 0xffff)
284  {
286  uint16_t v = htole16(datalen);
287  cstr_append_buf(script_in, &v, sizeof(v));
288  }
289  else
290  {
292  uint32_t v = htole32(datalen);
293  cstr_append_buf(script_in, &v, sizeof(v));
294  }
295  cstr_append_buf(script_in, data, datalen);
296 }
297 
298 btc_bool btc_script_build_multisig(cstring* script_in, unsigned int required_signatures, vector *pubkeys_chars)
299 {
300  cstr_resize(script_in, 0); //clear script
301 
302  if(required_signatures > 16 || pubkeys_chars->len > 16)
303  return false;
304  enum opcodetype op_req_sig = btc_encode_op_n(required_signatures);
305  cstr_append_buf(script_in, &op_req_sig, 1);
306 
307  int i;
308  for (i = 0; i < (int)pubkeys_chars->len; i++)
309  {
310  btc_pubkey *pkey = pubkeys_chars->data[i];
312  }
313 
314  enum opcodetype op_pub_len = btc_encode_op_n(pubkeys_chars->len);
315  cstr_append_buf(script_in, &op_pub_len, 1);
316 
317  enum opcodetype op_checkmultisig = OP_CHECKMULTISIG;
318  cstr_append_buf(script_in, &op_checkmultisig, 1);
319 
320  return true;
321 }
322 
323 btc_bool btc_script_build_p2pkh(cstring* script_in, const uint8_t *hash160)
324 {
325  cstr_resize(script_in, 0); //clear script
326 
327  btc_script_append_op(script_in, OP_DUP);
328  btc_script_append_op(script_in, OP_HASH160);
329 
330 
331  btc_script_append_pushdata(script_in, hash160, 20);
333  btc_script_append_op(script_in, OP_CHECKSIG);
334 
335  return true;
336 }
337 
338 btc_bool btc_script_build_p2sh(cstring* script_in, const uint8_t *hash160)
339 {
340  cstr_resize(script_in, 0); //clear script
341  btc_script_append_op(script_in, OP_HASH160);
342  btc_script_append_pushdata(script_in, hash160, 20);
343  btc_script_append_op(script_in, OP_EQUAL);
344 
345  return true;
346 }
uint8_t btc_bool
Definition: btc.h:34
char * str
Definition: cstr.h:43
size_t len
Definition: buffer.h:22
Definition: vector.h:39
void ** data
Definition: vector.h:41
btc_bool deser_skip(struct const_buffer *buf, size_t len)
Definition: serialize.c:92
btc_bool btc_script_build_p2sh(cstring *script_in, const uint8_t *hash160)
Definition: script.c:338
btc_script_op * btc_script_op_new()
Definition: script.c:81
enum btc_tx_out_type btc_script_classify(vector *ops)
Definition: script.c:243
static void btc_script_append_pushdata(cstring *script_in, unsigned char *data, size_t datalen)
Definition: script.c:272
btc_bool btc_script_is_scripthash(vector *ops)
Definition: script.c:213
#define BTC_ECKEY_COMPRESSED_LENGTH
Definition: btc.h:68
size_t datalen
Definition: script.h:206
#define BTC_ECKEY_UNCOMPRESSED_LENGTH
Definition: btc.h:67
const void * p
Definition: buffer.h:21
static btc_bool btc_script_is_pushdata(enum opcodetype op)
Definition: script.c:165
Definition: script.h:74
btc_bool btc_script_is_multisig(vector *ops)
Definition: script.c:227
opcodetype
Definition: script.h:49
btc_bool deser_u32(uint32_t *vo, struct const_buffer *buf)
Definition: serialize.c:126
void btc_script_op_free(btc_script_op *script_op)
Definition: script.c:90
btc_bool deser_bytes(void *po, struct const_buffer *buf, size_t len)
Definition: serialize.c:103
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
btc_tx_out_type
Definition: script.h:193
Definition: script.h:58
btc_bool deser_u16(uint16_t *vo, struct const_buffer *buf)
Definition: serialize.c:115
static btc_bool btc_script_is_op_pubkey(const btc_script_op *op)
Definition: script.c:175
#define vector_idx(vec, idx)
Definition: vector.h:59
static void btc_script_append_op(cstring *script_in, enum opcodetype op)
Definition: script.c:266
size_t len
Definition: cstr.h:44
static btc_bool btc_script_is_op_smallint(const btc_script_op *op)
Definition: script.c:221
static enum opcodetype btc_encode_op_n(int n)
Definition: script.c:257
size_t len
Definition: vector.h:42
btc_bool btc_script_build_multisig(cstring *script_in, unsigned int required_signatures, vector *pubkeys_chars)
Definition: script.c:298
btc_bool btc_script_is_pubkey(vector *ops)
Definition: script.c:194
btc_bool btc_script_build_p2pkh(cstring *script_in, const uint8_t *hash160)
Definition: script.c:323
void btc_script_op_free_cb(void *data)
Definition: script.c:100
static btc_bool btc_script_is_op(const btc_script_op *op, enum opcodetype opcode)
Definition: script.c:170
btc_bool btc_script_copy_without_op_codeseperator(const cstring *script_in, cstring *script_out)
Definition: script.c:36
enum opcodetype op
Definition: script.h:204
btc_bool compressed
Definition: ecc_key.h:46
btc_bool cstr_append_buf(cstring *s, const void *buf, size_t sz)
Definition: cstr.c:106
uint8_t pubkey[BTC_ECKEY_UNCOMPRESSED_LENGTH]
Definition: ecc_key.h:47
Definition: cstr.h:41
Definition: script.h:51
static btc_bool btc_script_is_op_pubkeyhash(const btc_script_op *op)
Definition: script.c:184
btc_bool btc_script_is_pubkeyhash(vector *ops)
Definition: script.c:202
unsigned char * data
Definition: script.h:205
btc_bool btc_script_get_ops(const cstring *script_in, vector *ops_out)
Definition: script.c:108
Definition: script.h:100