btcs

bitcoin script parser/evaluator/compiler/decompiler
git clone git://jb55.com/btcs
Log | Files | Refs | README | LICENSE

commit 25ccf3328c9ba80c12a981ecabda89afbd7a29d2
parent a7ab0ec421dec3b539a796cad96e05ea0b57ba40
Author: William Casarin <jb55@jb55.com>
Date:   Sun,  3 Dec 2017 15:14:24 -0800

data: initial data value type

Example
-------

  $ btcs <<< '@aa dup equal'

  script      0xaa OP_DUP OP_EQUAL
  script_hex  01aa7687
  stack       1
  stack_hex   51

Diffstat:
Mlexer.l | 5+++++
Mop.c | 7++++++-
Mparser.y | 3+++
Mscript.c | 24++++++++++++++++++++++++
Mscript.h | 1+
Mtest.c | 4++--
6 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/lexer.l b/lexer.l @@ -23,6 +23,11 @@ [oO][pP]_ {} +@[a-fA-F0-9]+ { + yylval.str = yytext + 1; + return T_DATA; +} + -?[0-9]+ { s64 i = strtoll(yytext, NULL, 10); yylval.val = val_from_int(i); diff --git a/op.c b/op.c @@ -372,7 +372,12 @@ val_print(struct val val) { case VT_DATA: { u16 len; u8 *data = byte_pool_get(val.ind, &len); - printf("0x", len); + + if (len == 0) + printf("0", len); + else + printf("0x", len); + print_bytes(data, len, 0); break; } diff --git a/parser.y b/parser.y @@ -21,10 +21,12 @@ void yyerror(const char* s); %token T_OP %token T_INT %token T_VAL +%token T_DATA %token T_NEWLINE T_QUIT T_EXAMPLE %type<opcode> T_OP %type<integer> T_INT +%type<str> T_DATA %type<val> T_VAL %type<str> T_EXAMPLE @@ -40,6 +42,7 @@ line: T_NEWLINE | T_INT { script_push_int(&g_reader_stack, $1); } | T_VAL { stack_push_val(&g_reader_stack, $1); } | T_OP { stack_push_op(&g_reader_stack, $1); } + | T_DATA { script_push_datastr(&g_reader_stack, $1); } | T_EXAMPLE { ; } diff --git a/script.c b/script.c @@ -690,6 +690,30 @@ script_push_int(struct stack *script, s64 intval) { void +script_push_datastr(struct stack *script, char *str) { + int count = 0; + u8 *bytes; + char *p = str; + u16 ind; + u16 nbytes = strlen(str) / 2; + struct val val; + + bytes = byte_pool_new(nbytes, &ind); + + /* WARNING: no sanitization or error-checking whatsoever */ + for(count = 0; count < nbytes; count++) { + sscanf(p, "%2hhx", &bytes[count]); + p += 2; + } + + val.type = VT_DATA; + val.ind = ind; + + stack_push_val(script, val); +} + + +void script_serialize(struct stack *stack, u8 *buf, int buflen, int* len) { struct val *valp; void **sp; diff --git a/script.h b/script.h @@ -15,6 +15,7 @@ int script_eval(u8 *script, size_t script_size, struct stack *stack); void script_print_ops(char * buf, size_t size); void script_print_vals(struct stack *); void script_push_int(struct stack *, s64); +void script_push_datastr(struct stack *, char *str); void script_serialize(struct stack *stack, u8 *buf, int buflen, int* len); diff --git a/test.c b/test.c @@ -113,8 +113,8 @@ TEST(big_int_serializes_ok) { 0x04, 0xff, 0xff, 0xff, 0x7f, OP_ADD }; static u8 expected_out[] = { 0x05, 0xfe, 0xff, 0xff, 0xff, 0 }; - script_push_int(script, 2147483647UL); - script_push_int(script, 2147483647UL); + script_push_int(script, 2147483647LL); + script_push_int(script, 2147483647LL); stack_push_op(script, OP_ADD); script_serialize(script, buf, ARRAY_SIZE(buf), &len);