Skip to content

Instantly share code, notes, and snippets.

@ajtowns
Created December 13, 2018 10:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ajtowns/0b0ef1de66f38b8df043b3ffd8c69976 to your computer and use it in GitHub Desktop.
Save ajtowns/0b0ef1de66f38b8df043b3ffd8c69976 to your computer and use it in GitHub Desktop.
#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