Merge branch 'FSM' into jl777

This commit is contained in:
jl777
2019-07-08 17:56:27 -11:00
22 changed files with 1582 additions and 89 deletions

View File

@@ -22,6 +22,15 @@
bool PegsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
// CCcustom
UniValue PegsInfo();
std::string PegsCreate(uint64_t txfee,int64_t amount,std::vector<uint256> bindtxids);
std::string PegsFund(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
std::string PegsGet(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
std::string PegsRedeem(uint64_t txfee,uint256 pegstxid, uint256 tokenid);
std::string PegsLiquidate(uint64_t txfee,uint256 pegstxid, uint256 tokenid, uint256 liquidatetxid);
std::string PegsExchange(uint64_t txfee,uint256 pegstxid, uint256 tokenid, int64_t amount);
UniValue PegsAccountHistory(uint256 pegstxid);
UniValue PegsAccountInfo(uint256 pegstxid);
UniValue PegsWorstAccounts(uint256 pegstxid);
UniValue PegsInfo(uint256 pegstxid);
#endif

View File

@@ -79,6 +79,7 @@ one other technical note is that komodod has the insight-explorer extensions bui
OPRETID_CHANNELSDATA = 0x14,
OPRETID_HEIRDATA = 0x15,
OPRETID_ROGUEGAMEDATA = 0x16,
OPRETID_PEGSDATA = 0x17,
// non cc contract data:
OPRETID_FIRSTNONCCDATA = 0x80,
@@ -126,7 +127,7 @@ struct CCcontract_info
// the same for tokens 1of2 keys cc
char tokens1of2addr[64];
CPubKey tokens1of2pk[2];
CPubKey tokens1of2pk[2]; uint8_t tokens1of2priv[32];
// this is for spending from two additional 'unspendable' CC addresses of other eval codes
// (that is, for spending from several cc contract 'unspendable' addresses):
@@ -249,7 +250,7 @@ CC *MakeTokensCCcond1(uint8_t evalcode, CPubKey pk);
CC *MakeTokensCCcond1(uint8_t evalcode, uint8_t evalcode2, CPubKey pk);
bool GetTokensCCaddress(struct CCcontract_info *cp, char *destaddr, CPubKey pk);
bool GetTokensCCaddress1of2(struct CCcontract_info *cp, char *destaddr, CPubKey pk, CPubKey pk2);
void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, char *coinaddr);
void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, uint8_t *priv, char *coinaddr);
int32_t CClib_initcp(struct CCcontract_info *cp,uint8_t evalcode);
bool IsCCInput(CScript const& scriptSig);

View File

@@ -397,6 +397,21 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true
}
}
//special check for tx when spending from 1of2 CC address and one of pubkeys is global CC pubkey
struct CCcontract_info *cpEvalCode1,CEvalCode1;
cpEvalCode1 = CCinit(&CEvalCode1,evalCode1);
CPubKey pk=GetUnspendable(cpEvalCode1,0);
testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode1, tx.vout[v].nValue, voutPubkeys[0], pk), std::string("dual-eval1 pegscc cc1of2 pk[0] globalccpk")) );
if (voutPubkeys.size() == 2) testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode1, tx.vout[v].nValue, voutPubkeys[1], pk), std::string("dual-eval1 pegscc cc1of2 pk[1] globalccpk")) );
if (evalCode2!=0)
{
struct CCcontract_info *cpEvalCode2,CEvalCode2;
cpEvalCode2 = CCinit(&CEvalCode2,evalCode2);
CPubKey pk=GetUnspendable(cpEvalCode2,0);
testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode2, tx.vout[v].nValue, voutPubkeys[0], pk), std::string("dual-eval2 pegscc cc1of2 pk[0] globalccpk")) );
if (voutPubkeys.size() == 2) testVouts.push_back( std::make_pair(MakeTokensCC1of2vout(evalCode2, tx.vout[v].nValue, voutPubkeys[1], pk), std::string("dual-eval2 pegscc cc1of2 pk[1] globalccpk")) );
}
// maybe it is single-eval or dual/three-eval token change?
std::vector<CPubKey> vinPubkeys, vinPubkeysUnfiltered;
ExtractTokensCCVinPubkeys(tx, vinPubkeysUnfiltered);

View File

