Browse Source

full script interpreter

release/v0.1
jl777 9 years ago
parent
commit
da0086720b
  1. 2
      iguana/iguana.sources
  2. 14
      iguana/iguana777.h
  3. 2432
      iguana/iguana_interpreter.c
  4. 27
      iguana/iguana_payments.c
  5. 290
      iguana/iguana_scripts.c
  6. 395
      iguana/iguana_sign.c
  7. 1
      iguana/iguana_unspents.c
  8. 11
      iguana/mini-gmp.c
  9. 32
      iguana/swaps/iguana_BTCswap.c
  10. 2
      m_onetime

2
iguana/iguana.sources

@ -1,2 +1,2 @@
SOURCES := SuperNET.c iguana_bundles.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c SuperNET_category.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c SuperNET_hexmsg.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c databases/iguana_DB.c SOURCES := SuperNET.c iguana_bundles.c iguana_interpreter.c mini-gmp.c main.c iguana_payments.c iguana_spendvectors.c iguana_sign.c iguana_txidfind.c iguana_realtime.c iguana_volatiles.c peggy_price.c SuperNET_category.c iguana_chains.c iguana_ramchain.c iguana_secp.c pangea_api.c peggy_ramkv.c SuperNET_hexmsg.c iguana_exchanges.c iguana_recv.c pangea_bets.c peggy_serdes.c SuperNET_keys.c iguana_rpc.c pangea_hand.c peggy_tx.c cards777.c iguana_init.c iguana_scripts.c pangea_json.c peggy_txind.c iguana777.c iguana_instantdex.c iguana_tradebots.c pangea_summary.c peggy_update.c iguana_accept.c iguana_json.c iguana_tx.c peggy.c poker.c iguana_bitmap.c iguana_msg.c iguana_unspents.c peggy_accts.c ramchain_api.c iguana_blocks.c iguana_peers.c iguana_wallet.c peggy_consensus.c databases/iguana_DB.c

14
iguana/iguana777.h

@ -523,7 +523,7 @@ struct vin_signer { bits256 privkey; char coinaddr[64]; uint8_t siglen,sig[80],r
struct vin_info struct vin_info
{ {
struct iguana_msgvin vin; uint64_t amount; struct iguana_msgvin vin; uint64_t amount; cJSON *extras; bits256 sigtxid;
int32_t M,N,validmask,spendlen,type,p2shlen,suffixlen,numpubkeys,numsigs,height,hashtype; int32_t M,N,validmask,spendlen,type,p2shlen,suffixlen,numpubkeys,numsigs,height,hashtype;
uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65]; uint32_t sequence,unspentind; struct vin_signer signers[16]; char coinaddr[65];
uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE]; uint8_t rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE],p2shscript[IGUANA_MAXSCRIPTSIZE];
@ -818,10 +818,14 @@ int32_t bitcoin_checklocktimeverify(uint8_t *script,int32_t n,uint32_t locktime)
struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t satoshis,int64_t insurance,char *account); struct bitcoin_spend *iguana_spendset(struct supernet_info *myinfo,struct iguana_info *coin,int64_t satoshis,int64_t insurance,char *account);
cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes); cJSON *bitcoin_hex2json(struct iguana_info *coin,bits256 *txidp,struct iguana_msgtx *msgtx,char *txbytes);
cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins); cJSON *iguana_signtx(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,char **signedtxp,struct bitcoin_spend *spend,cJSON *txobj,cJSON *vins);
cJSON *bitcoin_createtx(struct iguana_info *coin,uint32_t locktime); void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname);
cJSON *bitcoin_addoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis);
cJSON *bitcoin_txcreate(struct iguana_info *coin,int64_t locktime);
cJSON *bitcoin_txoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis);
cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys);
int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee); int32_t bitcoin_changescript(struct iguana_info *coin,uint8_t *changescript,int32_t n,uint64_t *changep,char *changeaddr,uint64_t inputsatoshis,uint64_t satoshis,uint64_t txfee);
cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys); //cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys);
int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs); int32_t bitcoin_verifytx(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,char *rawtxstr,struct vin_info *V,int32_t numinputs);
int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen); int32_t bitcoin_verify(void *ctx,uint8_t *sig,int32_t siglen,bits256 txhash2,uint8_t *pubkey,int32_t plen);
char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V); char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V);
@ -947,6 +951,8 @@ cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,c
bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey); bits256 bitcoin_pubkey33(void *ctx,uint8_t *data,bits256 privkey);
bits256 bitcoin_randkey(void *ctx); bits256 bitcoin_randkey(void *ctx);
int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig64,bits256 messagehash2,uint8_t *pubkey); int32_t bitcoin_recoververify(void *ctx,char *symbol,uint8_t *sig64,bits256 messagehash2,uint8_t *pubkey);
int32_t bitcoin_assembler(struct iguana_info *coin,uint8_t script[IGUANA_MAXSCRIPTSIZE],cJSON *scriptobj,int32_t interpret,int64_t nLockTime,struct vin_info *V);
cJSON *iguana_spendasm(struct iguana_info *coin,uint8_t *spendscript,int32_t spendlen);
extern int32_t HDRnet,netBLOCKS; extern int32_t HDRnet,netBLOCKS;

2432
iguana/iguana_interpreter.c

File diff suppressed because it is too large

27
iguana/iguana_payments.c

