@ -33,6 +33,8 @@ struct iguana_waddress *iguana_waddressfind(struct supernet_info *myinfo,struct
{
struct iguana_waddress * waddr ; int32_t len = ( int32_t ) strlen ( coinaddr ) + 1 ;
HASH_FIND ( hh , wacct - > waddr , coinaddr , len , waddr ) ;
if ( strcmp ( coin - > symbol , waddr - > symbol ) ! = 0 )
return ( 0 ) ;
//printf("%s (%s).%d in (%s)\n",waddr==0?"couldnt find":"found",coinaddr,len,wacct->account);
return ( waddr ) ;
}
@ -175,8 +177,10 @@ struct iguana_waddress *iguana_waddresssearch(struct supernet_info *myinfo,struc
{
if ( bitcoin_priv2wif ( waddr - > wifstr , waddr - > privkey , coin - > chain - > wiftype ) > 0 )
{
waddr - > wiftype = coin - > chain - > wiftype ;
waddr - > addrtype = coin - > chain - > pubtype ;
if ( waddr - > wiftype ! = coin - > chain - > wiftype )
printf ( " waddresssearch warning: mismatched wiftype %02x != %02x \n " , waddr - > wiftype , coin - > chain - > wiftype ) ;
if ( waddr - > addrtype ! = coin - > chain - > pubtype )
printf ( " waddresssearch warning: mismatched wiftype %02x != %02x \n " , waddr - > addrtype , coin - > chain - > pubtype ) ;
}
}
( * wacctp ) = wacct ;
@ -487,67 +491,6 @@ cJSON *iguana_walletjson(struct supernet_info *myinfo)
return ( wallet ) ;
}
void iguana_walletinitcheck ( struct supernet_info * myinfo , struct iguana_info * coin )
{
// "wallet":{"test":{"R9S7zZzzvgb4CkiBH1i7gnFcwJuL1MYbxN":"18ab9c89ce83929db720cf26b663bf762532276146cd9d3e1f89086fcdf00053"}}
cJSON * payload , * item , * array , * child ; char * account , * coinaddr , * privkeystr ; int32_t i , j , n , len ; struct iguana_waccount * wacct , * tmp ; struct iguana_waddress waddr ; bits256 privkey ; uint8_t addrtype , rmd160 [ 20 ] ;
if ( myinfo - > wallet = = 0 & & myinfo - > decryptstr ! = 0 & & ( payload = cJSON_Parse ( myinfo - > decryptstr ) ) ! = 0 )
{
if ( ( array = jobj ( payload , " wallet " ) ) ! = 0 )
{
n = cJSON_GetArraySize ( array ) ;
//printf("item.(%s) size.%d\n",jprint(array,0),n);
item = array - > child ;
for ( i = 0 ; i < n ; i + + )
{
if ( item ! = 0 & & ( account = item - > string ) ! = 0 )
{
child = item - > child ;
while ( child ! = 0 )
{
coinaddr = child - > string ;
privkeystr = child - > valuestring ;
if ( coinaddr ! = 0 & & privkeystr ! = 0 )
{
if ( ( wacct = iguana_waccountcreate ( myinfo , coin , account ) ) ! = 0 )
{
if ( iguana_waddresssearch ( myinfo , coin , & tmp , coinaddr ) = = 0 )
{
memset ( & waddr , 0 , sizeof ( waddr ) ) ;
strcpy ( waddr . coinaddr , coinaddr ) ;
waddr . addrtype = coin - > chain - > p2shtype ;
if ( bitcoin_addr2rmd160 ( & addrtype , rmd160 , coinaddr ) = = sizeof ( rmd160 ) & & addrtype = = coin - > chain - > p2shtype )
iguana_waddressadd ( myinfo , coin , wacct , & waddr , privkeystr ) ;
else
{
waddr . addrtype = coin - > chain - > pubtype ;
privkey = bits256_conv ( privkeystr ) ;
if ( iguana_waddresscalc ( coin - > chain - > pubtype , coin - > chain - > wiftype , & waddr , privkey ) ! = 0 )
iguana_waddressadd ( myinfo , coin , wacct , & waddr , 0 ) ;
}
} else printf ( " dup.(%s) " , coinaddr ) ;
len = ( int32_t ) strlen ( privkeystr ) ;
for ( j = 0 ; j < len ; j + + )
privkeystr [ j ] = 0 ;
for ( j = 0 ; j < len ; j + + )
privkeystr [ j ] = 0x20 + ( rand ( ) % 64 ) ;
privkey = rand256 ( 0 ) ;
}
}
child = child - > next ;
}
printf ( " account.(%s) \n " , account ) ;
}
item = item - > next ;
}
}
free_json ( payload ) ;
myinfo - > decryptstr = 0 ;
scrubfree ( myinfo - > decryptstr ) ;
myinfo - > dirty = 0 ;
}
}
int32_t iguana_walletemit ( struct supernet_info * myinfo , char * fname , struct iguana_info * coin , cJSON * array )
{
cJSON * item , * child ; uint8_t addrtype , wiftype , rmd160 [ 20 ] ; char p2shaddr [ 128 ] , str [ 64 ] , wifstr [ 128 ] , * account , * coinaddr , * privkeystr ; int32_t i , j , n ; FILE * fp ; bits256 privkey ;
@ -600,13 +543,91 @@ int32_t iguana_walletemit(struct supernet_info *myinfo,char *fname,struct iguana
return ( 0 ) ;
}
void iguana_walletiterate ( struct supernet_info * myinfo , int32_t flag )
char * walleterrstr [ ] = { " P2SH_withpriv " , " P2SH_withpub " , " rmd160_mismatch " , " pubkey_mismatch " , " missing_pubkey " , " account_mismatch " } ;
uint8_t iguana_waddrvalidate ( struct supernet_info * myinfo , struct iguana_info * coin , struct iguana_waccount * wacct , struct iguana_waddress * waddr , int32_t repairflag , int32_t * errors )
{
struct iguana_waccount * checkwacct ; struct iguana_waddress * checkwaddr ; uint8_t checkpub [ 33 ] , rmd160 [ 20 ] , addrtype , checktype , plen , flag = 0 ;
if ( waddr ! = 0 )
{
if ( ( checkwaddr = iguana_waddresssearch ( myinfo , coin , & checkwacct , waddr - > coinaddr ) ) ! = waddr | | checkwacct ! = wacct )
{
errors [ 5 ] + + ;
flag | = ( 5 < < 0 ) ;
if ( repairflag > 0 )
{
printf ( " waddrvalidate: need to manually setaccount to fix mismatch (%s:%s) <- (%s:%s) \n " , checkwacct ! = 0 ? checkwacct - > account : " " , checkwaddr ! = 0 ? checkwaddr - > coinaddr : " " , wacct ! = 0 ? wacct - > account : " " , waddr - > coinaddr ) ;
}
}
if ( waddr - > scriptlen > 0 )
{
checktype = coin - > chain - > p2shtype ;
if ( bits256_nonz ( waddr - > privkey ) ! = 0 )
{
errors [ 0 ] + + ;
flag | = ( 1 < < 0 ) ;
if ( repairflag > 0 )
memset ( & waddr - > privkey , 0 , sizeof ( waddr - > privkey ) ) ;
}
if ( bitcoin_pubkeylen ( waddr - > pubkey ) > 0 )
{
errors [ 1 ] + + ;
flag | = ( 1 < < 1 ) ;
if ( repairflag > 0 )
memset ( waddr - > pubkey , 0 , sizeof ( waddr - > pubkey ) ) ;
}
}
else checktype = coin - > chain - > pubtype ;
if ( bitcoin_addr2rmd160 ( & addrtype , rmd160 , waddr - > coinaddr ) ! = sizeof ( rmd160 ) | | addrtype ! = checktype | | memcmp ( rmd160 , waddr - > rmd160 , sizeof ( rmd160 ) ) ! = 0 )
{
errors [ 2 ] + + ;
flag | = ( 1 < < 2 ) ;
if ( repairflag > 0 )
{
waddr - > addrtype = checktype ;
memcpy ( waddr - > rmd160 , rmd160 , sizeof ( rmd160 ) ) ;
}
}
if ( waddr - > scriptlen = = 0 )
{
if ( bits256_nonz ( waddr - > privkey ) ! = 0 )
{
bitcoin_pubkey33 ( myinfo , checkpub , waddr - > privkey ) ;
if ( memcmp ( checkpub , waddr - > pubkey , sizeof ( checkpub ) ) ! = 0 )
{
errors [ 3 ] + + ;
flag | = ( 1 < < 3 ) ;
if ( repairflag > 0 )
memcpy ( waddr - > pubkey , checkpub , sizeof ( checkpub ) ) ;
}
}
if ( ( plen = bitcoin_pubkeylen ( waddr - > pubkey ) ) > 0 )
{
calc_rmd160_sha256 ( rmd160 , waddr - > pubkey , plen ) ;
if ( memcmp ( rmd160 , waddr - > rmd160 , sizeof ( rmd160 ) ) ! = 0 )
{
errors [ 4 ] + + ;
flag | = ( 1 < < 4 ) ;
if ( repairflag > 0 )
{
printf ( " waddrvalidate unrecoverable error: cant determine pubkey from rmd160 \n " ) ;
}
}
}
}
}
return ( flag ) ;
}
cJSON * iguana_walletiterate ( struct supernet_info * myinfo , struct iguana_info * coin , int32_t flag , cJSON * array , int32_t * goodp , int32_t * badp , int32_t * errors )
{
struct iguana_waccount * wacct , * tmp ; struct iguana_waddress * waddr , * tmp2 ; int32_t i ;
struct iguana_waccount * wacct , * tmp ; struct iguana_waddress * waddr , * tmp2 ; uint8_t errorflags ; int32_t i , good = 0 , bad = 0 , _errors [ 8 ] ; cJSON * item ;
if ( errors = = 0 )
errors = _errors ;
HASH_ITER ( hh , myinfo - > wallet , wacct , tmp )
{
HASH_ITER ( hh , wacct - > waddr , waddr , tmp2 )
{
wacct - > current = waddr ;
if ( flag < 0 )
{
memset ( & waddr - > privkey , 0 , sizeof ( waddr - > privkey ) ) ;
@ -621,7 +642,18 @@ void iguana_walletiterate(struct supernet_info *myinfo,int32_t flag)
free ( waddr ) ;
}
}
//else iguana_waddrvalidate(myinfo,coin,wacct,waddr,flag);
else
{
if ( ( errorflags = iguana_waddrvalidate ( myinfo , coin , wacct , waddr , flag , errors ) ) ! = 0 )
{
bad + + ;
if ( array ! = 0 & & ( item = cJSON_CreateObject ( ) ) ! = 0 )
{
jaddnum ( item , waddr - > coinaddr , errorflags ) ;
jaddi ( array , item ) ;
}
} else good + + ;
}
}
if ( flag < - 1 )
{
@ -629,9 +661,93 @@ void iguana_walletiterate(struct supernet_info *myinfo,int32_t flag)
free ( wacct ) ;
}
}
if ( goodp ! = 0 )
* goodp = good ;
if ( badp ! = 0 )
* badp = bad ;
return ( array ) ;
}
char * iguana_walletscan ( struct supernet_info * myinfo , struct iguana_info * coin , int32_t repairflag )
{
cJSON * retjson ; int32_t i , good , bad , errors [ 8 ] ;
memset ( errors , 0 , sizeof ( errors ) ) ;
good = bad = 0 ;
retjson = cJSON_CreateObject ( ) ;
jadd ( retjson , " result " , iguana_walletiterate ( myinfo , coin , repairflag , cJSON_CreateArray ( ) , & good , & bad , errors ) ) ;
jaddnum ( retjson , " good " , good ) ;
jaddnum ( retjson , " bad " , bad ) ;
for ( i = 0 ; i < sizeof ( errors ) / sizeof ( errors ) ; i + + )
{
if ( errors [ i ] ! = 0 )
jaddnum ( retjson , walleterrstr [ i ] , errors [ i ] ) ;
}
return ( jprint ( retjson , 1 ) ) ;
}
void iguana_walletlock ( struct supernet_info * myinfo )
void iguana_walletinitcheck ( struct supernet_info * myinfo , struct iguana_info * coin )
{
// "wallet":{"test":{"R9S7zZzzvgb4CkiBH1i7gnFcwJuL1MYbxN":"18ab9c89ce83929db720cf26b663bf762532276146cd9d3e1f89086fcdf00053"}}
cJSON * payload , * item , * array , * child ; char * account , * coinaddr , * privkeystr ; int32_t i , j , n , len ; struct iguana_waccount * wacct , * tmp ; struct iguana_waddress waddr ; bits256 privkey ; uint8_t addrtype , rmd160 [ 20 ] ;
if ( myinfo - > wallet = = 0 & & myinfo - > decryptstr ! = 0 & & ( payload = cJSON_Parse ( myinfo - > decryptstr ) ) ! = 0 )
{
if ( ( array = jobj ( payload , " wallet " ) ) ! = 0 )
{
n = cJSON_GetArraySize ( array ) ;
//printf("item.(%s) size.%d\n",jprint(array,0),n);
item = array - > child ;
for ( i = 0 ; i < n ; i + + )
{
if ( item ! = 0 & & ( account = item - > string ) ! = 0 )
{
child = item - > child ;
while ( child ! = 0 )
{
coinaddr = child - > string ;
privkeystr = child - > valuestring ;
if ( coinaddr ! = 0 & & privkeystr ! = 0 )
{
if ( ( wacct = iguana_waccountcreate ( myinfo , coin , account ) ) ! = 0 )
{
if ( iguana_waddresssearch ( myinfo , coin , & tmp , coinaddr ) = = 0 )
{
memset ( & waddr , 0 , sizeof ( waddr ) ) ;
strcpy ( waddr . coinaddr , coinaddr ) ;
waddr . addrtype = coin - > chain - > p2shtype ;
if ( bitcoin_addr2rmd160 ( & addrtype , rmd160 , coinaddr ) = = sizeof ( rmd160 ) & & addrtype = = coin - > chain - > p2shtype )
iguana_waddressadd ( myinfo , coin , wacct , & waddr , privkeystr ) ;
else
{
waddr . addrtype = coin - > chain - > pubtype ;
privkey = bits256_conv ( privkeystr ) ;
if ( iguana_waddresscalc ( coin - > chain - > pubtype , coin - > chain - > wiftype , & waddr , privkey ) ! = 0 )
iguana_waddressadd ( myinfo , coin , wacct , & waddr , 0 ) ;
}
} else printf ( " dup.(%s) " , coinaddr ) ;
len = ( int32_t ) strlen ( privkeystr ) ;
for ( j = 0 ; j < len ; j + + )
privkeystr [ j ] = 0 ;
for ( j = 0 ; j < len ; j + + )
privkeystr [ j ] = 0x20 + ( rand ( ) % 64 ) ;
privkey = rand256 ( 0 ) ;
}
}
child = child - > next ;
}
printf ( " account.(%s) \n " , account ) ;
}
item = item - > next ;
}
}
free_json ( payload ) ;
myinfo - > decryptstr = 0 ;
scrubfree ( myinfo - > decryptstr ) ;
myinfo - > dirty = 0 ;
}
iguana_walletiterate ( myinfo , coin , 1 , 0 , 0 , 0 , 0 ) ;
}
void iguana_walletlock ( struct supernet_info * myinfo , struct iguana_info * coin )
{
memset ( & myinfo - > persistent_priv , 0 , sizeof ( myinfo - > persistent_priv ) ) ;
memset ( myinfo - > secret , 0 , sizeof ( myinfo - > secret ) ) ;
@ -639,7 +755,7 @@ void iguana_walletlock(struct supernet_info *myinfo)
if ( myinfo - > decryptstr ! = 0 )
scrubfree ( myinfo - > decryptstr ) , myinfo - > decryptstr = 0 ;
myinfo - > expiration = 0 ;
iguana_walletiterate ( myinfo , - 2 ) ;
iguana_walletiterate ( myinfo , coin , - 2 , 0 , 0 , 0 , 0 ) ;
}
int64_t iguana_waccountbalance ( struct supernet_info * myinfo , struct iguana_info * coin , struct iguana_waccount * wacct , int32_t minconf , int32_t lastheight )
@ -830,7 +946,7 @@ ZERO_ARGS(bitcoinrpc,walletlock)
{
if ( remoteaddr ! = 0 )
return ( clonestr ( " { \" error \" : \" no remote \" } " ) ) ;
iguana_walletlock ( myinfo ) ;
iguana_walletlock ( myinfo , coin ) ;
return ( jsuccess ( ) ) ;
}
@ -1077,6 +1193,26 @@ STRING_ARG(bitcoinrpc,importwallet,filename)
return ( clonestr ( " { \" error \" : \" need to unlock wallet \" } " ) ) ;
}
ZERO_ARGS ( bitcoinrpc , checkwallet )
{
if ( remoteaddr ! = 0 )
return ( clonestr ( " { \" error \" : \" no remote \" } " ) ) ;
if ( myinfo - > expiration = = 0 )
return ( clonestr ( " { \" error \" : \" need to unlock wallet \" } " ) ) ;
myinfo - > expiration + + ;
return ( iguana_walletscan ( myinfo , coin , 1 ) ) ;
}
ZERO_ARGS ( bitcoinrpc , repairwallet )
{
if ( remoteaddr ! = 0 )
return ( clonestr ( " { \" error \" : \" no remote \" } " ) ) ;
if ( myinfo - > expiration = = 0 )
return ( clonestr ( " { \" error \" : \" need to unlock wallet \" } " ) ) ;
myinfo - > expiration + + ;
return ( iguana_walletscan ( myinfo , coin , 0 ) ) ;
}
// multiple address
STRING_AND_THREEINTS ( bitcoinrpc , getbalance , account , minconf , includeempty , lastheight )
{