Change behavior of ExtractDestination, Solver, and GetscriptAddress for crypto conditions
This commit is contained in:
@@ -187,13 +187,16 @@ void CCaddr3set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *
|
||||
|
||||
bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
|
||||
{
|
||||
CTxDestination address; txnouttype whichType;
|
||||
if ( ExtractDestination(scriptPubKey,address) != 0 )
|
||||
CTxDestination address;
|
||||
txnouttype whichType;
|
||||
std::vector<std::vector<unsigned char>> vvch = std::vector<std::vector<unsigned char>>();
|
||||
if (Solver(scriptPubKey, whichType, vvch) && vvch[0].size() == 20)
|
||||
{
|
||||
address = CKeyID(uint160(vvch[0]));
|
||||
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
|
||||
return(true);
|
||||
}
|
||||
fprintf(stderr,"ExtractDestination failed\n");
|
||||
fprintf(stderr,"Solver for scriptPubKey failed\n%s\n", scriptPubKey.ToString());
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -1630,7 +1630,37 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
|
||||
strcpy(voutaddr, CBitcoinAddress(voutaddress).ToString().c_str());
|
||||
strcpy(destaddr, CBitcoinAddress(destaddress).ToString().c_str());
|
||||
strcpy(cbaddr, CBitcoinAddress(cbaddress).ToString().c_str());
|
||||
if ( !strcmp(destaddr,voutaddr) && ( !strcmp(destaddr,cbaddr) || (height < 17840)) )
|
||||
if (newPOSEnforcement)
|
||||
{
|
||||
if (!strcmp(destaddr,voutaddr))
|
||||
{
|
||||
// allow delegation of stake, but require all ouputs to be
|
||||
// crypto conditions
|
||||
CStakeParams p;
|
||||
if (GetStakeParams(pblock->vtx[txn_count-1], p))
|
||||
{
|
||||
COptCCParams cpp;
|
||||
// loop through all outputs to make sure they are sent to the proper pubkey
|
||||
isPOS = true;
|
||||
for (auto vout : pblock->vtx[0].vout)
|
||||
{
|
||||
txnouttype tp;
|
||||
std::vector<std::vector<unsigned char>> vvch = std::vector<std::vector<unsigned char>>();
|
||||
// solve all outputs to check that destinations all go only to the pk
|
||||
// specified in the stake params
|
||||
if (!Solver(vout.scriptPubKey, tp, vvch) ||
|
||||
tp != TX_CRYPTOCONDITION ||
|
||||
vvch.size() < 2 ||
|
||||
p.pk != CPubKey(vvch[1]))
|
||||
{
|
||||
isPOS = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !strcmp(destaddr,voutaddr) && ( !strcmp(destaddr,cbaddr) || (height < 17840)) )
|
||||
{
|
||||
isPOS = true;
|
||||
}
|
||||
|
||||
@@ -400,7 +400,16 @@ bool ExtractDestination(const CScript& _scriptPubKey, CTxDestination& addressRet
|
||||
|
||||
else if (IsCryptoConditionsEnabled() != 0 && whichType == TX_CRYPTOCONDITION)
|
||||
{
|
||||
addressRet = CKeyID(uint160(vSolutions[0]));
|
||||
if (vSolutions.size() > 1)
|
||||
{
|
||||
CPubKey pk = CPubKey((vSolutions[1]));
|
||||
addressRet = pk;
|
||||
return pk.IsValid();
|
||||
}
|
||||
else
|
||||
{
|
||||
addressRet = CKeyID(uint160(vSolutions[0]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// Multisig txns have more than one address...
|
||||
@@ -454,7 +463,15 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto
|
||||
nRequiredRet = vSolutions.front()[0];
|
||||
for (unsigned int i = 1; i < vSolutions.size()-1; i++)
|
||||
{
|
||||
CTxDestination address = CKeyID(uint160(vSolutions[i]));
|
||||
CTxDestination address;
|
||||
if (vSolutions[i].size() == 20)
|
||||
{
|
||||
address = CKeyID(uint160(vSolutions[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
address = CPubKey(vSolutions[i]);
|
||||
}
|
||||
addressRet.push_back(address);
|
||||
}
|
||||
|
||||
|
||||
@@ -2085,6 +2085,17 @@ isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum)
|
||||
case TX_NULL_DATA:
|
||||
break;
|
||||
|
||||
case TX_CRYPTOCONDITION:
|
||||
// for now, default is that the first value returned will be the script, subsequent values will be
|
||||
// pubkeys. if we have the first pub key in our wallet, we consider this spendable
|
||||
if (vSolutions.size() > 1)
|
||||
{
|
||||
keyID = CPubKey(vSolutions[1]).GetID();
|
||||
if (this->HaveKey(keyID))
|
||||
return ISMINE_SPENDABLE;
|
||||
}
|
||||
break;
|
||||
|
||||
case TX_PUBKEY:
|
||||
keyID = CPubKey(vSolutions[0]).GetID();
|
||||
if (this->HaveKey(keyID))
|
||||
|
||||
@@ -62,6 +62,16 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& _scriptPubKey)
|
||||
case TX_NONSTANDARD:
|
||||
case TX_NULL_DATA:
|
||||
break;
|
||||
case TX_CRYPTOCONDITION:
|
||||
// for now, default is that the first value returned will be the script, subsequent values will be
|
||||
// pubkeys. if we have the first pub key in our wallet, we consider this spendable
|
||||
if (vSolutions.size() > 1)
|
||||
{
|
||||
keyID = CPubKey(vSolutions[1]).GetID();
|
||||
if (keystore.HaveKey(keyID))
|
||||
return ISMINE_SPENDABLE;
|
||||
}
|
||||
break;
|
||||
case TX_PUBKEY:
|
||||
keyID = CPubKey(vSolutions[0]).GetID();
|
||||
if (keystore.HaveKey(keyID))
|
||||
@@ -83,31 +93,6 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& _scriptPubKey)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TX_CRYPTOCONDITION:
|
||||
{
|
||||
// some crypto conditions we consider "mine" if our address is the first specified
|
||||
// extra address
|
||||
CScript subScript;
|
||||
vector<valtype> vParams;
|
||||
COptCCParams p;
|
||||
if (scriptPubKey.IsPayToCryptoCondition(&subScript, vParams))
|
||||
{
|
||||
if (vParams.size() > 1)
|
||||
{
|
||||
p = COptCCParams(vParams[0]);
|
||||
// if we are the primary output on a coinbase guard, it is ours
|
||||
if (p.IsValid() && p.evalCode == EVAL_COINBASEGUARD && vParams[1].size() == 20)
|
||||
{
|
||||
CKeyID adr = CKeyID(uint160(vParams[1]));
|
||||
if (keystore.HaveKey(keyID))
|
||||
return ISMINE_SPENDABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TX_MULTISIG:
|
||||
{
|
||||
// Only consider transactions "mine" if we own ALL the
|
||||
|
||||
Reference in New Issue
Block a user