Created
December 13, 2018 10:21
-
-
Save ajtowns/0b0ef1de66f38b8df043b3ffd8c69976 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <assert.h> | |
typedef unsigned char u8; | |
const u8 OP_MASK = 0x50; | |
const u8 OP_0 = 0x00; | |
const u8 OP_1NEG = 0x4f; | |
const u8 OP_1 = 0x51; | |
const u8 OP_16 = 0x60; | |
const u8 OP_PUSHDATA1 = 0x4c; | |
const u8 OP_PUSHDATA2 = 0x4d; | |
const u8 OP_PUSHDATA4 = 0x4e; | |
const u8 OP_ANYPUSH = 0x65; | |
const u8 OP_CLTV = 0xb1; | |
const u8 OP_DROP = 0x75; | |
const u8 OP_CHECKSIG = 0xac; | |
const u8 OP_INVALID = 0xff; | |
u8 pull_opcode(const u8 **cursor, size_t *max, void *pptr) | |
{ | |
if (*max < 1) { | |
*cursor = NULL; | |
*max = 0; | |
return OP_INVALID; | |
} | |
u8 opcode = **cursor; | |
size_t skip = *max + 1; | |
size_t pushdata_skip = 0; | |
if (opcode <= 75) { | |
skip = opcode; // push opcode bytes | |
} else if (opcode == OP_PUSHDATA1) { | |
pushdata_skip = 1; | |
if (*max > 1) skip = *(*cursor+1); | |
} else if (opcode == OP_PUSHDATA2) { | |
pushdata_skip = 2; | |
if (*max > 2) skip = *(*cursor+1) + *(*cursor+2)*256 + 3; | |
} else if (opcode == OP_PUSHDATA4) { | |
pushdata_skip = 4; | |
if (*max > 4) skip = *(*cursor+1) + *(*cursor+2)*256 + *(*cursor+3)*(256*256) + *(*cursor+4)*(256*256*256) + 5; | |
} else { | |
(*cursor)++; | |
(*max)--; | |
return opcode; | |
} | |
if (1 + skip + pushdata_skip > *max) { | |
*cursor = NULL; | |
*max = 0; | |
return OP_INVALID; | |
} | |
#if 0 | |
if (pptr) { | |
u8 **pptr = pptr; | |
size_t oldsize = tal_count(*pptr); | |
tal_resize(pptr, oldsize + skip); | |
memcpy(*pptr + oldsize, memcheck(*cursor + 1 + pushdata_skip, skip), skip); | |
} | |
#else | |
(void)pptr; | |
#endif | |
*cursor += 1 + pushdata_skip + skip; | |
*max -= 1 + pushdata_skip + skip; | |
return OP_ANYPUSH; | |
} | |
void push_masked_script(const u8* script, size_t len, void (*push)(const void *, size_t, void *), void *pushp) | |
{ | |
int skippush = 0; | |
const u8 *cursor = script; | |
size_t left = len; | |
const u8 *start = cursor; | |
while (left > 0) { | |
if (skippush) { | |
skippush = 0; | |
if (start < cursor) push(start, cursor-start, pushp); | |
u8 opcode = pull_opcode(&cursor, &left, NULL); | |
start = cursor; | |
if ((OP_1 <= opcode && opcode <= OP_16) || opcode == OP_1NEG) { | |
opcode = OP_ANYPUSH; | |
} | |
assert(opcode == OP_ANYPUSH); | |
push(&opcode, 1, pushp); | |
} else { | |
u8 opcode = pull_opcode(&cursor, &left, NULL); | |
if (opcode == OP_MASK) { | |
skippush = 1; | |
} | |
} | |
} | |
assert(cursor != NULL); | |
if (start < cursor) push(start, cursor-start, pushp); | |
} | |
void push_printer(const void *pv, size_t len, void *d) { | |
(void)d; | |
const u8 *p = pv; | |
while (len > 0) { | |
printf("%02x", *p); | |
p++; len--; | |
} | |
} | |
int main(void) { | |
u8 s0[] = { OP_MASK, 4, 0x00, 0x65, 0xcd, 0x1d, OP_CLTV, OP_DROP, | |
33, 2, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, | |
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, | |
OP_CHECKSIG }; | |
u8 s1[] = { OP_MASK, 4, 0x00, 0x65, 0xcd, 0x1d, OP_CLTV, OP_DROP, | |
OP_MASK, 33, 2, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, | |
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, | |
OP_CHECKSIG }; | |
(void)s0; | |
(void)s1; | |
push_printer(s0, sizeof(s0), NULL); printf("\n"); | |
push_masked_script(s0, sizeof(s0), push_printer, NULL); printf("\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment