Complete nothing at stake solution, waiting for confirm of masks
This commit is contained in:
@@ -232,7 +232,7 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
|
|||||||
strcpy(cp->normaladdr,AssetsNormaladdr);
|
strcpy(cp->normaladdr,AssetsNormaladdr);
|
||||||
strcpy(cp->CChexstr,AssetsCChexstr);
|
strcpy(cp->CChexstr,AssetsCChexstr);
|
||||||
memcpy(cp->CCpriv,AssetsCCpriv,32);
|
memcpy(cp->CCpriv,AssetsCCpriv,32);
|
||||||
cp->validate = AssetsValidate;
|
cp->validate = CoinbaseGuardValidate;
|
||||||
cp->ismyvin = IsAssetsInput;
|
cp->ismyvin = IsAssetsInput;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey)
|
|||||||
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
|
strcpy(destaddr,(char *)CBitcoinAddress(address).ToString().c_str());
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
fprintf(stderr,"Solver for scriptPubKey failed\n%s\n", scriptPubKey.ToString());
|
fprintf(stderr,"Solver for scriptPubKey failed\n%s\n", scriptPubKey.ToString().c_str());
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ bool GetCCParams(Eval* eval, const CTransaction &tx, uint32_t nIn,
|
|||||||
uint256 blockHash;
|
uint256 blockHash;
|
||||||
bool isValid = false;
|
bool isValid = false;
|
||||||
|
|
||||||
if (myGetTransaction(tx.vin[nIn].prevout.hash, txOut, blockHash))
|
if (myGetTransaction(tx.vin[nIn].prevout.hash, txOut, blockHash) && txOut.vout.size() > nIn)
|
||||||
{
|
{
|
||||||
CBlockIndex index;
|
CBlockIndex index;
|
||||||
if (eval->GetBlock(blockHash, index))
|
if (eval->GetBlock(blockHash, index))
|
||||||
@@ -218,7 +218,10 @@ bool GetCCParams(Eval* eval, const CTransaction &tx, uint32_t nIn,
|
|||||||
{
|
{
|
||||||
// read any available parameters in the output transaction
|
// read any available parameters in the output transaction
|
||||||
params.clear();
|
params.clear();
|
||||||
tx.vout[tx.vout.size() - 1].scriptPubKey.GetOpretData(params);
|
if (tx.vout.size() > 0 && tx.vout[tx.vout.size() - 1].scriptPubKey.IsOpReturn())
|
||||||
|
{
|
||||||
|
tx.vout[tx.vout.size() - 1].scriptPubKey.GetOpretData(params);
|
||||||
|
}
|
||||||
isValid = true;
|
isValid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -388,8 +391,8 @@ bool ProcessCC(struct CCcontract_info *cp,Eval* eval, std::vector<uint8_t> param
|
|||||||
cp->unspendableaddr2[0] = cp->unspendableaddr3[0] = 0;
|
cp->unspendableaddr2[0] = cp->unspendableaddr3[0] = 0;
|
||||||
if ( paramsNull.size() != 0 ) // Don't expect params
|
if ( paramsNull.size() != 0 ) // Don't expect params
|
||||||
return eval->Invalid("Cannot have params");
|
return eval->Invalid("Cannot have params");
|
||||||
else if ( ctx.vout.size() == 0 )
|
//else if ( ctx.vout.size() == 0 ) // spend can go to z-addresses
|
||||||
return eval->Invalid("no-vouts");
|
// return eval->Invalid("no-vouts");
|
||||||
else if ( (*cp->validate)(cp,eval,ctx,nIn) != 0 )
|
else if ( (*cp->validate)(cp,eval,ctx,nIn) != 0 )
|
||||||
{
|
{
|
||||||
//fprintf(stderr,"done CC %02x\n",cp->evalcode);
|
//fprintf(stderr,"done CC %02x\n",cp->evalcode);
|
||||||
|
|||||||
@@ -168,8 +168,7 @@ bool ValidateStakeTransaction(const CTransaction &stakeTx, CStakeParams &stakePa
|
|||||||
if (!validateSig || VerifyScript(stakeTx.vin[0].scriptSig,
|
if (!validateSig || VerifyScript(stakeTx.vin[0].scriptSig,
|
||||||
srcTx.vout[stakeTx.vin[0].prevout.n].scriptPubKey,
|
srcTx.vout[stakeTx.vin[0].prevout.n].scriptPubKey,
|
||||||
MANDATORY_SCRIPT_VERIFY_FLAGS,
|
MANDATORY_SCRIPT_VERIFY_FLAGS,
|
||||||
TransactionSignatureChecker(&stakeTx, 0, srcTx.vout[stakeTx.vin[0].prevout.n].nValue,
|
ServerTransactionSignatureChecker(&stakeTx, (uint32_t)0, srcTx.vout[stakeTx.vin[0].prevout.n].nValue, false),
|
||||||
PrecomputedTransactionData(stakeTx)),
|
|
||||||
consensusBranchId))
|
consensusBranchId))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -305,6 +304,34 @@ bool MakeCheatEvidence(CMutableTransaction &mtx, const CTransaction &ccTx, uint3
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct ccFulfillmentCheck {
|
||||||
|
int32_t childCount;
|
||||||
|
uint64_t fulfillmentMask;
|
||||||
|
} ccFulfillmentCheck;
|
||||||
|
|
||||||
|
int IsCCFulfilled(CC *cc, ccFulfillmentCheck *ctx);
|
||||||
|
|
||||||
|
// to figure out which node is signed
|
||||||
|
int CCFulfillmentVisitor(CC *cc, struct CCVisitor visitor)
|
||||||
|
{
|
||||||
|
ccFulfillmentCheck *pfc = (ccFulfillmentCheck *)(visitor.context);
|
||||||
|
int fulfilled = cc_isFulfilled(cc);
|
||||||
|
pfc->fulfillmentMask |= (fulfilled == 0) ? 0 : ((uint64_t)1) << (uint64_t)pfc->childCount;
|
||||||
|
printf("fullfilled: %x, pfc->fulfillmentMask: %x, pfc->childCount: %d\n", fulfilled, pfc->fulfillmentMask, pfc->childCount);
|
||||||
|
pfc->childCount++;
|
||||||
|
return fulfilled;
|
||||||
|
}
|
||||||
|
|
||||||
|
int IsCCFulfilled(CC *cc, ccFulfillmentCheck *ctx)
|
||||||
|
{
|
||||||
|
int fulfilled = cc_isFulfilled(cc);
|
||||||
|
// printf("Root IsFulfilled: %x\n", fulfilled);
|
||||||
|
|
||||||
|
struct CCVisitor visitor = {&CCFulfillmentVisitor, NULL, 0, (void *)ctx};
|
||||||
|
cc_visit(cc, visitor);
|
||||||
|
return fulfilled;
|
||||||
|
}
|
||||||
|
|
||||||
bool CoinbaseGuardValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint32_t nIn)
|
bool CoinbaseGuardValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint32_t nIn)
|
||||||
{
|
{
|
||||||
// This also supports a variable blockstomaturity option for backward feature compatibility
|
// This also supports a variable blockstomaturity option for backward feature compatibility
|
||||||
@@ -321,15 +348,19 @@ bool CoinbaseGuardValidate(struct CCcontract_info *cp, Eval* eval, const CTransa
|
|||||||
std::vector<std::vector<unsigned char>> params = std::vector<std::vector<unsigned char>>();
|
std::vector<std::vector<unsigned char>> params = std::vector<std::vector<unsigned char>>();
|
||||||
CTransaction txOut;
|
CTransaction txOut;
|
||||||
|
|
||||||
CC *cc = GetCryptoCondition(tx.vin[nIn].scriptSig);
|
bool signedByFirstKey = false;
|
||||||
|
|
||||||
// this should reflect the truth of whether the first key did sign the fulfillment
|
|
||||||
bool signedByFirstKey = true;
|
|
||||||
bool validCheat = false;
|
bool validCheat = false;
|
||||||
|
|
||||||
|
CC *cc = GetCryptoCondition(tx.vin[nIn].scriptSig);
|
||||||
|
|
||||||
if (cc)
|
if (cc)
|
||||||
{
|
{
|
||||||
printf("CryptoCondition code %x\n", *cc->code);
|
ccFulfillmentCheck fc = {0, 0};
|
||||||
|
IsCCFulfilled(cc, &fc);
|
||||||
|
|
||||||
|
// this should reflect the truth of whether the first key did sign the fulfillment
|
||||||
|
signedByFirstKey = ((fc.fulfillmentMask & (uint64_t)4) != 0);
|
||||||
|
validCheat = false;
|
||||||
|
|
||||||
// tx is the spending tx, the cc transaction comes back in txOut
|
// tx is the spending tx, the cc transaction comes back in txOut
|
||||||
if (GetCCParams(eval, tx, nIn, txOut, preConditions, params))
|
if (GetCCParams(eval, tx, nIn, txOut, preConditions, params))
|
||||||
|
|||||||
@@ -266,12 +266,11 @@ void *chainparams_commandline(void *ptr)
|
|||||||
mainParams.consensus.nLwmaPOSAjustedWeight = 46531;
|
mainParams.consensus.nLwmaPOSAjustedWeight = 46531;
|
||||||
}
|
}
|
||||||
|
|
||||||
mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = ASSETCHAINS_SAPLING;
|
|
||||||
mainParams.consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = ASSETCHAINS_OVERWINTER;
|
|
||||||
|
|
||||||
// only require coinbase protection on Verus from the Komodo family of coins
|
// only require coinbase protection on Verus from the Komodo family of coins
|
||||||
if (strcmp(ASSETCHAINS_SYMBOL,"VRSC") == 0)
|
if (strcmp(ASSETCHAINS_SYMBOL,"VRSC") == 0)
|
||||||
{
|
{
|
||||||
|
mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = 227520;
|
||||||
|
mainParams.consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = 227520 - 120;
|
||||||
mainParams.consensus.fCoinbaseMustBeProtected = true;
|
mainParams.consensus.fCoinbaseMustBeProtected = true;
|
||||||
checkpointData = //(Checkpoints::CCheckpointData)
|
checkpointData = //(Checkpoints::CCheckpointData)
|
||||||
{
|
{
|
||||||
@@ -291,6 +290,8 @@ void *chainparams_commandline(void *ptr)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
mainParams.consensus.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight = ASSETCHAINS_SAPLING;
|
||||||
|
mainParams.consensus.vUpgrades[Consensus::UPGRADE_OVERWINTER].nActivationHeight = ASSETCHAINS_OVERWINTER;
|
||||||
checkpointData = //(Checkpoints::CCheckpointData)
|
checkpointData = //(Checkpoints::CCheckpointData)
|
||||||
{
|
{
|
||||||
boost::assign::map_list_of
|
boost::assign::map_list_of
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ include_HEADERS = include/cryptoconditions.h
|
|||||||
libcryptoconditions_la_SOURCES = include/cryptoconditions.h
|
libcryptoconditions_la_SOURCES = include/cryptoconditions.h
|
||||||
libcryptoconditions_la_LIBADD = $(CRYPTOCONDITIONS_CORE) $(LIBSECP256K1)
|
libcryptoconditions_la_LIBADD = $(CRYPTOCONDITIONS_CORE) $(LIBSECP256K1)
|
||||||
|
|
||||||
AM_CFLAGS = -I$(top_srcdir)/src/asn -I$(top_srcdir)/include -I$(top_srcdir)/src/include \
|
AM_CFLAGS = -I$(top_srcdir)/src/asn -I./cryptoconditions/src/asn -I$(top_srcdir)/include -I$(top_srcdir)/src/include \
|
||||||
-Wall -Wno-pointer-sign -Wno-discarded-qualifiers
|
-Wall -Wno-pointer-sign -Wno-discarded-qualifiers
|
||||||
|
|
||||||
LIBSECP256K1=src/include/secp256k1/libsecp256k1.la
|
LIBSECP256K1=src/include/secp256k1/libsecp256k1.la
|
||||||
|
|||||||
@@ -56,8 +56,6 @@ typedef struct CC {
|
|||||||
};
|
};
|
||||||
} CC;
|
} CC;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Crypto Condition Visitor
|
* Crypto Condition Visitor
|
||||||
*/
|
*/
|
||||||
@@ -87,6 +85,7 @@ struct CC* cc_conditionFromJSON(cJSON *params, char *err);
|
|||||||
struct CC* cc_conditionFromJSONString(const char *json, char *err);
|
struct CC* cc_conditionFromJSONString(const char *json, char *err);
|
||||||
struct CC* cc_readConditionBinary(const uint8_t *cond_bin, size_t cond_bin_len);
|
struct CC* cc_readConditionBinary(const uint8_t *cond_bin, size_t cond_bin_len);
|
||||||
struct CC* cc_readFulfillmentBinary(const uint8_t *ffill_bin, size_t ffill_bin_len);
|
struct CC* cc_readFulfillmentBinary(const uint8_t *ffill_bin, size_t ffill_bin_len);
|
||||||
|
int cc_readFulfillmentBinaryExt(const unsigned char *ffill_bin, size_t ffill_bin_len, CC **ppcc);
|
||||||
struct CC* cc_new(int typeId);
|
struct CC* cc_new(int typeId);
|
||||||
struct cJSON* cc_conditionToJSON(const CC *cond);
|
struct cJSON* cc_conditionToJSON(const CC *cond);
|
||||||
char* cc_conditionToJSONString(const CC *cond);
|
char* cc_conditionToJSONString(const CC *cond);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ static void anonToJSON(const CC *cond, cJSON *params) {
|
|||||||
|
|
||||||
static unsigned char *anonFingerprint(const CC *cond) {
|
static unsigned char *anonFingerprint(const CC *cond) {
|
||||||
unsigned char *out = calloc(1, 32);
|
unsigned char *out = calloc(1, 32);
|
||||||
fprintf(stderr,"anon fingerprint %p %p\n",out,cond->fingerprint);
|
//fprintf(stderr,"anon fingerprint %p %p\n",out,cond->fingerprint);
|
||||||
memcpy(out, cond->fingerprint, 32);
|
memcpy(out, cond->fingerprint, 32);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#ifndef ASN1_CONSTRAINTS_VALIDATOR_H
|
#ifndef ASN1_CONSTRAINTS_VALIDATOR_H
|
||||||
#define ASN1_CONSTRAINTS_VALIDATOR_H
|
#define ASN1_CONSTRAINTS_VALIDATOR_H
|
||||||
|
|
||||||
#include <asn_system.h> /* Platform-dependent types */
|
#include "asn_system.h" /* Platform-dependent types */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#ifndef _PER_SUPPORT_H_
|
#ifndef _PER_SUPPORT_H_
|
||||||
#define _PER_SUPPORT_H_
|
#define _PER_SUPPORT_H_
|
||||||
|
|
||||||
#include <asn_system.h> /* Platform-specific types */
|
#include "asn_system.h" /* Platform-specific types */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@@ -216,6 +216,35 @@ end:
|
|||||||
return cond;
|
return cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cc_readFulfillmentBinaryExt(const unsigned char *ffill_bin, size_t ffill_bin_len, CC **ppcc) {
|
||||||
|
|
||||||
|
int error = 0;
|
||||||
|
unsigned char *buf = calloc(1,ffill_bin_len);
|
||||||
|
Fulfillment_t *ffill = 0;
|
||||||
|
asn_dec_rval_t rval = ber_decode(0, &asn_DEF_Fulfillment, (void **)&ffill, ffill_bin, ffill_bin_len);
|
||||||
|
if (rval.code != RC_OK) {
|
||||||
|
error = rval.code;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
// Do malleability check
|
||||||
|
asn_enc_rval_t rc = der_encode_to_buffer(&asn_DEF_Fulfillment, ffill, buf, ffill_bin_len);
|
||||||
|
if (rc.encoded == -1) {
|
||||||
|
fprintf(stderr, "FULFILLMENT NOT ENCODED\n");
|
||||||
|
error = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (rc.encoded != ffill_bin_len || 0 != memcmp(ffill_bin, buf, rc.encoded)) {
|
||||||
|
error = (rc.encoded == ffill_bin_len) ? -3 : -2;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppcc = fulfillmentToCC(ffill);
|
||||||
|
end:
|
||||||
|
free(buf);
|
||||||
|
if (ffill) ASN_STRUCT_FREE(asn_DEF_Fulfillment, ffill);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int cc_visit(CC *cond, CCVisitor visitor) {
|
int cc_visit(CC *cond, CCVisitor visitor) {
|
||||||
int out = visitor.visit(cond, visitor);
|
int out = visitor.visit(cond, visitor);
|
||||||
@@ -225,7 +254,6 @@ int cc_visit(CC *cond, CCVisitor visitor) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int cc_verify(const struct CC *cond, const unsigned char *msg, size_t msgLength, int doHashMsg,
|
int cc_verify(const struct CC *cond, const unsigned char *msg, size_t msgLength, int doHashMsg,
|
||||||
const unsigned char *condBin, size_t condBinLength,
|
const unsigned char *condBin, size_t condBinLength,
|
||||||
VerifyEval verifyEval, void *evalContext) {
|
VerifyEval verifyEval, void *evalContext) {
|
||||||
|
|||||||
@@ -1502,9 +1502,12 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
|
|||||||
{
|
{
|
||||||
if (pblock->GetRawVerusPOSHash(rawHash, height))
|
if (pblock->GetRawVerusPOSHash(rawHash, height))
|
||||||
{
|
{
|
||||||
posHash = UintToArith256(rawHash) / value;
|
if (posHash > target)
|
||||||
printf("PoS block\nblkHash: %s\nnNonce: %s\nrawHash: %s\nposHash: %s\nvalue: %lu\n",
|
{
|
||||||
pblock->GetHash().GetHex().c_str(), pblock->nNonce.GetHex().c_str(), rawHash.GetHex().c_str(), posHash.GetHex().c_str(), value);
|
posHash = UintToArith256(rawHash) / value;
|
||||||
|
printf("PoS block\nblkHash: %s\nnNonce: %s\nrawHash: %s\nposHash: %s\nvalue: %lu\n",
|
||||||
|
pblock->GetHash().GetHex().c_str(), pblock->nNonce.GetHex().c_str(), rawHash.GetHex().c_str(), posHash.GetHex().c_str(), value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1765,8 +1765,15 @@ void komodo_args(char *argv0)
|
|||||||
if ( (ASSETCHAINS_LWMAPOS = GetArg("-ac_veruspos",0)) != 0 )
|
if ( (ASSETCHAINS_LWMAPOS = GetArg("-ac_veruspos",0)) != 0 )
|
||||||
ASSETCHAINS_LWMAPOS = 50;
|
ASSETCHAINS_LWMAPOS = 50;
|
||||||
|
|
||||||
ASSETCHAINS_SAPLING = GetArg("-ac_sapling", 227520);
|
ASSETCHAINS_SAPLING = GetArg("-ac_sapling", -1);
|
||||||
ASSETCHAINS_OVERWINTER = GetArg("-ac_overwinter", (ASSETCHAINS_SAPLING - 120) > 1 ? (ASSETCHAINS_SAPLING - 120) : 1);
|
if (ASSETCHAINS_SAPLING == -1)
|
||||||
|
{
|
||||||
|
ASSETCHAINS_OVERWINTER = GetArg("-ac_overwinter", -1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSETCHAINS_OVERWINTER = GetArg("-ac_overwinter", (ASSETCHAINS_SAPLING - 120) > 1 ? (ASSETCHAINS_SAPLING - 120) : 1);
|
||||||
|
}
|
||||||
|
|
||||||
if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 && ASSETCHAINS_COMMISSION > 0 && ASSETCHAINS_COMMISSION <= 100000000 )
|
if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 && ASSETCHAINS_COMMISSION > 0 && ASSETCHAINS_COMMISSION <= 100000000 )
|
||||||
decode_hex(ASSETCHAINS_OVERRIDE_PUBKEY33,33,(char *)ASSETCHAINS_OVERRIDE_PUBKEY.c_str());
|
decode_hex(ASSETCHAINS_OVERRIDE_PUBKEY33,33,(char *)ASSETCHAINS_OVERRIDE_PUBKEY.c_str());
|
||||||
|
|||||||
@@ -1354,8 +1354,9 @@ int TransactionSignatureChecker::CheckCryptoCondition(
|
|||||||
if (ffillBin.empty())
|
if (ffillBin.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CC *cond = cc_readFulfillmentBinary((unsigned char*)ffillBin.data(), ffillBin.size()-1);
|
CC *cond;
|
||||||
if (!cond) return -1;
|
int error = cc_readFulfillmentBinaryExt((unsigned char*)ffillBin.data(), ffillBin.size()-1, &cond);
|
||||||
|
if (error || !cond) return -1;
|
||||||
|
|
||||||
if (!IsSupportedCryptoCondition(cond)) return 0;
|
if (!IsSupportedCryptoCondition(cond)) return 0;
|
||||||
if (!IsSignedCryptoCondition(cond)) return 0;
|
if (!IsSignedCryptoCondition(cond)) return 0;
|
||||||
@@ -1363,7 +1364,7 @@ int TransactionSignatureChecker::CheckCryptoCondition(
|
|||||||
uint256 sighash;
|
uint256 sighash;
|
||||||
int nHashType = ffillBin.back();
|
int nHashType = ffillBin.back();
|
||||||
try {
|
try {
|
||||||
sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId, this->txdata);
|
sighash = SignatureHash(CCPubKey(cond), *txTo, nIn, nHashType, amount, consensusBranchId, this->txdata);
|
||||||
} catch (logic_error ex) {
|
} catch (logic_error ex) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1391,8 +1392,8 @@ int TransactionSignatureChecker::CheckCryptoCondition(
|
|||||||
|
|
||||||
int TransactionSignatureChecker::CheckEvalCondition(const CC *cond) const
|
int TransactionSignatureChecker::CheckEvalCondition(const CC *cond) const
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Cannot check crypto-condition Eval outside of server\n");
|
//fprintf(stderr, "Cannot check crypto-condition Eval outside of server, returning true in pre-checks\n");
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -301,7 +301,7 @@ bool CScript::GetOpretData(std::vector<std::vector<unsigned char>>& vData) const
|
|||||||
{
|
{
|
||||||
vector<unsigned char> data;
|
vector<unsigned char> data;
|
||||||
opcodetype opcode;
|
opcodetype opcode;
|
||||||
const_iterator pc = begin();
|
CScript::const_iterator pc = this->begin();
|
||||||
std::vector<unsigned char> vch1 = std::vector<unsigned char>(1);
|
std::vector<unsigned char> vch1 = std::vector<unsigned char>(1);
|
||||||
|
|
||||||
vData.clear();
|
vData.clear();
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ private:
|
|||||||
bool store;
|
bool store;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ServerTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nIn, const CAmount& amount, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nIn, amount, txdataIn), store(storeIn) {}
|
ServerTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nIn, const CAmount& amount, bool storeIn, const PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nIn, amount, txdataIn), store(storeIn) {}
|
||||||
|
ServerTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nIn, const CAmount& amount, bool storeIn) : TransactionSignatureChecker(txToIn, nIn, amount), store(storeIn) {}
|
||||||
|
|
||||||
bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
|
bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
|
||||||
int CheckEvalCondition(const CC *cond) const;
|
int CheckEvalCondition(const CC *cond) const;
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
|
|||||||
if (!cc || cc_signTreeSecp256k1Msg32(cc, key.begin(), hash.begin()) == 0)
|
if (!cc || cc_signTreeSecp256k1Msg32(cc, key.begin(), hash.begin()) == 0)
|
||||||
return false;
|
return false;
|
||||||
vchSig = CCSigVec(cc);
|
vchSig = CCSigVec(cc);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -95,20 +96,81 @@ CC *CCcond1(uint8_t evalcode,CPubKey pk)
|
|||||||
return CCNewThreshold(2, {condCC, Sig});
|
return CCNewThreshold(2, {condCC, Sig});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<CCcontract_info> &GetCryptoConditions()
|
||||||
|
{
|
||||||
|
static bool initialized = false;
|
||||||
|
static std::vector<CCcontract_info> vCC = std::vector<CCcontract_info>();
|
||||||
|
CCcontract_info C;
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
C.evalcode = EVAL_COINBASEGUARD;
|
||||||
|
uint8_t privKey[32] = { 0x9b, 0x17, 0x66, 0xe5, 0x82, 0x66, 0xac, 0xb6, 0xba, 0x43, 0x83, 0x74, 0xf7, 0x63, 0x11, 0x3b, 0xf0, 0xf3, 0x50, 0x6f, 0xd9, 0x6b, 0x67, 0x85, 0xf9, 0x7a, 0xf0, 0x54, 0x4d, 0xb1, 0x30, 0x77 };
|
||||||
|
strcpy(C.unspendableCCaddr,"RGKRjeTBw4LYFotSDLT6RWzMHbhXri6BG6");
|
||||||
|
strcpy(C.normaladdr,"RFYE2yL3KknWdHK6uNhvWacYsCUtwzjY3u");
|
||||||
|
strcpy(C.CChexstr,"02adf84e0e075cf90868bd4e3d34a03420e034719649c41f371fc70d8e33aa2702");
|
||||||
|
memcpy(C.CCpriv, privKey, 32);
|
||||||
|
vCC.push_back(C);
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
return vCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetCCByUnspendableAddress(struct CCcontract_info *cp, char *addrstr)
|
||||||
|
{
|
||||||
|
std::vector<CCcontract_info> &vCC = GetCryptoConditions();
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < vCC.size(); i++)
|
||||||
|
{
|
||||||
|
if (strcmp(addrstr, vCC[i].unspendableCCaddr) == 0)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
*cp = vCC[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
bool CCinitLite(struct CCcontract_info *cp, uint8_t evalcode)
|
bool CCinitLite(struct CCcontract_info *cp, uint8_t evalcode)
|
||||||
{
|
{
|
||||||
cp->evalcode = evalcode;
|
std::vector<CCcontract_info> &vCC = GetCryptoConditions();
|
||||||
switch ( evalcode )
|
bool found = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < vCC.size(); i++)
|
||||||
{
|
{
|
||||||
case EVAL_COINBASEGUARD:
|
if (vCC[i].evalcode == evalcode)
|
||||||
uint8_t privKey[32] = { 0x9b, 0x17, 0x66, 0xe5, 0x82, 0x66, 0xac, 0xb6, 0xba, 0x43, 0x83, 0x74, 0xf7, 0x63, 0x11, 0x3b, 0xf0, 0xf3, 0x50, 0x6f, 0xd9, 0x6b, 0x67, 0x85, 0xf9, 0x7a, 0xf0, 0x54, 0x4d, 0xb1, 0x30, 0x77 };
|
{
|
||||||
strcpy(cp->unspendableCCaddr,"RGKRjeTBw4LYFotSDLT6RWzMHbhXri6BG6");
|
found = true;
|
||||||
strcpy(cp->normaladdr,"RFYE2yL3KknWdHK6uNhvWacYsCUtwzjY3u");
|
*cp = vCC[i];
|
||||||
strcpy(cp->CChexstr,"02adf84e0e075cf90868bd4e3d34a03420e034719649c41f371fc70d8e33aa2702");
|
break;
|
||||||
memcpy(cp->CCpriv, privKey,32);
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _Getscriptaddress(char *destaddr, const CScript &scriptPubKey)
|
||||||
|
{
|
||||||
|
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,"Solver for scriptPubKey failed\n%s\n", scriptPubKey.ToString().c_str());
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CScript _CCPubKey(const CC *cond)
|
||||||
|
{
|
||||||
|
unsigned char buf[1000];
|
||||||
|
size_t len = cc_conditionBinary(cond, buf);
|
||||||
|
return CScript() << std::vector<unsigned char>(buf, buf+len) << OP_CHECKCRYPTOCONDITION;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scriptPubKey, vector<valtype> &vSolutions,
|
static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scriptPubKey, vector<valtype> &vSolutions,
|
||||||
@@ -116,150 +178,101 @@ static bool SignStepCC(const BaseSignatureCreator& creator, const CScript& scrip
|
|||||||
{
|
{
|
||||||
CScript subScript;
|
CScript subScript;
|
||||||
vector<CPubKey> vPK;
|
vector<CPubKey> vPK;
|
||||||
vector<CKeyID> vKeyID = vector<CKeyID>();
|
|
||||||
vector<valtype> vParams = vector<valtype>();
|
vector<valtype> vParams = vector<valtype>();
|
||||||
COptCCParams p;
|
COptCCParams p;
|
||||||
|
|
||||||
|
// get information to sign with
|
||||||
|
CCcontract_info C;
|
||||||
|
|
||||||
scriptPubKey.IsPayToCryptoCondition(&subScript, vParams);
|
scriptPubKey.IsPayToCryptoCondition(&subScript, vParams);
|
||||||
if (vParams.size() > 1 && (p = COptCCParams(vParams[0])).IsValid())
|
if (vParams.empty())
|
||||||
|
{
|
||||||
|
// get the keyID address of the cc and if it is an unspendable cc address, use its pubkey
|
||||||
|
// we have nothing else
|
||||||
|
char addr[64];
|
||||||
|
if (_Getscriptaddress(addr, subScript) && GetCCByUnspendableAddress(&C, addr))
|
||||||
|
{
|
||||||
|
vPK.push_back(CPubKey(ParseHex(C.CChexstr)));
|
||||||
|
p = COptCCParams(p.VERSION, C.evalcode, 1, 1, vPK, vParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = COptCCParams(vParams[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.IsValid() && p.vKeys.size() >= p.n)
|
||||||
{
|
{
|
||||||
bool is1of2 = (p.m == 1 && p.n == 2);
|
bool is1of2 = (p.m == 1 && p.n == 2);
|
||||||
uint32_t extraAddrs = p.n;
|
|
||||||
CKey privKey;
|
CKey privKey;
|
||||||
|
|
||||||
// get information to sign with
|
|
||||||
CCcontract_info C;
|
|
||||||
|
|
||||||
// must be a valid cc eval code
|
// must be a valid cc eval code
|
||||||
if (CCinitLite(&C, p.evalCode))
|
if (CCinitLite(&C, p.evalCode))
|
||||||
{
|
{
|
||||||
// pay to cc address is a valid tx
|
// pay to cc address is a valid tx
|
||||||
if (!is1of2)
|
if (!is1of2)
|
||||||
{
|
{
|
||||||
try
|
bool havePriv = creator.KeyStore().GetKey(p.vKeys[0].GetID(), privKey);
|
||||||
|
|
||||||
|
// if we don't have the private key, it must be the unspendable address
|
||||||
|
if (!havePriv && (p.vKeys[0] == CPubKey(ParseHex(C.CChexstr))))
|
||||||
{
|
{
|
||||||
if (!extraAddrs)
|
privKey = CKey();
|
||||||
{
|
CPrivKey vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv));
|
||||||
vKeyID.push_back(CKeyID(uint160(vSolutions[0])));
|
privKey.SetPrivKey(vch, false);
|
||||||
// if this isn't our main CC address, we can't do anything with it
|
|
||||||
if (strcmp(C.unspendableCCaddr, CBitcoinAddress(CTxDestination(vKeyID[0])).ToString().c_str()) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// otherwise, push back the corresponding pub key
|
|
||||||
vPK.push_back(CPubKey(ParseHex(C.CChexstr)));
|
|
||||||
}
|
|
||||||
else if (vParams.size() > extraAddrs)
|
|
||||||
{
|
|
||||||
bool havePriv;
|
|
||||||
vKeyID.push_back(CKeyID(uint160(vParams[1])));
|
|
||||||
// if this isn't the normal CC address and we also don't have it in our keystore, fail
|
|
||||||
CBitcoinAddress addr = CBitcoinAddress(CTxDestination(vKeyID[0]));
|
|
||||||
if (strcmp(C.normaladdr, addr.ToString().c_str()) == 0 &&
|
|
||||||
!(havePriv = creator.KeyStore().GetKey(vKeyID[0], privKey)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
vPK.push_back(CPubKey());
|
|
||||||
|
|
||||||
// if we don't have the private key, it is the unspendable address
|
|
||||||
if (!havePriv)
|
|
||||||
{
|
|
||||||
vPK[0] = CPubKey(ParseHex(C.CChexstr));
|
|
||||||
privKey = CKey();
|
|
||||||
CPrivKey vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv));
|
|
||||||
privKey.SetPrivKey(vch, false);
|
|
||||||
}
|
|
||||||
else if (!creator.KeyStore().GetPubKey(vKeyID[0], vPK[0]))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (...)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"exception calculating 1of1 spend\n");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
else return false;
|
||||||
|
|
||||||
CC *cc = CCcond1(p.evalCode, vPK[0]);
|
CC *cc = CCcond1(p.evalCode, p.vKeys[0]);
|
||||||
|
|
||||||
if (cc)
|
if (cc)
|
||||||
{
|
{
|
||||||
vector<unsigned char> vch;
|
vector<unsigned char> vch;
|
||||||
if (creator.CreateSig(vch, vKeyID[0], scriptPubKey, consensusBranchId, &privKey, (void *)cc))
|
if (creator.CreateSig(vch, p.vKeys[0].GetID(), _CCPubKey(cc), consensusBranchId, &privKey, (void *)cc))
|
||||||
{
|
{
|
||||||
ret.push_back(vch);
|
ret.push_back(vch);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr,"vin has 1of1 CC signing error with address.(%s)\n", vKeyID[0].ToString().c_str());
|
fprintf(stderr,"vin has 1of1 CC signing error with address.(%s)\n", p.vKeys[0].GetID().ToString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_free(cc);
|
cc_free(cc);
|
||||||
return ret.size() != 0;
|
return ret.size() != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (extraAddrs > 1 && vParams.size() > extraAddrs)
|
else
|
||||||
{
|
{
|
||||||
// we need to get 2 addresses, and we will need the private key for one
|
// first of priv key in our key store or contract address is what we sign with
|
||||||
// to spend
|
for (auto pk : p.vKeys)
|
||||||
bool pkValid = false;
|
|
||||||
for (int i = 0; i < extraAddrs; i++)
|
|
||||||
{
|
{
|
||||||
// loop through in order and choose the first key we have a priv key to for signing
|
if (creator.KeyStore().GetKey(p.vKeys[0].GetID(), privKey) && privKey.IsValid())
|
||||||
try
|
break;
|
||||||
|
|
||||||
|
if (p.vKeys[0] == CPubKey(ParseHex(C.CChexstr)))
|
||||||
{
|
{
|
||||||
bool isCCAddr = false;
|
privKey = CKey();
|
||||||
CPubKey pk;
|
CPrivKey vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv));
|
||||||
vKeyID.push_back(CKeyID(uint160(vParams[i + 1])));
|
privKey.SetPrivKey(vch, false);
|
||||||
|
break;
|
||||||
// if this isn't the CC address and we also don't have the pubkey in our keystore, fail, because we won't
|
|
||||||
// be able to make the condition to fulfill
|
|
||||||
if (!(isCCAddr = (strcmp(C.normaladdr, CBitcoinAddress(CTxDestination(vKeyID[0])).ToString().c_str()) == 0)) &&
|
|
||||||
!creator.KeyStore().GetPubKey(vKeyID[0], pk))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (isCCAddr)
|
|
||||||
{
|
|
||||||
pk = CPubKey(ParseHex(C.CChexstr));
|
|
||||||
// only set the private key to this address if we don't have one yet
|
|
||||||
if (!pkValid)
|
|
||||||
{
|
|
||||||
privKey = CKey();
|
|
||||||
CPrivKey vch(&(C.CCpriv[0]), C.CCpriv + sizeof(C.CCpriv));
|
|
||||||
privKey.SetPrivKey(vch, false);
|
|
||||||
pkValid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!pkValid)
|
|
||||||
{
|
|
||||||
if (creator.KeyStore().GetKey(vKeyID[0], privKey))
|
|
||||||
pkValid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vPK.push_back(pk);
|
|
||||||
|
|
||||||
} catch (...)
|
|
||||||
{
|
|
||||||
fprintf(stderr,"exception calculating 1of2 spend\n");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pkValid)
|
if (!privKey.IsValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CC *cc = CCcond1of2(p.evalCode, vPK[0], vPK[1]);
|
CC *cc = CCcond1of2(p.evalCode, p.vKeys[0], p.vKeys[1]);
|
||||||
|
|
||||||
if (cc)
|
if (cc)
|
||||||
{
|
{
|
||||||
vector<unsigned char> vch;
|
vector<unsigned char> vch;
|
||||||
if (creator.CreateSig(vch, vKeyID[0], scriptPubKey, consensusBranchId, &privKey, (void *)cc))
|
if (creator.CreateSig(vch, p.vKeys[0].GetID(), _CCPubKey(cc), consensusBranchId, &privKey, (void *)cc))
|
||||||
{
|
{
|
||||||
ret.push_back(vch);
|
ret.push_back(vch);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr,"vin has 1of2 CC signing error with address.(%s)\n", vKeyID[0].ToString().c_str());
|
fprintf(stderr,"vin has 1of2 CC signing error with addresses.(%s)\n(%s)\n", p.vKeys[0].GetID().ToString().c_str(), p.vKeys[1].GetID().ToString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_free(cc);
|
cc_free(cc);
|
||||||
@@ -524,6 +537,7 @@ static Stacks CombineSignatures(const CScript& scriptPubKey, const BaseSignature
|
|||||||
return sigs2;
|
return sigs2;
|
||||||
case TX_PUBKEY:
|
case TX_PUBKEY:
|
||||||
case TX_PUBKEYHASH:
|
case TX_PUBKEYHASH:
|
||||||
|
case TX_CRYPTOCONDITION:
|
||||||
// Signatures are bigger than placeholders or empty scripts:
|
// Signatures are bigger than placeholders or empty scripts:
|
||||||
if (sigs1.script.empty() || sigs1.script[0].empty())
|
if (sigs1.script.empty() || sigs1.script[0].empty())
|
||||||
return sigs2;
|
return sigs2;
|
||||||
|
|||||||
Reference in New Issue
Block a user