Browse Source

First approach to make iguana work with 2 bytes prefix coins, like HUSH

Main additions:

+ bitcoin_address_ex
+ bitcoin_addr2rmd160_ex

These functions with support taddr param. For example, for HUSH prefix is
{ 0x1C, 0xB8 }, where is taddr = 0x1C and addrtype = 0xB8.

All functions that used bitcoin_address and bitcoin_addr2rmd160 should be
rewritten with new *_ex analogs. currently it's done only for functions
used in split funds.

Also, if we want to support other type of such coins, we should change
condition "if (strcmp(coin->chain->symbol, "HUSH") == 0)" on more universal.

For example we can taddr in struct iguana_chain, but this needs to rewrite
all logic, for example, init structures, init static struct iguana_chain Chains[]
array and other things.

Adding prefix byte causes global changes in iguana.

p.s. With these changes HUSH splitfund in iguana works fine, but we need
to test notarizations on testnet (!) first, and change these functions
calls:

bitcoin_address -> bitcoin_address_ex
bitcoin_addr2rmd160 -> bitcoin_addr2rmd160_ex

everywhere it used. This is not finished yet.
patch-5
DeckerSU 6 years ago
parent
commit
3ccea55958
  1. 7
      basilisk/basilisk_bitcoin.c
  2. 81
      iguana/exchanges/bitcoin.c
  3. 1
      iguana/exchanges/bitcoin.h
  4. 7
      iguana/iguana_payments.c
  5. 54
      iguana/iguana_wallet.c
  6. 1
      includes/iguana_funcs.h

7
basilisk/basilisk_bitcoin.c