@ -160,7 +160,7 @@ cJSON *iguana_scriptobj(struct iguana_info *coin,uint8_t rmd160[20],char *coinad
char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint64_t satoshis,char *comment,char *comment2,int32_t minconf,char *account) char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *coinaddr,uint64_t satoshis,char *comment,char *comment2,int32_t minconf,char *account)
{ {
uint8_t addrtype,rmd160[20],*rmdarray; int32_t i,numwaddrs,numrmds,numunspents=0; struct iguana_waddress **waddrs,*waddr; uint64_t *unspents; uint8_t addrtype,rmd160[20]; int32_t i,j,numwaddrs,numunspents=0; struct iguana_waddress **waddrs,*waddr; uint64_t *unspents;
//sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to] <amount> is a real and is rounded to 8 decimal places. Returns the transaction ID <txid> if successful. Y //sendtoaddress <bitcoinaddress> <amount> [comment] [comment-to] <amount> is a real and is rounded to 8 decimal places. Returns the transaction ID <txid> if successful. Y
if ( coinaddr != 0 && coinaddr[0] != 0 && satoshis != 0 ) if ( coinaddr != 0 && coinaddr[0] != 0 && satoshis != 0 )
{ {
@ -173,17 +173,12 @@ char *sendtoaddress(struct supernet_info *myinfo,struct iguana_info *coin,char *
unspents = (uint64_t *)((long)coin->blockspace + sizeof(*waddrs)*numwaddrs); unspents = (uint64_t *)((long)coin->blockspace + sizeof(*waddrs)*numwaddrs);
for (i=0; i<numwaddrs; i++) for (i=0; i<numwaddrs; i++)
{ {
if ( (waddr= waddrs[i]) != 0 ) if ( (waddr= waddrs[i]) != 0 && waddr->numunspents > 0 )
printf("(%s %.8f) ",waddr->coinaddr,dstr(waddr->balance)); {
} for (j=0; j<waddr->numunspents; j++)
if ( (rmdarray= iguana_rmdarray(coin,&numrmds,0,0)) != 0 ) printf("([%d].u%u) ",(uint32_t)(unspents[i]>>32),(uint32_t)unspents[i]);
{ printf("(%s %.8f)\n",waddr->coinaddr,dstr(waddr->balance));
numunspents = (int32_t)((sizeof(coin->blockspace) - sizeof(*waddrs)*numwaddrs) / sizeof(uint64_t)); }
iguana_unspents(myinfo,coin,0,minconf,coin->longestchain,rmdarray,numrmds,0,unspents,&numunspents);
if ( rmdarray != 0 )
free(rmdarray);
for (i=0; i<numunspents; i++)
printf("([%d].u%u) ",(uint32_t)(unspents[i]>>32),(uint32_t)unspents[i]);
} }
} }
printf("need to generate send %.8f to %s [%s] [%s] using numaddrs.%d numunspents.%d\n",dstr(satoshis),coinaddr,comment!=0?comment:"",comment2!=0?comment2:"",numwaddrs,numunspents); printf("need to generate send %.8f to %s [%s] [%s] using numaddrs.%d numunspents.%d\n",dstr(satoshis),coinaddr,comment!=0?comment:"",comment2!=0?comment2:"",numwaddrs,numunspents);
@ -631,7 +626,7 @@ cJSON *iguana_createvins(struct supernet_info *myinfo,struct iguana_info *coin,c
sequenceid = juint(item,"sequence"); sequenceid = juint(item,"sequence");
else sequenceid = 0xffffffff; else sequenceid = 0xffffffff;
jaddnum(newvin,"sequence",sequenceid); jaddnum(newvin,"sequence",sequenceid);
bitcoin_addinput(coin,txobj,txid,vout,sequenceid,spendscript,spendlen,redeemscript,p2shlen,0,0); bitcoin_txinput(coin,txobj,txid,vout,sequenceid,spendscript,spendlen,redeemscript,p2shlen,0,0);
jadd(newvin,"pubkeys",pubkeys); jadd(newvin,"pubkeys",pubkeys);
jaddi(newvins,newvin); jaddi(newvins,newvin);
} }
@ -644,7 +639,7 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime)
bits256 txid; int32_t offset,spendlen=0,n; uint8_t addrtype,rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; uint64_t satoshis; char *hexstr,*field,*txstr; cJSON *txobj,*item,*obj,*retjson = cJSON_CreateObject(); bits256 txid; int32_t offset,spendlen=0,n; uint8_t addrtype,rmd160[20],spendscript[IGUANA_MAXSCRIPTSIZE]; uint64_t satoshis; char *hexstr,*field,*txstr; cJSON *txobj,*item,*obj,*retjson = cJSON_CreateObject();
if ( remoteaddr != 0 ) if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}")); return(clonestr("{\"error\":\"no remote\"}"));
if ( coin != 0 && (txobj= bitcoin_createtx(coin,locktime)) != 0 ) if ( coin != 0 && (txobj= bitcoin_txcreate(coin,locktime)) != 0 )
{ {
iguana_createvins(myinfo,coin,txobj,vins); iguana_createvins(myinfo,coin,txobj,vins);
if ( (n= cJSON_GetArraySize(vouts)) > 0 ) if ( (n= cJSON_GetArraySize(vouts)) > 0 )
@ -694,7 +689,7 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime)
if ( (obj= jobj(item,"amount")) != 0 ) if ( (obj= jobj(item,"amount")) != 0 )
satoshis = jdouble(obj,0) * SATOSHIDEN; satoshis = jdouble(obj,0) * SATOSHIDEN;
else satoshis = 0; else satoshis = 0;
bitcoin_addoutput(coin,txobj,spendscript+offset,spendlen,satoshis); bitcoin_txoutput(coin,txobj,spendscript+offset,spendlen,satoshis);
} }
} }
break; break;
@ -705,7 +700,7 @@ ARRAY_OBJ_INT(bitcoinrpc,createrawtransaction,vins,vouts,locktime)
{ {
spendlen = bitcoin_standardspend(spendscript,0,rmd160); spendlen = bitcoin_standardspend(spendscript,0,rmd160);
satoshis = jdouble(item,0) * SATOSHIDEN; satoshis = jdouble(item,0) * SATOSHIDEN;
bitcoin_addoutput(coin,txobj,spendscript,spendlen,satoshis); bitcoin_txoutput(coin,txobj,spendscript,spendlen,satoshis);
} }
} }
} }

290
iguana/iguana_scripts.c

