|
|
@ -967,6 +967,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip |
|
|
|
free(stacks); |
|
|
|
return(-1); |
|
|
|
} |
|
|
|
printf("pushdata siglen.%d depth.%d\n",V->signers[i].siglen,stacks->stackdepth); |
|
|
|
} |
|
|
|
} |
|
|
|
for (i=0; i<V->N; i++) |
|
|
@ -975,7 +976,10 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip |
|
|
|
{ |
|
|
|
plen = bitcoin_pubkeylen(V->signers[i].pubkey); |
|
|
|
if ( V->suppress_pubkeys == 0 && (V->spendscript[0] != plen || V->spendscript[V->spendlen - 1] != IGUANA_OP_CHECKSIG || bitcoin_pubkeylen(&V->spendscript[1]) <= 0) ) |
|
|
|
{ |
|
|
|
iguana_pushdata(stacks,0,V->signers[i].pubkey,plen); |
|
|
|
printf("pushdata plen.%d depth.%d\n",plen,stacks->stackdepth); |
|
|
|
} else printf("skip pubkey push %d script[0].%d spendlen.%d depth.%d\n",plen,V->spendscript[0],V->spendlen,stacks->stackdepth); |
|
|
|
} |
|
|
|
} |
|
|
|
if ( V->userdatalen != 0 ) |
|
|
@ -1113,6 +1117,87 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip |
|
|
|
} |
|
|
|
memset(args,0,sizeof(args)); |
|
|
|
numargs = 0; |
|
|
|
if ( (op->flags & IGUANA_CONTROLFLAG) != 0 ) |
|
|
|
{ |
|
|
|
printf("control opcode depth.%d\n",stacks->stackdepth); |
|
|
|
switch ( op->opcode ) |
|
|
|
{ |
|
|
|
case IGUANA_OP_IF: case IGUANA_OP_NOTIF: |
|
|
|
if ( stacks->ifdepth >= IGUANA_MAXSTACKDEPTH ) |
|
|
|
{ |
|
|
|
printf("ifdepth.%d >= MAXSTACKDEPTH.%d\n",stacks->ifdepth,IGUANA_MAXSTACKDEPTH); |
|
|
|
errs++; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if ( stacks->stackdepth <= 0 ) |
|
|
|
errs++; |
|
|
|
else |
|
|
|
{ |
|
|
|
args[0] = iguana_pop(stacks); |
|
|
|
if ( iguana_isnonz(args[0]) == (op->opcode == IGUANA_OP_IF) ) |
|
|
|
{ |
|
|
|
val = 1; |
|
|
|
printf("OP_IF enabled depth.%d\n",stacks->stackdepth); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
val = -1; |
|
|
|
printf("OP_IF disabled depth.%d\n",stacks->stackdepth); |
|
|
|
} |
|
|
|
stacks->lastpath[++stacks->ifdepth] = val; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
case IGUANA_OP_ELSE: |
|
|
|
if ( stacks->stackdepth <= 0 ) |
|
|
|
errs++; |
|
|
|
else |
|
|
|
{ |
|
|
|
args[0] = iguana_pop(stacks); |
|
|
|
if ( stacks->ifdepth <= stacks->elsedepth ) |
|
|
|
{ |
|
|
|
printf("unhandled opcode.%02x stacks->ifdepth %d <= %d stacks->elsedepth\n",op->opcode,stacks->ifdepth,stacks->elsedepth); |
|
|
|
errs++; |
|
|
|
} |
|
|
|
stacks->lastpath[stacks->ifdepth] *= -1; |
|
|
|
printf("OP_ELSE status.%d depth.%d\n",stacks->lastpath[stacks->ifdepth],stacks->stackdepth); |
|
|
|
} |
|
|
|
break; |
|
|
|
case IGUANA_OP_ENDIF: |
|
|
|
if ( stacks->ifdepth <= 0 ) |
|
|
|
{ |
|
|
|
printf("endif without if offset.%ld\n",(long)str-(long)asmstr); |
|
|
|
errs++; |
|
|
|
} |
|
|
|
stacks->ifdepth--; |
|
|
|
printf("OP_ENDIF status.%d depth.%d\n",stacks->lastpath[stacks->ifdepth],stacks->stackdepth); |
|
|
|
break; |
|
|
|
case IGUANA_OP_VERIFY: |
|
|
|
//if ( stacks->stackdepth > 0 )
|
|
|
|
// args[0] = iguana_pop(stacks);
|
|
|
|
//else errs++;
|
|
|
|
break; |
|
|
|
case IGUANA_OP_RETURN: |
|
|
|
iguana_pushdata(stacks,0,0,0); |
|
|
|
errs++; |
|
|
|
break; |
|
|
|
} |
|
|
|
if ( errs != 0 ) |
|
|
|
break; |
|
|
|
continue; |
|
|
|
} |
|
|
|
if ( stacks->lastpath[stacks->ifdepth] != 0 ) |
|
|
|
{ |
|
|
|
if ( stacks->lastpath[stacks->ifdepth] < 0 ) |
|
|
|
{ |
|
|
|
printf("SKIP opcode.%02x depth.%d\n",op->opcode,stacks->stackdepth); |
|
|
|
if ( stacks->logarray ) |
|
|
|
jaddistr(stacks->logarray,"skip"); |
|
|
|
continue; |
|
|
|
} |
|
|
|
printf("conditional opcode.%02x stackdepth.%d\n",op->opcode,stacks->stackdepth); |
|
|
|
} |
|
|
|
if ( op->opcode <= IGUANA_OP_16 || ++numops <= MAX_OPS_PER_SCRIPT ) |
|
|
|
{ |
|
|
|
script[k++] = op->opcode; |
|
|
@ -1144,91 +1229,18 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip |
|
|
|
continue; |
|
|
|
if ( (op->flags & IGUANA_NOPFLAG) != 0 ) |
|
|
|
continue; |
|
|
|
if ( (op->flags & IGUANA_CONTROLFLAG) != 0 ) |
|
|
|
if ( (numargs= op->stackitems) > 0 ) |
|
|
|
{ |
|
|
|
printf("control opcode depth.%d\n",stacks->stackdepth); |
|
|
|
switch ( op->opcode ) |
|
|
|
if ( stacks->stackdepth < op->stackitems ) |
|
|
|
{ |
|
|
|
case IGUANA_OP_IF: case IGUANA_OP_NOTIF: |
|
|
|
if ( stacks->ifdepth >= IGUANA_MAXSTACKDEPTH ) |
|
|
|
{ |
|
|
|
printf("ifdepth.%d >= MAXSTACKDEPTH.%d\n",stacks->ifdepth,IGUANA_MAXSTACKDEPTH); |
|
|
|
errs++; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if ( stacks->stackdepth <= 0 ) |
|
|
|
errs++; |
|
|
|
else |
|
|
|
{ |
|
|
|
args[0] = iguana_pop(stacks); |
|
|
|
if ( iguana_isnonz(args[0]) == (op->opcode == IGUANA_OP_IF) ) |
|
|
|
{ |
|
|
|
val = 1; |
|
|
|
printf("OP_IF enabled depth.%d\n",stacks->stackdepth); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
val = -1; |
|
|
|
printf("OP_IF disabled depth.%d\n",stacks->stackdepth); |
|
|
|
} |
|
|
|
stacks->lastpath[++stacks->ifdepth] = val; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
case IGUANA_OP_ELSE: |
|
|
|
if ( stacks->stackdepth <= 0 ) |
|
|
|
errs++; |
|
|
|
else |
|
|
|
{ |
|
|
|
args[0] = iguana_pop(stacks); |
|
|
|
if ( stacks->ifdepth <= stacks->elsedepth ) |
|
|
|
{ |
|
|
|
printf("unhandled opcode.%02x stacks->ifdepth %d <= %d stacks->elsedepth\n",op->opcode,stacks->ifdepth,stacks->elsedepth); |
|
|
|
errs++; |
|
|
|
} |
|
|
|
stacks->lastpath[stacks->ifdepth] *= -1; |
|
|
|
printf("OP_ELSE status.%d depth.%d\n",stacks->lastpath[stacks->ifdepth],stacks->stackdepth); |
|
|
|
} |
|
|
|
break; |
|
|
|
case IGUANA_OP_ENDIF: |
|
|
|
if ( stacks->ifdepth <= 0 ) |
|
|
|
{ |
|
|
|
printf("endif without if offset.%ld\n",(long)str-(long)asmstr); |
|
|
|
errs++; |
|
|
|
} |
|
|
|
stacks->ifdepth--; |
|
|
|
printf("OP_ENDIF status.%d depth.%d\n",stacks->lastpath[stacks->ifdepth],stacks->stackdepth); |
|
|
|
break; |
|
|
|
case IGUANA_OP_VERIFY: |
|
|
|
if ( stacks->stackdepth > 0 ) |
|
|
|
args[0] = iguana_pop(stacks); |
|
|
|
else errs++; |
|
|
|
break; |
|
|
|
case IGUANA_OP_RETURN: |
|
|
|
iguana_pushdata(stacks,0,0,0); |
|
|
|
errs++; |
|
|
|
break; |
|
|
|
} |
|
|
|
if ( errs != 0 ) |
|
|
|
printf("stackdepth.%d needed.%d (%s) at offset.%ld\n",stacks->stackdepth,op->stackitems,str,(long)str-(long)asmstr); |
|
|
|
errs++; |
|
|
|
break; |
|
|
|
continue; |
|
|
|
} |
|
|
|
else if ( stacks->lastpath[stacks->ifdepth] >= 0 ) |
|
|
|
{ |
|
|
|
if ( (numargs= op->stackitems) > 0 ) |
|
|
|
{ |
|
|
|
if ( stacks->stackdepth < op->stackitems ) |
|
|
|
{ |
|
|
|
printf("stackdepth.%d needed.%d (%s) at offset.%ld\n",stacks->stackdepth,op->stackitems,str,(long)str-(long)asmstr); |
|
|
|
errs++; |
|
|
|
break; |
|
|
|
} |
|
|
|
for (i=0; i<numargs; i++) |
|
|
|
args[numargs - 1 - i] = iguana_pop(stacks); |
|
|
|
} |
|
|
|
printf("%02x: numargs.%d depth.%d\n",op->opcode,numargs,stacks->stackdepth); |
|
|
|
for (i=0; i<numargs; i++) |
|
|
|
args[numargs - 1 - i] = iguana_pop(stacks); |
|
|
|
} |
|
|
|
printf("%02x: numargs.%d depth.%d\n",op->opcode,numargs,stacks->stackdepth); |
|
|
|
if ( stacks->logarray != 0 ) |
|
|
|
{ |
|
|
|
char tmpstr[1096]; |
|
|
@ -1243,18 +1255,7 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip |
|
|
|
jadd(item,(char *)op->hh.key,array); |
|
|
|
jaddi(stacks->logarray,item); |
|
|
|
} |
|
|
|
if ( stacks->lastpath[stacks->ifdepth] != 0 ) |
|
|
|
{ |
|
|
|
if ( stacks->lastpath[stacks->ifdepth] < 0 ) |
|
|
|
{ |
|
|
|
printf("SKIP opcode.%02x depth.%d\n",op->opcode,stacks->stackdepth); |
|
|
|
if ( stacks->logarray ) |
|
|
|
jaddistr(stacks->logarray,"skip"); |
|
|
|
continue; |
|
|
|
} |
|
|
|
printf("conditional opcode.%02x stackdepth.%d\n",op->opcode,stacks->stackdepth); |
|
|
|
} |
|
|
|
else if ( (op->flags & IGUANA_EXECUTIONILLEGAL) != 0 ) |
|
|
|
if ( (op->flags & IGUANA_EXECUTIONILLEGAL) != 0 ) |
|
|
|
{ |
|
|
|
printf("opcode not allowed to run.%s at %ld\n",(char *)op->hh.key,(long)str-(long)asmstr); |
|
|
|
errs++; |
|
|
@ -1381,7 +1382,11 @@ int32_t bitcoin_assembler(struct iguana_info *coin,cJSON *logarray,uint8_t scrip |
|
|
|
iguana_stack(stacks,args,0,"","0"); |
|
|
|
iguana_stack(stacks,args,1,"0",""); |
|
|
|
break; |
|
|
|
case IGUANA_OP_DUP: iguana_stack(stacks,args,1,"0","0"); break; |
|
|
|
case IGUANA_OP_DUP: |
|
|
|
printf("before dup stackdepth.%d\n",stacks->stackdepth); |
|
|
|
iguana_stack(stacks,args,1,"0","0"); |
|
|
|
printf("after dup stackdepth.%d\n",stacks->stackdepth); |
|
|
|
break; |
|
|
|
case IGUANA_OP_2DUP: iguana_stack(stacks,args,2,"01","01"); break; |
|
|
|
case IGUANA_OP_NIP: |
|
|
|
if ( args[0].data != 0 ) |
|
|
|