]>
Commit | Line | Data |
---|---|---|
563581af | 1 | #include "cryptoconditions/include/cryptoconditions.h" |
8a8e10f0 | 2 | #include "script/cc.h" |
563581af SS |
3 | |
4 | ||
5 | bool IsCryptoConditionsEnabled() | |
6 | { | |
7 | return 0 != ASSETCHAINS_CC; | |
8 | } | |
9 | ||
0574c740 | 10 | bool IsSupportedCryptoCondition(const CC *cond, int evalCode) |
563581af SS |
11 | { |
12 | int mask = cc_typeMask(cond); | |
13 | ||
14 | if (mask & ~CCEnabledTypes) return false; | |
15 | ||
6da11b8b | 16 | // Also require that the condition have at least one signable node or be a PBaaS compatible condition |
17 | // and at least have an eval node instead | |
18 | if (!(mask & CCSigningNodes) && !(evalCode >= CCFirstEvalOnly && evalCode <= CCLastEvalOnly && mask & CCEvalNode)) return false; | |
563581af SS |
19 | |
20 | return true; | |
21 | } | |
22 | ||
563581af SS |
23 | bool IsSignedCryptoCondition(const CC *cond) |
24 | { | |
25 | if (!cc_isFulfilled(cond)) return false; | |
26 | if (1 << cc_typeId(cond) & CCSigningNodes) return true; | |
27 | if (cc_typeId(cond) == CC_Threshold) | |
28 | for (int i=0; i<cond->size; i++) | |
29 | if (IsSignedCryptoCondition(cond->subconditions[i])) return true; | |
30 | return false; | |
31 | } | |
561f3e18 SS |
32 | |
33 | ||
e625be68 SS |
34 | static unsigned char* CopyPubKey(CPubKey pkIn) |
35 | { | |
36 | unsigned char* pk = (unsigned char*) malloc(33); | |
37 | memcpy(pk, pkIn.begin(), 33); // TODO: compressed? | |
38 | return pk; | |
39 | } | |
40 | ||
770924f5 | 41 | static unsigned char* CopyKeyIDChars(uint8_t *chars) |
3a27113e | 42 | { |
43 | unsigned char* pk = (unsigned char*) malloc(33); | |
770924f5 | 44 | memcpy(pk, chars, 20); // only the keyID |
45 | memset(pk + 20, 0, 13); | |
3a27113e | 46 | return pk; |
47 | } | |
e625be68 SS |
48 | |
49 | CC* CCNewThreshold(int t, std::vector<CC*> v) | |
50 | { | |
51 | CC *cond = cc_new(CC_Threshold); | |
52 | cond->threshold = t; | |
53 | cond->size = v.size(); | |
54 | cond->subconditions = (CC**) calloc(v.size(), sizeof(CC*)); | |
55 | memcpy(cond->subconditions, v.data(), v.size() * sizeof(CC*)); | |
56 | return cond; | |
57 | } | |
58 | ||
e625be68 SS |
59 | CC* CCNewSecp256k1(CPubKey k) |
60 | { | |
61 | CC *cond = cc_new(CC_Secp256k1); | |
62 | cond->publicKey = CopyPubKey(k); | |
63 | return cond; | |
64 | } | |
65 | ||
770924f5 | 66 | CC* CCNewHashedSecp256k1(CKeyID keyID) |
3a27113e | 67 | { |
68 | CC *cond = cc_new(CC_Secp256k1); | |
770924f5 | 69 | |
70 | cond->publicKey = CopyKeyIDChars(keyID.begin()); | |
3a27113e | 71 | return cond; |
72 | } | |
e625be68 | 73 | |
39c9911e | 74 | CC* CCNewEval(std::vector<unsigned char> code) |
e625be68 SS |
75 | { |
76 | CC *cond = cc_new(CC_Eval); | |
39c9911e SS |
77 | cond->code = (unsigned char*) malloc(code.size()); |
78 | memcpy(cond->code, code.data(), code.size()); | |
79 | cond->codeLength = code.size(); | |
e625be68 SS |
80 | return cond; |
81 | } | |
82 | ||
b7c685b8 | 83 | std::vector<unsigned char> CCPubKeyVec(const CC *cond) |
84 | { | |
a4f9bc97 | 85 | unsigned char buf[MAX_BINARY_CC_SIZE]; |
86 | size_t len = cc_conditionBinary(cond, buf, MAX_BINARY_CC_SIZE); | |
b7c685b8 | 87 | return std::vector<unsigned char>(buf, buf+len); |
88 | } | |
89 | ||
a4f9bc97 | 90 | CScript CCPubKey(const CC *cond) |
91 | { | |
92 | return CScript() << CCPubKeyVec(cond) << OP_CHECKCRYPTOCONDITION; | |
93 | } | |
561f3e18 SS |
94 | |
95 | CScript CCSig(const CC *cond) | |
96 | { | |
a4f9bc97 | 97 | unsigned char buf[MAX_BINARY_CC_SIZE]; |
98 | size_t len = cc_fulfillmentBinary(cond, buf, MAX_BINARY_CC_SIZE); | |
561f3e18 SS |
99 | auto ffill = std::vector<unsigned char>(buf, buf+len); |
100 | ffill.push_back(1); // SIGHASH_ALL | |
101 | return CScript() << ffill; | |
102 | } | |
103 | ||
8a727a26 | 104 | std::vector<unsigned char> CCSigVec(const CC *cond) |
105 | { | |
a4f9bc97 | 106 | unsigned char buf[MAX_BINARY_CC_SIZE]; |
107 | size_t len = cc_fulfillmentBinary(cond, buf, MAX_BINARY_CC_SIZE); | |
8a727a26 | 108 | auto ffill = std::vector<unsigned char>(buf, buf+len); |
109 | ffill.push_back(1); // SIGHASH_ALL | |
110 | return ffill; | |
111 | } | |
561f3e18 | 112 | |
48afc74f | 113 | std::vector<unsigned char> CCPartialSigVec(const CC *cond) |
114 | { | |
a4f9bc97 | 115 | unsigned char buf[MAX_BINARY_CC_SIZE]; |
116 | size_t len = cc_partialFulfillmentBinary(cond, buf, MAX_BINARY_CC_SIZE); | |
48afc74f | 117 | auto ffill = std::vector<unsigned char>(buf, buf+len); |
118 | ffill.push_back(1); // SIGHASH_ALL | |
119 | return ffill; | |
120 | } | |
121 | ||
561f3e18 SS |
122 | std::string CCShowStructure(CC *cond) |
123 | { | |
124 | std::string out; | |
125 | if (cc_isAnon(cond)) { | |
126 | out = "A" + std::to_string(cc_typeId(cond)); | |
127 | } | |
128 | else if (cc_typeId(cond) == CC_Threshold) { | |
129 | out += "(" + std::to_string(cond->threshold) + " of "; | |
130 | for (int i=0; i<cond->size; i++) { | |
131 | out += CCShowStructure(cond->subconditions[i]); | |
132 | if (i < cond->size - 1) out += ","; | |
133 | } | |
134 | out += ")"; | |
135 | } | |
136 | else { | |
137 | out = std::to_string(cc_typeId(cond)); | |
138 | } | |
139 | return out; | |
140 | } | |
141 | ||
142 | ||
143 | CC* CCPrune(CC *cond) | |
144 | { | |
145 | std::vector<unsigned char> ffillBin; | |
146 | GetPushData(CCSig(cond), ffillBin); | |
147 | return cc_readFulfillmentBinary(ffillBin.data(), ffillBin.size()-1); | |
148 | } | |
149 | ||
150 | ||
151 | bool GetPushData(const CScript &sig, std::vector<unsigned char> &data) | |
152 | { | |
153 | opcodetype opcode; | |
154 | auto pc = sig.begin(); | |
155 | if (sig.GetOp(pc, opcode, data)) return opcode > OP_0 && opcode <= OP_PUSHDATA4; | |
156 | return false; | |
157 | } | |
158 | ||
159 | ||
160 | bool GetOpReturnData(const CScript &sig, std::vector<unsigned char> &data) | |
161 | { | |
162 | auto pc = sig.begin(); | |
163 | opcodetype opcode; | |
164 | if (sig.GetOp2(pc, opcode, NULL)) | |
165 | if (opcode == OP_RETURN) | |
166 | if (sig.GetOp(pc, opcode, data)) | |
167 | return opcode > OP_0 && opcode <= OP_PUSHDATA4; | |
168 | return false; | |
169 | } |