typedef std::vector<unsigned char> valtype;
-TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
+TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, const CScript &scriptPubKey, uint32_t spendHeight, int nHashTypeIn)
+ : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn, &scriptPubKey, keystoreIn, spendHeight) {}
-bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, uint32_t consensusBranchId, CKey *pprivKey, void *extraData) const
+TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn)
+ : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
+
+bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char> &vchSig, const CKeyID& address, const CScript& scriptCode, uint32_t consensusBranchId, CKey *pprivKey, void *extraData) const
{
CKey key;
if (pprivKey)
return false;
}
- if (scriptCode.IsPayToCryptoCondition())
+ COptCCParams p;
+ if (scriptCode.IsPayToCryptoCondition(p))
{
- CC *cc = (CC *)extraData;
-
- //CPubKey pubKey = key.GetPubKey();
- //printf("signing with pubkey: %s, ID: %s\n\n", HexBytes(&(std::vector<unsigned char>(pubKey.begin(), pubKey.end())[0]), pubKey.size()).c_str(), pubKey.GetID().GetHex().c_str());
-
- // assume either 1of1 or 1of2. if the condition created by the
- if (!cc || cc_signTreeSecp256k1Msg32(cc, key.begin(), hash.begin()) == 0)
- return false;
-
- /*
- char *jsonCondStr = cc_conditionToJSONString(cc);
- if (jsonCondStr)
+ if (p.IsValid() && p.version >= p.VERSION_V3)
{
- printf("Freshly signed condition: %s\n", jsonCondStr);
- cJSON_free(jsonCondStr);
- uint8_t buf[2000];
- int ccLen = cc_conditionBinary(cc, buf, 2000);
- if (ccLen)
+ CSmartTransactionSignatures signatures(nHashType, std::map<uint160, CSmartTransactionSignature>());
+ if (vchSig.size())
{
- CC *transformedCC = cc_readConditionBinary(buf, ccLen);
- if (transformedCC)
+ signatures = CSmartTransactionSignatures(vchSig);
+ if (!signatures.IsValid())
{
- jsonCondStr = cc_conditionToJSONString(transformedCC);
- if (jsonCondStr)
- {
- printf("Signed, transformed condition: %s\n", jsonCondStr);
- cJSON_free(jsonCondStr);
- }
- cc_free(transformedCC);
+ return false;
}
}
+ unsigned char *onesig;
+ if (!cc_MakeSecp256k1Signature(hash.begin(), key.begin(), &onesig))
+ {
+ return false;
+ }
+ CSmartTransactionSignature signature(CSmartTransactionSignature::SIGTYPE_SECP256K1, key.GetPubKey(), std::vector<unsigned char>(onesig, onesig + CSmartTransactionSignature::SIGTYPE_SECP256K1_LEN));
+ free(onesig);
+ signatures.AddSignature(signature);
+ vchSig = signatures.AsVector();
+
+
+ /*
+ printf("signatures: %s\n", signatures.ToUniValue().write().c_str());
+ CC *cc = (CC *)extraData;
+ if (!cc || cc_signTreeSecp256k1Msg32(cc, key.begin(), hash.begin()) == 0)
+ return false;
+ char *jsonCondStr = cc_conditionToJSONString(cc);
+ if (jsonCondStr)
+ {
+ printf("Signed condition: %s\n", jsonCondStr);
+ cJSON_free(jsonCondStr);
+ }
+ */
}
- */
+ else
+ {
+ CC *cc = (CC *)extraData;
- vchSig = CCPartialSigVec(cc);
+ if (!cc || cc_signTreeSecp256k1Msg32(cc, key.begin(), hash.begin()) == 0)
+ return false;
+ vchSig = CCSigVec(cc);
+ }
return true;
}
else
bool ccValid = master.IsValid();
std::vector<CConditionObj<COptCCParams>> conditions;
std::map<uint160, CTxDestination> destMap; // all destinations
- std::map<uint160, CIdentity> idMap; // identities located by id
std::map<uint160, CKey> privKeyMap; // private keys located for each id
std::vector<CC*> ccs;
}
else
{
- idMap[destId] = id;
for (auto oneKey : id.primaryAddresses)
{
destMap[GetDestinationID(oneKey)] = oneKey;
}
else
{
- ccs.push_back(MakeCCcondMofN(vCC, oneP.m));
+ if (vCC.size() == 1)
+ {
+ ccs.push_back(vCC[0]);
+ }
+ else
+ {
+ ccs.push_back(MakeCCcondMofN(vCC, oneP.m));
+ }
}
-
}
}
vector<unsigned char> vch = ret.size() ? ret[0] : vector<unsigned char>();
bool error = false;
+ CScript signScript = _CCPubKey(outputCC);
// loop and sign
for (auto privKey : privKeys)
{
- if (vch.size())
- {
- CC *signedCC = nullptr;
- error = cc_readPartialFulfillmentBinaryExt(&vch[0], vch.size() - 1, &signedCC) || !signedCC;
-
- // we must always retain all eval nodes... ensure that any partial signature does so to prevent circumventing any eval condition
- if (cc_countEvals(signedCC) != cc_countEvals(outputCC))
- {
- error = true;
- cc_free(signedCC);
- }
-
- if (!error)
- {
- cc_free(outputCC);
- outputCC = signedCC;
- }
- }
- if (error || !(creator.CreateSig(vch, privKey.first, _CCPubKey(outputCC), consensusBranchId, &privKey.second, (void *)outputCC)))
+ // if we have an error or can't sign and it isn't fulfilled, fail, if we have no error, can't sign again, and we have a fulfilled sig, it must be optimized and OK
+ if (error || (!creator.CreateSig(vch, privKey.first, scriptPubKey, consensusBranchId, &privKey.second, (void *)outputCC)))
{
error = true;
//CPubKey errKey = privKey.second.GetPubKey();
return false;
}
+ COptCCParams p;
+ if (scriptPubKey.IsPayToCryptoCondition(p) && p.IsValid())
+ {
+ return SignStepCC(creator, scriptPubKey, vSolutions, ret, consensusBranchId);
+ }
+
CKeyID keyID;
switch (whichTypeRet)
}
return false;
- case TX_CRYPTOCONDITION:
- return SignStepCC(creator, scriptPubKey, vSolutions, ret, consensusBranchId);
-
case TX_MULTISIG:
ret.push_back(valtype()); // workaround CHECKMULTISIG bug
return (SignN(vSolutions, creator, scriptPubKey, ret, consensusBranchId));
CKey *key,
void *extraData) const
{
- // Create a dummy signature that is a valid DER-encoding
- vchSig.assign(72, '\000');
- vchSig[0] = 0x30;
- vchSig[1] = 69;
- vchSig[2] = 0x02;
- vchSig[3] = 33;
- vchSig[4] = 0x01;
- vchSig[4 + 33] = 0x02;
- vchSig[5 + 33] = 32;
- vchSig[6 + 33] = 0x01;
- vchSig[6 + 33 + 32] = SIGHASH_ALL;
+ if (scriptCode.IsPayToCryptoCondition())
+ {
+ vchSig = CCPartialSigVec(MakeCCcondOneSig(keyid));
+ }
+ else
+ {
+ // Create a dummy signature that is a valid DER-encoding
+ vchSig.assign(72, '\000');
+ vchSig[0] = 0x30;
+ vchSig[1] = 69;
+ vchSig[2] = 0x02;
+ vchSig[3] = 33;
+ vchSig[4] = 0x01;
+ vchSig[4 + 33] = 0x02;
+ vchSig[5 + 33] = 32;
+ vchSig[6 + 33] = 0x01;
+ vchSig[6 + 33 + 32] = SIGHASH_ALL;
+ }
return true;
}