@ -486,7 +486,9 @@ cJSON *iguana_voutjson(struct iguana_info *coin,struct iguana_msgvout *vout,int3
return ( json ) ;
}
bits256 bitcoin_sigtxid ( struct iguana_info * coin , int32_t height , uint8_t * serialized , int32_t maxlen , struct iguana_msgtx * msgtx , int32_t vini , uint8_t * spendscript , int32_t spendlen , int32_t hashtype , char * vpnstr , int32_t suppress_pubkeys )
// TODO: with changes it bitcoin_sigtxid need additionally check bitcoin_verifyvins (!)
// Old args: bits256 bitcoin_sigtxid(struct iguana_info *coin,int32_t height,uint8_t *serialized,int32_t maxlen,struct iguana_msgtx *msgtx,int32_t vini,uint8_t *spendscript,int32_t spendlen,int32_t hashtype,char *vpnstr,int32_t suppress_pubkeys)
bits256 bitcoin_sigtxid ( struct iguana_info * coin , int32_t height , uint8_t * serialized , int32_t maxlen , struct iguana_msgtx * msgtx , int32_t vini , uint8_t * spendscript , int32_t spendlen , uint64_t spendamount , int32_t hashtype , char * vpnstr , int32_t suppress_pubkeys , int32_t zcash )
{
int32_t i , len ; bits256 sigtxid , txid , revsigtxid ; struct iguana_msgtx dest ;
dest = * msgtx ;
@ -500,42 +502,51 @@ bits256 bitcoin_sigtxid(struct iguana_info *coin,int32_t height,uint8_t *seriali
printf ( " currently only SIGHASH_ALL supported, not %d \n " , hashtype ) ;
return ( sigtxid ) ;
}
for ( i = 0 ; i < dest . tx_in ; i + + )
{
if ( i = = vini )
{
dest . vins [ i ] . vinscript = spendscript ;
dest . vins [ i ] . scriptlen = spendlen ;
//int32_t j; for (j=0; j<spendlen; j++)
// printf("%02x",spendscript[j]);
//printf(" tmpscript.%d vini.%d\n",spendlen,vini);
}
else
{
dest . vins [ i ] . vinscript = ( uint8_t * ) " " ;
dest . vins [ i ] . scriptlen = 0 ;
}
dest . vins [ i ] . p2shlen = 0 ;
dest . vins [ i ] . redeemscript = 0 ;
dest . vins [ i ] . userdata = 0 ;
dest . vins [ i ] . userdatalen = 0 ;
}
len = iguana_rwmsgtx ( coin , height , 1 , 0 , serialized , maxlen , & dest , & txid , vpnstr , 0 , 0 , 0 , suppress_pubkeys ) ;
//for (i=0; i<len; i++)
// printf("%02x",serialized[i]);
//printf(" <- sigtx len.%d supp.%d user[0].%d\n",len,suppress_pubkeys,dest.vins[0].userdatalen);
if ( len > 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 &&
{
# ifdef BTC2_VERSION
if ( height > = BTC2_HARDFORK_HEIGHT )
hashtype | = ( 0x777 < < 20 ) ;
# endif
len + = iguana_rwnum ( 1 , & serialized [ len ] , sizeof ( hashtype ) , & hashtype ) ;
revsigtxid = bits256_doublesha256 ( 0 , serialized , len ) ;
for ( i = 0 ; i < sizeof ( revsigtxid ) ; i + + )
sigtxid . bytes [ 31 - i ] = revsigtxid . bytes [ i ] ;
//char str[65]; printf("SIGTXID.(%s) numvouts.%d\n",bits256_str(str,sigtxid),dest.tx_out);
}
uint32_t overwintered = dest . version > > 31 ;
uint32_t version = dest . version & 0x7FFFFFFF ;
if ( overwintered & & version > = 3 ) {
// TODO: implement signing for overwintered & sapling
}
else {
for ( i = 0 ; i < dest . tx_in ; i + + )
{
if ( i = = vini )
{
dest . vins [ i ] . vinscript = spendscript ;
dest . vins [ i ] . scriptlen = spendlen ;
//int32_t j; for (j=0; j<spendlen; j++)
// printf("%02x",spendscript[j]);
//printf(" tmpscript.%d vini.%d\n",spendlen,vini);
}
else
{
dest . vins [ i ] . vinscript = ( uint8_t * ) " " ;
dest . vins [ i ] . scriptlen = 0 ;
}
dest . vins [ i ] . p2shlen = 0 ;
dest . vins [ i ] . redeemscript = 0 ;
dest . vins [ i ] . userdata = 0 ;
dest . vins [ i ] . userdatalen = 0 ;
}
len = iguana_rwmsgtx ( coin , height , 1 , 0 , serialized , maxlen , & dest , & txid , vpnstr , 0 , 0 , 0 , suppress_pubkeys ) ;
//for (i=0; i<len; i++)
// printf("%02x",serialized[i]);
//printf(" <- sigtx len.%d supp.%d user[0].%d\n",len,suppress_pubkeys,dest.vins[0].userdatalen);
if ( len > 0 ) // (dest.tx_in != 1 || bits256_nonz(dest.vins[0].prev_hash) != 0) && dest.vins[0].scriptlen > 0 &&
{
# ifdef BTC2_VERSION
if ( height > = BTC2_HARDFORK_HEIGHT )
hashtype | = ( 0x777 < < 20 ) ;
# endif
len + = iguana_rwnum ( 1 , & serialized [ len ] , sizeof ( hashtype ) , & hashtype ) ;
revsigtxid = bits256_doublesha256 ( 0 , serialized , len ) ;
for ( i = 0 ; i < sizeof ( revsigtxid ) ; i + + )
sigtxid . bytes [ 31 - i ] = revsigtxid . bytes [ i ] ;
//char str[65]; printf("SIGTXID.(%s) numvouts.%d\n",bits256_str(str,sigtxid),dest.tx_out);
}
}
free ( dest . vins ) ;
free ( dest . vouts ) ;
return ( sigtxid ) ;
@ -587,11 +598,40 @@ int32_t iguana_vinarray_check(cJSON *vinarray,bits256 txid,int32_t vout)
int32_t iguana_rwmsgtx ( struct iguana_info * coin , int32_t height , int32_t rwflag , cJSON * json , uint8_t * serialized , int32_t maxsize , struct iguana_msgtx * msg , bits256 * txidp , char * vpnstr , uint8_t * extraspace , int32_t extralen , cJSON * vins , int32_t suppress_pubkeys )
{
int32_t i , n , len = 0 , extraused = 0 ; uint8_t spendscript [ IGUANA_MAXSCRIPTSIZE ] , * txstart = serialized , * sigser = 0 ; char txidstr [ 65 ] ; cJSON * vinarray = 0 , * voutarray = 0 ; bits256 sigtxid ;
int32_t i , n , len = 0 , extraused = 0 ; uint8_t spendscript [ IGUANA_MAXSCRIPTSIZE ] , * txstart = serialized , * sigser = 0 ; char txidstr [ 65 ] ; uint64_t spendamount ; cJSON * vinarray = 0 , * voutarray = 0 ; bits256 sigtxid ;
uint32_t zcash = ( strcmp ( coin - > symbol , " VRSC " ) = = 0 | | strcmp ( coin - > symbol , " VRSCTEST " ) = = 0 ) ; // we definitely need to determine somehow zcash-based coins here instead of compare coin names
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > version ) , & msg - > version ) ;
uint32_t overwintered = msg - > version > > 31 ;
uint32_t version = msg - > version ;
// for version 4 the ZK proof size is 192, otherwise 296
uint32_t zksnark_proof_size = ZKSNARK_PROOF_SIZE ;
if ( zcash ) {
if ( overwintered ) {
version = msg - > version & 0x7FFFFFFF ;
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > version_group_id ) , & msg - > version_group_id ) ;
if ( version > = 4 ) {
zksnark_proof_size = GROTH_PROOF_SIZE ;
}
}
}
if ( json ! = 0 )
{
jaddnum ( json , " version " , msg - > version ) ;
if ( overwintered ) {
jaddnum ( json , " version " , msg - > version & 0x7FFFFFFF ) ;
}
else {
jaddnum ( json , " version " , msg - > version ) ;
}
cJSON_AddBoolToObject ( json , " overwintered " , overwintered ) ;
if ( overwintered ) {
char group_id_str [ 10 ] ;
sprintf ( group_id_str , " %x " , msg - > version_group_id ) ;
jaddstr ( json , " versiongroupid " , group_id_str ) ;
}
vinarray = cJSON_CreateArray ( ) ;
voutarray = cJSON_CreateArray ( ) ;
if ( rwflag = = 0 )
@ -674,7 +714,160 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJ
jaddi ( voutarray , iguana_voutjson ( coin , & msg - > vouts [ i ] , i , * txidp ) ) ;
}
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > lock_time ) , & msg - > lock_time ) ;
//printf("lock_time.%08x len.%d\n",msg->lock_time,len);
if ( zcash & & overwintered ) {
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > expiry_height ) , & msg - > expiry_height ) ;
if ( json ! = 0 ) {
jaddnum ( json , " expiryheight " , msg - > expiry_height ) ;
}
if ( version > = 4 ) {
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > value_balance ) , & msg - > value_balance ) ;
if ( json ! = 0 ) {
jaddnum ( json , " valueBalance " , dstr ( msg - > value_balance ) ) ;
}
cJSON * v_shielded_spend = cJSON_CreateArray ( ) ;
cJSON * v_shielded_output = cJSON_CreateArray ( ) ;
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_spend_num ) , & msg - > shielded_spend_num ) ;
if ( msg - > shielded_spend_num > 0 ) {
if ( extraused + sizeof ( struct sapling_spend_description ) * msg - > shielded_spend_num > extralen ) {
printf ( " extraused.%d + shielded_spend.%d > extralen.%d \n " , extraused , msg - > shielded_spend_num ,
extralen ) ;
return ( - 1 ) ;
}
msg - > shielded_spends = ( struct sapling_spend_description * ) & extraspace [ extraused ] ;
extraused + = ( sizeof ( struct sapling_spend_description ) * msg - > shielded_spend_num ) ;
for ( i = 0 ; i < msg - > shielded_spend_num ; i + + ) {
len + = iguana_rwbignum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_spends [ i ] . cv ) , msg - > shielded_spends [ i ] . cv . bytes ) ;
len + = iguana_rwbignum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_spends [ i ] . anchor ) , msg - > shielded_spends [ i ] . anchor . bytes ) ;
len + = iguana_rwbignum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_spends [ i ] . nullifier ) , msg - > shielded_spends [ i ] . nullifier . bytes ) ;
len + = iguana_rwbignum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_spends [ i ] . rk ) , msg - > shielded_spends [ i ] . rk . bytes ) ;
if ( rwflag = = 1 ) {
memcpy ( & serialized [ len ] , msg - > shielded_spends [ i ] . zkproof , GROTH_PROOF_SIZE ) ;
}
else {
memcpy ( msg - > shielded_spends [ i ] . zkproof , & serialized [ len ] , GROTH_PROOF_SIZE ) ;
}
len + = GROTH_PROOF_SIZE ;
if ( rwflag = = 1 ) {
memcpy ( & serialized [ len ] , msg - > shielded_spends [ i ] . spend_auth_sig , SAPLING_AUTH_SIG_SIZE ) ;
}
else {
memcpy ( msg - > shielded_spends [ i ] . spend_auth_sig , & serialized [ len ] , SAPLING_AUTH_SIG_SIZE ) ;
}
len + = SAPLING_AUTH_SIG_SIZE ;
if ( json ! = 0 ) {
cJSON * spend_item = cJSON_CreateObject ( ) ;
jaddbits256 ( spend_item , " cv " , msg - > shielded_spends [ i ] . cv ) ;
jaddbits256 ( spend_item , " anchor " , msg - > shielded_spends [ i ] . anchor ) ;
jaddbits256 ( spend_item , " nullifier " , msg - > shielded_spends [ i ] . nullifier ) ;
jaddbits256 ( spend_item , " rk " , msg - > shielded_spends [ i ] . rk ) ;
char proof_str [ GROTH_PROOF_SIZE * 2 + 1 ] ;
init_hexbytes_noT ( proof_str , msg - > shielded_spends [ i ] . zkproof , GROTH_PROOF_SIZE ) ;
jaddstr ( spend_item , " proof " , proof_str ) ;
char auth_sig_str [ SAPLING_AUTH_SIG_SIZE * 2 + 1 ] ;
init_hexbytes_noT ( auth_sig_str , msg - > shielded_spends [ i ] . spend_auth_sig , SAPLING_AUTH_SIG_SIZE ) ;
jaddstr ( spend_item , " spendAuthSig " , auth_sig_str ) ;
jaddi ( v_shielded_spend , spend_item ) ;
}
}
}
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_output_num ) , & msg - > shielded_output_num ) ;
if ( msg - > shielded_output_num > 0 ) {
if ( extraused + sizeof ( struct sapling_output_description ) * msg - > shielded_output_num > extralen ) {
printf ( " extraused.%d + shielded_output.%d > extralen.%d \n " , extraused , msg - > shielded_output_num ,
extralen ) ;
return ( - 1 ) ;
}
msg - > shielded_outputs = ( struct sapling_output_description * ) & extraspace [ extraused ] ;
extraused + = ( sizeof ( struct sapling_output_description ) * msg - > shielded_output_num ) ;
for ( i = 0 ; i < msg - > shielded_output_num ; i + + ) {
len + = iguana_rwbignum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_outputs [ i ] . cv ) , msg - > shielded_outputs [ i ] . cv . bytes ) ;
len + = iguana_rwbignum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_outputs [ i ] . cm ) , msg - > shielded_outputs [ i ] . cm . bytes ) ;
len + = iguana_rwbignum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_outputs [ i ] . ephemeral_key ) , msg - > shielded_outputs [ i ] . ephemeral_key . bytes ) ;
if ( rwflag = = 1 ) {
memcpy ( & serialized [ len ] , msg - > shielded_outputs [ i ] . enc_ciphertext , ENC_CIPHER_SIZE ) ;
}
else {
memcpy ( msg - > shielded_outputs [ i ] . enc_ciphertext , & serialized [ len ] , ENC_CIPHER_SIZE ) ;
}
len + = ENC_CIPHER_SIZE ;
if ( rwflag = = 1 ) {
memcpy ( & serialized [ len ] , msg - > shielded_outputs [ i ] . out_ciphertext , OUT_CIPHER_SIZE ) ;
}
else {
memcpy ( msg - > shielded_outputs [ i ] . out_ciphertext , & serialized [ len ] , OUT_CIPHER_SIZE ) ;
}
len + = OUT_CIPHER_SIZE ;
if ( rwflag = = 1 ) {
memcpy ( & serialized [ len ] , msg - > shielded_outputs [ i ] . zkproof , GROTH_PROOF_SIZE ) ;
}
else {
memcpy ( msg - > shielded_outputs [ i ] . zkproof , & serialized [ len ] , GROTH_PROOF_SIZE ) ;
}
len + = GROTH_PROOF_SIZE ;
if ( json ! = 0 ) {
cJSON * output_item = cJSON_CreateObject ( ) ;
jaddbits256 ( output_item , " cv " , msg - > shielded_outputs [ i ] . cv ) ;
jaddbits256 ( output_item , " cmu " , msg - > shielded_outputs [ i ] . cm ) ;
jaddbits256 ( output_item , " ephemeralKey " , msg - > shielded_outputs [ i ] . ephemeral_key ) ;
char enc_cip_str [ ENC_CIPHER_SIZE * 2 + 1 ] ;
init_hexbytes_noT ( enc_cip_str , msg - > shielded_outputs [ i ] . enc_ciphertext , ENC_CIPHER_SIZE ) ;
jaddstr ( output_item , " encCiphertext " , enc_cip_str ) ;
char out_cip_str [ OUT_CIPHER_SIZE * 2 + 1 ] ;
init_hexbytes_noT ( out_cip_str , msg - > shielded_outputs [ i ] . out_ciphertext , OUT_CIPHER_SIZE ) ;
jaddstr ( output_item , " outCiphertext " , out_cip_str ) ;
jaddi ( v_shielded_output , output_item ) ;
char proof_str [ GROTH_PROOF_SIZE * 2 + 1 ] ;
init_hexbytes_noT ( proof_str , msg - > shielded_outputs [ i ] . zkproof , GROTH_PROOF_SIZE ) ;
jaddstr ( output_item , " proof " , proof_str ) ;
}
}
}
if ( json ! = 0 ) {
cJSON_AddItemToObject ( json , " vShieldedSpend " , v_shielded_spend ) ;
cJSON_AddItemToObject ( json , " vShieldedOutput " , v_shielded_output ) ;
}
}
}
//printf("lock_time.%08x len.%d\n",msg->lock_time,len);
if ( zcash = = LP_IS_ZCASHPROTOCOL & & msg - > version > 1 )
{
struct iguana_msgjoinsplit joinsplit ; uint8_t joinsplitpubkey [ 33 ] , joinsplitsig [ 64 ] ;
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > numjoinsplits ) , & msg - > numjoinsplits ) ;
if ( msg - > numjoinsplits > 0 )
{
for ( i = 0 ; i < msg - > numjoinsplits ; i + + )
len + = iguana_rwjoinsplit ( rwflag , & serialized [ len ] , & joinsplit , zksnark_proof_size ) ;
if ( rwflag ! = 0 )
{
memset ( joinsplitpubkey , 0 , sizeof ( joinsplitpubkey ) ) ; // for now
memset ( joinsplitsig , 0 , sizeof ( joinsplitsig ) ) ; // set to actuals
memcpy ( & serialized [ len ] , joinsplitpubkey + 1 , 32 ) , len + = 32 ;
memcpy ( & serialized [ len ] , joinsplitsig , 64 ) , len + = 64 ;
}
else
{
joinsplitpubkey [ 0 ] = 0x02 ; // need to verify its not 0x03
memcpy ( joinsplitpubkey + 1 , & serialized [ len ] , 32 ) , len + = 32 ;
memcpy ( joinsplitsig , & serialized [ len ] , 64 ) , len + = 64 ;
}
}
}
if ( zcash = = 1 & & msg - > version > = 4 & & ! ( msg - > shielded_spend_num = = 0 & & msg - > shielded_output_num = = 0 ) ) {
if ( rwflag = = 1 ) {
memcpy ( & serialized [ len ] , msg - > binding_sig , 64 ) , len + = 64 ;
}
else {
memcpy ( msg - > binding_sig , & serialized [ len ] , 64 ) , len + = 64 ;
}
if ( json ! = 0 ) {
char binding_sig_str [ 64 * 2 + 1 ] ;
init_hexbytes_noT ( binding_sig_str , msg - > binding_sig , 64 ) ;
jaddstr ( json , " bindingSig " , binding_sig_str ) ;
}
}
if ( strcmp ( coin - > symbol , " VPN " ) = = 0 )
{
uint16_t ddosflag = 0 ;
@ -702,9 +895,23 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJ
memset ( sigtxid . bytes , 0 , sizeof ( sigtxid ) ) ;
if ( vins ! = 0 & & jitem ( vins , i ) ! = 0 )
{
uint32_t sighash = SIGHASH_ALL ; // in marketmaker we use LP_sighash(symbol,zcash) to determine sighash (depends on zcash type), but here SIGHASH_ALL is enough for now
iguana_vinobjset ( & msg - > vins [ i ] , jitem ( vins , i ) , spendscript , sizeof ( spendscript ) ) ;
sigtxid = bitcoin_sigtxid ( coin , height , sigser , maxsize * 2 , msg , i , msg - > vins [ i ] . spendscript , msg - > vins [ i ] . spendlen , SIGHASH_ALL , vpnstr , suppress_pubkeys ) ;
//printf("after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s)\n",i,msg->vins[i].vinscript,msg->vins[i].spendscript,msg->vins[i].spendlen,jprint(jitem(vins,i),0));
printf ( " [ Decker ] vins.(%d) = %s \n " , i , jprint ( vins , i ) ) ;
// TODO: *** how to get spendamount here from msg->vins[i] ? fix bitcoin_sigtxid (!)
//uint64_t spendamount = LP_outpoint_amount(symbol, msg->vins[i].prev_hash, msg->vins[i].prev_vout);
struct supernet_info * myinfo = SuperNET_MYINFO ( 0 ) ; cJSON * jtxout = 0 ;
jtxout = dpow_gettxout ( 0 , coin , msg - > vins [ i ] . prev_hash , msg - > vins [ i ] . prev_vout ) ;
spendamount = jdouble ( jtxout , " value " ) * SATOSHIDEN ;
//printf("JSON (txout): %s\n", cJSON_Print(jtxout));
//printf("spendamount = %.8f\n", dstr(spendamount));
free ( jtxout ) ;
sigtxid = bitcoin_sigtxid ( coin , height , sigser , maxsize * 2 , msg , i , msg - > vins [ i ] . spendscript , msg - > vins [ i ] . spendlen , spendamount , SIGHASH_ALL , vpnstr , suppress_pubkeys , zcash ) ;
printf ( " after vini.%d vinscript.%p spendscript.%p spendlen.%d (%s) \n " , i , msg - > vins [ i ] . vinscript , msg - > vins [ i ] . spendscript , msg - > vins [ i ] . spendlen , jprint ( jitem ( vins , i ) , 0 ) ) ;
if ( iguana_vinarray_check ( vinarray , msg - > vins [ i ] . prev_hash , msg - > vins [ i ] . prev_vout ) < 0 )
jaddi ( vinarray , iguana_vinjson ( coin , & msg - > vins [ i ] , sigtxid ) ) ;
if ( msg - > vins [ i ] . spendscript = = spendscript )
@ -729,6 +936,7 @@ int32_t iguana_rwmsgtx(struct iguana_info *coin,int32_t height,int32_t rwflag,cJ
jaddnum ( json , " size " , len ) ;
jaddbits256 ( json , " txid " , * txidp ) ;
//printf("TX.(%s) %p\n",jprint(json,0),json);
printf ( " JSON after: %s \n " , cJSON_Print ( json ) ) ;
}
msg - > allocsize = len ;
return ( len ) ;
@ -745,7 +953,19 @@ bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,
vpnstr [ 0 ] = 0 ;
if ( ( msg - > version = juint ( txobj , " version " ) ) = = 0 )
msg - > version = 1 ;
if ( is_cJSON_True ( cJSON_GetObjectItem ( txobj , " overwintered " ) ) ) {
msg - > version = 1 < < 31 | msg - > version ;
//msg->version_group_id = (uint32_t)strtol(jstr(txobj, "versiongroupid"), NULL, 16);
msg - > version_group_id = strtoul ( jstr ( txobj , " versiongroupid " ) , NULL , 16 ) ;
msg - > expiry_height = juint ( txobj , " expiryheight " ) ;
if ( msg - > version > = 4 ) {
msg - > value_balance = ( uint64_t ) ( jdouble ( txobj , " valueBalance " ) * SATOSHIDEN ) ;
}
}
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > version ) , & msg - > version ) ;
if ( is_cJSON_True ( cJSON_GetObjectItem ( txobj , " overwintered " ) ) ) {
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > version_group_id ) , & msg - > version_group_id ) ;
}
if ( coin - > chain - > isPoS ! = 0 )
{
if ( ( msg - > timestamp = juint ( txobj , " timestamp " ) ) = = 0 )
@ -793,11 +1013,22 @@ bits256 iguana_parsetxobj(struct supernet_info *myinfo,struct iguana_info *coin,
}
msg - > lock_time = jint ( txobj , " locktime " ) ;
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > lock_time ) , & msg - > lock_time ) ;
if ( is_cJSON_True ( cJSON_GetObjectItem ( txobj , " overwintered " ) ) ) {
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > expiry_height ) , & msg - > expiry_height ) ;
if ( msg - > version > = 4 ) {
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > value_balance ) , & msg - > value_balance ) ;
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_spend_num ) , & msg - > shielded_spend_num ) ;
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > shielded_output_num ) , & msg - > shielded_output_num ) ;
}
len + = iguana_rwnum ( rwflag , & serialized [ len ] , sizeof ( msg - > numjoinsplits ) , & msg - > numjoinsplits ) ;
}
//msg->txid = jbits256(txobj,"txid");
* txstartp = 0 ;
msg - > allocsize = len ;
msg - > txid = txid = bits256_doublesha256 ( 0 , serialized , len ) ;
return ( txid ) ;
msg - > txid = txid = bits256_doublesha256 ( 0 , serialized , len ) ; // bits256_calctxid(coin->symbol, serialized, len);
return ( txid ) ;
}
char * iguana_rawtxbytes ( struct iguana_info * coin , int32_t height , cJSON * json , struct iguana_msgtx * msgtx , int32_t suppress_pubkeys )
@ -976,7 +1207,7 @@ int32_t iguana_msgtx_Vset(struct iguana_info *coin,uint8_t *serialized,int32_t m
int32_t bitcoin_verifyvins ( struct iguana_info * coin , int32_t height , bits256 * signedtxidp , char * * signedtx , struct iguana_msgtx * msgtx , uint8_t * serialized , int32_t maxlen , struct vin_info * V , uint32_t sighash , int32_t signtx , int32_t suppress_pubkeys )
{
bits256 sigtxid ; uint8_t * sig , * script ; struct vin_info * vp ; char vpnstr [ 64 ] ; int32_t scriptlen , complete = 0 , j , vini = 0 , flag = 0 , siglen , numvouts , numsigs ;
bits256 sigtxid ; uint8_t * sig , * script ; struct vin_info * vp ; char vpnstr [ 64 ] ; int32_t scriptlen , complete = 0 , j , vini = 0 , flag = 0 , siglen , numvouts , numsigs ; uint64_t spendamount ;
numvouts = msgtx - > tx_out ;
vpnstr [ 0 ] = 0 ;
* signedtx = 0 ;
@ -994,7 +1225,16 @@ int32_t bitcoin_verifyvins(struct iguana_info *coin,int32_t height,bits256 *sign
script = msgtx - > vins [ vini ] . spendscript ;
scriptlen = msgtx - > vins [ vini ] . spendlen ;
}
sigtxid = bitcoin_sigtxid ( coin , height , serialized , maxlen , msgtx , vini , script , scriptlen , sighash , vpnstr , suppress_pubkeys ) ;
uint32_t zcash = ( strcmp ( coin - > symbol , " VRSC " ) = = 0 | | strcmp ( coin - > symbol , " VRSCTEST " ) = = 0 ) ; // we definitely need to determine somehow zcash-based coins here instead of compare coin names
struct supernet_info * myinfo = SuperNET_MYINFO ( 0 ) ; cJSON * jtxout = 0 ;
jtxout = dpow_gettxout ( 0 , coin , msgtx - > vins [ vini ] . prev_hash , msgtx - > vins [ vini ] . prev_vout ) ;
spendamount = jdouble ( jtxout , " value " ) * SATOSHIDEN ;
//printf("JSON (txout): %s\n", cJSON_Print(jtxout));
//printf("spendamount = %.8f\n", dstr(spendamount));
free ( jtxout ) ;
sigtxid = bitcoin_sigtxid ( coin , height , serialized , maxlen , msgtx , vini , script , scriptlen , spendamount , sighash , vpnstr , suppress_pubkeys , zcash ) ;
if ( bits256_nonz ( sigtxid ) ! = 0 )
{
vp = & V [ vini ] ;
@ -1271,18 +1511,31 @@ cJSON *bitcoin_txinput(struct iguana_info *coin,cJSON *txobj,bits256 txid,int32_
return ( txobj ) ;
}
cJSON * bitcoin_txcreate ( char * symbol , int32_t isPoS , int64_t locktime , uint32_t txversion , uint32_t timestamp )
cJSON * bitcoin_txcreate ( char * symbol , int32_t isPoS , int64_t locktime , uint32_t txversion , uint32_t timestamp )
{
cJSON * json = cJSON_CreateObject ( ) ;
jaddnum ( json , " version " , txversion ) ;
if ( locktime = = 0 & & strcmp ( symbol , " KMD " ) = = 0 )
locktime = ( uint32_t ) time ( NULL ) - 55 ;
jaddnum ( json , " locktime " , locktime ) ;
if ( isPoS ! = 0 )
jaddnum ( json , " timestamp " , timestamp = = 0 ? time ( NULL ) : timestamp ) ;
jadd ( json , " vin " , cJSON_CreateArray ( ) ) ;
jadd ( json , " vout " , cJSON_CreateArray ( ) ) ;
return ( json ) ;
cJSON * json = cJSON_CreateObject ( ) ;
jaddnum ( json , " version " , txversion ) ;
if ( txversion > = 3 ) {
cJSON_AddBoolToObject ( json , " overwintered " , 1 ) ;
jaddnum ( json , " expiryheight " , 0 ) ;
if ( txversion = = 3 ) {
jaddstr ( json , " versiongroupid " , " 03c48270 " ) ;
}
else if ( txversion = = 4 ) {
jaddstr ( json , " versiongroupid " , " 892f2085 " ) ;
jaddnum ( json , " valueBalance " , 0. ) ;
jadd ( json , " vShieldedSpend " , cJSON_CreateArray ( ) ) ;
jadd ( json , " vShieldedOutput " , cJSON_CreateArray ( ) ) ;
}
}
if ( locktime = = 0 & & strcmp ( symbol , " KMD " ) = = 0 )
locktime = ( uint32_t ) time ( NULL ) - 55 ;
jaddnum ( json , " locktime " , locktime ) ;
if ( isPoS ! = 0 )
jaddnum ( json , " timestamp " , timestamp = = 0 ? time ( NULL ) : timestamp ) ;
jadd ( json , " vin " , cJSON_CreateArray ( ) ) ;
jadd ( json , " vout " , cJSON_CreateArray ( ) ) ;
return ( json ) ;
}
cJSON * bitcoin_txoutput ( cJSON * txobj , uint8_t * paymentscript , int32_t len , uint64_t satoshis )