@ -584,7 +584,12 @@ char *iguana_utxoduplicates(struct supernet_info *myinfo,struct iguana_info *coi
*completedp = 0;
if ( signedtxidp != 0 )
memset(signedtxidp,0,sizeof(*signedtxidp));
bitcoin_address(changeaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33);
if (strcmp(coin->chain->symbol, "HUSH") == 0)
bitcoin_address_ex(coin->chain->symbol, changeaddr, 0x1c, coin->chain->pubtype, myinfo->persistent_pubkey33, 33);
else
bitcoin_address(changeaddr, coin->chain->pubtype, myinfo->persistent_pubkey33, 33);
txfee = (coin->txfee + duplicates*coin->txfee/10);
if ( strcmp(coin->symbol,"GAME") == 0 )
printf("GAME txfee %.8f\n",dstr(txfee));

81
iguana/exchanges/bitcoin.c

@ -22,6 +22,51 @@ char *bitcoind_passthru(char *coinstr,char *serverport,char *userpass,char *meth
return(bitcoind_RPC(0,coinstr,serverport,userpass,method,params,0));
}
int32_t bitcoin_addr2rmd160_ex(char *symbol, uint8_t taddr, uint8_t *addrtypep, uint8_t rmd160[20], char *coinaddr)
{
bits256 hash; uint8_t *buf, _buf[26], data5[128], rmd21[21]; char prefixaddr[64], hrp[64]; int32_t len, len5, offset;
*addrtypep = 0;
memset(rmd160, 0, 20);
if (coinaddr == 0 || coinaddr[0] == 0)
return(0);
if (coinaddr[0] == '0' && coinaddr[1] == 'x' && is_hexstr(coinaddr + 2, 0) == 40) // for ETH
{
decode_hex(rmd160, 20, coinaddr + 2); // not rmd160 hash but hopefully close enough;
return(20);
}
offset = 1 + (taddr != 0);
memset(rmd160, 0, 20);
*addrtypep = 0;
buf = _buf;
if ((len = bitcoin_base58decode(buf, coinaddr)) >= 4)
{
// validate with trailing hash, then remove hash
hash = bits256_doublesha256(0, buf, 20 + offset);
*addrtypep = (taddr == 0) ? *buf : buf[1];
memcpy(rmd160, buf + offset, 20);
if ((buf[20 + offset] & 0xff) == hash.bytes[31] && (buf[21 + offset] & 0xff) == hash.bytes[30] && (buf[22 + offset] & 0xff) == hash.bytes[29] && (buf[23 + offset] & 0xff) == hash.bytes[28])
{
//printf("coinaddr.(%s) valid checksum addrtype.%02x\n",coinaddr,*addrtypep);
return(20);
}
else if ((strcmp(symbol, "GRS") == 0 || strcmp(symbol, "SMART") == 0) && (buf[20 + offset] & 0xff) == hash.bytes[0] && (buf[21 + offset] & 0xff) == hash.bytes[1] && (buf[22 + offset] & 0xff) == hash.bytes[2] && (buf[23 + offset] & 0xff) == hash.bytes[3])
return(20);
else if (strcmp(symbol, "BTC") != 0 || *addrtypep == 0 || *addrtypep == 5)
{
int32_t i;
//if ( len > 20 )
// hash = bits256_calcaddrhash(symbol,buf,len);
for (i = 0; i<len; i++)
printf("%02x ", hash.bytes[i]);
char str[65]; printf("\n%s addrtype.%d taddr.%02x checkhash.(%s) len.%d mismatch %02x %02x %02x %02x vs %02x %02x %02x %02x (%s)\n", symbol, *addrtypep, taddr, coinaddr, len, buf[len - 1] & 0xff, buf[len - 2] & 0xff, buf[len - 3] & 0xff, buf[len - 4] & 0xff, hash.bytes[31], hash.bytes[30], hash.bytes[29], hash.bytes[28], bits256_str(str, hash));
}
}
return(0);
}
int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr)
{
bits256 hash; uint8_t *buf,_buf[25]; int32_t len;
@ -75,6 +120,42 @@ char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,
return(coinaddr);
}
char *bitcoin_address_ex(char *symbol, char *coinaddr, uint8_t taddr, uint8_t addrtype, uint8_t *pubkey_or_rmd160, int32_t len)
{
static void *ctx;
int32_t offset, i, len5; char prefixed[64]; uint8_t data[64], data5[64], bigpubkey[65]; bits256 hash; struct iguana_info *coin;
coinaddr[0] = 0;
offset = 1 + (taddr != 0);
if (len != 20)
{
calc_rmd160_sha256(data + offset, pubkey_or_rmd160, len);
//for (i=0; i<20; i++)
// printf("%02x",data[offset+i]);
//printf(" rmd160\n");
}
else memcpy(data + offset, pubkey_or_rmd160, 20);
if (taddr != 0)
{
data[0] = taddr;
data[1] = addrtype;
}
else data[0] = addrtype;
hash = bits256_doublesha256(0, data, 20 + offset);
for (i = 0; i<4; i++)
data[20 + offset + i] = hash.bytes[31 - i];
if ((coinaddr = bitcoin_base58encode(coinaddr, data, 24 + offset)) != 0)
{
//printf("coinaddr.%p %s\n",coinaddr,coinaddr!=0?coinaddr:"null");
}
else printf("null coinaddr taddr.%02x\n", taddr);
return(coinaddr);
}
int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr)
{
uint8_t rmd160[20],addrtype; char checkaddr[128];

1
iguana/exchanges/bitcoin.h

@ -46,6 +46,7 @@
int32_t bitcoin_validaddress(struct iguana_info *coin,char *coinaddr);
int32_t bitcoin_cltvscript(uint8_t p2shtype,char *ps2h_coinaddr,uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,char *senderaddr,char *otheraddr,uint8_t secret160[20],uint32_t locktime);
int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr);
int32_t bitcoin_addr2rmd160_ex(char *symbol, uint8_t taddr, uint8_t *addrtypep, uint8_t rmd160[20], char *coinaddr);
char *bitcoin_cltvtx(struct iguana_info *coin,char *changeaddr,char *senderaddr,char *senders_otheraddr,char *otheraddr,uint32_t locktime,uint64_t satoshis,bits256 txid,int32_t vout,uint64_t inputsatoshis,bits256 privkey);
int32_t bitcoin_MofNspendscript(uint8_t p2sh_rmd160[20],uint8_t *script,int32_t n,const struct vin_info *vp);

7
iguana/iguana_payments.c

@ -522,7 +522,12 @@ char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJS
printf("illegal destination address.(%s)\n",changeaddr);
return(0);
}
bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr);
if (strcmp(coin->symbol, "HUSH") == 0)
bitcoin_addr2rmd160_ex(coin->symbol, 0x1c, &addrtype, rmd160, changeaddr);
else
bitcoin_addr2rmd160(&addrtype,rmd160,changeaddr);
spendlen = bitcoin_standardspend(spendscript,0,rmd160);
bitcoin_txoutput(txobj,spendscript,spendlen,change);
if ( opreturn != 0 )

54
iguana/iguana_wallet.c

