Browse Source

test

release/v0.1
jl777 9 years ago
parent
commit
9f5b17cd4a
  1. 541
      iguana/exchanges/bitcoin.c
  2. 8
      iguana/exchanges/bitcoin.h
  3. 9
      iguana/iguana777.h
  4. 14
      iguana/iguana_ramchain.c
  5. 2
      iguana/iguana_rpc.c
  6. 7
      iguana/iguana_tx.c
  7. 3
      pnacl_main.h

541
iguana/exchanges/bitcoin.c

@ -31,219 +31,6 @@ static const char base58_chars[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijk
#define IGUANA_SCRIPT_DATA 11
#define IGUANA_SCRIPT_STRANGE 15
int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20])
{
script[n++] = SCRIPT_OP_DUP;
script[n++] = SCRIPT_OP_HASH160;
script[n++] = 20; memcpy(&script[n],rmd160,20); n += 20;
script[n++] = SCRIPT_OP_EQUALVERIFY;
script[n++] = SCRIPT_OP_CHECKSIG;
return(n);
}
int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime)
{
script[n++] = (locktime >> 24), script[n++] = (locktime >> 16), script[n++] = (locktime >> 8), script[n++] = locktime;
script[n++] = OP_CHECKLOCKTIMEVERIFY;
script[n++] = OP_DROP;
return(n);
}
char *create_atomictx_cltvspend(char *scriptstr,uint8_t *rmd160A,uint8_t *rmd160B,uint32_t locktime)
{
// OP_IF
// <timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG
// OP_ELSE
// OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG // standard spend
// OP_ENDIF
uint8_t hex[4096]; int32_t n = 0;
hex[n++] = SCRIPT_OP_IF;
n = bitcoin_checklocktimeverify(hex,n,locktime);
n = bitcoin_standardspend(hex,n,rmd160A);
hex[n++] = SCRIPT_OP_ELSE;
n = bitcoin_standardspend(hex,n,rmd160B);
hex[n++] = SCRIPT_OP_ENDIF;
init_hexbytes_noT(scriptstr,hex,n);
return(scriptstr);
}
/*struct vin_signer { bits256 privkey; uint8_t siglen,sig[80],pubkey[65]; };
struct vin_info
{
struct iguana_msgvin vin;
int32_t M,N,validmask,voutlen;
struct vin_signer signers[16];
uint8_t voutscript[IGUANA_MAXSCRIPTSIZE];
};*/
int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,int32_t txi)
{
uint8_t addrtype; char rmd160str[41]; int32_t scriptlen = 0;
if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_76AC )
addrtype = coin->chain->pubtype;
else addrtype = coin->chain->p2shtype;
btc_convrmd160(coinaddr,addrtype,rmd160);
init_hexbytes_noT(rmd160str,rmd160,20);
//printf("addrtype.%d\n",addrtype);
switch ( type )
{
case IGUANA_SCRIPT_NULL:
strcpy(asmstr,txi == 0 ? "coinbase" : "PoSbase");
coinaddr[0] = 0;
break;
case IGUANA_SCRIPT_76AC:
sprintf(asmstr,"OP_DUP %s OP_CHECKSIG",rmd160str);
break;
case IGUANA_SCRIPT_76A988AC:
sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG",rmd160str);
break;
case IGUANA_SCRIPT_P2SH:
script[0] = SCRIPT_OP_HASH160, script[1] = 0x14;
memcpy(&script[2],rmd160,20);
script[22] = SCRIPT_OP_EQUAL;
sprintf(asmstr,"OP_HASH160 %s OP_EQUAL",coinaddr);
scriptlen = 23;
break;
case IGUANA_SCRIPT_OPRETURN: strcpy(asmstr,"OP_RETURN"); break;
case IGUANA_SCRIPT_3of3: strcpy(asmstr,"3 of 3 MSIG"); break;
case IGUANA_SCRIPT_2of3: strcpy(asmstr,"2 of 3 MSIG"); break;
case IGUANA_SCRIPT_1of3: strcpy(asmstr,"1 of 3 MSIG"); break;
case IGUANA_SCRIPT_2of2: strcpy(asmstr,"2 of 2 MSIG"); break;
case IGUANA_SCRIPT_1of2: strcpy(asmstr,"1 of 2 MSIG"); break;
case IGUANA_SCRIPT_MSIG: strcpy(asmstr,"NON-STANDARD MSIG"); break;
case IGUANA_SCRIPT_DATA: strcpy(asmstr,"DATA ONLY"); break;
case IGUANA_SCRIPT_STRANGE: strcpy(asmstr,"STRANGE SCRIPT"); break;
default: printf("unexpected script type\n"); break;
}
return(0);
}
int32_t _iguana_calcrmd160(struct iguana_info *coin,uint8_t rmd160[20],uint8_t msigs160[16][20],int32_t *Mp,int32_t *nump,uint8_t *pk_script,int32_t pk_scriptlen,bits256 txid,int32_t vout)
{
static uint8_t zero_rmd160[20];
char hexstr[8192]; uint8_t sha256[32],*script,type; int32_t i,n,m,plen;
if ( nump != 0 )
*nump = 0;
type = IGUANA_SCRIPT_STRANGE;
if ( pk_scriptlen == 0 )
{
if ( zero_rmd160[0] == 0 )
{
vcalc_sha256(0,sha256,pk_script,pk_scriptlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb
init_hexbytes_noT(hexstr,zero_rmd160,20);
char str[65]; printf("iguana_calcrmd160 zero len %s -> %s\n",bits256_str(str,*(bits256 *)sha256),hexstr);
}
memcpy(rmd160,zero_rmd160,sizeof(zero_rmd160));
return(IGUANA_SCRIPT_NULL);
}
else if ( pk_script[0] == 0x6a )
type = IGUANA_SCRIPT_OPRETURN;
else if ( pk_script[0] == 0x76 && pk_script[1] == 0xa9 && pk_script[2] == 20 && pk_script[pk_script[2]+3] == 0x88 && pk_script[pk_script[2]+4] == 0xac )
{
//printf("IGUANA_SCRIPT_76A988AC plen.%d vs %d pk_scriptlen\n",pk_script[2]+4,pk_scriptlen);
// 76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac
//vcalc_sha256(0,sha256,&pk_script[3],pk_script[2]);
//calc_rmd160(0,rmd160,sha256,sizeof(sha256));
memcpy(rmd160,&pk_script[3],20);
if ( (plen= pk_script[2]+5) < pk_scriptlen )
{
while ( plen < pk_scriptlen )
if ( pk_script[plen++] != 0x61 ) // nop
return(IGUANA_SCRIPT_STRANGE);
}
return(IGUANA_SCRIPT_76A988AC);
}
// 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac
else if ( pk_script[0] > 0 && pk_script[0] < 76 && pk_script[pk_scriptlen-1] == 0xac && pk_script[0] == pk_scriptlen-2 )
{
vcalc_sha256(0,sha256,&pk_script[1],pk_script[0]);
calc_rmd160(0,rmd160,sha256,sizeof(sha256));
return(IGUANA_SCRIPT_76AC);
}
else if ( pk_script[0] == 0xa9 && pk_script[1] == 0x14 && pk_scriptlen == 23 && pk_script[22] == 0x87 )
{
memcpy(rmd160,pk_script+2,20);
return(IGUANA_SCRIPT_P2SH);
}
else if ( pk_scriptlen > 34 && pk_script[pk_scriptlen-1] == 0xae && (n= pk_script[pk_scriptlen-2]) >= 0x51 && n <= 0x60 && (m= pk_script[0]) >= 0x51 && m <= n ) // m of n multisig
{
m -= 0x50, n -= 0x50;
if ( msigs160 != 0 && nump != 0 && *Mp != 0 )
{
script = pk_script+1;
for (i=0; i<n; i++,script += plen)
{
plen = *script++;
vcalc_sha256(0,sha256,script,plen);
calc_rmd160(0,msigs160[i],sha256,sizeof(sha256));
}
if ( (int32_t)((long)script - (long)pk_script) == pk_scriptlen-2 )
{
*nump = n;
*Mp = m;
//printf("M.%d N.%d\n",m,n);
}
}
vcalc_sha256(0,sha256,pk_script,pk_scriptlen);
calc_rmd160(0,rmd160,sha256,sizeof(sha256));
if ( n == 3 )
{
if ( m == 3 )
return(IGUANA_SCRIPT_3of3);
else if ( m == 2 )
return(IGUANA_SCRIPT_2of3);
else if ( m == 1 )
return(IGUANA_SCRIPT_1of3);
}
else if ( n == 2 )
{
if ( m == 2 )
return(IGUANA_SCRIPT_2of2);
else if ( m == 1 )
return(IGUANA_SCRIPT_1of2);
}
printf("strange msig M.%d of N.%d\n",m,n);
return(IGUANA_SCRIPT_MSIG);
}
else if ( pk_scriptlen == pk_script[0]+1 )
{
//printf("just data.%d\n",pk_scriptlen);
memcpy(rmd160,zero_rmd160,sizeof(zero_rmd160));
return(IGUANA_SCRIPT_DATA);
}
if ( type != IGUANA_SCRIPT_OPRETURN )
{
if ( pk_scriptlen < sizeof(hexstr)/2-1)
{
static FILE *fp;
init_hexbytes_noT(hexstr,pk_script,pk_scriptlen);
char str[65]; printf("unparsed script.(%s).%d in %s len.%d\n",hexstr,pk_scriptlen,bits256_str(str,txid),pk_scriptlen);
if ( 1 && fp == 0 )
fp = fopen("unparsed.txt","w");
if ( fp != 0 )
fprintf(fp,"%s\n",hexstr), fflush(fp);
} else sprintf(hexstr,"pkscript overflowed %ld\n",(long)sizeof(hexstr));
}
vcalc_sha256(0,sha256,pk_script,pk_scriptlen);
calc_rmd160(0,rmd160,sha256,sizeof(sha256));
return(type);
}
int32_t iguana_calcrmd160(struct iguana_info *coin,uint8_t rmd160[20],uint8_t msigs160[16][20],int32_t *Mp,int32_t *nump,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout)
{
int32_t type,scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE];
char asmstr[IGUANA_MAXSCRIPTSIZE*3],coinaddr[65];
type = _iguana_calcrmd160(coin,rmd160,msigs160,Mp,nump,pk_script,pk_scriptlen,debugtxid,vout);
scriptlen = iguana_scriptgen(coin,coinaddr,script,asmstr,rmd160,type,vout);
if ( scriptlen != pk_scriptlen || memcmp(script,pk_script,scriptlen) != 0 )
{
printf("iguana_calcrmd160 type.%d error regenerating scriptlen.%d vs %d\n",type,scriptlen,pk_scriptlen);
}
return(type);
}
void bn_mpi2bn(BIGNUM *vo,uint8_t *data,int32_t datalen)
{
uint8_t vch2[64 + 4]; uint32_t i,vch2_len = (int32_t)datalen + 4;
@ -499,6 +286,317 @@ int32_t bitcoin_verify(uint8_t *sig,int32_t siglen,uint8_t *data,int32_t datalen
return(retval);
}
int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66])
{
script[n++] = pubkey[0]; memcpy(&script[n],pubkey,pubkey[0]+1); n += pubkey[0]+1;
script[n++] = SCRIPT_OP_CHECKSIG;
return(n);
}
int32_t bitcoin_p2shspend(uint8_t *script,int32_t n,uint8_t rmd160[20])
{
script[n++] = SCRIPT_OP_HASH160;
script[n++] = 0x14; memcpy(&script[n],rmd160,0x14); n += 0x14;
script[n++] = SCRIPT_OP_EQUAL;
return(n);
}
int32_t bitcoin_standardspend(uint8_t *script,int32_t n,uint8_t rmd160[20])
{
script[n++] = SCRIPT_OP_DUP;
script[n++] = SCRIPT_OP_HASH160;
script[n++] = 0x14; memcpy(&script[n],rmd160,0x14); n += 0x14;
script[n++] = SCRIPT_OP_EQUALVERIFY;
script[n++] = SCRIPT_OP_CHECKSIG;
return(n);
}
int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime)
{
script[n++] = (locktime >> 24), script[n++] = (locktime >> 16), script[n++] = (locktime >> 8), script[n++] = locktime;
script[n++] = OP_CHECKLOCKTIMEVERIFY;
script[n++] = OP_DROP;
return(n);
}
int32_t bitcoin_pubkeylen(uint8_t *pubkey)
{
if ( pubkey[0] == 2 || pubkey[0] == 3 )
return(33);
else if ( pubkey[0] == 4 )
return(65);
else return(-1);
}
int32_t bitcoin_MofN(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,struct vin_info *vp,int32_t M,int32_t N)
{
uint8_t sha256[32]; int32_t i,plen;
script[n++] = 0x50 + M;
for (i=0; i<N; i++)
{
if ( (plen= bitcoin_pubkeylen(vp->signers[i].pubkey)) < 0 )
return(-1);
memcpy(&script[n],vp->signers[i].pubkey,plen);
n += plen;
}
script[n++] = 0x50 + N;
script[n++] = SCRIPT_OP_CHECKMULTISIG;
vcalc_sha256(0,sha256,script,n);
calc_rmd160(0,p2sh_rmd160,sha256,sizeof(sha256));
return(n);
}
char *create_atomictx_cltvspend(char *scriptstr,uint8_t *rmd160A,uint8_t *rmd160B,uint32_t locktime)
{
// OP_IF
// <timestamp> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG
// OP_ELSE
// OP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG // standard spend
// OP_ENDIF
uint8_t hex[4096]; int32_t n = 0;
hex[n++] = SCRIPT_OP_IF;
n = bitcoin_checklocktimeverify(hex,n,locktime);
n = bitcoin_standardspend(hex,n,rmd160A);
hex[n++] = SCRIPT_OP_ELSE;
n = bitcoin_standardspend(hex,n,rmd160B);
hex[n++] = SCRIPT_OP_ENDIF;
init_hexbytes_noT(scriptstr,hex,n);
return(scriptstr);
}
/*
struct vin_signer { bits256 privkey; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; };
struct vin_info
{
struct iguana_msgvin vin;
int32_t M,N,validmask,spendlen,p2shflag;
struct vin_signer signers[16];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE];
};
*/
int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,int32_t txi,struct vin_info *vp)
{
uint8_t addrtype; char rmd160str[41]; int32_t i,m,n,flag = 0,scriptlen = 0;
m = n = 1;
if ( type == IGUANA_SCRIPT_76A988AC || type == IGUANA_SCRIPT_76AC || type == IGUANA_SCRIPT_P2SH )
{
if ( type == IGUANA_SCRIPT_P2SH )
addrtype = coin->chain->p2shtype;
else addrtype = coin->chain->pubtype;
init_hexbytes_noT(rmd160str,rmd160,20);
btc_convrmd160(coinaddr,addrtype,rmd160);
}
//printf("addrtype.%d\n",addrtype);
switch ( type )
{
case IGUANA_SCRIPT_NULL:
strcpy(asmstr,txi == 0 ? "coinbase " : "PoSbase ");
flag++;
coinaddr[0] = 0;
break;
case IGUANA_SCRIPT_76AC:
sprintf(asmstr,"OP_DUP %s OP_CHECKSIG // %s",rmd160str,coinaddr);
scriptlen = bitcoin_pubkeyspend(script,0,vp->signers[0].pubkey);
break;
case IGUANA_SCRIPT_76A988AC:
sprintf(asmstr,"OP_DUP OP_HASH160 %s OP_EQUALVERIFY OP_CHECKSIG // %s",rmd160str,coinaddr);
scriptlen = bitcoin_standardspend(script,0,rmd160);
break;
case IGUANA_SCRIPT_P2SH:
sprintf(asmstr,"OP_HASH160 %s OP_EQUAL // %s",rmd160str,coinaddr);
scriptlen = bitcoin_p2shspend(script,0,rmd160);
break;
case IGUANA_SCRIPT_OPRETURN:
strcpy(asmstr,"OP_RETURN ");
flag++;
break;
case IGUANA_SCRIPT_3of3: m = 3, n = 3; break;
case IGUANA_SCRIPT_2of3: m = 2, n = 3; break;
case IGUANA_SCRIPT_1of3: m = 1, n = 3; break;
case IGUANA_SCRIPT_2of2: m = 2, n = 2; break;
case IGUANA_SCRIPT_1of2: m = 1, n = 2; break;
case IGUANA_SCRIPT_MSIG: m = vp->M, n = vp->N; break;
case IGUANA_SCRIPT_DATA:
strcpy(asmstr,"DATA ONLY");
flag++;
break;
case IGUANA_SCRIPT_STRANGE:
strcpy(asmstr,"STRANGE SCRIPT ");
flag++;
break;
default: printf("unexpected script type\n"); break;
}
if ( n > 1 )
{
scriptlen = bitcoin_MofN(rmd160,script,0,vp,m,n);
sprintf(asmstr,"%d ",m);
for (i=0; i<n; i++)
{
init_hexbytes_noT(asmstr + strlen(asmstr),vp->signers[i].pubkey,bitcoin_pubkeylen(vp->signers[i].pubkey));
strcat(asmstr," ");
}
sprintf(asmstr + strlen(asmstr),"%d // M.%d of N.%d [",n,m,n);
for (i=0; i<n; i++)
sprintf(asmstr + strlen(asmstr),"%s%s",vp->signers[i].coinaddr,i<n-1?" ":"");
strcat(asmstr,"]\n");
}
if ( flag != 0 && vp->spendlen > 0 )
init_hexbytes_noT(asmstr + strlen(asmstr),vp->spendscript,vp->spendlen);
return(0);
}
int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp)
{
static uint8_t zero_rmd160[20];
char hexstr[8192]; uint8_t sha256[32],*script,type; int32_t i,n,m,plen;
vp->N = 1;
vp->M = 1;
type = IGUANA_SCRIPT_STRANGE;
if ( vp->spendlen == 0 )
{
if ( zero_rmd160[0] == 0 )
{
vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen); // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
calc_rmd160(0,zero_rmd160,sha256,sizeof(sha256)); // b472a266d0bd89c13706a4132ccfb16f7c3b9fcb
init_hexbytes_noT(hexstr,zero_rmd160,20);
char str[65]; printf("iguana_calcrmd160 zero len %s -> %s\n",bits256_str(str,*(bits256 *)sha256),hexstr);
}
memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160));
return(IGUANA_SCRIPT_NULL);
}
else if ( vp->spendscript[0] == SCRIPT_OP_RETURN )
type = IGUANA_SCRIPT_OPRETURN;
else if ( vp->spendscript[0] == SCRIPT_OP_DUP && vp->spendscript[1] == SCRIPT_OP_HASH160 && vp->spendscript[2] == 20 && vp->spendscript[vp->spendscript[2]+3] == SCRIPT_OP_EQUALVERIFY && vp->spendscript[vp->spendscript[2]+4] == SCRIPT_OP_CHECKSIG )
{
//printf("IGUANA_SCRIPT_76A988AC plen.%d vs %d vp->spendlen\n",vp->spendscript[2]+4,vp->spendlen);
// 76a9145f69cb73016264270dae9f65c51f60d0e4d6fd4488ac
//vcalc_sha256(0,sha256,&vp->spendscript[3],vp->spendscript[2]);
//calc_rmd160(0,vp->rmd160,sha256,sizeof(sha256));
memcpy(vp->rmd160,&vp->spendscript[3],20);
if ( (plen= vp->spendscript[2]+5) < vp->spendlen )
{
while ( plen < vp->spendlen )
if ( vp->spendscript[plen++] != 0x61 ) // nop
return(IGUANA_SCRIPT_STRANGE);
}
return(IGUANA_SCRIPT_76A988AC);
}
// 21035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055eac
else if ( vp->spendscript[0] > 0 && vp->spendscript[0] < 76 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKSIG && vp->spendscript[0] == vp->spendlen-2 )
{
memcpy(vp->signers[0].pubkey,&vp->spendscript[1],vp->spendscript[0]);
vcalc_sha256(0,sha256,vp->signers[0].pubkey,vp->spendscript[0]);
calc_rmd160(0,vp->rmd160,sha256,sizeof(sha256));
return(IGUANA_SCRIPT_76AC);
}
else if ( vp->spendscript[0] == SCRIPT_OP_HASH160 && vp->spendscript[1] == 0x14 && vp->spendlen == 23 && vp->spendscript[22] == SCRIPT_OP_EQUAL )
{
memcpy(vp->rmd160,vp->spendscript+2,20);
return(IGUANA_SCRIPT_P2SH);
}
else if ( vp->spendlen > 34 && vp->spendscript[vp->spendlen-1] == SCRIPT_OP_CHECKMULTISIG && (n= vp->spendscript[vp->spendlen-2]) >= 0x51 && n <= 0x60 && (m= vp->spendscript[0]) >= 0x51 && m <= n ) // m of n multisig
{
m -= 0x50, n -= 0x50;
script = vp->spendscript+1;
for (i=0; i<n; i++,script += plen)
{
plen = *script++;
if ( bitcoin_pubkeylen(script) != plen )
{
printf("invalid pubkey[%d] len %d\n",bitcoin_pubkeylen(script),script[0]);
return(-1);
}
memcpy(vp->signers[i].pubkey,script,plen);
vcalc_sha256(0,sha256,vp->signers[i].pubkey,plen);
calc_rmd160(0,vp->signers[i].rmd160,sha256,sizeof(sha256));
bitcoin_address(vp->signers[i].coinaddr,coin->chain->pubtype,vp->signers[i].pubkey,plen);
}
if ( (int32_t)((long)script - (long)vp->spendscript) == vp->spendlen-2 )
{
vp->N = n;
vp->M = m;
//printf("M.%d N.%d\n",m,n);
}
vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen);
calc_rmd160(0,vp->rmd160,sha256,sizeof(sha256));
if ( n == 3 )
{
if ( m == 3 )
return(IGUANA_SCRIPT_3of3);
else if ( m == 2 )
return(IGUANA_SCRIPT_2of3);
else if ( m == 1 )
return(IGUANA_SCRIPT_1of3);
}
else if ( n == 2 )
{
if ( m == 2 )
return(IGUANA_SCRIPT_2of2);
else if ( m == 1 )
return(IGUANA_SCRIPT_1of2);
}
printf("strange msig M.%d of N.%d\n",m,n);
return(IGUANA_SCRIPT_MSIG);
}
else if ( vp->spendlen == vp->spendscript[0]+1 )
{
//printf("just data.%d\n",vp->spendlen);
memcpy(vp->rmd160,zero_rmd160,sizeof(zero_rmd160));
return(IGUANA_SCRIPT_DATA);
}
if ( type != IGUANA_SCRIPT_OPRETURN )
{
if ( vp->spendlen < sizeof(hexstr)/2-1)
{
static FILE *fp;
init_hexbytes_noT(hexstr,vp->spendscript,vp->spendlen);
char str[65]; printf("unparsed script.(%s).%d in %s len.%d\n",hexstr,vp->spendlen,bits256_str(str,vp->vin.prev_hash),vp->spendlen);
if ( 1 && fp == 0 )
fp = fopen("unparsed.txt","w");
if ( fp != 0 )
fprintf(fp,"%s\n",hexstr), fflush(fp);
} else sprintf(hexstr,"pkscript overflowed %ld\n",(long)sizeof(hexstr));
}
vcalc_sha256(0,sha256,vp->spendscript,vp->spendlen);
calc_rmd160(0,vp->rmd160,sha256,sizeof(sha256));
return(type);
}
/*
struct vin_signer { bits256 privkey; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; };
struct vin_info
{
struct iguana_msgvin vin;
int32_t M,N,validmask,spendlen,p2shflag;
struct vin_signer signers[16];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE];
};
*/
int32_t iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence)
{
int32_t scriptlen; uint8_t script[IGUANA_MAXSCRIPTSIZE]; char asmstr[IGUANA_MAXSCRIPTSIZE*3];
memset(vp,0,sizeof(*vp));
vp->vin.prev_hash = debugtxid, vp->vin.prev_vout = vout;
vp->spendlen = pk_scriptlen;
vp->vin.sequence = sequence;
memcpy(vp->spendscript,pk_script,pk_scriptlen);
vp->vin.script = vp->spendscript, vp->vin.prev_vout = pk_scriptlen;
if ( (vp->type= _iguana_calcrmd160(coin,vp)) >= 0 )
{
scriptlen = iguana_scriptgen(coin,vp->coinaddr,script,asmstr,vp->rmd160,vp->type,vout,vp);
if ( scriptlen != pk_scriptlen || memcmp(script,pk_script,scriptlen) != 0 )
{
printf("iguana_calcrmd160 type.%d error regenerating scriptlen.%d vs %d\n",vp->type,scriptlen,pk_scriptlen);
}
}
return(vp->type);
}
int32_t iguana_parsevoutobj(struct iguana_info *coin,uint8_t *serialized,int32_t maxsize,struct iguana_msgvout *vout,cJSON *voutobj)
{
int32_t len = 0; cJSON *skey; char *hexstr;
@ -552,22 +650,23 @@ int32_t iguana_parsevinobj(struct iguana_info *coin,uint8_t *serialized,int32_t
cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int32_t txi,bits256 txid)
{
// 035f1321ed17d387e4433b2fa229c53616057964af065f98bfcae2233c5108055e OP_CHECKSIG
char scriptstr[8192+1],coinaddr[65],asmstr[16384]; int32_t i,M,N,asmtype;
uint8_t rmd160[20],msigs160[16][20],addrtype,space[8192];
char scriptstr[8192+1],coinaddr[65],asmstr[16384]; int32_t i,asmtype; struct vin_info V;
uint8_t addrtype,space[8192];
cJSON *addrs,*skey,*json = cJSON_CreateObject();
jaddnum(json,"value",dstr(vout->value));
jaddnum(json,"n",txi);
//"scriptPubKey":{"asm":"OP_DUP OP_HASH160 5f69cb73016264270dae9f65c51f60d0e4d6fd44 OP_EQUALVERIFY OP_CHECKSIG","reqSigs":1,"type":"pubkeyhash","addresses":["RHyh1V9syARTf2pyxibz7v27D5paBeWza5"]}
if ( vout->pk_script != 0 && vout->pk_scriptlen*2+1 < sizeof(scriptstr) )
{
if ( (asmtype= iguana_calcrmd160(coin,rmd160,msigs160,&M,&N,vout->pk_script,vout->pk_scriptlen,txid,txi)) >= 0 )
memset(&V,0,sizeof(V));
if ( (asmtype= iguana_calcrmd160(coin,&V,vout->pk_script,vout->pk_scriptlen,txid,txi,0xffffffff)) >= 0 )
{
skey = cJSON_CreateObject();
addrtype = iguana_scriptgen(coin,coinaddr,space,asmstr,rmd160,asmtype,txi);
addrtype = iguana_scriptgen(coin,V.coinaddr,space,asmstr,V.rmd160,asmtype,txi,&V);
if ( asmstr[0] != 0 )
jaddstr(skey,"asm",asmstr);
addrs = cJSON_CreateArray();
if ( M == 0 )
if ( V.M == 0 )
{
if ( asmtype == 2 )
{
@ -579,10 +678,10 @@ cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int3
}
else
{
jaddnum(skey,"reqSigs",M);
for (i=0; i<N; i++)
jaddnum(skey,"reqSigs",V.M);
for (i=0; i<V.N; i++)
{
btc_convrmd160(coinaddr,coin->chain->pubtype,msigs160[i]);
btc_convrmd160(coinaddr,coin->chain->pubtype,V.signers[i].pubkey);
jaddistr(addrs,coinaddr);
}
}

8
iguana/exchanges/bitcoin.h

@ -22,18 +22,20 @@
#define SIGHASH_SINGLE 3
#define SIGHASH_ANYONECANPAY 0x80
#define SCRIPT_OP_TRUE 0x51
#define SCRIPT_OP_2 0x52
#define SCRIPT_OP_3 0x53
#define SCRIPT_OP_IF 0x63
#define SCRIPT_OP_ELSE 0x67
#define SCRIPT_OP_RETURN 0x6a
#define SCRIPT_OP_DUP 0x76
#define SCRIPT_OP_ENDIF 0x68
#define SCRIPT_OP_TRUE 0x51
#define SCRIPT_OP_2 0x52
#define SCRIPT_OP_3 0x53
#define OP_DROP 0x75
#define SCRIPT_OP_EQUALVERIFY 0x88
#define SCRIPT_OP_HASH160 0xa9
#define SCRIPT_OP_EQUAL 0x87
#define SCRIPT_OP_CHECKSIG 0xac
#define SCRIPT_OP_CHECKMULTISIG 0xae
#define OP_CHECKSEQUENCEVERIFY 0xb2
#define OP_CHECKLOCKTIMEVERIFY 0xb1

9
iguana/iguana777.h

@ -465,13 +465,14 @@ struct iguana_info
struct iguana_waccount *wallet;
};
struct vin_signer { bits256 privkey; uint8_t siglen,sig[80],rmd160[20],pubkey[65]; };
struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],rmd160[20],pubkey[66]; };
struct vin_info
{
struct iguana_msgvin vin;
int32_t M,N,validmask,spendlen,p2shflag;
int32_t M,N,validmask,spendlen,type;
struct vin_signer signers[16];
char coinaddr[65];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE];
};
@ -520,7 +521,7 @@ int64_t iguana_verifyaccount(struct iguana_info *coin,struct iguana_account *acc
int32_t iguana_initramchain(struct iguana_info *coin,int32_t initialheight,int32_t mapflags,int32_t fullverify);
void iguana_syncramchain(struct iguana_info *coin);
//int32_t iguana_validateramchain(struct iguana_info *coin,int64_t *netp,uint64_t *creditsp,uint64_t *debitsp,int32_t height,struct iguana_block *block,int32_t hwmheight,struct iguana_prevdep *lp);
int32_t iguana_calcrmd160(struct iguana_info *coin,uint8_t rmd160[20],uint8_t msigs160[16][20],int32_t *Mp,int32_t *nump,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout);
int32_t iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp,uint8_t *pk_script,int32_t pk_scriptlen,bits256 debugtxid,int32_t vout,uint32_t sequence);
uint32_t iguana_updatescript(struct iguana_info *coin,uint32_t blocknum,uint32_t txidind,uint32_t spendind,uint32_t unspentind,uint64_t value,uint8_t *script,int32_t scriptlen,uint32_t sequence);
void iguana_gotblockM(struct iguana_info *coin,struct iguana_peer *addr,struct iguana_txblock *txdata,struct iguana_msgtx *txarray,struct iguana_msghdr *H,uint8_t *data,int32_t datalen);
int32_t iguana_parseblock(struct iguana_info *coin,struct iguana_block *block,struct iguana_msgtx *tx,int32_t numtx);
@ -681,7 +682,7 @@ void iguana_bundleiclear(struct iguana_info *coin,struct iguana_bundle *bp,int32
int32_t hcalc_bitsize(uint64_t x);
struct iguana_pkhash *iguana_pkhashfind(struct iguana_info *coin,struct iguana_pkhash *p,uint8_t rmd160[20]);
struct iguana_txid *iguana_txidfind(struct iguana_info *coin,int32_t *heightp,struct iguana_txid *tx,bits256 txid);
int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,int32_t txi);
int32_t iguana_scriptgen(struct iguana_info *coin,char *coinaddr,uint8_t *script,char *asmstr,uint8_t rmd160[20],uint8_t type,int32_t txi,struct vin_info *vp);
int32_t iguana_ramchain_spendtxid(struct iguana_info *coin,bits256 *txidp,struct iguana_txid *T,int32_t numtxids,bits256 *X,int32_t numexternaltxids,struct iguana_spend *s);
struct iguana_info *iguana_coinselect();
void iguana_dedicatedloop(struct iguana_info *coin,struct iguana_peer *addr);

14
iguana/iguana_ramchain.c

@ -370,16 +370,20 @@ uint32_t iguana_ramchain_addpkhash(struct iguana_info *coin,RAMCHAIN_FUNC,uint8_
uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,RAMCHAIN_FUNC,uint64_t value,uint8_t *script,int32_t scriptlen,bits256 txid,int32_t vout,uint8_t type)
{
//struct iguana_unspent { uint64_t value; uint32_t txidind,pkind,prevunspentind; } __attribute__((packed));
uint8_t rmd160[20],msigs160[16][20]; int32_t M,N; uint32_t unspentind; struct iguana_unspent20 *u;
uint32_t unspentind; struct iguana_unspent20 *u; struct vin_info V;
unspentind = ramchain->H.unspentind++;
u = &U[unspentind];
if ( scriptlen == -20 )
memcpy(rmd160,script,20);
else type = iguana_calcrmd160(coin,rmd160,msigs160,&M,&N,script,scriptlen,txid,vout);
memcpy(V.rmd160,script,20);
else
{
memset(&V,0,sizeof(V));
type = iguana_calcrmd160(coin,&V,script,scriptlen,txid,vout,0xffffffff);
}
if ( ramchain->H.ROflag != 0 )
{
//printf("%p U[%d] txidind.%d pkind.%d\n",u,unspentind,ramchain->txidind,pkind);
if ( u->txidind != ramchain->H.txidind || u->value != value || memcmp(u->rmd160,rmd160,sizeof(rmd160)) != 0 )
if ( u->txidind != ramchain->H.txidind || u->value != value || memcmp(u->rmd160,V.rmd160,sizeof(V.rmd160)) != 0 )
{
printf("iguana_ramchain_addunspent20: mismatched values.(%.8f %d) vs (%.8f %d)\n",dstr(u->value),u->txidind,dstr(value),ramchain->H.txidind);
return(0);
@ -390,7 +394,7 @@ uint32_t iguana_ramchain_addunspent20(struct iguana_info *coin,RAMCHAIN_FUNC,uin
u->value = value;
u->type = type;
u->txidind = ramchain->H.txidind;
memcpy(u->rmd160,rmd160,sizeof(rmd160));
memcpy(u->rmd160,V.rmd160,sizeof(V.rmd160));
}
return(unspentind);
}

2
iguana/iguana_rpc.c

@ -705,7 +705,7 @@ cJSON *SuperNET_urlconv(char *value,int32_t bufsize,char *urlstr)
char *SuperNET_rpcparse(struct supernet_info *myinfo,char *retbuf,int32_t bufsize,int32_t *jsonflagp,int32_t *postflagp,char *urlstr,char *remoteaddr)
{
cJSON *tokens,*argjson,*json = 0; long filesize;
char symbol[16],buf[4096],helpfname[512],urlmethod[16],*data,url[1024],*retstr,*filestr,*token = 0; int32_t i,j,n,num=0;
char symbol[16],buf[4096],urlmethod[16],*data,url[1024],*retstr,*filestr,*token = 0; int32_t i,j,n,num=0;
//printf("rpcparse.(%s)\n",urlstr);
for (i=0; i<sizeof(urlmethod)-1&&urlstr[i]!=0&&urlstr[i]!=' '; i++)
urlmethod[i] = urlstr[i];

7
iguana/iguana_tx.c

@ -43,8 +43,8 @@ void iguana_vinset(struct iguana_info *coin,int32_t height,struct iguana_msgvin
int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmstr,int32_t height,struct iguana_msgvout *vout,struct iguana_txid *tx,int32_t i)
{
struct iguana_unspent *u,*U; uint32_t unspentind,scriptlen = 0; struct iguana_bundle *bp; char coinaddr[65];
struct iguana_ramchaindata *rdata; struct iguana_pkhash *P,*p;
struct iguana_ramchaindata *rdata; uint32_t unspentind,scriptlen = 0; struct iguana_bundle *bp;
struct iguana_unspent *u,*U; char coinaddr[65]; struct iguana_pkhash *P,*p; struct vin_info V;
memset(vout,0,sizeof(*vout));
if ( height >= 0 && height < coin->chain->bundlesize*coin->bundlescount && (bp= coin->bundles[height / coin->chain->bundlesize]) != 0 && (rdata= bp->ramchain.H.data) != 0 && i < tx->numvouts )
{
@ -57,7 +57,8 @@ int32_t iguana_voutset(struct iguana_info *coin,uint8_t *scriptspace,char *asmst
p = &P[u->pkind];
vout->value = u->value;
vout->pk_script = scriptspace;
scriptlen = iguana_scriptgen(coin,coinaddr,scriptspace,asmstr,p->rmd160,u->type,i);
memset(&V,0,sizeof(V));
scriptlen = iguana_scriptgen(coin,coinaddr,scriptspace,asmstr,p->rmd160,u->type,i,&V);
}
vout->pk_scriptlen = scriptlen;
return(scriptlen);

3
pnacl_main.h

@ -620,7 +620,8 @@ int CHROMEAPP_HANDLER(struct PP_Var params,struct PP_Var *output,const char **ou
PNACL_message("inside Handle_%s\n",CHROMEAPP_STR);
CHECK_PARAM_COUNT(CHROMEAPP_STR, 1);
PARAM_STRING(0,jsonstr);
retstr = CHROMEAPP_JSON(jsonstr);
if ( (retstr= CHROMEAPP_JSON(jsonstr)) == 0 )
retstr = clonestr("{\"error\":\"null return\"}");
CREATE_RESPONSE(CHROMEAPP_STR);
RESPONSE_STRING(retstr);
return 0;

Loading…
Cancel
Save