@@ -96,6 +96,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
//This is a must to avoid hardfork change of validation in every CC, because there could be maximum one normal vin at the begining with current validation.
for (i=0; i<n; i++)
{
if (i==0 && mtx.vin[i].prevout.n==10e8) continue;
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
{
if ( vintx.vout[mtx.vin[i].prevout.n].scriptPubKey.IsPayToCryptoCondition() == 0 && ccvins==0)
@@ -114,6 +115,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
memset(utxovalues,0,sizeof(utxovalues));
for (i=0; i<n; i++)
{
if (i==0 && mtx.vin[i].prevout.n==10e8) continue;
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
{
utxovout = mtx.vin[i].prevout.n;
@@ -145,6 +147,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
n = mtx.vin.size();
for (i=0; i<n; i++)
{
if (i==0 && mtx.vin[i].prevout.n==10e8) continue;
if ( GetTransaction(mtx.vin[i].prevout.hash,vintx,hashBlock,false) != 0 )
{
utxovout = mtx.vin[i].prevout.n;
@@ -235,7 +238,7 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
else if (strcmp(cp->tokens1of2addr, destaddr) == 0)
{
//fprintf(stderr,"FinalizeCCTx() matched %s cp->tokens1of2addr!\n", cp->tokens1of2addr);
privkey = myprivkey;
privkey = cp->tokens1of2priv;//myprivkey;
if (othercond1of2tokens == 0)
// NOTE: if additionalEvalcode2 is not set then it is dual-eval cc else three-eval cc
// TODO: verify evalcodes order if additionalEvalcode2 is not 0

View File

@@ -187,7 +187,7 @@ void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *
}
// set pubkeys, myprivkey and 1of2 cc addr for spending from 1of2 cryptocondition vout:
void CCaddr1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2,uint8_t *priv,char *coinaddr)
void CCaddr1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, uint8_t *priv, char *coinaddr)
{
cp->coins1of2pk[0] = pk1;
cp->coins1of2pk[1] = pk2;
@@ -197,10 +197,11 @@ void CCaddr1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2,uint8_t
// set pubkeys, myprivkey and 1of2 cc addr for spending from 1of2 token cryptocondition vout
// to get tokenaddr use GetTokensCCaddress()
void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, char *tokenaddr)
void CCaddrTokens1of2set(struct CCcontract_info *cp, CPubKey pk1, CPubKey pk2, uint8_t *priv, char *tokenaddr)
{
cp->tokens1of2pk[0] = pk1;
cp->tokens1of2pk[1] = pk2;
memcpy(cp->tokens1of2priv,priv,32);
strcpy(cp->tokens1of2addr, tokenaddr);
}

View File

@@ -451,7 +451,7 @@ int64_t AddChannelsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx, C
mtx.vin.push_back(CTxIn(txid,0,CScript()));
mtx.vin.push_back(CTxIn(txid,marker,CScript()));
Myprivkey(myprivkey);
if (tokenid!=zeroid) CCaddrTokens1of2set(cp,srcpub,destpub,coinaddr);
if (tokenid!=zeroid) CCaddrTokens1of2set(cp,srcpub,destpub,myprivkey,coinaddr);
else CCaddr1of2set(cp,srcpub,destpub,myprivkey,coinaddr);
return totalinputs;
}

View File

@@ -98,8 +98,9 @@ public:
}
static void CCaddrCoinsOrTokens1of2set(struct CCcontract_info *cp, CPubKey ownerPubkey, CPubKey heirPubkey, char *coinaddr) {
CCaddrTokens1of2set(cp, ownerPubkey, heirPubkey, coinaddr);
uint8_t mypriv[32];
Myprivkey(mypriv);
CCaddrTokens1of2set(cp, ownerPubkey, heirPubkey, mypriv, coinaddr);
}
};

View File

@@ -681,7 +681,7 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
return Invalid("invalid-params");
// Control all aspects of this transaction
// It should not be at all malleable
if (MakeImportCoinTransaction(proof, burnTx, payouts, importTx.nExpiryHeight).GetHash() != importTx.GetHash()) // ExistsImportTombstone prevents from duplication
if (ASSETCHAINS_SELFIMPORT!="PEGSCC" && MakeImportCoinTransaction(proof, burnTx, payouts, importTx.nExpiryHeight).GetHash() != importTx.GetHash()) // ExistsImportTombstone prevents from duplication
return Invalid("non-canonical");
// burn params
if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCcid, payoutsHash, rawproof))
@@ -736,10 +736,17 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
else if ( UnmarshalBurnTx(burnTx,srcaddr,receipt)==0 || CheckCODAimport(importTx,burnTx,payouts,srcaddr,receipt) < 0 )
return Invalid("CODA-import-failure");
}
else if ( targetSymbol == "PEGSCC" )
{
if ( ASSETCHAINS_SELFIMPORT != "PEGSCC" )
return Invalid("PEGSCC-import-when-not PEGSCC");
// else if ( CheckPUBKEYimport(merkleBranchProof,rawproof,burnTx,payouts) < 0 )
// return Invalid("PEGSCC-import-failure");
}
else if ( targetSymbol == "PUBKEY" )
{
if ( ASSETCHAINS_SELFIMPORT != "PUBKEY" )
return Invalid("PUBKEY-import-when-notPUBKEY");
return Invalid("PUBKEY-import-when-not PUBKEY");
else if ( CheckPUBKEYimport(merkleBranchProof,rawproof,burnTx,payouts) < 0 )
return Invalid("PUBKEY-import-failure");
}
@@ -747,7 +754,7 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params, const CTransaction &imp
{
if ( targetSymbol != ASSETCHAINS_SELFIMPORT )
return Invalid("invalid-gateway-import-coin");
else if ( UnmarshalBurnTx(burnTx,bindtxid,publishers,txids,burntxid,height,burnvout,rawburntx,destpub,amount)==0 || CheckGATEWAYimport(importTx,burnTx,targetSymbol,rawproof,bindtxid,publishers,txids,burntxid,height,burnvout,rawburntx,destpub,amount) < 0 )
else if ( UnmarshalBurnTx(burnTx,bindtxid,publishers,txids,burntxid,height,burnvout,rawburntx,destpub,amount)==0 || CheckGATEWAYimport(importTx,burnTx,targetSymbol,rawproof,bindtxid,publishers,txids,burntxid,height,burnvout,rawburntx,destpub,amount) < 0 )
return Invalid("GATEWAY-import-failure");
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -604,6 +604,11 @@ CAmount CCoinsViewCache::GetValueIn(int32_t nHeight,int64_t *interestp,const CTr
return 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.IsPegsImport() && i==0)
{
nResult = GetCoinImportValue(tx);
continue;
}
value = GetOutputFor(tx.vin[i]).nValue;
nResult += value;
#ifdef KOMODO_ENABLE_INTEREST
@@ -675,6 +680,7 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
{
if (!tx.IsMint()) {
for (unsigned int i = 0; i < tx.vin.size(); i++) {
if (tx.IsPegsImport() && i==0) continue;
const COutPoint &prevout = tx.vin[i].prevout;
const CCoins* coins = AccessCoins(prevout.hash);
if (!coins || !coins->IsAvailable(prevout.n)) {
@@ -696,7 +702,7 @@ double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight) const
// use the maximum priority for all (partially or fully) shielded transactions.
// (Note that coinbase transactions cannot contain JoinSplits, or Sapling shielded Spends or Outputs.)
if (tx.vjoinsplit.size() > 0 || tx.vShieldedSpend.size() > 0 || tx.vShieldedOutput.size() > 0 || tx.IsCoinImport()) {
if (tx.vjoinsplit.size() > 0 || tx.vShieldedSpend.size() > 0 || tx.vShieldedOutput.size() > 0 || tx.IsCoinImport() || tx.IsPegsImport()) {
return MAX_PRIORITY;
}

View File

@@ -75,6 +75,18 @@ CTransaction MakeImportCoinTransaction(const ImportProof proof, const CTransacti
return CTransaction(mtx);
}
CTransaction MakePegsImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector<CTxOut> payouts, uint32_t nExpiryHeightOverride)
{
CMutableTransaction mtx; uint256 accounttxid,pegstxid,tokenid; CScript opret; CScript scriptSig;
mtx=MakeImportCoinTransaction(proof,burnTx,payouts);
// for spending markers in import tx - to track account state
accounttxid=burnTx.vin[0].prevout.hash;
mtx.vin.push_back(CTxIn(accounttxid,0,CScript()));
mtx.vin.push_back(CTxIn(accounttxid,1,CScript()));
return (mtx);
}
CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string targetSymbol, const std::vector<CTxOut> payouts, const std::vector<uint8_t> rawproof)
{
@@ -123,13 +135,30 @@ CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymb
return CTxOut(value, CScript() << OP_RETURN << opret);
}
CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid,std::string targetSymbol,const std::vector<CTxOut> payouts,std::vector<uint8_t> rawproof,uint256 pegstxid,
uint256 tokenid,CPubKey srcpub,int64_t amount,std::pair<int64_t,int64_t> account)
{
std::vector<uint8_t> opret;
opret = E_MARSHAL(ss << (uint8_t)EVAL_IMPORTCOIN;
ss << VARINT(targetCCid);
ss << targetSymbol;
ss << SerializeHash(payouts);
ss << rawproof;
ss << pegstxid;
ss << tokenid;
ss << srcpub;
ss << amount;
ss << account);
return CTxOut(value, CScript() << OP_RETURN << opret);
}
bool UnmarshalImportTx(const CTransaction importTx, ImportProof &proof, CTransaction &burnTx, std::vector<CTxOut> &payouts)
{
if (importTx.vout.size() < 1)
return false;
if (importTx.vin.size() != 1 || importTx.vin[0].scriptSig != (CScript() << E_MARSHAL(ss << EVAL_IMPORTCOIN))) {
if ((!importTx.IsPegsImport() && importTx.vin.size() != 1) || importTx.vin[0].scriptSig != (CScript() << E_MARSHAL(ss << EVAL_IMPORTCOIN))) {
LOGSTREAM("importcoin", CCLOG_INFO, stream << "UnmarshalImportTx() incorrect import tx vin" << std::endl);
return false;
}
@@ -263,17 +292,35 @@ bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid,std::vector<CPu
ss >> amount));
}
bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokenid,CPubKey &srcpub, int64_t &amount,std::pair<int64_t,int64_t> &account)
{
std::vector<uint8_t> burnOpret,rawproof; bool isEof=true;
uint32_t targetCCid; uint256 payoutsHash; std::string targetSymbol;
uint8_t evalCode;
if (burnTx.vout.size() == 0) return false;
GetOpReturnData(burnTx.vout.back().scriptPubKey, burnOpret);
return (E_UNMARSHAL(burnOpret, ss >> evalCode;
ss >> VARINT(targetCCid);
ss >> targetSymbol;
ss >> payoutsHash;
ss >> rawproof;
ss >> pegstxid;
ss >> tokenid;
ss >> srcpub;
ss >> amount;
ss >> account));
}
/*
* Required by main
*/
CAmount GetCoinImportValue(const CTransaction &tx)
{
ImportProof proof;
CTransaction burnTx;
std::vector<CTxOut> payouts;
ImportProof proof; CTransaction burnTx; std::vector<CTxOut> payouts;
bool isNewImportTx = false;
if ((isNewImportTx = UnmarshalImportTx(tx, proof, burnTx, payouts))) {
if (burnTx.vout.size() > 0) {
vscript_t vburnOpret;

View File

@@ -95,16 +95,20 @@ public:
CAmount GetCoinImportValue(const CTransaction &tx);
CTransaction MakeImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector<CTxOut> payouts, uint32_t nExpiryHeightOverride = 0);
CTransaction MakePegsImportCoinTransaction(const ImportProof proof, const CTransaction burnTx, const std::vector<CTxOut> payouts, uint32_t nExpiryHeightOverride = 0);
CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, const std::string targetSymbol, const std::vector<CTxOut> payouts, const std::vector<uint8_t> rawproof);
CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymbol, const std::vector<CTxOut> payouts,std::vector<uint8_t> rawproof,
uint256 bindtxid,std::vector<CPubKey> publishers,std::vector<uint256>txids,uint256 burntxid,int32_t height,int32_t burnvout,std::string rawburntx,CPubKey destpub, int64_t amount);
CTxOut MakeBurnOutput(CAmount value, uint32_t targetCCid, std::string targetSymbol, const std::vector<CTxOut> payouts,std::vector<uint8_t> rawproof,std::string srcaddr,
std::string receipt);
CTxOut MakeBurnOutput(CAmount value,uint32_t targetCCid,std::string targetSymbol,const std::vector<CTxOut> payouts,std::vector<uint8_t> rawproof,uint256 pegstxid,
uint256 tokenid,CPubKey srcpub,int64_t amount,std::pair<int64_t,int64_t> account);
bool UnmarshalBurnTx(const CTransaction burnTx, std::string &targetSymbol, uint32_t *targetCCid, uint256 &payoutsHash,std::vector<uint8_t> &rawproof);
bool UnmarshalBurnTx(const CTransaction burnTx, std::string &srcaddr, std::string &receipt);
bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &bindtxid,std::vector<CPubKey> &publishers,std::vector<uint256> &txids,uint256& burntxid,int32_t &height,int32_t &burnvout,std::string &rawburntx,CPubKey &destpub, int64_t &amount);
bool UnmarshalBurnTx(const CTransaction burnTx,uint256 &pegstxid,uint256 &tokenid,CPubKey &srcpub,int64_t &amount,std::pair<int64_t,int64_t> &account);
bool UnmarshalImportTx(const CTransaction importTx, ImportProof &proof, CTransaction &burnTx,std::vector<CTxOut> &payouts);
bool VerifyCoinImport(const CScript& scriptSig, TransactionSignatureChecker& checker, CValidationState &state);