@ -321,7 +321,10 @@ cJSON *iguana_getaddressesbyaccount(struct supernet_info *myinfo,struct iguana_i
{
HASH_ITER(hh,subset->waddr,waddr,tmp2)
{
bitcoin_address(coinaddr,coin->chain->pubtype,waddr->rmd160,20);
if (strcmp(coin->chain->symbol, "HUSH") == 0)
bitcoin_address_ex(coin->chain->symbol, coinaddr, 0x1c, coin->chain->pubtype, waddr->rmd160, 20);
else
bitcoin_address(coinaddr, coin->chain->pubtype, waddr->rmd160, 20);
printf("%s ",coinaddr);
jaddistr(array,coinaddr);
}
@ -329,12 +332,20 @@ cJSON *iguana_getaddressesbyaccount(struct supernet_info *myinfo,struct iguana_i
}
else
{
bitcoin_address(refaddr,coin->chain->pubtype,myinfo->persistent_pubkey33,33);
HASH_ITER(hh,myinfo->wallet,subset,tmp)
if (strcmp(coin->chain->symbol, "HUSH") == 0)
bitcoin_address_ex(coin->chain->symbol, refaddr, 0x1c, coin->chain->pubtype, myinfo->persistent_pubkey33, 33);
else
bitcoin_address(refaddr, coin->chain->pubtype, myinfo->persistent_pubkey33, 33);
HASH_ITER(hh,myinfo->wallet,subset,tmp)
{
HASH_ITER(hh,subset->waddr,waddr,tmp2)
{
bitcoin_address(coinaddr,coin->chain->pubtype,waddr->rmd160,20);
if (strcmp(coin->chain->symbol, "HUSH") == 0)
bitcoin_address_ex(coin->chain->symbol, coinaddr, 0x1c, coin->chain->pubtype, waddr->rmd160, 20);
else
bitcoin_address(coinaddr, coin->chain->pubtype, waddr->rmd160, 20);
jaddistr(array,coinaddr);
if ( strcmp(coinaddr,refaddr) == 0 )
refaddr[0] = 0;
@ -359,17 +370,36 @@ int32_t iguana_addressvalidate(struct iguana_info *coin,uint8_t *addrtypep,char
char checkaddr[64]; uint8_t rmd160[20];
*addrtypep = 0;
memset(rmd160,0,sizeof(rmd160));
bitcoin_addr2rmd160(addrtypep,rmd160,address);
if (strcmp(coin->symbol, "HUSH") == 0)
bitcoin_addr2rmd160_ex(coin->symbol, 0x1c, addrtypep, rmd160, address);
else
bitcoin_addr2rmd160(addrtypep,rmd160,address);
//int32_t i; for (i=0; i<20; i++)
// printf("%02x",rmd160[i]); // 764692cd5473f62ffa8a93e55d876f567623de07
//printf(" rmd160 addrtype.%02x\n",*addrtypep);
if ( bitcoin_address(checkaddr,*addrtypep,rmd160,20) == checkaddr && strcmp(address,checkaddr) == 0 && (*addrtypep == coin->chain->pubtype || *addrtypep == coin->chain->p2shtype) )
return(0);
else
{
//printf(" checkaddr.(%s) address.(%s) type.%02x vs (%02x %02x)\n",checkaddr,address,*addrtypep,coin->chain->pubtype,coin->chain->p2shtype);
return(-1);
}
if (strcmp(coin->symbol, "HUSH") == 0)
{
if (bitcoin_address_ex(coin->symbol, checkaddr, 0x1c, *addrtypep, rmd160, 20) == checkaddr && strcmp(address, checkaddr) == 0 && (*addrtypep == coin->chain->pubtype || *addrtypep == coin->chain->p2shtype))
return(0);
else
{
//printf(" checkaddr.(%s) address.(%s) type.%02x vs (%02x %02x)\n",checkaddr,address,*addrtypep,coin->chain->pubtype,coin->chain->p2shtype);
return(-1);
}
}
else
{
if (bitcoin_address(checkaddr, *addrtypep, rmd160, 20) == checkaddr && strcmp(address, checkaddr) == 0 && (*addrtypep == coin->chain->pubtype || *addrtypep == coin->chain->p2shtype))
return(0);
else
{
//printf(" checkaddr.(%s) address.(%s) type.%02x vs (%02x %02x)\n",checkaddr,address,*addrtypep,coin->chain->pubtype,coin->chain->p2shtype);
return(-1);
}
}
}
cJSON *iguana_waddressjson(struct iguana_info *coin,cJSON *item,struct iguana_waddress *waddr)

1
includes/iguana_funcs.h

@ -560,6 +560,7 @@ bits256 calc_categoryhashes(bits256 *subhashp,char *category,char *subcategory);
struct gecko_chain *category_find(bits256 categoryhash,bits256 subhash);
void *category_subscribe(struct supernet_info *myinfo,bits256 category,bits256 keyhash);
char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len);
char *bitcoin_address_ex(char *symbol, char *coinaddr, uint8_t taddr, uint8_t addrtype, uint8_t *pubkey_or_rmd160, int32_t len);
char *SuperNET_JSON(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *json,char *remoteaddr,uint16_t port);
int64_t iguana_txdetails(struct supernet_info *myinfo,struct iguana_info *coin,cJSON *item,bits256 txid,int32_t vout,int32_t height);
int32_t iguana_txidheight(struct supernet_info *myinfo,struct iguana_info *coin,bits256 txid);

Loading…
Cancel
Save