@ -16,290 +16,6 @@
#include "iguana777.h" #include "iguana777.h"
#include "exchanges/bitcoin.h" #include "exchanges/bitcoin.h"
enum opcodetype
{
// push value
OP_0 = 0x00,
OP_FALSE = OP_0,
OP_PUSHDATA1 = 0x4c,
OP_PUSHDATA2 = 0x4d,
OP_PUSHDATA4 = 0x4e,
OP_1NEGATE = 0x4f,
OP_RESERVED = 0x50,
OP_1 = 0x51,
OP_TRUE=OP_1,
OP_2 = 0x52,
OP_3 = 0x53,
OP_4 = 0x54,
OP_5 = 0x55,
OP_6 = 0x56,
OP_7 = 0x57,
OP_8 = 0x58,
OP_9 = 0x59,
OP_10 = 0x5a,
OP_11 = 0x5b,
OP_12 = 0x5c,
OP_13 = 0x5d,
OP_14 = 0x5e,
OP_15 = 0x5f,
OP_16 = 0x60,
// control
OP_NOP = 0x61,
OP_VER = 0x62,
OP_IF = 0x63,
OP_NOTIF = 0x64,
OP_VERIF = 0x65,
OP_VERNOTIF = 0x66,
OP_ELSE = 0x67,
OP_ENDIF = 0x68,
OP_VERIFY = 0x69,
OP_RETURN = 0x6a,
// stack ops
OP_TOALTSTACK = 0x6b,
OP_FROMALTSTACK = 0x6c,
OP_2DROP = 0x6d,
OP_2DUP = 0x6e,
OP_3DUP = 0x6f,
OP_2OVER = 0x70,
OP_2ROT = 0x71,
OP_2SWAP = 0x72,
OP_IFDUP = 0x73,
OP_DEPTH = 0x74,
OP_DROP = 0x75,
OP_DUP = 0x76,
OP_NIP = 0x77,
OP_OVER = 0x78,
OP_PICK = 0x79,
OP_ROLL = 0x7a,
OP_ROT = 0x7b,
OP_SWAP = 0x7c,
OP_TUCK = 0x7d,
// splice ops
OP_CAT = 0x7e,
OP_SUBSTR = 0x7f,
OP_LEFT = 0x80,
OP_RIGHT = 0x81,
OP_SIZE = 0x82,
// bit logic
OP_INVERT = 0x83,
OP_AND = 0x84,
OP_OR = 0x85,
OP_XOR = 0x86,
OP_EQUAL = 0x87,
OP_EQUALVERIFY = 0x88,
OP_RESERVED1 = 0x89,
OP_RESERVED2 = 0x8a,
// numeric
OP_1ADD = 0x8b,
OP_1SUB = 0x8c,
OP_2MUL = 0x8d,
OP_2DIV = 0x8e,
OP_NEGATE = 0x8f,
OP_ABS = 0x90,
OP_NOT = 0x91,
OP_0NOTEQUAL = 0x92,
OP_ADD = 0x93,
OP_SUB = 0x94,
OP_MUL = 0x95,
OP_DIV = 0x96,
OP_MOD = 0x97,
OP_LSHIFT = 0x98,
OP_RSHIFT = 0x99,
OP_BOOLAND = 0x9a,
OP_BOOLOR = 0x9b,
OP_NUMEQUAL = 0x9c,
OP_NUMEQUALVERIFY = 0x9d,
OP_NUMNOTEQUAL = 0x9e,
OP_LESSTHAN = 0x9f,
OP_GREATERTHAN = 0xa0,
OP_LESSTHANOREQUAL = 0xa1,
OP_GREATERTHANOREQUAL = 0xa2,
OP_MIN = 0xa3,
OP_MAX = 0xa4,
OP_WITHIN = 0xa5,
// crypto
OP_RIPEMD160 = 0xa6,
OP_SHA1 = 0xa7,
OP_SHA256 = 0xa8,
OP_HASH160 = 0xa9,
OP_HASH256 = 0xaa,
OP_CODESEPARATOR = 0xab,
OP_CHECKSIG = 0xac,
OP_CHECKSIGVERIFY = 0xad,
OP_CHECKMULTISIG = 0xae,
OP_CHECKMULTISIGVERIFY = 0xaf,
// expansion
OP_NOP1 = 0xb0,
OP_NOP2 = 0xb1,
OP_NOP3 = 0xb2,
OP_NOP4 = 0xb3,
OP_NOP5 = 0xb4,
OP_NOP6 = 0xb5,
OP_NOP7 = 0xb6,
OP_NOP8 = 0xb7,
OP_NOP9 = 0xb8,
OP_NOP10 = 0xb9,
// template matching params
OP_SMALLINTEGER = 0xfa,
OP_PUBKEYS = 0xfb,
OP_PUBKEYHASH = 0xfd,
OP_PUBKEY = 0xfe,
OP_INVALIDOPCODE = 0xff,
};
const char *get_opname(int32_t *extralenp,enum opcodetype opcode)
{
*extralenp = 0;
switch (opcode)
{
// push value
case OP_0 : return "0";
case OP_PUSHDATA1 : *extralenp = 1; return "OP_PUSHDATA1";
case OP_PUSHDATA2 : *extralenp = 2; return "OP_PUSHDATA2";
case OP_PUSHDATA4 : *extralenp = 4; return "OP_PUSHDATA4";
case OP_1NEGATE : return "-1";
case OP_RESERVED : return "OP_RESERVED";
case OP_1 : return "1";
case OP_2 : return "2";
case OP_3 : return "3";
case OP_4 : return "4";
case OP_5 : return "5";
case OP_6 : return "6";
case OP_7 : return "7";
case OP_8 : return "8";
case OP_9 : return "9";
case OP_10 : return "10";
case OP_11 : return "11";
case OP_12 : return "12";
case OP_13 : return "13";
case OP_14 : return "14";
case OP_15 : return "15";
case OP_16 : return "16";
// control
case OP_NOP : return "OP_NOP";
case OP_VER : return "OP_VER";
case OP_IF : return "OP_IF";
case OP_NOTIF : return "OP_NOTIF";
case OP_VERIF : return "OP_VERIF";
case OP_VERNOTIF : return "OP_VERNOTIF";
case OP_ELSE : return "OP_ELSE";
case OP_ENDIF : return "OP_ENDIF";
case OP_VERIFY : return "OP_VERIFY";
case OP_RETURN : return "OP_RETURN";
// stack ops
case OP_TOALTSTACK : return "OP_TOALTSTACK";
case OP_FROMALTSTACK : return "OP_FROMALTSTACK";
case OP_2DROP : return "OP_2DROP";
case OP_2DUP : return "OP_2DUP";
case OP_3DUP : return "OP_3DUP";
case OP_2OVER : return "OP_2OVER";
case OP_2ROT : return "OP_2ROT";
case OP_2SWAP : return "OP_2SWAP";
case OP_IFDUP : return "OP_IFDUP";
case OP_DEPTH : return "OP_DEPTH";
case OP_DROP : return "OP_DROP";
case OP_DUP : return "OP_DUP";
case OP_NIP : return "OP_NIP";
case OP_OVER : return "OP_OVER";
case OP_PICK : return "OP_PICK";
case OP_ROLL : return "OP_ROLL";
case OP_ROT : return "OP_ROT";
case OP_SWAP : return "OP_SWAP";
case OP_TUCK : return "OP_TUCK";
// splice ops
case OP_CAT : return "OP_CAT";
case OP_SUBSTR : return "OP_SUBSTR";
case OP_LEFT : return "OP_LEFT";
case OP_RIGHT : return "OP_RIGHT";
case OP_SIZE : return "OP_SIZE";
// bit logic
case OP_INVERT : return "OP_INVERT";
case OP_AND : return "OP_AND";
case OP_OR : return "OP_OR";
case OP_XOR : return "OP_XOR";
case OP_EQUAL : return "OP_EQUAL";
case OP_EQUALVERIFY : return "OP_EQUALVERIFY";
case OP_RESERVED1 : return "OP_RESERVED1";
case OP_RESERVED2 : return "OP_RESERVED2";
// numeric
case OP_1ADD : return "OP_1ADD";
case OP_1SUB : return "OP_1SUB";
case OP_2MUL : return "OP_2MUL";
case OP_2DIV : return "OP_2DIV";
case OP_NEGATE : return "OP_NEGATE";
case OP_ABS : return "OP_ABS";
case OP_NOT : return "OP_NOT";
case OP_0NOTEQUAL : return "OP_0NOTEQUAL";
case OP_ADD : return "OP_ADD";
case OP_SUB : return "OP_SUB";
case OP_MUL : return "OP_MUL";
case OP_DIV : return "OP_DIV";
case OP_MOD : return "OP_MOD";
case OP_LSHIFT : return "OP_LSHIFT";
case OP_RSHIFT : return "OP_RSHIFT";
case OP_BOOLAND : return "OP_BOOLAND";
case OP_BOOLOR : return "OP_BOOLOR";
case OP_NUMEQUAL : return "OP_NUMEQUAL";
case OP_NUMEQUALVERIFY : return "OP_NUMEQUALVERIFY";
case OP_NUMNOTEQUAL : return "OP_NUMNOTEQUAL";
case OP_LESSTHAN : return "OP_LESSTHAN";
case OP_GREATERTHAN : return "OP_GREATERTHAN";
case OP_LESSTHANOREQUAL : return "OP_LESSTHANOREQUAL";
case OP_GREATERTHANOREQUAL : return "OP_GREATERTHANOREQUAL";
case OP_MIN : return "OP_MIN";
case OP_MAX : return "OP_MAX";
case OP_WITHIN : return "OP_WITHIN";
// crypto
case OP_RIPEMD160 : return "OP_RIPEMD160";
case OP_SHA1 : return "OP_SHA1";
case OP_SHA256 : return "OP_SHA256";
case OP_HASH160 : return "OP_HASH160";
case OP_HASH256 : return "OP_HASH256";
case OP_CODESEPARATOR : return "OP_CODESEPARATOR";
case OP_CHECKSIG : return "OP_CHECKSIG";
case OP_CHECKSIGVERIFY : return "OP_CHECKSIGVERIFY";
case OP_CHECKMULTISIG : return "OP_CHECKMULTISIG";
case OP_CHECKMULTISIGVERIFY : return "OP_CHECKMULTISIGVERIFY";
// expanson
case OP_NOP1 : return "OP_NOP1";
case OP_NOP2 : return "OP_NOP2";
case OP_NOP3 : return "OP_NOP3";
case OP_NOP4 : return "OP_NOP4";
case OP_NOP5 : return "OP_NOP5";
case OP_NOP6 : return "OP_NOP6";
case OP_NOP7 : return "OP_NOP7";
case OP_NOP8 : return "OP_NOP8";
case OP_NOP9 : return "OP_NOP9";
case OP_NOP10 : return "OP_NOP10";
case OP_INVALIDOPCODE : return "OP_INVALIDOPCODE";
// Note:
// The template matching params OP_SMALLDATA/etc are defined in opcodetype enum
// as kind of implementation hack, they are *NOT* real opcodes. If found in real
// Script, just let the default: case deal with them.
default: return "OP_UNKNOWN";
}
}
int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66]) int32_t bitcoin_pubkeyspend(uint8_t *script,int32_t n,uint8_t pubkey[66])
{ {
int32_t plen = bitcoin_pubkeylen(pubkey); int32_t plen = bitcoin_pubkeylen(pubkey);
@ -563,12 +279,6 @@ int32_t iguana_scriptgen(struct iguana_info *coin,int32_t *Mp,int32_t *nump,char
return(scriptlen); return(scriptlen);
} }
int32_t iguana_expandscript(struct iguana_info *coin,char *asmstr,int32_t maxlen,uint8_t *script,int32_t scriptlen)
{
asmstr[0] = 0;
return(0);
}
int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp) int32_t _iguana_calcrmd160(struct iguana_info *coin,struct vin_info *vp)
{ {
static uint8_t zero_rmd160[20]; static uint8_t zero_rmd160[20];

395
iguana/iguana_sign.c

@ -100,62 +100,6 @@ int32_t iguana_voutparse(int32_t rwflag,uint8_t *serialized,struct iguana_msgvou
return(len); return(len);
} }
cJSON *iguana_scriptpubkeys(struct iguana_info *coin,uint8_t *script,int32_t scriptlen,bits256 txid,int16_t vout,uint32_t sequenceid)
{
int32_t type,i,n,plen; struct vin_info V; cJSON *pubkeys; char pubkeystr[256];
pubkeys = cJSON_CreateArray();
if ( (type= iguana_calcrmd160(coin,0,&V,script,scriptlen,txid,vout,sequenceid)) >= 0 )
{
if ( (n= V.N) == 0 )
n = 1;
for (i=0; i<n; i++)
{
if ( (plen= bitcoin_pubkeylen(V.signers[i].pubkey)) > 0 )
init_hexbytes_noT(pubkeystr,V.signers[i].pubkey,plen);
else pubkeystr[0] = 0;
jaddistr(pubkeys,pubkeystr);
}
}
return(pubkeys);
}
void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname)
{
char *scriptstr,scriptbuf[8192+256]; int32_t len; cJSON *scriptobj;
if ( scriptlen < 0 )
return;
if ( scriptlen > sizeof(scriptbuf) )
len = (scriptlen << 1) + 256, scriptstr = malloc(len);
else scriptstr = scriptbuf, len = sizeof(scriptbuf);
init_hexbytes_noT(scriptstr,script,scriptlen);
if ( strcmp(fieldname,"coinbase") == 0 )
jaddstr(dest,"coinbase",scriptstr);
else
{
scriptobj = cJSON_CreateObject();
jaddstr(scriptobj,"hex",scriptstr);
iguana_expandscript(coin,scriptstr,len,script,scriptlen);
if ( scriptstr[0] != 0 )
jaddstr(scriptobj,"asm",scriptstr);
if ( scriptstr != scriptbuf )
free(scriptstr);
jadd(dest,fieldname,scriptobj);
}
}
cJSON *iguana_pubkeysjson(uint8_t *pubkeyptrs[],int32_t numpubkeys)
{
int32_t i,plen; char pubkeystr[256]; cJSON *pubkeysjson = cJSON_CreateArray();
for (i=0; i<numpubkeys; i++)
{
if ( pubkeyptrs != 0 && (plen= bitcoin_pubkeylen(pubkeyptrs[i])) > 0 )
init_hexbytes_noT(pubkeystr,pubkeyptrs[i],plen);
else pubkeystr[0] = 0;
jaddistr(pubkeysjson,pubkeystr);
}
return(pubkeysjson);
}
cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin) cJSON *iguana_vinjson(struct iguana_info *coin,struct iguana_msgvin *vin)
{ {
char str[65]; int32_t vout; cJSON *json = cJSON_CreateObject(); char str[65]; int32_t vout; cJSON *json = cJSON_CreateObject();
@ -457,7 +401,7 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t rwflag,cJSON *json,uint8
*txidp = bits256_doublesha256(txidstr,txstart,len); *txidp = bits256_doublesha256(txidstr,txstart,len);
if ( json != 0 ) if ( json != 0 )
{ {
jaddnum(json,"locktime",msg->lock_time); jadd64bits(json,"locktime",msg->lock_time);
jaddnum(json,"size",len); jaddnum(json,"size",len);
jaddbits256(json,"txid",*txidp); jaddbits256(json,"txid",*txidp);
//printf("TX.(%s) %p\n",jprint(json,0),json); //printf("TX.(%s) %p\n",jprint(json,0),json);
@ -507,7 +451,7 @@ bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,
len += iguana_parsevoutobj(coin,&serialized[len],maxsize,&msg->vouts[i],jitem(array,i)); len += iguana_parsevoutobj(coin,&serialized[len],maxsize,&msg->vouts[i],jitem(array,i));
} }
} }
msg->lock_time = juint(txobj,"locktime"); msg->lock_time = (int32_t)j64bits(txobj,"locktime");
msg->txid = jbits256(txobj,"txid"); msg->txid = jbits256(txobj,"txid");
*txstartp = len; *txstartp = len;
if ( (msg->allocsize= iguana_rwmsgtx(coin,1,0,&serialized[len],maxsize-len,msg,&txid,vpnstr)) < 0 ) if ( (msg->allocsize= iguana_rwmsgtx(coin,1,0,&serialized[len],maxsize-len,msg,&txid,vpnstr)) < 0 )
@ -535,74 +479,6 @@ char *iguana_rawtxbytes(struct iguana_info *coin,cJSON *json,struct iguana_msgtx
return(txbytes); return(txbytes);
} }
cJSON *bitcoin_createtx(struct iguana_info *coin,uint32_t locktime)
{
cJSON *json = cJSON_CreateObject();
if ( locktime == 0 )
{
jaddnum(json,"version",1);
jaddnum(json,"locktime",0);
}
else
{
jaddnum(json,"version",4);
jaddnum(json,"locktime",locktime);
}
if ( coin->chain->hastimestamp != 0 )
jaddnum(json,"timestamp",time(NULL));
jadd(json,"vin",cJSON_CreateArray());
jadd(json,"vout",cJSON_CreateArray());
return(json);
}
cJSON *bitcoin_addoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis)
{
char *hexstr; cJSON *item,*skey,*vouts = jduplicate(jobj(txobj,"vout"));
jdelete(txobj,"vout");
item = cJSON_CreateObject();
jadd64bits(item,"satoshis",satoshis);
skey = cJSON_CreateObject();
hexstr = malloc(len*2 + 1);
init_hexbytes_noT(hexstr,paymentscript,len);
jaddstr(skey,"hex",hexstr);
//printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0));
free(hexstr);
jadd(item,"scriptPubkey",skey);
jaddi(vouts,item);
jadd(txobj,"vout",vouts);
return(txobj);
}
cJSON *bitcoin_addinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys)
{
cJSON *item,*vins; char p2shscriptstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t *script,len;
vins = jduplicate(jobj(txobj,"vin"));
jdelete(txobj,"vin");
item = cJSON_CreateObject();
if ( spendscript != 0 && spendscript > 0 )
{
iguana_addscript(coin,item,spendscript,spendlen,"scriptPubKey");
script = spendscript, len = spendlen;
}
else if ( redeemscript != 0 && p2shlen > 0 )
{
init_hexbytes_noT(p2shscriptstr,redeemscript,p2shlen);
jaddstr(item,"redeemScript",p2shscriptstr);
script = redeemscript, len = p2shlen;
} else script = 0;
if ( script != 0 && numpubkeys == 0 )
jadd(item,"pubkeys",iguana_scriptpubkeys(coin,script,len,txid,vout,sequenceid));
else if ( pubkeys != 0 && numpubkeys > 0 )
jadd(item,"pubkeys",iguana_pubkeysjson(pubkeys,numpubkeys));
jaddbits256(item,"txid",txid);
jaddnum(item,"vout",vout);
jaddnum(item,"sequence",sequenceid);
jaddi(vins,item);
jadd(txobj,"vin",vins);
//printf("addvin -> (%s)\n",jprint(txobj,0));
return(txobj);
}
char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V) char *bitcoin_json2hex(struct supernet_info *myinfo,struct iguana_info *coin,bits256 *txidp,cJSON *txjson,struct vin_info *V)
{ {
int32_t txstart; uint8_t *serialized; struct iguana_msgtx msgtx; char *txbytes = 0; int32_t txstart; uint8_t *serialized; struct iguana_msgtx msgtx; char *txbytes = 0;
@ -743,7 +619,7 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m
int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,int32_t sighash) int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **signedtx,struct iguana_msgtx *msgtx,uint8_t *serialized,int32_t maxlen,struct vin_info *V,int32_t sighash)
{ {
bits256 sigtxid; uint8_t *sig; struct vin_info *vp; char vpnstr[64]; int32_t complete=1,plen,i,j,vini=0,flag=0,siglen,numvouts,numsigs; bits256 sigtxid; uint8_t *sig; struct vin_info *vp; char vpnstr[64]; int32_t complete=0,plen,i,j,vini=0,flag=0,siglen,numvouts,numsigs;
numvouts = msgtx->tx_out; numvouts = msgtx->tx_out;
vpnstr[0] = 0; vpnstr[0] = 0;
*signedtx = 0; *signedtx = 0;
@ -754,6 +630,7 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **
if ( bits256_nonz(sigtxid) != 0 ) if ( bits256_nonz(sigtxid) != 0 )
{ {
vp = &V[vini]; vp = &V[vini];
vp->sigtxid = sigtxid;
for (j=numsigs=0; j<vp->N; j++) for (j=numsigs=0; j<vp->N; j++)
{ {
sig = vp->signers[j].sig; sig = vp->signers[j].sig;
@ -787,8 +664,8 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,bits256 *signedtxidp,char **
numsigs++; numsigs++;
} }
} }
if ( numsigs < vp->M ) if ( numsigs >= vp->M )
complete = 0; complete = 1;
} }
} }
iguana_msgtx_Vset(coin,serialized,maxlen,msgtx,V); iguana_msgtx_Vset(coin,serialized,maxlen,msgtx,V);
@ -1020,11 +897,171 @@ int32_t bitcoin_txaddspend(struct iguana_info *coin,cJSON *txobj,char *destaddre
{ {
bitcoin_addr2rmd160(&addrtype,rmd160,destaddress); bitcoin_addr2rmd160(&addrtype,rmd160,destaddress);
scriptlen = bitcoin_standardspend(outputscript,0,rmd160); scriptlen = bitcoin_standardspend(outputscript,0,rmd160);
bitcoin_addoutput(coin,txobj,outputscript,scriptlen,satoshis); bitcoin_txoutput(coin,txobj,outputscript,scriptlen,satoshis);
return(0); return(0);
} else return(-1); } else return(-1);
} }
cJSON *bitcoin_txscript(struct iguana_info *coin,char *asmstr,char **vardata,int32_t numvars)
{
int32_t i; cJSON *scriptjson,*array;
scriptjson = cJSON_CreateObject();
jaddstr(scriptjson,"asm",asmstr);
jaddnum(scriptjson,"numvars",numvars);
if ( numvars > 0 )
{
array = cJSON_CreateArray();
for (i=0; i<numvars; i++)
jaddistr(array,vardata[i]);
jadd(scriptjson,"args",array);
}
return(scriptjson);
}
cJSON *iguana_scriptpubkeys(struct iguana_info *coin,uint8_t *script,int32_t scriptlen,bits256 txid,int16_t vout,uint32_t sequenceid)
{
int32_t type,i,n,plen; struct vin_info V; cJSON *pubkeys; char pubkeystr[256];
pubkeys = cJSON_CreateArray();
if ( (type= iguana_calcrmd160(coin,0,&V,script,scriptlen,txid,vout,sequenceid)) >= 0 )
{
if ( (n= V.N) == 0 )
n = 1;
for (i=0; i<n; i++)
{
if ( (plen= bitcoin_pubkeylen(V.signers[i].pubkey)) > 0 )
init_hexbytes_noT(pubkeystr,V.signers[i].pubkey,plen);
else pubkeystr[0] = 0;
jaddistr(pubkeys,pubkeystr);
}
}
return(pubkeys);
}
void iguana_addscript(struct iguana_info *coin,cJSON *dest,uint8_t *script,int32_t scriptlen,char *fieldname)
{
char *scriptstr,scriptbuf[8192+256]; int32_t len; cJSON *scriptobj;
if ( scriptlen < 0 )
return;
if ( scriptlen > sizeof(scriptbuf) )
len = (scriptlen << 1) + 256, scriptstr = malloc(len);
else scriptstr = scriptbuf, len = sizeof(scriptbuf);
init_hexbytes_noT(scriptstr,script,scriptlen);
if ( strcmp(fieldname,"coinbase") == 0 )
jaddstr(dest,"coinbase",scriptstr);
else
{
scriptobj = cJSON_CreateObject();
jaddstr(scriptobj,"hex",scriptstr);
iguana_expandscript(coin,scriptstr,len,script,scriptlen);
if ( scriptstr[0] != 0 )
jaddstr(scriptobj,"asm",scriptstr);
if ( scriptstr != scriptbuf )
free(scriptstr);
jadd(dest,fieldname,scriptobj);
}
}
cJSON *iguana_pubkeysjson(uint8_t *pubkeyptrs[],int32_t numpubkeys)
{
int32_t i,plen; char pubkeystr[256]; cJSON *pubkeysjson = cJSON_CreateArray();
for (i=0; i<numpubkeys; i++)
{
if ( pubkeyptrs != 0 && (plen= bitcoin_pubkeylen(pubkeyptrs[i])) > 0 )
init_hexbytes_noT(pubkeystr,pubkeyptrs[i],plen);
else pubkeystr[0] = 0;
jaddistr(pubkeysjson,pubkeystr);
}
return(pubkeysjson);
}
cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_t vout,uint32_t sequenceid,uint8_t *spendscript,int32_t spendlen,uint8_t *redeemscript,int32_t p2shlen,uint8_t *pubkeys[],int32_t numpubkeys)
{
cJSON *item,*vins; char p2shscriptstr[IGUANA_MAXSCRIPTSIZE*2+1]; uint8_t *script,len;
vins = jduplicate(jobj(txobj,"vin"));
jdelete(txobj,"vin");
item = cJSON_CreateObject();
if ( spendscript != 0 && spendscript > 0 )
{
iguana_addscript(coin,item,spendscript,spendlen,"scriptPubKey");
script = spendscript, len = spendlen;
}
else if ( redeemscript != 0 && p2shlen > 0 )
{
init_hexbytes_noT(p2shscriptstr,redeemscript,p2shlen);
jaddstr(item,"redeemScript",p2shscriptstr);
script = redeemscript, len = p2shlen;
} else script = 0;
if ( script != 0 && numpubkeys == 0 )
jadd(item,"pubkeys",iguana_scriptpubkeys(coin,script,len,txid,vout,sequenceid));
else if ( pubkeys != 0 && numpubkeys > 0 )
jadd(item,"pubkeys",iguana_pubkeysjson(pubkeys,numpubkeys));
jaddbits256(item,"txid",txid);
jaddnum(item,"vout",vout);
jaddnum(item,"sequence",sequenceid);
jaddi(vins,item);
jadd(txobj,"vin",vins);
//printf("addvin -> (%s)\n",jprint(txobj,0));
return(txobj);
}
cJSON *bitcoin_txcreate(struct iguana_info *coin,int64_t locktime)
{
cJSON *json = cJSON_CreateObject();
if ( locktime == 0 )
{
jaddnum(json,"version",1);
jadd64bits(json,"locktime",0);
}
else
{
jaddnum(json,"version",4);
jadd64bits(json,"locktime",locktime);
}
if ( coin->chain->hastimestamp != 0 )
jaddnum(json,"timestamp",time(NULL));
jadd(json,"vin",cJSON_CreateArray());
jadd(json,"vout",cJSON_CreateArray());
return(json);
}
cJSON *bitcoin_txoutput(struct iguana_info *coin,cJSON *txobj,uint8_t *paymentscript,int32_t len,uint64_t satoshis)
{
char *hexstr; cJSON *item,*skey,*vouts = jduplicate(jobj(txobj,"vout"));
jdelete(txobj,"vout");
item = cJSON_CreateObject();
jadd64bits(item,"satoshis",satoshis);
skey = cJSON_CreateObject();
hexstr = malloc(len*2 + 1);
init_hexbytes_noT(hexstr,paymentscript,len);
jaddstr(skey,"hex",hexstr);
//printf("addoutput.(%s %s)\n",hexstr,jprint(skey,0));
free(hexstr);
jadd(item,"scriptPubkey",skey);
jaddi(vouts,item);
jadd(txobj,"vout",vouts);
return(txobj);
}
int32_t iguana_interpreter(struct iguana_info *coin,int64_t nLockTime,struct vin_info *V,int32_t numvins)
{
uint8_t script[IGUANA_MAXSCRIPTSIZE]; int32_t vini,scriptlen,errs = 0; cJSON *spendscript;
for (vini=0; vini<numvins; vini++)
{
spendscript = iguana_spendasm(coin,V[vini].spendscript,V[vini].spendlen);
if ( (scriptlen= bitcoin_assembler(coin,script,spendscript,1,nLockTime,&V[vini])) <= 0 )
{
errs++;
}
else if ( scriptlen != V[vini].spendlen || memcmp(script,V[vini].spendscript,scriptlen) != 0 )
{
errs++;
}
}
if ( errs != 0 )
return(-errs);
else return(0);
}
#include "../includes/iguana_apidefs.h" #include "../includes/iguana_apidefs.h"
#include "../includes/iguana_apideclares.h" #include "../includes/iguana_apideclares.h"
@ -1044,7 +1081,7 @@ P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount
if ( M > N || N > 3 ) if ( M > N || N > 3 )
return(clonestr("{\"error\":\"illegal M or N\"}")); return(clonestr("{\"error\":\"illegal M or N\"}"));
memset(&V,0,sizeof(V)); memset(&V,0,sizeof(V));
txobj = bitcoin_createtx(active,0); txobj = bitcoin_txcreate(active,0);
if ( destaddress[0] != 0 && destamount > 0. ) if ( destaddress[0] != 0 && destamount > 0. )
bitcoin_txaddspend(active,txobj,destaddress,destamount * SATOSHIDEN); bitcoin_txaddspend(active,txobj,destaddress,destamount * SATOSHIDEN);
if ( destaddress2[0] != 0 && destamount2 > 0. ) if ( destaddress2[0] != 0 && destamount2 > 0. )
@ -1073,7 +1110,7 @@ P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount
decode_hex(pubkeys[2],(int32_t)strlen(pubC)>>1,pubC); decode_hex(pubkeys[2],(int32_t)strlen(pubC)>>1,pubC);
pubkeyptrs[2] = pubkeys[2]; pubkeyptrs[2] = pubkeys[2];
} }
bitcoin_addinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N); bitcoin_txinput(active,txobj,vintxid,vinvout,0xffffffff,spendscript,spendlen,V.p2shscript,V.p2shlen,pubkeyptrs,N);
bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen); bitcoin_address(msigaddr,active->chain->p2shtype,V.p2shscript,V.p2shlen);
retjson = cJSON_CreateObject(); retjson = cJSON_CreateObject();
if ( bitcoin_verifyvins(active,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL) == 0 ) if ( bitcoin_verifyvins(active,&signedtxid,&signedtx,&msgtx,serialized,sizeof(serialized),&V,SIGHASH_ALL) == 0 )
@ -1087,30 +1124,19 @@ P2SH_SPENDAPI(iguana,spendmsig,activecoin,vintxid,vinvout,destaddress,destamount
return(jprint(retjson,1)); return(jprint(retjson,1));
} }
STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash) int32_t iguana_signrawtransaction(struct supernet_info *myinfo,struct iguana_info *coin,struct iguana_msgtx *msgtx,char **signedtxp,bits256 *signedtxidp,struct vin_info *V,int32_t numinputs,char *rawtx,cJSON *vins,cJSON *privkeys)
{ {
char *privkeystr,*signedtx = 0; struct vin_info *V; bits256 txid,signedtxid,privkey; int32_t len,i,n,complete,maxsize,numinputs = 1; uint8_t *serialized=0,*serialized2=0,*serialized3=0; struct iguana_msgtx msgtx; cJSON *txobj,*item,*retjson; int uselessbitcoin_error = 0; uint8_t *serialized,*serialized2,*serialized3; int32_t i,len,n,maxsize,complete = 0; char *checkstr,*privkeystr,*signedtx = 0; bits256 privkey,txid; cJSON *item; cJSON *txobj;
retjson = cJSON_CreateObject(); maxsize = 1000000;
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
if ( myinfo->expiration == 0 )
return(clonestr("{\"error\":\"need to unlock wallet\"}"));
//printf("rawtx.(%s) vins.(%s) privkeys.(%s) sighash.(%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),sighash);
if ( sighash == 0 || sighash[0] == 0 )
sighash = "ALL";
if ( strcmp(sighash,"ALL") != 0 )
jaddstr(retjson,"error","only sighash all (ALL) supported for now");
maxsize = 65536;
if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize ) if ( rawtx != 0 && rawtx[0] != 0 && (len= (int32_t)strlen(rawtx)>>1) < maxsize )
{ {
serialized = malloc(maxsize); serialized = malloc(maxsize);
serialized2 = malloc(maxsize); serialized2 = malloc(maxsize);
serialized3 = malloc(maxsize); serialized3 = malloc(maxsize);
memset(&msgtx,0,sizeof(msgtx)); memset(msgtx,0,sizeof(*msgtx));
decode_hex(serialized,len,rawtx); decode_hex(serialized,len,rawtx);
if ( (txobj= bitcoin_hex2json(coin,&txid,&msgtx,rawtx)) != 0 ) if ( (txobj= bitcoin_hex2json(coin,&txid,msgtx,rawtx)) != 0 )
{ {
char *checkstr;
//printf("txobj.(%s)\n",jprint(txobj,0)); //printf("txobj.(%s)\n",jprint(txobj,0));
if ( (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 ) if ( (checkstr= bitcoin_json2hex(myinfo,coin,&txid,txobj,0)) != 0 )
{ {
@ -1119,11 +1145,8 @@ STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighas
printf("RAW.(%s) ->\nNEW.(%s)\n",rawtx,checkstr); printf("RAW.(%s) ->\nNEW.(%s)\n",rawtx,checkstr);
free_json(txobj); free_json(txobj);
free(checkstr); free(checkstr);
free(serialized); free(serialized), free(serialized2), free(serialized3);
free(serialized2); return(-2);
free(serialized3);
jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "hex2json -> json2hex error");
return(jprint(retjson,1));
} }
free(checkstr); free(checkstr);
} }
@ -1131,9 +1154,8 @@ STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighas
} }
if ( (numinputs= cJSON_GetArraySize(vins)) > 0 ) if ( (numinputs= cJSON_GetArraySize(vins)) > 0 )
{ {
V = calloc(numinputs,sizeof(*V)); memset(msgtx,0,sizeof(*msgtx));
memset(&msgtx,0,sizeof(msgtx)); if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,msgtx,&txid,"") > 0 && numinputs == msgtx->tx_in )
if ( iguana_rwmsgtx(coin,0,0,serialized,maxsize,&msgtx,&txid,"") > 0 && numinputs == msgtx.tx_in )
{ {
if ( (n= cJSON_GetArraySize(privkeys)) > 0 ) if ( (n= cJSON_GetArraySize(privkeys)) > 0 )
{ {
@ -1146,30 +1168,49 @@ STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighas
iguana_ensure_privkey(myinfo,coin,privkey); iguana_ensure_privkey(myinfo,coin,privkey);
} }
} }
signedtx = 0; iguana_vininfo_create(myinfo,coin,serialized2,maxsize,msgtx,vins,numinputs,V);
iguana_vininfo_create(myinfo,coin,serialized2,maxsize,&msgtx,vins,numinputs,V); if ( (complete= bitcoin_verifyvins(coin,signedtxidp,&signedtx,msgtx,serialized3,maxsize,V,SIGHASH_ALL)) > 0 )
complete = bitcoin_verifyvins(coin,&signedtxid,&signedtx,&msgtx,serialized3,maxsize,V,SIGHASH_ALL);
free(V);
if ( signedtx != 0 )
{ {
jaddstr(retjson,"result",signedtx); iguana_interpreter(coin,j64bits(txobj,"locktime"),V,numinputs);
jadd(retjson,"complete",complete!=0?jtrue():jfalse()); }
free(signedtx);
} else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no transaction from verifyvins");
} }
else }
} else return(-1);
*signedtxp = signedtx;
return(complete);
}
STRING_ARRAY_OBJ_STRING(bitcoinrpc,signrawtransaction,rawtx,vins,privkeys,sighash)
{
char *signedtx = 0; struct vin_info *V; bits256 signedtxid; int32_t complete,numinputs = 1; struct iguana_msgtx msgtx; cJSON *retjson; int uselessbitcoin_error = 0;
retjson = cJSON_CreateObject();
if ( remoteaddr != 0 )
return(clonestr("{\"error\":\"no remote\"}"));
if ( myinfo->expiration == 0 )
return(clonestr("{\"error\":\"need to unlock wallet\"}"));
//printf("rawtx.(%s) vins.(%s) privkeys.(%s) sighash.(%s)\n",rawtx,jprint(vins,0),jprint(privkeys,0),sighash);
if ( sighash == 0 || sighash[0] == 0 )
sighash = "ALL";
if ( strcmp(sighash,"ALL") != 0 )
jaddstr(retjson,"error","only sighash all (ALL) supported for now");
if ( (numinputs= cJSON_GetArraySize(vins)) > 0 )
{
V = calloc(numinputs,sizeof(*V));
memset(&msgtx,0,sizeof(msgtx));
if ( (complete= iguana_signrawtransaction(myinfo,coin,&msgtx,&signedtx,&signedtxid,V,numinputs,rawtx,vins,privkeys)) >= 0 )
{
if ( signedtx != 0 )
{ {
/*char *testscript = "76a914010966776006953d5567439e5e39f86a0d273bee88ac"; jaddstr(retjson,"result",signedtx);
uint8_t script[256]; bits256 sigtxid; int32_t scriptlen = (int32_t)strlen(testscript) >> 1; jadd(retjson,"complete",complete!=0?jtrue():jfalse());
decode_hex(script,scriptlen,testscript); free(signedtx);
sigtxid = bitcoin_sigtxid(coin,serialized,sizeof(serialized),&msgtx,0,msgtx.vins[0].spendscript,msgtx.vins[0].spendlen,SIGHASH_ALL,""); } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no transaction from verifyvins");
char str[65]; printf("sigtxid.(%s)\n",bits256_str(str,sigtxid));*/ }
jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "couldnt load serialized tx or mismatched numinputs"); else if ( complete == -2 )
} jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "hex2json -> json2hex error");
} else jaddstr(retjson,"error","no inputs"); else if ( complete == -1 )
free(serialized); jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "couldnt load serialized tx or mismatched numinputs");
free(serialized2); free(V);
free(serialized3);
} else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no rawtx or rawtx too big"); } else jaddstr(retjson,"error",uselessbitcoin_error != 0 ? "-22" : "no rawtx or rawtx too big");
return(jprint(retjson,1)); return(jprint(retjson,1));
} }