View File

@@ -74,7 +74,7 @@ uint64_t ASSETCHAINS_TIMELOCKGTE = _ASSETCHAINS_TIMELOCKOFF;
uint64_t ASSETCHAINS_TIMEUNLOCKFROM = 0, ASSETCHAINS_TIMEUNLOCKTO = 0,ASSETCHAINS_CBOPRET=0;
uint64_t ASSETCHAINS_LASTERA = 1;
uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS];
uint64_t ASSETCHAINS_ENDSUBSIDY[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_HALVING[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_DECAY[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_NOTARY_PAY[ASSETCHAINS_MAX_ERAS],ASSETCHAINS_PEGSCCPARAMS[3];
uint8_t ASSETCHAINS_CCDISABLES[256];
std::vector<std::string> ASSETCHAINS_PRICES,ASSETCHAINS_STOCKS;

View File

@@ -1692,7 +1692,9 @@ int8_t equihash_params_possible(uint64_t n, uint64_t k)
void komodo_args(char *argv0)
{
std::string name,addn,hexstr,symbol; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[32756],disablebits[32],*extraptr=0; FILE *fp; uint64_t val; uint16_t port; int32_t i,nonz=0,baseid,len,n,extralen = 0; uint64_t ccenables[256], ccEnablesHeight[512] = {0};
std::string name,addn,hexstr,symbol; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[32756],disablebits[32],*extraptr=0;
FILE *fp; uint64_t val; uint16_t port; int32_t i,nonz=0,baseid,len,n,extralen = 0; uint64_t ccenables[256], ccEnablesHeight[512] = {0}; CTransaction earlytx; uint256 hashBlock;
IS_KOMODO_NOTARY = GetBoolArg("-notary", false);
IS_STAKED_NOTARY = GetArg("-stakednotary", -1);
KOMODO_NSPV = GetArg("-nSPV",0);
@@ -1786,6 +1788,12 @@ void komodo_args(char *argv0)
printf("KOMODO_REWIND %d\n",KOMODO_REWIND);
}
KOMODO_EARLYTXID = Parseuint256(GetArg("-earlytxid","0").c_str());
CTransaction tx; uint256 blockhash;
if (KOMODO_EARLYTXID!=zeroid && myGetTransaction(KOMODO_EARLYTXID,tx,blockhash) && (mapBlockIndex[blockhash]->GetHeight() == 0 || mapBlockIndex[blockhash]->GetHeight() > 100))
{
fprintf(stderr,"error: earlytx can be only in first 100 blocks or tx does not exist\n");
StartShutdown();
}
ASSETCHAINS_EARLYTXIDCONTRACT = GetArg("-ac_earlytxidcontract",0);
if ( name.c_str()[0] != 0 )
{
@@ -1939,7 +1947,7 @@ void komodo_args(char *argv0)
}
}*/
}
if ( ASSETCHAINS_BEAMPORT != 0 && ASSETCHAINS_CODAPORT != 0 )
if ( ASSETCHAINS_BEAMPORT != 0 )
{
fprintf(stderr,"can only have one of -ac_beam or -ac_coda\n");
StartShutdown();
@@ -1953,18 +1961,33 @@ void komodo_args(char *argv0)
StartShutdown();
}
}
else if ( ASSETCHAINS_SELFIMPORT == "BEAM" && ASSETCHAINS_BEAMPORT == 0 )
else if ( ASSETCHAINS_SELFIMPORT == "BEAM" )
{
fprintf(stderr,"missing -ac_beam for BEAM rpcport\n");
StartShutdown();
if (ASSETCHAINS_BEAMPORT == 0)
{
fprintf(stderr,"missing -ac_beam for BEAM rpcport\n");
StartShutdown();
}
}
else if ( ASSETCHAINS_SELFIMPORT == "CODA" && ASSETCHAINS_CODAPORT == 0 )
else if ( ASSETCHAINS_SELFIMPORT == "CODA" )
{
fprintf(stderr,"missing -ac_coda for CODA rpcport\n");
StartShutdown();
if (ASSETCHAINS_CODAPORT == 0)
{
fprintf(stderr,"missing -ac_coda for CODA rpcport\n");
StartShutdown();
}
}
else if ( ASSETCHAINS_SELFIMPORT == "PEGSCC")
{
Split(GetArg("-ac_pegsccparams",""), ASSETCHAINS_PEGSCCPARAMS, 0);
if (ASSETCHAINS_ENDSUBSIDY[0]!=1 || ASSETCHAINS_COMMISSION!=0)
{
fprintf(stderr,"when using import for pegsCC these must be set: -ac_end=1 -ac_perc=0\n");
StartShutdown();
}
}
// else it can be gateway coin
else if (!ASSETCHAINS_SELFIMPORT.empty() && (ASSETCHAINS_ENDSUBSIDY[0]!=1 || ASSETCHAINS_SUPPLY>10 || ASSETCHAINS_COMMISSION!=0))
else if (!ASSETCHAINS_SELFIMPORT.empty() && (ASSETCHAINS_ENDSUBSIDY[0]!=1 || ASSETCHAINS_SUPPLY>0 || ASSETCHAINS_COMMISSION!=0))
{
fprintf(stderr,"when using gateway import these must be set: -ac_end=1 -ac_supply=0 -ac_perc=0\n");
StartShutdown();

View File

@@ -738,6 +738,7 @@ bool komodo_dailysnapshot(int32_t height)
for (unsigned int j = tx.vin.size(); j-- > 0;)
{
uint256 blockhash; CTransaction txin;
if (tx.IsPegsImport() && j==0) continue;
if ( !tx.IsCoinImport() && !tx.IsCoinBase() && myGetTransaction(tx.vin[j].prevout.hash,txin,blockhash) )
{
int vout = tx.vin[j].prevout.n;
@@ -1015,6 +1016,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs,
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.IsPegsImport() && i==0) continue;
const CTxOut& prev = mapInputs.GetOutputFor(tx.vin[i]);
vector<vector<unsigned char> > vSolutions;
@@ -1092,6 +1094,7 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
unsigned int nSigOps = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.IsPegsImport() && i==0) continue;
const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
if (prevout.scriptPubKey.IsPayToScriptHash())
nSigOps += prevout.scriptPubKey.GetSigOpCount(tx.vin[i].scriptSig);
@@ -1876,7 +1879,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
return state.Invalid(false, REJECT_DUPLICATE, "already have coins");
}
if (tx.IsCoinImport())
if (tx.IsCoinImport() || tx.IsPegsImport())
{
// Inverse of normal case; if input exists, it's been spent
if (ExistsImportTombstone(tx, view))
@@ -1948,7 +1951,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Keep track of transactions that spend a coinbase, which we re-scan
// during reorgs to ensure COINBASE_MATURITY is still met.
bool fSpendsCoinbase = false;
if (!fSkipExpiry && !tx.IsCoinImport()) {
if (!fSkipExpiry && !tx.IsCoinImport() && !tx.IsPegsImport()) {
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
const CCoins *coins = view.AccessCoins(txin.prevout.hash);
if (coins->IsCoinBase()) {
@@ -1988,7 +1991,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Continuously rate-limit free (really, very-low-fee) transactions
// This mitigates 'penny-flooding' -- sending thousands of free transactions just to
// be annoying or make others' transactions take longer to confirm.
if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize) && !tx.IsCoinImport())
if (fLimitFree && nFees < ::minRelayTxFee.GetFee(nSize) && !tx.IsCoinImport() && !tx.IsPegsImport())
{
static CCriticalSection csFreeLimiter;
static double dFreeCount;
@@ -2011,7 +2014,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
dFreeCount += nSize;
}
if (!tx.IsCoinImport() && fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
if (!tx.IsCoinImport() && !tx.IsPegsImport() && fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
{
string errmsg = strprintf("absurdly high fees %s, %d > %d",
hash.ToString(),
@@ -2692,6 +2695,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund
{
txundo.vprevout.reserve(tx.vin.size());
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
if (tx.IsPegsImport() && txin.prevout.n==10e8) continue;
CCoinsModifier coins = inputs.ModifyCoins(txin.prevout.hash);
unsigned nPos = txin.prevout.n;
@@ -2715,7 +2719,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, CTxUndo &txund
inputs.ModifyCoins(tx.GetHash())->FromTx(tx, nHeight); // add outputs
// Unorthodox state
if (tx.IsCoinImport()) {
if (tx.IsCoinImport() || tx.IsPegsImport()) {
// add a tombstone for the burnTx
AddImportTombstone(tx, inputs, nHeight);
}
@@ -2759,6 +2763,11 @@ namespace Consensus {
CAmount nFees = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.IsPegsImport() && i==0)
{
nValueIn=GetCoinImportValue(tx);
continue;
}
const COutPoint &prevout = tx.vin[i].prevout;
const CCoins *coins = inputs.AccessCoins(prevout.hash);
assert(coins);
@@ -2870,6 +2879,7 @@ bool ContextualCheckInputs(
// still computed and checked, and any change will be caught at the next checkpoint.
if (fScriptChecks) {
for (unsigned int i = 0; i < tx.vin.size(); i++) {
if (tx.IsPegsImport() && i==0) continue;
const COutPoint &prevout = tx.vin[i].prevout;
const CCoins* coins = inputs.AccessCoins(prevout.hash);
assert(coins);
@@ -2905,7 +2915,7 @@ bool ContextualCheckInputs(
}
}
if (tx.IsCoinImport())
if (tx.IsCoinImport() || tx.IsPegsImport())
{
LOCK(cs_main);
ServerTransactionSignatureChecker checker(&tx, 0, 0, false, txdata);
@@ -3191,10 +3201,12 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
// restore inputs
if (!tx.IsMint()) {
const CTxUndo &txundo = blockUndo.vtxundo[i-1];
CTxUndo &txundo = blockUndo.vtxundo[i-1];
if (tx.IsPegsImport()) txundo.vprevout.insert(txundo.vprevout.begin(),CTxInUndo());
if (txundo.vprevout.size() != tx.vin.size())
return error("DisconnectBlock(): transaction and undo data inconsistent");
for (unsigned int j = tx.vin.size(); j-- > 0;) {
if (tx.IsPegsImport() && j==0) continue;
const COutPoint &out = tx.vin[j].prevout;
const CTxInUndo &undo = txundo.vprevout[j];
if (!ApplyTxInUndo(undo, view, out))
@@ -3228,7 +3240,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
}
}
}
else if (tx.IsCoinImport())
else if (tx.IsCoinImport() || tx.IsPegsImport())
{
RemoveImportTombstone(tx, view);
}
@@ -3578,6 +3590,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
{
for (size_t j = 0; j < tx.vin.size(); j++)
{
if (tx.IsPegsImport() && j==0) continue;
const CTxIn input = tx.vin[j];
const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);

View File

@@ -323,6 +323,13 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
if (tx.IsPegsImport() && txin.prevout.n==10e8)
{
CAmount nValueIn = GetCoinImportValue(tx); // burn amount
nTotalIn += nValueIn;
dPriority += (double)nValueIn * 1000; // flat multiplier... max = 1e16.
continue;
}
// Read prev transaction
if (!view.HaveCoins(txin.prevout.hash))
{

View File

@@ -46,6 +46,7 @@
#include "zcash/Proof.hpp"
extern uint32_t ASSETCHAINS_MAGIC;
extern std::string ASSETCHAINS_SELFIMPORT;
// Overwinter transaction version
static const int32_t OVERWINTER_TX_VERSION = 3;
@@ -711,6 +712,11 @@ public:
return (vin.size() == 1 && vin[0].prevout.n == 10e8);
}
bool IsPegsImport() const
{
return (ASSETCHAINS_SELFIMPORT=="PEGSCC" && vin[0].prevout.n == 10e8);
}
friend bool operator==(const CTransaction& a, const CTransaction& b)
{
return a.hash == b.hash;

View File

@@ -206,7 +206,7 @@ void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue&
UniValue in(UniValue::VOBJ);
if (tx.IsCoinBase())
in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
else if (tx.IsCoinImport()) {
else if (tx.IsCoinImport() && txin.prevout.n==10e8) {
in.push_back(Pair("is_import", "1"));
ImportProof proof; CTransaction burnTx; std::vector<CTxOut> payouts; CTxDestination importaddress;
if (UnmarshalImportTx(tx, proof, burnTx, payouts))

View File

@@ -566,6 +566,18 @@ static const CRPCCommand vRPCCommands[] =
//{ "tokens", "tokenfillswap", &tokenfillswap, true },
{ "tokens", "tokenconvert", &tokenconvert, true },
// pegs
{ "pegs", "pegscreate", &pegscreate, true },
{ "pegs", "pegsfund", &pegsfund, true },
{ "pegs", "pegsget", &pegsget, true },
{ "pegs", "pegsredeem", &pegsredeem, true },
{ "pegs", "pegsliquidate", &pegsliquidate, true },
{ "pegs", "pegsexchange", &pegsexchange, true },
{ "pegs", "pegsaccounthistory", &pegsaccounthistory, true },
{ "pegs", "pegsaccountinfo", &pegsaccountinfo, true },
{ "pegs", "pegsworstaccounts", &pegsworstaccounts, true },
{ "pegs", "pegsinfo", &pegsinfo, true },
/* Address index */
{ "addressindex", "getaddressmempool", &getaddressmempool, true },
{ "addressindex", "getaddressutxos", &getaddressutxos, false },

View File

@@ -349,6 +349,16 @@ extern UniValue FSMcreate(const UniValue& params, bool fHelp);
extern UniValue FSMlist(const UniValue& params, bool fHelp);
extern UniValue FSMinfo(const UniValue& params, bool fHelp);
extern UniValue auctionaddress(const UniValue& params, bool fHelp);
extern UniValue pegscreate(const UniValue& params, bool fHelp);
extern UniValue pegsfund(const UniValue& params, bool fHelp);
extern UniValue pegsget(const UniValue& params, bool fHelp);
extern UniValue pegsredeem(const UniValue& params, bool fHelp);
extern UniValue pegsliquidate(const UniValue& params, bool fHelp);
extern UniValue pegsexchange(const UniValue& params, bool fHelp);
extern UniValue pegsaccounthistory(const UniValue& params, bool fHelp);
extern UniValue pegsaccountinfo(const UniValue& params, bool fHelp);
extern UniValue pegsworstaccounts(const UniValue& params, bool fHelp);
extern UniValue pegsinfo(const UniValue& params, bool fHelp);
extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
//extern UniValue getnewaddress64(const UniValue& params, bool fHelp); // in rpcwallet.cpp

View File

@@ -121,7 +121,10 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry,
const CTransaction& tx = mapTx.find(hash)->GetTx();
if (!tx.IsCoinImport()) {
for (unsigned int i = 0; i < tx.vin.size(); i++)
{
if (tx.IsPegsImport() && i==0) continue;
mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i);
}
}
BOOST_FOREACH(const JSDescription &joinsplit, tx.vjoinsplit) {
BOOST_FOREACH(const uint256 &nf, joinsplit.nullifiers) {
@@ -147,6 +150,7 @@ void CTxMemPool::addAddressIndex(const CTxMemPoolEntry &entry, const CCoinsViewC
uint256 txhash = tx.GetHash();
for (unsigned int j = 0; j < tx.vin.size(); j++) {
if (tx.IsPegsImport() && j==0) continue;
const CTxIn input = tx.vin[j];
const CTxOut &prevout = view.GetOutputFor(input);
@@ -252,6 +256,7 @@ void CTxMemPool::addSpentIndex(const CTxMemPoolEntry &entry, const CCoinsViewCac
uint256 txhash = tx.GetHash();
for (unsigned int j = 0; j < tx.vin.size(); j++) {
if (tx.IsPegsImport() && j==0) continue;
const CTxIn input = tx.vin[j];
const CTxOut &prevout = view.GetOutputFor(input);

View File

@@ -5355,6 +5355,7 @@ int32_t verus_staked(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &nBits
#include "../cc/CCHeir.h"
#include "../cc/CCMarmara.h"
#include "../cc/CCPayments.h"
#include "../cc/CCPegs.h"
int32_t ensure_CCrequirements(uint8_t evalcode)
{
@@ -7992,8 +7993,206 @@ UniValue heirlist(const UniValue& params, bool fHelp)
return (HeirList());
}
UniValue pegscreate(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); int32_t i; std::vector<uint256> txids;
uint8_t N; std::string hex; uint256 txid; int64_t amount;
if ( fHelp || params.size()<3)
throw runtime_error("pegscreate amount N bindtxid1 [bindtxid2 ...]\n");
if ( ensure_CCrequirements(EVAL_PEGS) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
amount = atof((char *)params[0].get_str().c_str()) * COIN + 0.00000000499999;
N = atoi((char *)params[1].get_str().c_str());
if ( params.size() < N+1 )
throw runtime_error("not enough parameters for N gatewaysbind\n");
for (i=0; i<N; i++)
{
txid = Parseuint256(params[i+2].get_str().c_str());
txids.push_back(txid);
}
hex = PegsCreate(0,amount,txids);
RETURN_IF_ERROR(CCerror);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt pegscreate");
return(result);
}
UniValue pegsfund(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string hex; uint256 pegstxid,tokenid; int64_t amount;
if ( fHelp || params.size()!=3)
throw runtime_error("pegsfund pegstxid tokenid amount\n");
if ( ensure_CCrequirements(EVAL_PEGS) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
pegstxid = Parseuint256(params[0].get_str().c_str());
tokenid = Parseuint256(params[1].get_str().c_str());
amount = atof((char *)params[2].get_str().c_str()) * COIN + 0.00000000499999;
hex = PegsFund(0,pegstxid,tokenid,amount);
RETURN_IF_ERROR(CCerror);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt pegsfund");
return(result);
}
UniValue pegsget(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string hex; uint256 pegstxid,tokenid; int64_t amount;
if ( fHelp || params.size()!=3)
throw runtime_error("pegsget pegstxid tokenid amount\n");
if ( ensure_CCrequirements(EVAL_PEGS) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
pegstxid = Parseuint256(params[0].get_str().c_str());
tokenid = Parseuint256(params[1].get_str().c_str());
amount = atof((char *)params[2].get_str().c_str()) * COIN + 0.00000000499999;
hex = PegsGet(0,pegstxid,tokenid,amount);
RETURN_IF_ERROR(CCerror);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt pegsget");
return(result);
}
UniValue pegsredeem(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string hex; uint256 pegstxid,tokenid; int64_t amount;
if ( fHelp || params.size()!=2)
throw runtime_error("pegsredem pegstxid tokenid\n");
if ( ensure_CCrequirements(EVAL_PEGS) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
pegstxid = Parseuint256(params[0].get_str().c_str());
tokenid = Parseuint256(params[1].get_str().c_str());
hex = PegsRedeem(0,pegstxid,tokenid);
RETURN_IF_ERROR(CCerror);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt pegsredeem");
return(result);
}
UniValue pegsliquidate(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string hex; uint256 pegstxid,tokenid,accounttxid;
if ( fHelp || params.size()!=3)
throw runtime_error("pegsliquidate pegstxid tokenid accounttxid\n");
if ( ensure_CCrequirements(EVAL_PEGS) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
pegstxid = Parseuint256(params[0].get_str().c_str());
tokenid = Parseuint256(params[1].get_str().c_str());
accounttxid = Parseuint256(params[2].get_str().c_str());
hex = PegsLiquidate(0,pegstxid,tokenid,accounttxid);
RETURN_IF_ERROR(CCerror);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt pegsliquidate");
return(result);
}
UniValue pegsexchange(const UniValue& params, bool fHelp)
{
UniValue result(UniValue::VOBJ); std::string hex; uint256 pegstxid,tokenid,accounttxid; int64_t amount;
if ( fHelp || params.size()!=3)
throw runtime_error("pegsliquidate pegstxid tokenid accounttxid\n");
if ( ensure_CCrequirements(EVAL_PEGS) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
pegstxid = Parseuint256(params[0].get_str().c_str());
tokenid = Parseuint256(params[1].get_str().c_str());
amount = atof((char *)params[2].get_str().c_str()) * COIN + 0.00000000499999;
hex = PegsExchange(0,pegstxid,tokenid,amount);
RETURN_IF_ERROR(CCerror);
if ( hex.size() > 0 )
{
result.push_back(Pair("result", "success"));
result.push_back(Pair("hex", hex));
} else ERR_RESULT("couldnt pegsliquidate");
return(result);
}
UniValue pegsaccounthistory(const UniValue& params, bool fHelp)
{
uint256 pegstxid;
if ( fHelp || params.size() != 1 )
throw runtime_error("pegsaccounthistory pegstxid\n");
if ( ensure_CCrequirements(EVAL_GATEWAYS) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
pegstxid = Parseuint256((char *)params[0].get_str().c_str());
return(PegsAccountHistory(pegstxid));
}
UniValue pegsaccountinfo(const UniValue& params, bool fHelp)
{
uint256 pegstxid;
if ( fHelp || params.size() != 1 )
throw runtime_error("pegsaccountinfo pegstxid\n");
if ( ensure_CCrequirements(EVAL_GATEWAYS) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
pegstxid = Parseuint256((char *)params[0].get_str().c_str());
return(PegsAccountInfo(pegstxid));
}
UniValue pegsworstaccounts(const UniValue& params, bool fHelp)
{
uint256 pegstxid;
if ( fHelp || params.size() != 1 )
throw runtime_error("pegsworstaccounts pegstxid\n");
if ( ensure_CCrequirements(EVAL_GATEWAYS) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
pegstxid = Parseuint256((char *)params[0].get_str().c_str());
return(PegsWorstAccounts(pegstxid));
}
UniValue pegsinfo(const UniValue& params, bool fHelp)
{
uint256 pegstxid;
if ( fHelp || params.size() != 1 )
throw runtime_error("pegsinfo pegstxid\n");
if ( ensure_CCrequirements(EVAL_GATEWAYS) < 0 )
throw runtime_error("to use CC contracts, you need to launch daemon with valid -pubkey= for an address in your wallet\n");
const CKeyStore& keystore = *pwalletMain;
LOCK2(cs_main, pwalletMain->cs_wallet);
pegstxid = Parseuint256((char *)params[0].get_str().c_str());
return(PegsInfo(pegstxid));
}
extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
extern UniValue convertpassphrase(const UniValue& params, bool fHelp);