This commit is contained in:
Scott Sadler
2018-04-09 11:53:13 -03:00
parent e36af93bab
commit 8a8e10f02f
16 changed files with 40 additions and 63 deletions

137
src/script/cc.cpp Normal file
View File

@@ -0,0 +1,137 @@
#include "cryptoconditions/include/cryptoconditions.h"
#include "script/cc.h"
bool IsCryptoConditionsEnabled()
{
return 0 != ASSETCHAINS_CC;
}
bool IsSupportedCryptoCondition(const CC *cond)
{
int mask = cc_typeMask(cond);
if (mask & ~CCEnabledTypes) return false;
// Also require that the condition have at least one signable node
if (!(mask & CCSigningNodes)) return false;
return true;
}
bool IsSignedCryptoCondition(const CC *cond)
{
if (!cc_isFulfilled(cond)) return false;
if (1 << cc_typeId(cond) & CCSigningNodes) return true;
if (cc_typeId(cond) == CC_Threshold)
for (int i=0; i<cond->size; i++)
if (IsSignedCryptoCondition(cond->subconditions[i])) return true;
return false;
}
static unsigned char* CopyPubKey(CPubKey pkIn)
{
unsigned char* pk = (unsigned char*) malloc(33);
memcpy(pk, pkIn.begin(), 33); // TODO: compressed?
return pk;
}
CC* CCNewThreshold(int t, std::vector<CC*> v)
{
CC *cond = cc_new(CC_Threshold);
cond->threshold = t;
cond->size = v.size();
cond->subconditions = (CC**) calloc(v.size(), sizeof(CC*));
memcpy(cond->subconditions, v.data(), v.size() * sizeof(CC*));
return cond;
}
CC* CCNewSecp256k1(CPubKey k)
{
CC *cond = cc_new(CC_Secp256k1);
cond->publicKey = CopyPubKey(k);
return cond;
}
CC* CCNewEval(std::vector<unsigned char> code)
{
CC *cond = cc_new(CC_Eval);
cond->code = (unsigned char*) malloc(code.size());
memcpy(cond->code, code.data(), code.size());
cond->codeLength = code.size();
return cond;
}
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;
}
CScript CCSig(const CC *cond)
{
unsigned char buf[10000];
size_t len = cc_fulfillmentBinary(cond, buf, 10000);
auto ffill = std::vector<unsigned char>(buf, buf+len);
ffill.push_back(1); // SIGHASH_ALL
return CScript() << ffill;
}
std::string CCShowStructure(CC *cond)
{
std::string out;
if (cc_isAnon(cond)) {
out = "A" + std::to_string(cc_typeId(cond));
}
else if (cc_typeId(cond) == CC_Threshold) {
out += "(" + std::to_string(cond->threshold) + " of ";
for (int i=0; i<cond->size; i++) {
out += CCShowStructure(cond->subconditions[i]);
if (i < cond->size - 1) out += ",";
}
out += ")";
}
else {
out = std::to_string(cc_typeId(cond));
}
return out;
}
CC* CCPrune(CC *cond)
{
std::vector<unsigned char> ffillBin;
GetPushData(CCSig(cond), ffillBin);
return cc_readFulfillmentBinary(ffillBin.data(), ffillBin.size()-1);
}
bool GetPushData(const CScript &sig, std::vector<unsigned char> &data)
{
opcodetype opcode;
auto pc = sig.begin();
if (sig.GetOp(pc, opcode, data)) return opcode > OP_0 && opcode <= OP_PUSHDATA4;
return false;
}
bool GetOpReturnData(const CScript &sig, std::vector<unsigned char> &data)
{
auto pc = sig.begin();
opcodetype opcode;
if (sig.GetOp2(pc, opcode, NULL))
if (opcode == OP_RETURN)
if (sig.GetOp(pc, opcode, data))
return opcode > OP_0 && opcode <= OP_PUSHDATA4;
return false;
}

83
src/script/cc.h Normal file
View File

@@ -0,0 +1,83 @@
#ifndef SCRIPT_CC_H
#define SCRIPT_CC_H
#include "pubkey.h"
#include "script/script.h"
#include "cryptoconditions/include/cryptoconditions.h"
extern int32_t ASSETCHAINS_CC;
bool IsCryptoConditionsEnabled();
// Limit acceptable condition types
// Prefix not enabled because no current use case, ambiguity on how to combine with secp256k1
// RSA not enabled because no current use case, not implemented
const int CCEnabledTypes = 1 << CC_Secp256k1 | \
1 << CC_Threshold | \
1 << CC_Eval | \
1 << CC_Preimage | \
1 << CC_Ed25519;
const int CCSigningNodes = 1 << CC_Ed25519 | 1 << CC_Secp256k1;
/*
* Check if the server can accept the condition based on it's structure / types
*/
bool IsSupportedCryptoCondition(const CC *cond);
/*
* Check if crypto condition is signed. Can only accept signed conditions.
*/
bool IsSignedCryptoCondition(const CC *cond);
/*
* Construct crypto conditions
*/
CC* CCNewPreimage(std::vector<unsigned char> preimage);
CC* CCNewEval(std::vector<unsigned char> code);
CC* CCNewSecp256k1(CPubKey k);
CC* CCNewThreshold(int t, std::vector<CC*> v);
/*
* Turn a condition into a scriptPubKey
*/
CScript CCPubKey(const CC *cond);
/*
* Turn a condition into a scriptSig
*
* Note: This will fail in undefined ways if the condition is missing signatures
*/
CScript CCSig(const CC *cond);
/*
* Produces a string showing the structure of a CC condition
*/
std::string CCShowStructure(CC *cond);
/*
* Take a signed CC, encode it, and decode it again. This has the effect
* of removing branches unneccesary for fulfillment.
*/
CC* CCPrune(CC *cond);
/*
* Get PUSHDATA from a script
*/
bool GetPushData(const CScript &sig, std::vector<unsigned char> &data);
/*
* Get OP_RETURN data from a script
*/
bool GetOpReturnData(const CScript &sig, std::vector<unsigned char> &data);
#endif /* SCRIPT_CC_H */

View File

@@ -8,7 +8,7 @@
#include "script_error.h"
#include "primitives/transaction.h"
#include "komodo_cc.h"
#include "script/cc.h"
#include <vector>
#include <stdint.h>

View File

@@ -7,7 +7,7 @@
#include "tinyformat.h"
#include "utilstrencodings.h"
#include "komodo_cc.h"
#include "script/cc.h"
#include "cryptoconditions/include/cryptoconditions.h"
namespace {

View File

@@ -4,7 +4,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "serverchecker.h"
#include "komodo_cc.h"
#include "script/cc.h"
#include "cc/eval.h"
#include "pubkey.h"

View File

@@ -9,7 +9,7 @@
#include "script/script.h"
#include "util.h"
#include "utilstrencodings.h"
#include "komodo_cc.h"
#include "script/cc.h"
#include <boost/foreach.hpp>