1
iguana/iguana_unspents.c

@ -358,6 +358,7 @@ int64_t iguana_unspentset(struct supernet_info *myinfo,struct iguana_info *coin)
} }
} }
} }
printf("available %.8f\n",dstr(sum));
return(sum); return(sum);
} }

11
iguana/mini-gmp.c

@ -194,6 +194,13 @@ see https://www.gnu.org/licenses/. */
(x) = (y); \ (x) = (y); \
(y) = __mp_size_t_swap__tmp; \ (y) = __mp_size_t_swap__tmp; \
} while (0) } while (0)
#define MP_SIZE_sT_SWAP(x, y) \
do { \
uint32_t __mp_size_t_swap__tmp = (x); \
(x) = (y); \
(y) = __mp_size_t_swap__tmp; \
} while (0)
#define MP_BITCNT_T_SWAP(x,y) \ #define MP_BITCNT_T_SWAP(x,y) \
do { \ do { \
mp_bitcnt_t __mp_bitcnt_t_swap__tmp = (x); \ mp_bitcnt_t __mp_bitcnt_t_swap__tmp = (x); \
@ -4135,8 +4142,8 @@ void mpz_set_si (mpz_t r, signed long int x)
void mpz_swap (mpz_t u, mpz_t v) void mpz_swap (mpz_t u, mpz_t v)
{ {
MP_SIZE_T_SWAP (u->_mp_size, v->_mp_size); MP_SIZE_sT_SWAP (u->_mp_size, v->_mp_size);
MP_SIZE_T_SWAP (u->_mp_alloc, v->_mp_alloc); MP_SIZE_sT_SWAP (u->_mp_alloc, v->_mp_alloc);
MP_PTR_SWAP (u->_mp_d, v->_mp_d); MP_PTR_SWAP (u->_mp_d, v->_mp_d);
} }

32
iguana/swaps/iguana_BTCswap.c

@ -104,7 +104,7 @@ void iguana_addinputs(struct iguana_info *coin,struct bitcoin_spend *spend,cJSON
break; break;
pubkeyptrs[j] = spend->inputs[i].pubkeys[j]; pubkeyptrs[j] = spend->inputs[i].pubkeys[j];
} }
bitcoin_addinput(coin,txobj,spend->inputs[i].txid,spend->inputs[i].vout,spend->inputs[i].sequence,spend->inputs[i].spendscript,spend->inputs[i].spendlen,spend->inputs[i].p2shscript,spend->inputs[i].p2shlen,j>0?pubkeyptrs:0,j); bitcoin_txinput(coin,txobj,spend->inputs[i].txid,spend->inputs[i].vout,spend->inputs[i].sequence,spend->inputs[i].spendscript,spend->inputs[i].spendlen,spend->inputs[i].p2shscript,spend->inputs[i].p2shlen,j>0?pubkeyptrs:0,j);
} }
} }
@ -116,14 +116,14 @@ struct bitcoin_statetx *instantdex_feetx(struct supernet_info *myinfo,struct ins
insurance = IGUANA_BTCDMULT * instantdex_insurance(coin,instantdex_BTCsatoshis(A->offer.price64,A->offer.basevolume64)); insurance = IGUANA_BTCDMULT * instantdex_insurance(coin,instantdex_BTCsatoshis(A->offer.price64,A->offer.basevolume64));
if ( (spend= iguana_spendset(myinfo,coin,insurance,coin->chain->txfee,0)) != 0 ) if ( (spend= iguana_spendset(myinfo,coin,insurance,coin->chain->txfee,0)) != 0 )
{ {
txobj = bitcoin_createtx(coin,0); txobj = bitcoin_txcreate(coin,0);
n = instantdex_outputinsurance(paymentscript,0,insurance,A->orderid); n = instantdex_outputinsurance(paymentscript,0,insurance,A->orderid);
bitcoin_addoutput(coin,txobj,paymentscript,n,insurance); bitcoin_txoutput(coin,txobj,paymentscript,n,insurance);
iguana_addinputs(coin,spend,txobj,0xffffffff); iguana_addinputs(coin,spend,txobj,0xffffffff);
if ( spend->change > coin->chain->txfee ) if ( spend->change > coin->chain->txfee )
{ {
len = bitcoin_standardspend(paymentscript,0,spend->change160); len = bitcoin_standardspend(paymentscript,0,spend->change160);
bitcoin_addoutput(coin,txobj,paymentscript,len,spend->change); bitcoin_txoutput(coin,txobj,paymentscript,len,spend->change);
} }
txobj = iguana_signtx(myinfo,coin,&txid,&feetx,spend,txobj,0); txobj = iguana_signtx(myinfo,coin,&txid,&feetx,spend,txobj,0);
if ( feetx != 0 ) if ( feetx != 0 )
@ -203,13 +203,13 @@ struct bitcoin_statetx *instantdex_bobtx(struct supernet_info *myinfo,struct igu
if ( coin == 0 ) if ( coin == 0 )
return(0); return(0);
locktime = (uint32_t)(reftime + INSTANTDEX_LOCKTIME * (1 + depositflag)); locktime = (uint32_t)(reftime + INSTANTDEX_LOCKTIME * (1 + depositflag));
txobj = bitcoin_createtx(coin,locktime); txobj = bitcoin_txcreate(coin,locktime);
insurance = instantdex_insurance(coin,amount); insurance = instantdex_insurance(coin,amount);
if ( (spend= iguana_spendset(myinfo,coin,amount + insurance,coin->chain->txfee,0)) != 0 ) if ( (spend= iguana_spendset(myinfo,coin,amount + insurance,coin->chain->txfee,0)) != 0 )
{ {
calc_rmd160_sha256(secret,priv.bytes,sizeof(priv)); calc_rmd160_sha256(secret,priv.bytes,sizeof(priv));
n = instantdex_bobscript(script,0,&secretstart,locktime,pub1,secret,pub2); n = instantdex_bobscript(script,0,&secretstart,locktime,pub1,secret,pub2);
bitcoin_addoutput(coin,txobj,script,n,amount + depositflag*insurance*100); bitcoin_txoutput(coin,txobj,script,n,amount + depositflag*insurance*100);
iguana_addinputs(coin,spend,txobj,0xffffffff); iguana_addinputs(coin,spend,txobj,0xffffffff);
txobj = iguana_signtx(myinfo,coin,&txid,&signedtx,spend,txobj,0); txobj = iguana_signtx(myinfo,coin,&txid,&signedtx,spend,txobj,0);
if ( signedtx != 0 ) if ( signedtx != 0 )
@ -307,9 +307,9 @@ struct bitcoin_statetx *instantdex_alicetx(struct supernet_info *myinfo,struct i
cJSON *txobj; int32_t n; char *signedtx = 0; uint8_t script[1024]; struct bitcoin_spend *spend; struct bitcoin_statetx *ptr = 0; bits256 txid; cJSON *txobj; int32_t n; char *signedtx = 0; uint8_t script[1024]; struct bitcoin_spend *spend; struct bitcoin_statetx *ptr = 0; bits256 txid;
if ( altcoin != 0 && (spend= iguana_spendset(myinfo,altcoin,amount,altcoin->chain->txfee,0)) != 0 ) if ( altcoin != 0 && (spend= iguana_spendset(myinfo,altcoin,amount,altcoin->chain->txfee,0)) != 0 )
{ {
txobj = bitcoin_createtx(altcoin,0); txobj = bitcoin_txcreate(altcoin,0);
n = instantdex_alicescript(script,0,msigaddr,altcoin->chain->p2shtype,pubAm,pubBn); n = instantdex_alicescript(script,0,msigaddr,altcoin->chain->p2shtype,pubAm,pubBn);
bitcoin_addoutput(altcoin,txobj,script,n,amount); bitcoin_txoutput(altcoin,txobj,script,n,amount);
iguana_addinputs(altcoin,spend,txobj,0xffffffff); iguana_addinputs(altcoin,spend,txobj,0xffffffff);
txobj = iguana_signtx(myinfo,altcoin,&txid,&signedtx,spend,txobj,0); txobj = iguana_signtx(myinfo,altcoin,&txid,&signedtx,spend,txobj,0);
if ( signedtx != 0 ) if ( signedtx != 0 )
@ -1072,17 +1072,17 @@ char *instantdex_bailintx(struct iguana_info *coin,bits256 *txidp,struct bitcoin
uint8_t p2shscript[256],scriptv0[128],scriptv1[128],changescript[128],pubkey[35]; uint8_t p2shscript[256],scriptv0[128],scriptv1[128],changescript[128],pubkey[35];
p2shlen = bitcoin_2of2spendscript(&scriptv0len,scriptv0,p2shscript,A0,B0); p2shlen = bitcoin_2of2spendscript(&scriptv0len,scriptv0,p2shscript,A0,B0);
txobj = bitcoin_createtx(coin,0); txobj = bitcoin_createtx(coin,0);
bitcoin_addoutput(coin,txobj,scriptv0,scriptv0len,spend->satoshis); bitcoin_txoutput(coin,txobj,scriptv0,scriptv0len,spend->satoshis);
if ( isbob != 0 ) if ( isbob != 0 )
{ {
scriptv1len = bitcoin_revealsecret160(scriptv1,0,x); scriptv1len = bitcoin_revealsecret160(scriptv1,0,x);
scriptv1len = bitcoin_pubkeyspend(scriptv1,scriptv1len,pubkey); scriptv1len = bitcoin_pubkeyspend(scriptv1,scriptv1len,pubkey);
} else scriptv1len = bitcoin_p2shspend(scriptv1,0,x); } else scriptv1len = bitcoin_p2shspend(scriptv1,0,x);
bitcoin_addoutput(coin,txobj,scriptv1,scriptv1len,spend->txfee); bitcoin_txoutput(coin,txobj,scriptv1,scriptv1len,spend->txfee);
if ( (scriptv2len= bitcoin_changescript(coin,changescript,0,&change,spend->changeaddr,spend->input_satoshis,spend->satoshis,spend->txfee)) > 0 ) if ( (scriptv2len= bitcoin_changescript(coin,changescript,0,&change,spend->changeaddr,spend->input_satoshis,spend->satoshis,spend->txfee)) > 0 )
bitcoin_addoutput(coin,txobj,changescript,scriptv2len,change); bitcoin_txoutput(coin,txobj,changescript,scriptv2len,change);
for (i=0; i<spend->numinputs; i++) for (i=0; i<spend->numinputs; i++)
bitcoin_addinput(coin,txobj,spend->inputs[i].txid,spend->inputs[i].vout,0xffffffff); bitcoin_txinput(coin,txobj,spend->inputs[i].txid,spend->inputs[i].vout,0xffffffff);
rawtxstr = bitcoin_json2hex(coin,&txid,txobj,0); rawtxstr = bitcoin_json2hex(coin,&txid,txobj,0);
char str[65]; printf("%s_bailin.%s (%s)\n",isbob!=0?"bob":"alice",bits256_str(str,txid),rawtxstr); char str[65]; printf("%s_bailin.%s (%s)\n",isbob!=0?"bob":"alice",bits256_str(str,txid),rawtxstr);
V = calloc(spend->numinputs,sizeof(*V)); V = calloc(spend->numinputs,sizeof(*V));
@ -1107,7 +1107,7 @@ cJSON *instantdex_bailinspend(struct iguana_info *coin,bits256 privkey,uint64_t
calc_rmd160_sha256(rmd160,p2shscript,n); calc_rmd160_sha256(rmd160,p2shscript,n);
scriptv0len = bitcoin_p2shspend(scriptv0,0,rmd160); scriptv0len = bitcoin_p2shspend(scriptv0,0,rmd160);
txobj = bitcoin_createtx(coin,0); txobj = bitcoin_createtx(coin,0);
bitcoin_addoutput(coin,txobj,scriptv0,scriptv0len,amount); bitcoin_txoutput(coin,txobj,scriptv0,scriptv0len,amount);
return(txobj); return(txobj);
} }
@ -1144,8 +1144,8 @@ char *instantdex_payouttx(struct iguana_info *coin,char *sigstr,int32_t *siglenp
{ {
struct vin_info V; cJSON *txobj; struct vin_info V; cJSON *txobj;
txobj = instantdex_bailinspend(coin,sharedprivs[1],amount); txobj = instantdex_bailinspend(coin,sharedprivs[1],amount);
bitcoin_addinput(coin,txobj,bailintxid,0,0xffffffff); bitcoin_txinput(coin,txobj,bailintxid,0,0xffffffff);
bitcoin_addinput(coin,txobj,bailintxid,1,0xffffffff); bitcoin_txinput(coin,txobj,bailintxid,1,0xffffffff);
memset(&V,0,sizeof(V)); memset(&V,0,sizeof(V));
if ( othersigstr != 0 ) if ( othersigstr != 0 )
{ {
@ -1171,7 +1171,7 @@ char *instantdex_refundtx(struct iguana_info *coin,bits256 *txidp,bits256 bailin
{ {
char sigstr[256]; int32_t siglen; struct vin_info V; cJSON *txobj; char sigstr[256]; int32_t siglen; struct vin_info V; cJSON *txobj;
txobj = instantdex_bailinspend(coin,priv2,amount - txfee); txobj = instantdex_bailinspend(coin,priv2,amount - txfee);
bitcoin_addinput(coin,txobj,bailintxid,0,0xffffffff); bitcoin_txinput(coin,txobj,bailintxid,0,0xffffffff);
return(instantdex_bailinsign(coin,bailinpriv,sigstr,&siglen,txidp,&V,txobj,isbob)); return(instantdex_bailinsign(coin,bailinpriv,sigstr,&siglen,txidp,&V,txobj,isbob));
} }

2
m_onetime

@ -6,7 +6,7 @@ cd ..
git clone https://github.com/ElementsProject/secp256k1-zkp.git git clone https://github.com/ElementsProject/secp256k1-zkp.git
cd secp256k1-zkp cd secp256k1-zkp
./autogen.sh ./autogen.sh
./configure --enable-experimental --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof ./configure --enable-endomorphism --enable-module-ecdh --enable-module-schnorr --enable-module-rangeproof --enable-experimental --enable-module_recovery
make make
cp .libs/libsecp256k1.a ../SuperNET/includes/ cp .libs/libsecp256k1.a ../SuperNET/includes/
cd ../SuperNET cd ../SuperNET

Loading…
Cancel
Save