]> Git Repo - VerusCoin.git/blame - src/komodo_utils.h
Change print
[VerusCoin.git] / src / komodo_utils.h
CommitLineData
d019c447 1/******************************************************************************
713c2a94 2 * Copyright © 2014-2018 The SuperNET Developers. *
d019c447 3 * *
4 * See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
5 * the top-level directory of this distribution for the individual copyright *
6 * holder information and the developer policies on copyright and licensing. *
7 * *
8 * Unless otherwise agreed in a custom licensing agreement, no part of the *
9 * SuperNET software, including this file may be copied, modified, propagated *
10 * or distributed except according to the terms contained in the LICENSE file *
11 * *
12 * Removal or modification of this copyright notice is prohibited. *
13 * *
14 ******************************************************************************/
5416af1d 15#include "komodo_defs.h"
16
9d365796 17#ifdef _WIN32
18#include <sodium.h>
19#include <boost/date_time/posix_time/posix_time.hpp>
20#include <boost/thread.hpp>
21#endif
3eea72f2 22
453e1052 23#define SATOSHIDEN ((uint64_t)100000000L)
32b1b443 24#define dstr(x) ((double)(x) / SATOSHIDEN)
b67b154f 25#define portable_mutex_t pthread_mutex_t
26#define portable_mutex_init(ptr) pthread_mutex_init(ptr,NULL)
27#define portable_mutex_lock pthread_mutex_lock
28#define portable_mutex_unlock pthread_mutex_unlock
32b1b443 29
2552dbb4 30struct allocitem { uint32_t allocsize,type; };
0a912c89 31struct queueitem { struct queueitem *next,*prev; uint32_t allocsize,type; };
32
a18fbdc5 33typedef struct queue
34{
35 struct queueitem *list;
0a912c89 36 pthread_mutex_t mutex;
a18fbdc5 37 char name[64],initflag;
38} queue_t;
39
d019c447 40#include "mini-gmp.c"
3eea72f2 41
42#define CRYPTO777_PUBSECPSTR "020e46e79a2a8d12b9b5d12c7a91adb4e454edfae43c0a0cb805427d2ac7613fd9"
b62d7030 43#define CRYPTO777_KMDADDR "RXL3YXG2ceaB6C5hfJcN4fvmLH2C34knhA"
878412df 44#define CRYPTO777_RMD160STR "f1dce4182fce875748c4986b240ff7d7bc3fffb0"
b62d7030 45
d019c447 46#define KOMODO_PUBTYPE 60
47
d019c447 48struct sha256_vstate { uint64_t length; uint32_t state[8],curlen; uint8_t buf[64]; };
49struct rmd160_vstate { uint64_t length; uint8_t buf[64]; uint32_t curlen, state[5]; };
50
51// following is ported from libtom
52
53#define STORE32L(x, y) \
54{ (y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \
55(y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); }
56
57#define LOAD32L(x, y) \
58{ x = (uint32_t)(((uint64_t)((y)[3] & 255)<<24) | \
59((uint32_t)((y)[2] & 255)<<16) | \
60((uint32_t)((y)[1] & 255)<<8) | \
61((uint32_t)((y)[0] & 255))); }
62
63#define STORE64L(x, y) \
64{ (y)[7] = (uint8_t)(((x)>>56)&255); (y)[6] = (uint8_t)(((x)>>48)&255); \
65(y)[5] = (uint8_t)(((x)>>40)&255); (y)[4] = (uint8_t)(((x)>>32)&255); \
66(y)[3] = (uint8_t)(((x)>>24)&255); (y)[2] = (uint8_t)(((x)>>16)&255); \
67(y)[1] = (uint8_t)(((x)>>8)&255); (y)[0] = (uint8_t)((x)&255); }
68
69#define LOAD64L(x, y) \
70{ x = (((uint64_t)((y)[7] & 255))<<56)|(((uint64_t)((y)[6] & 255))<<48)| \
71(((uint64_t)((y)[5] & 255))<<40)|(((uint64_t)((y)[4] & 255))<<32)| \
72(((uint64_t)((y)[3] & 255))<<24)|(((uint64_t)((y)[2] & 255))<<16)| \
73(((uint64_t)((y)[1] & 255))<<8)|(((uint64_t)((y)[0] & 255))); }
74
75#define STORE32H(x, y) \
76{ (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255); \
77(y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); }
78
79#define LOAD32H(x, y) \
80{ x = (uint32_t)(((uint64_t)((y)[0] & 255)<<24) | \
81((uint32_t)((y)[1] & 255)<<16) | \
82((uint32_t)((y)[2] & 255)<<8) | \
83((uint32_t)((y)[3] & 255))); }
84
85#define STORE64H(x, y) \
86{ (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255); \
87(y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255); \
88(y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255); \
89(y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); }
90
91#define LOAD64H(x, y) \
92{ x = (((uint64_t)((y)[0] & 255))<<56)|(((uint64_t)((y)[1] & 255))<<48) | \
93(((uint64_t)((y)[2] & 255))<<40)|(((uint64_t)((y)[3] & 255))<<32) | \
94(((uint64_t)((y)[4] & 255))<<24)|(((uint64_t)((y)[5] & 255))<<16) | \
95(((uint64_t)((y)[6] & 255))<<8)|(((uint64_t)((y)[7] & 255))); }
96
97// Various logical functions
98#define RORc(x, y) ( ((((uint32_t)(x)&0xFFFFFFFFUL)>>(uint32_t)((y)&31)) | ((uint32_t)(x)<<(uint32_t)(32-((y)&31)))) & 0xFFFFFFFFUL)
99#define Ch(x,y,z) (z ^ (x & (y ^ z)))
100#define Maj(x,y,z) (((x | y) & z) | (x & y))
101#define S(x, n) RORc((x),(n))
102#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
103#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
104#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
105#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
106#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
107#define MIN(x, y) ( ((x)<(y))?(x):(y) )
108
109static inline int32_t sha256_vcompress(struct sha256_vstate * md,uint8_t *buf)
110{
111 uint32_t S[8],W[64],t0,t1,i;
112 for (i=0; i<8; i++) // copy state into S
113 S[i] = md->state[i];
114 for (i=0; i<16; i++) // copy the state into 512-bits into W[0..15]
115 LOAD32H(W[i],buf + (4*i));
116 for (i=16; i<64; i++) // fill W[16..63]
117 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
9d365796 118
d019c447 119#define RND(a,b,c,d,e,f,g,h,i,ki) \
120t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
121t1 = Sigma0(a) + Maj(a, b, c); \
122d += t0; \
123h = t0 + t1;
9d365796 124
d019c447 125 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
126 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
127 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
128 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
129 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
130 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
131 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
132 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
133 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
134 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
135 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
136 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
137 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
138 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
139 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
140 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
141 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
142 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
143 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
144 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
145 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
146 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
147 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
148 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
149 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
150 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
151 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
152 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
153 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
154 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
155 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
156 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
157 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
158 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
159 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
160 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
161 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
162 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
163 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
164 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
165 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
166 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
167 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
168 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
169 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
170 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
171 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
172 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
173 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
174 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
175 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
176 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
177 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
178 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
179 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
180 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
181 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
182 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
183 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
184 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
185 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
186 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
187 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
188 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
189#undef RND
190 for (i=0; i<8; i++) // feedback
191 md->state[i] = md->state[i] + S[i];
192 return(0);
193}
194
195#undef RORc
196#undef Ch
197#undef Maj
198#undef S
199#undef R
200#undef Sigma0
201#undef Sigma1
202#undef Gamma0
203#undef Gamma1
204
205static inline void sha256_vinit(struct sha256_vstate * md)
206{
207 md->curlen = 0;
208 md->length = 0;
209 md->state[0] = 0x6A09E667UL;
210 md->state[1] = 0xBB67AE85UL;
211 md->state[2] = 0x3C6EF372UL;
212 md->state[3] = 0xA54FF53AUL;
213 md->state[4] = 0x510E527FUL;
214 md->state[5] = 0x9B05688CUL;
215 md->state[6] = 0x1F83D9ABUL;
216 md->state[7] = 0x5BE0CD19UL;
217}
218
219static inline int32_t sha256_vprocess(struct sha256_vstate *md,const uint8_t *in,uint64_t inlen)
220{
221 uint64_t n; int32_t err;
222 if ( md->curlen > sizeof(md->buf) )
223 return(-1);
224 while ( inlen > 0 )
225 {
226 if ( md->curlen == 0 && inlen >= 64 )
227 {
228 if ( (err= sha256_vcompress(md,(uint8_t *)in)) != 0 )
229 return(err);
230 md->length += 64 * 8, in += 64, inlen -= 64;
231 }
232 else
233 {
234 n = MIN(inlen,64 - md->curlen);
235 memcpy(md->buf + md->curlen,in,(size_t)n);
236 md->curlen += n, in += n, inlen -= n;
237 if ( md->curlen == 64 )
238 {
239 if ( (err= sha256_vcompress(md,md->buf)) != 0 )
240 return(err);
241 md->length += 8*64;
242 md->curlen = 0;
243 }
244 }
245 }
246 return(0);
247}
248
249static inline int32_t sha256_vdone(struct sha256_vstate *md,uint8_t *out)
250{
251 int32_t i;
252 if ( md->curlen >= sizeof(md->buf) )
253 return(-1);
254 md->length += md->curlen * 8; // increase the length of the message
255 md->buf[md->curlen++] = (uint8_t)0x80; // append the '1' bit
256 // if len > 56 bytes we append zeros then compress. Then we can fall back to padding zeros and length encoding like normal.
257 if ( md->curlen > 56 )
258 {
259 while ( md->curlen < 64 )
260 md->buf[md->curlen++] = (uint8_t)0;
261 sha256_vcompress(md,md->buf);
262 md->curlen = 0;
263 }
264 while ( md->curlen < 56 ) // pad upto 56 bytes of zeroes
265 md->buf[md->curlen++] = (uint8_t)0;
266 STORE64H(md->length,md->buf+56); // store length
267 sha256_vcompress(md,md->buf);
268 for (i=0; i<8; i++) // copy output
269 STORE32H(md->state[i],out+(4*i));
270 return(0);
271}
272
273void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len)
274{
275 struct sha256_vstate md;
276 sha256_vinit(&md);
277 sha256_vprocess(&md,src,len);
278 sha256_vdone(&md,hash);
279}
280
281bits256 bits256_doublesha256(char *deprecated,uint8_t *data,int32_t datalen)
282{
283 bits256 hash,hash2; int32_t i;
284 vcalc_sha256(0,hash.bytes,data,datalen);
285 vcalc_sha256(0,hash2.bytes,hash.bytes,sizeof(hash));
286 for (i=0; i<sizeof(hash); i++)
287 hash.bytes[i] = hash2.bytes[sizeof(hash) - 1 - i];
288 return(hash);
289}
290
52198432 291
d019c447 292// rmd160: the five basic functions F(), G() and H()
293#define F(x, y, z) ((x) ^ (y) ^ (z))
294#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
295#define H(x, y, z) (((x) | ~(y)) ^ (z))
296#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
297#define J(x, y, z) ((x) ^ ((y) | ~(z)))
298#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
299
300/* the ten basic operations FF() through III() */
301#define FF(a, b, c, d, e, x, s) \
302(a) += F((b), (c), (d)) + (x);\
303(a) = ROLc((a), (s)) + (e);\
304(c) = ROLc((c), 10);
305
306#define GG(a, b, c, d, e, x, s) \
307(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
308(a) = ROLc((a), (s)) + (e);\
309(c) = ROLc((c), 10);
310
311#define HH(a, b, c, d, e, x, s) \
312(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
313(a) = ROLc((a), (s)) + (e);\
314(c) = ROLc((c), 10);
315
316#define II(a, b, c, d, e, x, s) \
317(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
318(a) = ROLc((a), (s)) + (e);\
319(c) = ROLc((c), 10);
320
321#define JJ(a, b, c, d, e, x, s) \
322(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
323(a) = ROLc((a), (s)) + (e);\
324(c) = ROLc((c), 10);
325
326#define FFF(a, b, c, d, e, x, s) \
327(a) += F((b), (c), (d)) + (x);\
328(a) = ROLc((a), (s)) + (e);\
329(c) = ROLc((c), 10);
330
331#define GGG(a, b, c, d, e, x, s) \
332(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
333(a) = ROLc((a), (s)) + (e);\
334(c) = ROLc((c), 10);
335
336#define HHH(a, b, c, d, e, x, s) \
337(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
338(a) = ROLc((a), (s)) + (e);\
339(c) = ROLc((c), 10);
340
341#define III(a, b, c, d, e, x, s) \
342(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
343(a) = ROLc((a), (s)) + (e);\
344(c) = ROLc((c), 10);
345
346#define JJJ(a, b, c, d, e, x, s) \
347(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
348(a) = ROLc((a), (s)) + (e);\
349(c) = ROLc((c), 10);
350
351static int32_t rmd160_vcompress(struct rmd160_vstate *md,uint8_t *buf)
352{
353 uint32_t aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16];
354 int i;
9d365796 355
d019c447 356 /* load words X */
357 for (i = 0; i < 16; i++){
358 LOAD32L(X[i], buf + (4 * i));
359 }
9d365796 360
d019c447 361 /* load state */
362 aa = aaa = md->state[0];
363 bb = bbb = md->state[1];
364 cc = ccc = md->state[2];
365 dd = ddd = md->state[3];
366 ee = eee = md->state[4];
9d365796 367
d019c447 368 /* round 1 */
369 FF(aa, bb, cc, dd, ee, X[ 0], 11);
370 FF(ee, aa, bb, cc, dd, X[ 1], 14);
371 FF(dd, ee, aa, bb, cc, X[ 2], 15);
372 FF(cc, dd, ee, aa, bb, X[ 3], 12);
373 FF(bb, cc, dd, ee, aa, X[ 4], 5);
374 FF(aa, bb, cc, dd, ee, X[ 5], 8);
375 FF(ee, aa, bb, cc, dd, X[ 6], 7);
376 FF(dd, ee, aa, bb, cc, X[ 7], 9);
377 FF(cc, dd, ee, aa, bb, X[ 8], 11);
378 FF(bb, cc, dd, ee, aa, X[ 9], 13);
379 FF(aa, bb, cc, dd, ee, X[10], 14);
380 FF(ee, aa, bb, cc, dd, X[11], 15);
381 FF(dd, ee, aa, bb, cc, X[12], 6);
382 FF(cc, dd, ee, aa, bb, X[13], 7);
383 FF(bb, cc, dd, ee, aa, X[14], 9);
384 FF(aa, bb, cc, dd, ee, X[15], 8);
9d365796 385
d019c447 386 /* round 2 */
387 GG(ee, aa, bb, cc, dd, X[ 7], 7);
388 GG(dd, ee, aa, bb, cc, X[ 4], 6);
389 GG(cc, dd, ee, aa, bb, X[13], 8);
390 GG(bb, cc, dd, ee, aa, X[ 1], 13);
391 GG(aa, bb, cc, dd, ee, X[10], 11);
392 GG(ee, aa, bb, cc, dd, X[ 6], 9);
393 GG(dd, ee, aa, bb, cc, X[15], 7);
394 GG(cc, dd, ee, aa, bb, X[ 3], 15);
395 GG(bb, cc, dd, ee, aa, X[12], 7);
396 GG(aa, bb, cc, dd, ee, X[ 0], 12);
397 GG(ee, aa, bb, cc, dd, X[ 9], 15);
398 GG(dd, ee, aa, bb, cc, X[ 5], 9);
399 GG(cc, dd, ee, aa, bb, X[ 2], 11);
400 GG(bb, cc, dd, ee, aa, X[14], 7);
401 GG(aa, bb, cc, dd, ee, X[11], 13);
402 GG(ee, aa, bb, cc, dd, X[ 8], 12);
9d365796 403
d019c447 404 /* round 3 */
405 HH(dd, ee, aa, bb, cc, X[ 3], 11);
406 HH(cc, dd, ee, aa, bb, X[10], 13);
407 HH(bb, cc, dd, ee, aa, X[14], 6);
408 HH(aa, bb, cc, dd, ee, X[ 4], 7);
409 HH(ee, aa, bb, cc, dd, X[ 9], 14);
410 HH(dd, ee, aa, bb, cc, X[15], 9);
411 HH(cc, dd, ee, aa, bb, X[ 8], 13);
412 HH(bb, cc, dd, ee, aa, X[ 1], 15);
413 HH(aa, bb, cc, dd, ee, X[ 2], 14);
414 HH(ee, aa, bb, cc, dd, X[ 7], 8);
415 HH(dd, ee, aa, bb, cc, X[ 0], 13);
416 HH(cc, dd, ee, aa, bb, X[ 6], 6);
417 HH(bb, cc, dd, ee, aa, X[13], 5);
418 HH(aa, bb, cc, dd, ee, X[11], 12);
419 HH(ee, aa, bb, cc, dd, X[ 5], 7);
420 HH(dd, ee, aa, bb, cc, X[12], 5);
9d365796 421
d019c447 422 /* round 4 */
423 II(cc, dd, ee, aa, bb, X[ 1], 11);
424 II(bb, cc, dd, ee, aa, X[ 9], 12);
425 II(aa, bb, cc, dd, ee, X[11], 14);
426 II(ee, aa, bb, cc, dd, X[10], 15);
427 II(dd, ee, aa, bb, cc, X[ 0], 14);
428 II(cc, dd, ee, aa, bb, X[ 8], 15);
429 II(bb, cc, dd, ee, aa, X[12], 9);
430 II(aa, bb, cc, dd, ee, X[ 4], 8);
431 II(ee, aa, bb, cc, dd, X[13], 9);
432 II(dd, ee, aa, bb, cc, X[ 3], 14);
433 II(cc, dd, ee, aa, bb, X[ 7], 5);
434 II(bb, cc, dd, ee, aa, X[15], 6);
435 II(aa, bb, cc, dd, ee, X[14], 8);
436 II(ee, aa, bb, cc, dd, X[ 5], 6);
437 II(dd, ee, aa, bb, cc, X[ 6], 5);
438 II(cc, dd, ee, aa, bb, X[ 2], 12);
9d365796 439
d019c447 440 /* round 5 */
441 JJ(bb, cc, dd, ee, aa, X[ 4], 9);
442 JJ(aa, bb, cc, dd, ee, X[ 0], 15);
443 JJ(ee, aa, bb, cc, dd, X[ 5], 5);
444 JJ(dd, ee, aa, bb, cc, X[ 9], 11);
445 JJ(cc, dd, ee, aa, bb, X[ 7], 6);
446 JJ(bb, cc, dd, ee, aa, X[12], 8);
447 JJ(aa, bb, cc, dd, ee, X[ 2], 13);
448 JJ(ee, aa, bb, cc, dd, X[10], 12);
449 JJ(dd, ee, aa, bb, cc, X[14], 5);
450 JJ(cc, dd, ee, aa, bb, X[ 1], 12);
451 JJ(bb, cc, dd, ee, aa, X[ 3], 13);
452 JJ(aa, bb, cc, dd, ee, X[ 8], 14);
453 JJ(ee, aa, bb, cc, dd, X[11], 11);
454 JJ(dd, ee, aa, bb, cc, X[ 6], 8);
455 JJ(cc, dd, ee, aa, bb, X[15], 5);
456 JJ(bb, cc, dd, ee, aa, X[13], 6);
9d365796 457
d019c447 458 /* parallel round 1 */
459 JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
460 JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
461 JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
462 JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
463 JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
464 JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
465 JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
466 JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
467 JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
468 JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
469 JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
470 JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
471 JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
472 JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
473 JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
474 JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
9d365796 475
d019c447 476 /* parallel round 2 */
477 III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
478 III(ddd, eee, aaa, bbb, ccc, X[11], 13);
479 III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
480 III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
481 III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
482 III(eee, aaa, bbb, ccc, ddd, X[13], 8);
483 III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
484 III(ccc, ddd, eee, aaa, bbb, X[10], 11);
485 III(bbb, ccc, ddd, eee, aaa, X[14], 7);
486 III(aaa, bbb, ccc, ddd, eee, X[15], 7);
487 III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
488 III(ddd, eee, aaa, bbb, ccc, X[12], 7);
489 III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
490 III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
491 III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
492 III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
9d365796 493
d019c447 494 /* parallel round 3 */
495 HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
496 HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
497 HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
498 HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
499 HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
500 HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
501 HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
502 HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
503 HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
504 HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
505 HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
506 HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
507 HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
508 HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
509 HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
510 HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
9d365796 511
d019c447 512 /* parallel round 4 */
513 GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
514 GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
515 GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
516 GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
517 GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
518 GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
519 GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
520 GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
521 GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
522 GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
523 GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
524 GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
525 GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
526 GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
527 GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
528 GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
9d365796 529
d019c447 530 /* parallel round 5 */
531 FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
532 FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
533 FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
534 FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
535 FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
536 FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
537 FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
538 FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
539 FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
540 FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
541 FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
542 FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
543 FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
544 FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
545 FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
546 FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
9d365796 547
d019c447 548 /* combine results */
549 ddd += cc + md->state[1]; /* final result for md->state[0] */
550 md->state[1] = md->state[2] + dd + eee;
551 md->state[2] = md->state[3] + ee + aaa;
552 md->state[3] = md->state[4] + aa + bbb;
553 md->state[4] = md->state[0] + bb + ccc;
554 md->state[0] = ddd;
9d365796 555
d019c447 556 return 0;
557}
558
559/**
560 Initialize the hash state
561 @param md The hash state you wish to initialize
562 @return 0 if successful
563 */
564int rmd160_vinit(struct rmd160_vstate * md)
565{
566 md->state[0] = 0x67452301UL;
567 md->state[1] = 0xefcdab89UL;
568 md->state[2] = 0x98badcfeUL;
569 md->state[3] = 0x10325476UL;
570 md->state[4] = 0xc3d2e1f0UL;
571 md->curlen = 0;
572 md->length = 0;
573 return 0;
574}
575#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \
576int func_name (struct rmd160_vstate * md, const unsigned char *in, unsigned long inlen) \
577{ \
578unsigned long n; \
579int err; \
580if (md->curlen > sizeof(md->buf)) { \
581return -1; \
582} \
583while (inlen > 0) { \
584if (md->curlen == 0 && inlen >= block_size) { \
585if ((err = compress_name (md, (unsigned char *)in)) != 0) { \
586return err; \
587} \
588md->length += block_size * 8; \
589in += block_size; \
590inlen -= block_size; \
591} else { \
592n = MIN(inlen, (block_size - md->curlen)); \
593memcpy(md->buf + md->curlen, in, (size_t)n); \
594md->curlen += n; \
595in += n; \
596inlen -= n; \
597if (md->curlen == block_size) { \
598if ((err = compress_name (md, md->buf)) != 0) { \
599return err; \
600} \
601md->length += 8*block_size; \
602md->curlen = 0; \
603} \
604} \
605} \
606return 0; \
607}
608
609/**
610 Process a block of memory though the hash
611 @param md The hash state
612 @param in The data to hash
613 @param inlen The length of the data (octets)
614 @return 0 if successful
615 */
616HASH_PROCESS(rmd160_vprocess, rmd160_vcompress, rmd160, 64)
617
618/**
619 Terminate the hash to get the digest
620 @param md The hash state
621 @param out [out] The destination of the hash (20 bytes)
622 @return 0 if successful
623 */
624int rmd160_vdone(struct rmd160_vstate * md, unsigned char *out)
625{
626 int i;
627 if (md->curlen >= sizeof(md->buf)) {
628 return -1;
629 }
630 /* increase the length of the message */
631 md->length += md->curlen * 8;
9d365796 632
d019c447 633 /* append the '1' bit */
634 md->buf[md->curlen++] = (unsigned char)0x80;
9d365796 635
d019c447 636 /* if the length is currently above 56 bytes we append zeros
637 * then compress. Then we can fall back to padding zeros and length
638 * encoding like normal.
639 */
640 if (md->curlen > 56) {
641 while (md->curlen < 64) {
642 md->buf[md->curlen++] = (unsigned char)0;
643 }
644 rmd160_vcompress(md, md->buf);
645 md->curlen = 0;
646 }
647 /* pad upto 56 bytes of zeroes */
648 while (md->curlen < 56) {
649 md->buf[md->curlen++] = (unsigned char)0;
650 }
651 /* store length */
652 STORE64L(md->length, md->buf+56);
653 rmd160_vcompress(md, md->buf);
654 /* copy output */
655 for (i = 0; i < 5; i++) {
656 STORE32L(md->state[i], out+(4*i));
657 }
658 return 0;
659}
660
661void calc_rmd160(char deprecated[41],uint8_t buf[20],uint8_t *msg,int32_t len)
662{
663 struct rmd160_vstate md;
664 rmd160_vinit(&md);
665 rmd160_vprocess(&md,msg,len);
666 rmd160_vdone(&md, buf);
667}
52198432 668#undef F
669#undef G
670#undef H
671#undef I
672#undef J
673#undef ROLc
674#undef FF
675#undef GG
676#undef HH
677#undef II
678#undef JJ
679#undef FFF
680#undef GGG
681#undef HHH
682#undef III
683#undef JJJ
3eea72f2 684
1e81ccb7 685static const uint32_t crc32_tab[] = {
686 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
687 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
688 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
689 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
690 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
691 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
692 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
693 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
694 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
695 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
696 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
697 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
698 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
699 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
700 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
701 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
702 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
703 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
704 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
705 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
706 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
707 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
708 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
709 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
710 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
711 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
712 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
713 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
714 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
715 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
716 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
717 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
718 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
719 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
720 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
721 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
722 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
723 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
724 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
725 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
726 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
727 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
728 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
729};
730
731uint32_t calc_crc32(uint32_t crc,const void *buf,size_t size)
732{
733 const uint8_t *p;
9d365796 734
1e81ccb7 735 p = (const uint8_t *)buf;
736 crc = crc ^ ~0U;
9d365796 737
1e81ccb7 738 while (size--)
739 crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
9d365796 740
1e81ccb7 741 return crc ^ ~0U;
742}
743
d019c447 744void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen)
745{
746 bits256 hash;
747 vcalc_sha256(0,hash.bytes,data,datalen);
748 calc_rmd160(0,rmd160,hash.bytes,sizeof(hash));
749}
750
751int32_t bitcoin_addr2rmd160(uint8_t *addrtypep,uint8_t rmd160[20],char *coinaddr)
752{
753 bits256 hash; uint8_t *buf,_buf[25]; int32_t len;
754 memset(rmd160,0,20);
755 *addrtypep = 0;
756 buf = _buf;
757 if ( (len= bitcoin_base58decode(buf,coinaddr)) >= 4 )
758 {
759 // validate with trailing hash, then remove hash
760 hash = bits256_doublesha256(0,buf,21);
761 *addrtypep = *buf;
762 memcpy(rmd160,buf+1,20);
763 if ( (buf[21]&0xff) == hash.bytes[31] && (buf[22]&0xff) == hash.bytes[30] &&(buf[23]&0xff) == hash.bytes[29] && (buf[24]&0xff) == hash.bytes[28] )
764 {
765 //printf("coinaddr.(%s) valid checksum addrtype.%02x\n",coinaddr,*addrtypep);
766 return(20);
767 }
768 else
769 {
770 int32_t i;
771 if ( len > 20 )
772 {
773 hash = bits256_doublesha256(0,buf,len);
774 }
775 for (i=0; i<len; i++)
776 printf("%02x ",buf[i]);
7637aa7f 777 printf("\nhex checkhash.(%s) len.%d mismatch %02x %02x %02x %02x vs %02x %02x %02x %02x\n",coinaddr,len,buf[len-1]&0xff,buf[len-2]&0xff,buf[len-3]&0xff,buf[len-4]&0xff,hash.bytes[31],hash.bytes[30],hash.bytes[29],hash.bytes[28]);
d019c447 778 }
779 }
780 return(0);
781}
782
783char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len)
784{
785 int32_t i; uint8_t data[25]; bits256 hash;// char checkaddr[65];
786 if ( len != 20 )
787 calc_rmd160_sha256(data+1,pubkey_or_rmd160,len);
788 else memcpy(data+1,pubkey_or_rmd160,20);
789 //btc_convrmd160(checkaddr,addrtype,data+1);
790 data[0] = addrtype;
791 hash = bits256_doublesha256(0,data,21);
792 for (i=0; i<4; i++)
793 data[21+i] = hash.bytes[31-i];
794 if ( (coinaddr= bitcoin_base58encode(coinaddr,data,25)) != 0 )
795 {
796 //uint8_t checktype,rmd160[20];
797 //bitcoin_addr2rmd160(&checktype,rmd160,coinaddr);
798 //if ( strcmp(checkaddr,coinaddr) != 0 )
799 // printf("checkaddr.(%s) vs coinaddr.(%s) %02x vs [%02x] memcmp.%d\n",checkaddr,coinaddr,addrtype,checktype,memcmp(rmd160,data+1,20));
800 }
801 return(coinaddr);
802}
803
dfa036b6 804#define MAX_CURRENCIES 32
18d9697a 805char CURRENCIES[][8] = { "USD", "EUR", "JPY", "GBP", "AUD", "CAD", "CHF", "NZD", // major currencies
806 "CNY", "RUB", "MXN", "BRL", "INR", "HKD", "TRY", "ZAR", "PLN", "NOK", "SEK", "DKK", "CZK", "HUF", "ILS", "KRW", "MYR", "PHP", "RON", "SGD", "THB", "BGN", "IDR", "HRK",
807 "KMD" };
808
809int32_t komodo_baseid(char *origbase)
810{
811 int32_t i; char base[64];
812 for (i=0; origbase[i]!=0&&i<sizeof(base); i++)
813 base[i] = toupper((int32_t)(origbase[i] & 0xff));
814 base[i] = 0;
815 for (i=0; i<=MAX_CURRENCIES; i++)
816 if ( strcmp(CURRENCIES[i],base) == 0 )
817 return(i);
dd051793 818 //printf("illegal base.(%s) %s\n",origbase,base);
18d9697a 819 return(-1);
820}
821
8e3430ee 822int32_t komodo_is_issuer()
823{
654dfaaf 824 if ( ASSETCHAINS_SYMBOL[0] != 0 && komodo_baseid(ASSETCHAINS_SYMBOL) >= 0 )
8e3430ee 825 return(1);
826 else return(0);
827}
828
d2a115d8 829int32_t bitweight(uint64_t x)
830{
831 int i,wt = 0;
832 for (i=0; i<64; i++)
833 if ( (1LL << i) & x )
834 wt++;
835 return(wt);
836}
837
1e81ccb7 838int32_t _unhex(char c)
839{
840 if ( c >= '0' && c <= '9' )
841 return(c - '0');
842 else if ( c >= 'a' && c <= 'f' )
843 return(c - 'a' + 10);
844 else if ( c >= 'A' && c <= 'F' )
845 return(c - 'A' + 10);
846 return(-1);
847}
848
849int32_t is_hexstr(char *str,int32_t n)
850{
851 int32_t i;
852 if ( str == 0 || str[0] == 0 )
853 return(0);
854 for (i=0; str[i]!=0; i++)
855 {
856 if ( n > 0 && i >= n )
857 break;
858 if ( _unhex(str[i]) < 0 )
859 break;
860 }
861 if ( n == 0 )
862 return(i);
863 return(i == n);
864}
865
866int32_t unhex(char c)
867{
868 int32_t hex;
869 if ( (hex= _unhex(c)) < 0 )
870 {
871 //printf("unhex: illegal hexchar.(%c)\n",c);
872 }
873 return(hex);
874}
875
876unsigned char _decode_hex(char *hex) { return((unhex(hex[0])<<4) | unhex(hex[1])); }
877
878int32_t decode_hex(uint8_t *bytes,int32_t n,char *hex)
879{
880 int32_t adjust,i = 0;
881 //printf("decode.(%s)\n",hex);
4f569c79 882 if ( is_hexstr(hex,n) <= 0 )
1e81ccb7 883 {
884 memset(bytes,0,n);
885 return(n);
886 }
e37f280f 887 if ( hex[n-1] == '\n' || hex[n-1] == '\r' )
4f569c79 888 hex[--n] = 0;
1e81ccb7 889 if ( n == 0 || (hex[n*2+1] == 0 && hex[n*2] != 0) )
890 {
891 if ( n > 0 )
892 {
893 bytes[0] = unhex(hex[0]);
894 printf("decode_hex n.%d hex[0] (%c) -> %d hex.(%s) [n*2+1: %d] [n*2: %d %c] len.%ld\n",n,hex[0],bytes[0],hex,hex[n*2+1],hex[n*2],hex[n*2],(long)strlen(hex));
895 }
896 bytes++;
897 hex++;
898 adjust = 1;
899 } else adjust = 0;
900 if ( n > 0 )
901 {
902 for (i=0; i<n; i++)
903 bytes[i] = _decode_hex(&hex[i*2]);
904 }
905 //bytes[i] = 0;
906 return(n + adjust);
907}
908
32b1b443 909char hexbyte(int32_t c)
910{
911 c &= 0xf;
912 if ( c < 10 )
913 return('0'+c);
914 else if ( c < 16 )
915 return('a'+c-10);
916 else return(0);
917}
918
919int32_t init_hexbytes_noT(char *hexbytes,unsigned char *message,long len)
920{
921 int32_t i;
922 if ( len <= 0 )
923 {
924 hexbytes[0] = 0;
925 return(1);
926 }
927 for (i=0; i<len; i++)
928 {
929 hexbytes[i*2] = hexbyte((message[i]>>4) & 0xf);
930 hexbytes[i*2 + 1] = hexbyte(message[i] & 0xf);
931 //printf("i.%d (%02x) [%c%c]\n",i,message[i],hexbytes[i*2],hexbytes[i*2+1]);
932 }
933 hexbytes[len*2] = 0;
934 //printf("len.%ld\n",len*2+1);
935 return((int32_t)len*2+1);
936}
937
938char *bits256_str(char hexstr[65],bits256 x)
939{
940 init_hexbytes_noT(hexstr,x.bytes,sizeof(x));
941 return(hexstr);
942}
943
1e81ccb7 944int32_t iguana_rwnum(int32_t rwflag,uint8_t *serialized,int32_t len,void *endianedp)
945{
946 int32_t i; uint64_t x;
947 if ( rwflag == 0 )
948 {
949 x = 0;
950 for (i=len-1; i>=0; i--)
951 {
952 x <<= 8;
953 x |= serialized[i];
954 }
955 switch ( len )
956 {
957 case 1: *(uint8_t *)endianedp = (uint8_t)x; break;
958 case 2: *(uint16_t *)endianedp = (uint16_t)x; break;
959 case 4: *(uint32_t *)endianedp = (uint32_t)x; break;
960 case 8: *(uint64_t *)endianedp = (uint64_t)x; break;
961 }
962 }
963 else
964 {
965 x = 0;
966 switch ( len )
967 {
968 case 1: x = *(uint8_t *)endianedp; break;
969 case 2: x = *(uint16_t *)endianedp; break;
970 case 4: x = *(uint32_t *)endianedp; break;
971 case 8: x = *(uint64_t *)endianedp; break;
972 }
973 for (i=0; i<len; i++,x >>= 8)
974 serialized[i] = (uint8_t)(x & 0xff);
975 }
976 return(len);
977}
978
979int32_t iguana_rwbignum(int32_t rwflag,uint8_t *serialized,int32_t len,uint8_t *endianedp)
980{
981 int32_t i;
982 if ( rwflag == 0 )
983 {
984 for (i=0; i<len; i++)
985 endianedp[i] = serialized[i];
986 }
987 else
988 {
989 for (i=0; i<len; i++)
990 serialized[i] = endianedp[i];
991 }
992 return(len);
993}
994
64bb0834 995int32_t komodo_scriptitemlen(int32_t *opretlenp,uint8_t *script)
996{
997 int32_t opretlen,len = 0;
998 if ( (opretlen= script[len++]) >= 0x4c )
999 {
1000 if ( opretlen == 0x4c )
1001 opretlen = script[len++];
1002 else if ( opretlen == 0x4d )
1003 {
4206dee5 1004 opretlen = script[len] + (script[len+1] << 8);
1005 len += 2;
1006 //opretlen = script[len++];
1007 //opretlen = (opretlen << 8) | script[len++];
64bb0834 1008 }
1009 }
1010 *opretlenp = opretlen;
1011 return(len);
1012}
1013
1e81ccb7 1014int32_t komodo_opreturnscript(uint8_t *script,uint8_t type,uint8_t *opret,int32_t opretlen)
1015{
1016 int32_t offset = 0;
1017 script[offset++] = 0x6a;
1018 opretlen++;
1019 if ( opretlen >= 0x4c )
1020 {
1021 if ( opretlen > 0xff )
1022 {
1023 script[offset++] = 0x4d;
1024 script[offset++] = opretlen & 0xff;
1025 script[offset++] = (opretlen >> 8) & 0xff;
1026 }
1027 else
1028 {
1029 script[offset++] = 0x4c;
1030 script[offset++] = opretlen;
1031 }
1032 } else script[offset++] = opretlen;
795751ec 1033 script[offset++] = type; // covered by opretlen
1034 memcpy(&script[offset],opret,opretlen-1);
1035 return(offset + opretlen - 1);
1e81ccb7 1036}
438d3f35 1037
fd1799a6 1038long _stripwhite(char *buf,int accept)
1039{
1040 int32_t i,j,c;
1041 if ( buf == 0 || buf[0] == 0 )
1042 return(0);
1043 for (i=j=0; buf[i]!=0; i++)
1044 {
1045 buf[j] = c = buf[i];
1046 if ( c == accept || (c != ' ' && c != '\n' && c != '\r' && c != '\t' && c != '\b') )
1047 j++;
1048 }
1049 buf[j] = 0;
1050 return(j);
1051}
1052
2c36c760 1053char *clonestr(char *str)
1054{
1055 char *clone;
1056 if ( str == 0 || str[0] == 0 )
1057 {
1058 printf("warning cloning nullstr.%p\n",str);
1059#ifdef __APPLE__
1060 while ( 1 ) sleep(1);
1061#endif
1062 str = (char *)"<nullstr>";
1063 }
1064 clone = (char *)malloc(strlen(str)+16);
1065 strcpy(clone,str);
1066 return(clone);
1067}
1068
f3d5295c 1069int32_t safecopy(char *dest,char *src,long len)
1070{
1071 int32_t i = -1;
1072 if ( src != 0 && dest != 0 && src != dest )
1073 {
1074 if ( dest != 0 )
1075 memset(dest,0,len);
1076 for (i=0; i<len&&src[i]!=0; i++)
1077 dest[i] = src[i];
1078 if ( i == len )
1079 {
1080 printf("safecopy: %s too long %ld\n",src,len);
1081#ifdef __APPLE__
1082 //getchar();
1083#endif
1084 return(-1);
1085 }
1086 dest[i] = 0;
1087 }
1088 return(i);
1089}
1090
fd1799a6 1091char *parse_conf_line(char *line,char *field)
1092{
1093 line += strlen(field);
1094 for (; *line!='='&&*line!=0; line++)
1095 break;
1096 if ( *line == 0 )
1097 return(0);
1098 if ( *line == '=' )
1099 line++;
83c2d095 1100 while ( line[strlen(line)-1] == '\r' || line[strlen(line)-1] == '\n' || line[strlen(line)-1] == ' ' )
5ae7efc1 1101 line[strlen(line)-1] = 0;
e78fb5d3 1102 //printf("LINE.(%s)\n",line);
fd1799a6 1103 _stripwhite(line,0);
1104 return(clonestr(line));
1105}
1106
38550ae9 1107double OS_milliseconds()
1108{
1109 struct timeval tv; double millis;
1110 gettimeofday(&tv,NULL);
1111 millis = ((double)tv.tv_sec * 1000. + (double)tv.tv_usec / 1000.);
1112 //printf("tv_sec.%ld usec.%d %f\n",tv.tv_sec,tv.tv_usec,millis);
1113 return(millis);
1114}
1115
9d365796 1116#ifndef _WIN32
f9557624 1117void OS_randombytes(unsigned char *x,long xlen)
5e39a3aa 1118{
1119 static int fd = -1;
1120 int32_t i;
1121 if (fd == -1) {
1122 for (;;) {
1123 fd = open("/dev/urandom",O_RDONLY);
1124 if (fd != -1) break;
1125 sleep(1);
1126 }
1127 }
1128 while (xlen > 0) {
1129 if (xlen < 1048576) i = (int32_t)xlen; else i = 1048576;
1130 i = (int32_t)read(fd,x,i);
1131 if (i < 1) {
1132 sleep(1);
1133 continue;
1134 }
1135 if ( 0 )
1136 {
1137 int32_t j;
1138 for (j=0; j<i; j++)
1139 printf("%02x ",x[j]);
1140 printf("-> %p\n",x);
1141 }
1142 x += i;
1143 xlen -= i;
1144 }
1145}
9d365796 1146#endif
5e39a3aa 1147
429dabb5 1148void lock_queue(queue_t *queue)
1149{
1150 if ( queue->initflag == 0 )
1151 {
1152 portable_mutex_init(&queue->mutex);
1153 queue->initflag = 1;
1154 }
1155 portable_mutex_lock(&queue->mutex);
1156}
1157
5fa92ab2 1158void queue_enqueue(char *name,queue_t *queue,struct queueitem *item)
429dabb5 1159{
429dabb5 1160 if ( queue->name[0] == 0 && name != 0 && name[0] != 0 )
5fa92ab2 1161 strcpy(queue->name,name);
1162 if ( item == 0 )
429dabb5 1163 {
5fa92ab2 1164 printf("FATAL type error: queueing empty value\n");
429dabb5 1165 return;
1166 }
429dabb5 1167 lock_queue(queue);
429dabb5 1168 DL_APPEND(queue->list,item);
1169 portable_mutex_unlock(&queue->mutex);
429dabb5 1170}
1171
5fa92ab2 1172struct queueitem *queue_dequeue(queue_t *queue)
429dabb5 1173{
1174 struct queueitem *item = 0;
1175 lock_queue(queue);
1176 if ( queue->list != 0 )
1177 {
1178 item = queue->list;
429dabb5 1179 DL_DELETE(queue->list,item);
1180 }
1181 portable_mutex_unlock(&queue->mutex);
5fa92ab2 1182 return(item);
429dabb5 1183}
1184
405e2bdd 1185void *queue_delete(queue_t *queue,struct queueitem *copy,int32_t copysize)
429dabb5 1186{
429dabb5 1187 struct queueitem *item = 0;
1188 lock_queue(queue);
1189 if ( queue->list != 0 )
1190 {
1191 DL_FOREACH(queue->list,item)
1192 {
9d365796 1193 #ifdef _WIN32
1194 if ( item == copy || (item->allocsize == copysize && memcmp((void *)((intptr_t)item + sizeof(struct queueitem)),(void *)((intptr_t)copy + sizeof(struct queueitem)),copysize) == 0) )
1195 #else
5fa92ab2 1196 if ( item == copy || (item->allocsize == copysize && memcmp((void *)((long)item + sizeof(struct queueitem)),(void *)((long)copy + sizeof(struct queueitem)),copysize) == 0) )
9d365796 1197 #endif
429dabb5 1198 {
1199 DL_DELETE(queue->list,item);
1200 portable_mutex_unlock(&queue->mutex);
5fa92ab2 1201 printf("name.(%s) deleted item.%p list.%p\n",queue->name,item,queue->list);
429dabb5 1202 return(item);
1203 }
1204 }
1205 }
1206 portable_mutex_unlock(&queue->mutex);
1207 return(0);
1208}
1209
1210void *queue_free(queue_t *queue)
1211{
1212 struct queueitem *item = 0;
1213 lock_queue(queue);
1214 if ( queue->list != 0 )
1215 {
1216 DL_FOREACH(queue->list,item)
1217 {
1218 DL_DELETE(queue->list,item);
5fa92ab2 1219 free(item);
429dabb5 1220 }
1221 //printf("name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list);
1222 }
1223 portable_mutex_unlock(&queue->mutex);
1224 return(0);
1225}
1226
1227void *queue_clone(queue_t *clone,queue_t *queue,int32_t size)
1228{
1229 struct queueitem *ptr,*item = 0;
1230 lock_queue(queue);
1231 if ( queue->list != 0 )
1232 {
1233 DL_FOREACH(queue->list,item)
1234 {
5fa92ab2 1235 ptr = (struct queueitem *)calloc(1,sizeof(*ptr));
429dabb5 1236 memcpy(ptr,item,size);
a856c56a 1237 queue_enqueue(queue->name,clone,ptr);
429dabb5 1238 }
1239 //printf("name.(%s) dequeue.%p list.%p\n",queue->name,item,queue->list);
1240 }
1241 portable_mutex_unlock(&queue->mutex);
1242 return(0);
1243}
1244
1245int32_t queue_size(queue_t *queue)
1246{
1247 int32_t count = 0;
1248 struct queueitem *tmp;
1249 lock_queue(queue);
1250 DL_COUNT(queue->list,tmp,count);
1251 portable_mutex_unlock(&queue->mutex);
1252 return count;
1253}
a18fbdc5 1254
1255void iguana_initQ(queue_t *Q,char *name)
1256{
25314868 1257 struct queueitem *item,*I;
a18fbdc5 1258 memset(Q,0,sizeof(*Q));
96d1da77 1259 I = (struct queueitem *)calloc(1,sizeof(*I));
a18fbdc5 1260 strcpy(Q->name,name);
25314868 1261 queue_enqueue(name,Q,I);
5fa92ab2 1262 if ( (item= queue_dequeue(Q)) != 0 )
1263 free(item);
a18fbdc5 1264}
561ff778 1265
05e307ec 1266uint16_t komodo_userpass(char *username,char *password,FILE *fp)
561ff778 1267{
05e307ec 1268 char *rpcuser,*rpcpassword,*str,line[8192]; uint16_t port = 0;
561ff778 1269 rpcuser = rpcpassword = 0;
1270 username[0] = password[0] = 0;
1271 while ( fgets(line,sizeof(line),fp) != 0 )
1272 {
1273 if ( line[0] == '#' )
1274 continue;
1275 //printf("line.(%s) %p %p\n",line,strstr(line,(char *)"rpcuser"),strstr(line,(char *)"rpcpassword"));
1276 if ( (str= strstr(line,(char *)"rpcuser")) != 0 )
1277 rpcuser = parse_conf_line(str,(char *)"rpcuser");
1278 else if ( (str= strstr(line,(char *)"rpcpassword")) != 0 )
1279 rpcpassword = parse_conf_line(str,(char *)"rpcpassword");
05e307ec 1280 else if ( (str= strstr(line,(char *)"rpcport")) != 0 )
1281 {
1282 port = atoi(parse_conf_line(str,(char *)"rpcport"));
21abd4df 1283 //printf("rpcport.%u in file\n",port);
05e307ec 1284 }
561ff778 1285 }
1286 if ( rpcuser != 0 && rpcpassword != 0 )
1287 {
1288 strcpy(username,rpcuser);
1289 strcpy(password,rpcpassword);
1290 }
1291 //printf("rpcuser.(%s) rpcpassword.(%s) KMDUSERPASS.(%s) %u\n",rpcuser,rpcpassword,KMDUSERPASS,port);
1292 if ( rpcuser != 0 )
1293 free(rpcuser);
1294 if ( rpcpassword != 0 )
1295 free(rpcpassword);
05e307ec 1296 return(port);
561ff778 1297}
1298
0ded57c8 1299void komodo_statefname(char *fname,char *symbol,char *str)
ab918767 1300{
1301 int32_t n,len;
1302 sprintf(fname,"%s",GetDataDir(false).string().c_str());
4eb91c7a 1303 if ( (n= (int32_t)strlen(ASSETCHAINS_SYMBOL)) != 0 )
ab918767 1304 {
1305 len = (int32_t)strlen(fname);
29255d5f 1306 if ( strcmp(ASSETCHAINS_SYMBOL,&fname[len - n]) == 0 )
ab918767 1307 fname[len - n] = 0;
ab918767 1308 else
1309 {
a4ddd789 1310 printf("unexpected fname.(%s) vs %s [%s] n.%d len.%d (%s)\n",fname,symbol,ASSETCHAINS_SYMBOL,n,len,&fname[len - n]);
ab918767 1311 return;
1312 }
1313 }
643d946e 1314 else
1315 {
9cb1ec9c 1316#ifdef _WIN32
643d946e 1317 strcat(fname,"\\");
20533bd8 1318#else
643d946e 1319 strcat(fname,"/");
20533bd8 1320#endif
643d946e 1321 }
1322 if ( symbol != 0 && symbol[0] != 0 && strcmp("KMD",symbol) != 0 )
1323 {
413d04bf 1324 strcat(fname,symbol);
643d946e 1325 //printf("statefname.(%s) -> (%s)\n",symbol,fname);
9cb1ec9c 1326#ifdef _WIN32
643d946e 1327 strcat(fname,"\\");
1740e3aa 1328#else
643d946e 1329 strcat(fname,"/");
1740e3aa 1330#endif
643d946e 1331 }
0ded57c8 1332 strcat(fname,str);
643d946e 1333 //printf("test.(%s) -> [%s] statename.(%s) %s\n",test,ASSETCHAINS_SYMBOL,symbol,fname);
ab918767 1334}
1335
561ff778 1336void komodo_configfile(char *symbol,uint16_t port)
1337{
1338 static char myusername[512],mypassword[8192];
9850ab03 1339 FILE *fp; uint16_t kmdport; uint8_t buf2[33]; char fname[512],buf[128],username[512],password[8192]; uint32_t crc,r,r2,i;
347acd7f 1340 if ( symbol != 0 && port != 0 )
1341 {
1342 r = (uint32_t)time(NULL);
1343 r2 = OS_milliseconds();
1344 memcpy(buf,&r,sizeof(r));
1345 memcpy(&buf[sizeof(r)],&r2,sizeof(r2));
1346 memcpy(&buf[sizeof(r)+sizeof(r2)],symbol,strlen(symbol));
1347 crc = calc_crc32(0,(uint8_t *)buf,(int32_t)(sizeof(r)+sizeof(r2)+strlen(symbol)));
9d365796 1348 #ifdef _WIN32
1349 randombytes_buf(buf2,sizeof(buf2));
1350 #else
347acd7f 1351 OS_randombytes(buf2,sizeof(buf2));
9d365796 1352 #endif
347acd7f 1353 for (i=0; i<sizeof(buf2); i++)
1354 sprintf(&password[i*2],"%02x",buf2[i]);
1355 password[i*2] = 0;
1356 sprintf(buf,"%s.conf",symbol);
1357 BITCOIND_PORT = port;
9cb1ec9c 1358#ifdef _WIN32
c1428363 1359 sprintf(fname,"%s\\%s",GetDataDir(false).string().c_str(),buf);
561ff778 1360#else
c1428363 1361 sprintf(fname,"%s/%s",GetDataDir(false).string().c_str(),buf);
561ff778 1362#endif
347acd7f 1363 if ( (fp= fopen(fname,"rb")) == 0 )
1364 {
95c46396 1365#ifndef FROM_CLI
347acd7f 1366 if ( (fp= fopen(fname,"wb")) != 0 )
1367 {
acb93848 1368 fprintf(fp,"rpcuser=user%u\nrpcpassword=pass%s\nrpcport=%u\nserver=1\ntxindex=1\nrpcworkqueue=64\nrpcallowip=127.0.0.1\n",crc,password,port);
347acd7f 1369 fclose(fp);
1370 printf("Created (%s)\n",fname);
1371 } else printf("Couldnt create (%s)\n",fname);
95c46396 1372#endif
347acd7f 1373 }
1374 else
561ff778 1375 {
347acd7f 1376 komodo_userpass(myusername,mypassword,fp);
1377 mapArgs["-rpcpassword"] = mypassword;
1378 mapArgs["-rpcusername"] = myusername;
1379 //fprintf(stderr,"myusername.(%s)\n",myusername);
561ff778 1380 fclose(fp);
347acd7f 1381 }
561ff778 1382 }
cad9f4c8 1383 strcpy(fname,GetDataDir().string().c_str());
9cb1ec9c 1384#ifdef _WIN32
561ff778 1385 while ( fname[strlen(fname)-1] != '\\' )
1386 fname[strlen(fname)-1] = 0;
323832c3 1387 strcat(fname,"komodo.conf");
561ff778 1388#else
1389 while ( fname[strlen(fname)-1] != '/' )
1390 fname[strlen(fname)-1] = 0;
b55c2367 1391#ifdef __APPLE__
1392 strcat(fname,"Komodo.conf");
1393#else
323832c3 1394 strcat(fname,"komodo.conf");
b55c2367 1395#endif
561ff778 1396#endif
561ff778 1397 if ( (fp= fopen(fname,"rb")) != 0 )
1398 {
9850ab03 1399 if ( (kmdport= komodo_userpass(username,password,fp)) != 0 )
1400 KMD_PORT = kmdport;
561ff778 1401 sprintf(KMDUSERPASS,"%s:%s",username,password);
1402 fclose(fp);
43cc3df6 1403//printf("KOMODO.(%s) -> userpass.(%s)\n",fname,KMDUSERPASS);
6ec3d43c 1404 } //else printf("couldnt open.(%s)\n",fname);
561ff778 1405}
1406
05e307ec 1407uint16_t komodo_userpass(char *userpass,char *symbol)
0ded57c8 1408{
7c130297 1409 FILE *fp; uint16_t port = 0; char fname[512],username[512],password[512],confname[KOMODO_ASSETCHAIN_MAXLEN];
0ded57c8 1410 userpass[0] = 0;
609fbcc2 1411 if ( strcmp("KMD",symbol) == 0 )
b55c2367 1412 {
1413#ifdef __APPLE__
1414 sprintf(confname,"Komodo.conf");
1415#else
609fbcc2 1416 sprintf(confname,"komodo.conf");
b55c2367 1417#endif
1418 }
609fbcc2 1419 else sprintf(confname,"%s.conf",symbol);
0ded57c8 1420 komodo_statefname(fname,symbol,confname);
1421 if ( (fp= fopen(fname,"rb")) != 0 )
1422 {
05e307ec 1423 port = komodo_userpass(username,password,fp);
0ded57c8 1424 sprintf(userpass,"%s:%s",username,password);
a643c078 1425 if ( strcmp(symbol,ASSETCHAINS_SYMBOL) == 0 )
1426 strcpy(ASSETCHAINS_USERPASS,userpass);
0ded57c8 1427 fclose(fp);
1428 return((int32_t)strlen(userpass));
1429 }
05e307ec 1430 return(port);
0ded57c8 1431}
1432
8683bd8d 1433uint32_t komodo_assetmagic(char *symbol,uint64_t supply,uint8_t *extraptr,int32_t extralen)
3aca2705 1434{
8683bd8d 1435 uint8_t buf[512]; uint32_t crc0=0; int32_t len = 0; bits256 hash;
550824a8 1436 if ( strcmp(symbol,"KMD") == 0 )
1437 return(0x8de4eef9);
3aca2705 1438 len = iguana_rwnum(1,&buf[len],sizeof(supply),(void *)&supply);
1439 strcpy((char *)&buf[len],symbol);
1440 len += strlen(symbol);
8683bd8d 1441 if ( extraptr != 0 && extralen != 0 )
1442 {
1443 vcalc_sha256(0,hash.bytes,extraptr,extralen);
1444 crc0 = hash.uints[0];
1445 }
1446 return(calc_crc32(crc0,buf,len));
3aca2705 1447}
1448
2cd57608 1449uint16_t komodo_assetport(uint32_t magic,int32_t extralen)
3aca2705 1450{
550824a8 1451 if ( magic == 0x8de4eef9 )
950baa0e 1452 return(7770);
2cd57608 1453 else if ( extralen == 0 )
1454 return(8000 + (magic % 7777));
1455 else return(16000 + (magic % 49500));
3aca2705 1456}
1457
8683bd8d 1458uint16_t komodo_port(char *symbol,uint64_t supply,uint32_t *magicp,uint8_t *extraptr,int32_t extralen)
3aca2705 1459{
550824a8 1460 if ( symbol == 0 || symbol[0] == 0 || strcmp("KMD",symbol) == 0 )
1461 {
1462 *magicp = 0x8de4eef9;
950baa0e 1463 return(7770);
550824a8 1464 }
8683bd8d 1465 *magicp = komodo_assetmagic(symbol,supply,extraptr,extralen);
2cd57608 1466 return(komodo_assetport(*magicp,extralen));
3aca2705 1467}
1468
8683bd8d 1469/*void komodo_ports(uint16_t ports[MAX_CURRENCIES])
3aca2705 1470{
e7a90cf9 1471 int32_t i; uint32_t magic;
3aca2705 1472 for (i=0; i<MAX_CURRENCIES; i++)
1473 {
e7a90cf9 1474 ports[i] = komodo_port(CURRENCIES[i],10,&magic);
3aca2705 1475 printf("%u ",ports[i]);
1476 }
1477 printf("ports\n");
8683bd8d 1478}*/
3aca2705 1479
4a4e912b 1480char *iguanafmtstr = (char *)"curl --url \"http://127.0.0.1:7778\" --data \"{\\\"conf\\\":\\\"%s.conf\\\",\\\"path\\\":\\\"${HOME#\"/\"}/.komodo/%s\\\",\\\"unitval\\\":\\\"20\\\",\\\"zcash\\\":1,\\\"RELAY\\\":1,\\\"VALIDATE\\\":1,\\\"prefetchlag\\\":-1,\\\"poll\\\":100,\\\"active\\\":1,\\\"agent\\\":\\\"iguana\\\",\\\"method\\\":\\\"addcoin\\\",\\\"startpend\\\":4,\\\"endpend\\\":4,\\\"services\\\":129,\\\"maxpeers\\\":8,\\\"newcoin\\\":\\\"%s\\\",\\\"name\\\":\\\"%s\\\",\\\"hasheaders\\\":1,\\\"useaddmultisig\\\":0,\\\"netmagic\\\":\\\"%s\\\",\\\"p2p\\\":%u,\\\"rpc\\\":%u,\\\"pubval\\\":60,\\\"p2shval\\\":85,\\\"wifval\\\":188,\\\"txfee_satoshis\\\":\\\"10000\\\",\\\"isPoS\\\":0,\\\"minoutput\\\":10000,\\\"minconfirms\\\":2,\\\"genesishash\\\":\\\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\\\",\\\"protover\\\":170002,\\\"genesisblock\\\":\\\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\\\",\\\"debug\\\":0,\\\"seedipaddr\\\":\\\"%s\\\"}\"";
7b7049d3 1481
ab8ef450 1482
8683bd8d 1483int32_t komodo_whoami(char *pubkeystr,int32_t height,uint32_t timestamp)
58033467 1484{
9d365796 1485 int32_t i,notaryid;
58033467 1486 for (i=0; i<33; i++)
c96e160a 1487 sprintf(&pubkeystr[i<<1],"%02x",NOTARY_PUBKEY33[i]);
58033467 1488 pubkeystr[66] = 0;
8683bd8d 1489 komodo_chosennotary(&notaryid,height,NOTARY_PUBKEY33,timestamp);
58033467 1490 return(notaryid);
1491}
1492
34017212 1493char *argv0suffix[] =
1494{
0b7ef289 1495 (char *)"mnzd", (char *)"mnz-cli", (char *)"mnzd.exe", (char *)"mnz-cli.exe", (char *)"btchd", (char *)"btch-cli", (char *)"btchd.exe", (char *)"btch-cli.exe"
34017212 1496};
1497
1498char *argv0names[] =
1499{
0b7ef289 1500 (char *)"MNZ", (char *)"MNZ", (char *)"MNZ", (char *)"MNZ", (char *)"BTCH", (char *)"BTCH", (char *)"BTCH", (char *)"BTCH"
34017212 1501};
1502
1503void komodo_args(char *argv0)
561ff778 1504{
6f74fa28 1505 extern int64_t MAX_MONEY;
ce5dd547 1506 std::string name,addn; char *dirname,fname[512],arg0str[64],magicstr[9]; uint8_t magic[4],extrabuf[256],*extraptr=0; FILE *fp; uint64_t val; int32_t i,baseid,len,n,extralen = 0;
0e1af8a8 1507 IS_KOMODO_NOTARY = GetBoolArg("-notary", false);
2626c7e3 1508 if ( (KOMODO_EXCHANGEWALLET= GetBoolArg("-exchange", false)) != 0 )
1509 fprintf(stderr,"KOMODO_EXCHANGEWALLET mode active\n");
0e1af8a8 1510 NOTARY_PUBKEY = GetArg("-pubkey", "");
1511 if ( strlen(NOTARY_PUBKEY.c_str()) == 66 )
6cd01056 1512 {
0e1af8a8 1513 USE_EXTERNAL_PUBKEY = 1;
8683bd8d 1514 //KOMODO_PAX = 1;
1515 } //else KOMODO_PAX = GetArg("-pax",0);
0e1af8a8 1516 name = GetArg("-ac_name","");
89559d85 1517 if ( argv0 != 0 )
1518 {
1519 len = (int32_t)strlen(argv0);
1520 for (i=0; i<sizeof(argv0suffix)/sizeof(*argv0suffix); i++)
1521 {
1522 n = (int32_t)strlen(argv0suffix[i]);
1523 if ( strcmp(&argv0[len - n],argv0suffix[i]) == 0 )
1524 {
1525 //printf("ARGV0.(%s) -> matches suffix (%s) -> ac_name.(%s)\n",argv0,argv0suffix[i],argv0names[i]);
1526 name = argv0names[i];
1527 break;
34017212 1528 }
1529 }
1530 }
713c2a94 1531 ASSETCHAINS_CC = GetArg("-ac_cc",0);
acad2983 1532 if ( (KOMODO_REWIND= GetArg("-rewind",0)) != 0 )
4476ddfa 1533 {
1534 printf("KOMODO_REWIND %d\n",KOMODO_REWIND);
acad2983 1535 }
0e1af8a8 1536 if ( name.c_str()[0] != 0 )
561ff778 1537 {
0e1af8a8 1538 ASSETCHAINS_SUPPLY = GetArg("-ac_supply",10);
8683bd8d 1539 ASSETCHAINS_ENDSUBSIDY = GetArg("-ac_end",0);
1540 ASSETCHAINS_REWARD = GetArg("-ac_reward",0);
1541 ASSETCHAINS_HALVING = GetArg("-ac_halving",0);
1542 ASSETCHAINS_DECAY = GetArg("-ac_decay",0);
1543 ASSETCHAINS_COMMISSION = GetArg("-ac_perc",0);
1544 ASSETCHAINS_OVERRIDE_PUBKEY = GetArg("-ac_pubkey","");
4786d20c 1545 if ( (ASSETCHAINS_STAKED= GetArg("-ac_staked",0)) > 100 )
1546 ASSETCHAINS_STAKED = 100;
6e94384f 1547 if ( ASSETCHAINS_HALVING != 0 && ASSETCHAINS_HALVING < 1440 )
8683bd8d 1548 {
6e94384f 1549 ASSETCHAINS_HALVING = 1440;
1550 printf("ASSETCHAINS_HALVING must be at least 1440 blocks\n");
8683bd8d 1551 }
1552 if ( ASSETCHAINS_DECAY == 100000000 && ASSETCHAINS_ENDSUBSIDY == 0 )
1553 {
1554 ASSETCHAINS_DECAY = 0;
1555 printf("ASSETCHAINS_DECAY of 100000000 means linear and that needs ASSETCHAINS_ENDSUBSIDY\n");
1556 }
1557 else if ( ASSETCHAINS_DECAY > 100000000 )
1558 {
1559 ASSETCHAINS_DECAY = 0;
1560 printf("ASSETCHAINS_DECAY cant be more than 100000000\n");
1561 }
d209491a 1562 if ( strlen(ASSETCHAINS_OVERRIDE_PUBKEY.c_str()) == 66 && ASSETCHAINS_COMMISSION > 0 && ASSETCHAINS_COMMISSION <= 100000000 )
8683bd8d 1563 decode_hex(ASSETCHAINS_OVERRIDE_PUBKEY33,33,(char *)ASSETCHAINS_OVERRIDE_PUBKEY.c_str());
e8a05f61 1564 else if ( ASSETCHAINS_COMMISSION != 0 )
8683bd8d 1565 {
1566 ASSETCHAINS_COMMISSION = 0;
d209491a 1567 printf("ASSETCHAINS_COMMISSION needs an ASETCHAINS_OVERRIDE_PUBKEY and cant be more than 100000000 (100%%)\n");
8683bd8d 1568 }
1569 if ( ASSETCHAINS_ENDSUBSIDY != 0 || ASSETCHAINS_REWARD != 0 || ASSETCHAINS_HALVING != 0 || ASSETCHAINS_DECAY != 0 || ASSETCHAINS_COMMISSION != 0 )
1570 {
479f8ea9 1571 fprintf(stderr,"end.%llu blocks, reward %.8f halving.%llu blocks, decay.%llu perc %.4f%% ac_pub=[%02x...]\n",(long long)ASSETCHAINS_ENDSUBSIDY,dstr(ASSETCHAINS_REWARD),(long long)ASSETCHAINS_HALVING,(long long)ASSETCHAINS_DECAY,dstr(ASSETCHAINS_COMMISSION)*100,ASSETCHAINS_OVERRIDE_PUBKEY33[0]);
8683bd8d 1572 extraptr = extrabuf;
1573 memcpy(extraptr,ASSETCHAINS_OVERRIDE_PUBKEY33,33), extralen = 33;
1574 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_ENDSUBSIDY),(void *)&ASSETCHAINS_ENDSUBSIDY);
1575 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_REWARD),(void *)&ASSETCHAINS_REWARD);
1576 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_HALVING),(void *)&ASSETCHAINS_HALVING);
1577 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(ASSETCHAINS_DECAY),(void *)&ASSETCHAINS_DECAY);
713c2a94 1578 val = ASSETCHAINS_COMMISSION | (((uint64_t)ASSETCHAINS_STAKED & 0xff) << 32) | (((uint64_t)ASSETCHAINS_CC & 0xffffff) << 40);
ce5dd547 1579 extralen += iguana_rwnum(1,&extraptr[extralen],sizeof(val),(void *)&val);
8683bd8d 1580 }
6ed911ff 1581 addn = GetArg("-seednode","");
1582 if ( strlen(addn.c_str()) > 0 )
b6a7cb2c 1583 ASSETCHAINS_SEED = 1;
0e1af8a8 1584 strncpy(ASSETCHAINS_SYMBOL,name.c_str(),sizeof(ASSETCHAINS_SYMBOL)-1);
4e5442b5 1585 if ( (baseid= komodo_baseid(ASSETCHAINS_SYMBOL)) >= 0 && baseid < 32 )
1586 MAX_MONEY = komodo_maxallowed(baseid);
253cd526 1587 else if ( ASSETCHAINS_REWARD == 0 )
1588 MAX_MONEY = (ASSETCHAINS_SUPPLY+1) * SATOSHIDEN;
1589 else MAX_MONEY = (ASSETCHAINS_SUPPLY+1) * SATOSHIDEN + ASSETCHAINS_REWARD * (ASSETCHAINS_ENDSUBSIDY==0 ? 10000000 : ASSETCHAINS_ENDSUBSIDY);
10ad05f6 1590 MAX_MONEY += (MAX_MONEY * ASSETCHAINS_COMMISSION) / SATOSHIDEN;
9cdcf7ab 1591 //printf("baseid.%d MAX_MONEY.%s %.8f\n",baseid,ASSETCHAINS_SYMBOL,(double)MAX_MONEY/SATOSHIDEN);
8683bd8d 1592 ASSETCHAINS_PORT = komodo_port(ASSETCHAINS_SYMBOL,ASSETCHAINS_SUPPLY,&ASSETCHAINS_MAGIC,extraptr,extralen);
0e1af8a8 1593 while ( (dirname= (char *)GetDataDir(false).string().c_str()) == 0 || dirname[0] == 0 )
1594 {
1595 fprintf(stderr,"waiting for datadir\n");
9d365796 1596 #ifndef _WIN32
0e1af8a8 1597 sleep(3);
9d365796 1598 #else
1599 boost::this_thread::sleep(boost::posix_time::milliseconds(3000));
1600 #endif
0e1af8a8 1601 }
935fc055 1602 //fprintf(stderr,"Got datadir.(%s)\n",dirname);
0e1af8a8 1603 if ( ASSETCHAINS_SYMBOL[0] != 0 )
eda3ca93 1604 {
6051a4bc 1605 int32_t komodo_baseid(char *origbase);
eda3ca93 1606 extern int COINBASE_MATURITY;
347acd7f 1607 komodo_configfile(ASSETCHAINS_SYMBOL,ASSETCHAINS_PORT + 1);
4d3e5409 1608 komodo_userpass(ASSETCHAINS_USERPASS,ASSETCHAINS_SYMBOL);
ab918767 1609 COINBASE_MATURITY = 1;
9de70efe 1610 //fprintf(stderr,"ASSETCHAINS_PORT %s %u (%s)\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_PORT,ASSETCHAINS_USERPASS);
dab92e65 1611 }
8683bd8d 1612 //ASSETCHAINS_NOTARIES = GetArg("-ac_notaries","");
1613 //komodo_assetchain_pubkeys((char *)ASSETCHAINS_NOTARIES.c_str());
6e575e43 1614 iguana_rwnum(1,magic,sizeof(ASSETCHAINS_MAGIC),(void *)&ASSETCHAINS_MAGIC);
1615 for (i=0; i<4; i++)
1616 sprintf(&magicstr[i<<1],"%02x",magic[i]);
1617 magicstr[8] = 0;
95c46396 1618#ifndef FROM_CLI
6e575e43 1619 sprintf(fname,"gen%s",ASSETCHAINS_SYMBOL);
1620 if ( (fp= fopen(fname,"wb")) != 0 )
1621 {
4a4e912b 1622 fprintf(fp,iguanafmtstr,name.c_str(),name.c_str(),name.c_str(),name.c_str(),magicstr,ASSETCHAINS_PORT,ASSETCHAINS_PORT+1,"78.47.196.146");
6e575e43 1623 fclose(fp);
b6a7cb2c 1624 //printf("created (%s)\n",fname);
6e575e43 1625 } else printf("error creating (%s)\n",fname);
95c46396 1626#endif
935fc055 1627 }
1628 else
1629 {
523a5dc7 1630 char fname[512],username[512],password[4096]; int32_t iter; FILE *fp;
935fc055 1631 ASSETCHAINS_PORT = 8777;
b55c2367 1632 for (iter=0; iter<2; iter++)
1633 {
1634 strcpy(fname,GetDataDir().string().c_str());
9cb1ec9c 1635#ifdef _WIN32
b55c2367 1636 while ( fname[strlen(fname)-1] != '\\' )
1637 fname[strlen(fname)-1] = 0;
1638 if ( iter == 0 )
1248a49e 1639 strcat(fname,"Komodo\\komodo.conf");
1640 else strcat(fname,"Bitcoin\\bitcoin.conf");
7cce5f6a 1641#else
b55c2367 1642 while ( fname[strlen(fname)-1] != '/' )
1643 fname[strlen(fname)-1] = 0;
1644#ifdef __APPLE__
1645 if ( iter == 0 )
1646 strcat(fname,"Komodo/Komodo.conf");
1647 else strcat(fname,"Bitcoin/Bitcoin.conf");
1648#else
1649 if ( iter == 0 )
1650 strcat(fname,".komodo/komodo.conf");
1651 else strcat(fname,".bitcoin/bitcoin.conf");
7cce5f6a 1652#endif
b55c2367 1653#endif
1654 if ( (fp= fopen(fname,"rb")) != 0 )
1655 {
1656 komodo_userpass(username,password,fp);
1657 sprintf(iter == 0 ? KMDUSERPASS : BTCUSERPASS,"%s:%s",username,password);
1658 fclose(fp);
1659 //printf("KOMODO.(%s) -> userpass.(%s)\n",fname,KMDUSERPASS);
6ec3d43c 1660 } //else printf("couldnt open.(%s)\n",fname);
eea23236 1661 if ( IS_KOMODO_NOTARY == 0 )
1662 break;
b55c2367 1663 }
935fc055 1664 }
8683bd8d 1665 BITCOIND_PORT = GetArg("-rpcport", BaseParams().RPCPort());
9d365796 1666 //fprintf(stderr,"%s chain params initialized\n",ASSETCHAINS_SYMBOL);
1bfdde1d 1667}
1668
ab918767 1669void komodo_nameset(char *symbol,char *dest,char *source)
1bfdde1d 1670{
ab918767 1671 if ( source[0] == 0 )
1bfdde1d 1672 {
8a7c9241 1673 strcpy(symbol,(char *)"KMD");
1674 strcpy(dest,(char *)"BTC");
1bfdde1d 1675 }
1676 else
1677 {
ab918767 1678 strcpy(symbol,source);
8a7c9241 1679 strcpy(dest,(char *)"KMD");
ab918767 1680 }
1681}
1682
ab918767 1683struct komodo_state *komodo_stateptrget(char *base)
1684{
1685 int32_t baseid;
8a7c9241 1686 if ( base == 0 || base[0] == 0 || strcmp(base,(char *)"KMD") == 0 )
2d116f01 1687 return(&KOMODO_STATES[33]);
ab918767 1688 else if ( (baseid= komodo_baseid(base)) >= 0 )
1689 return(&KOMODO_STATES[baseid+1]);
2d116f01 1690 else return(&KOMODO_STATES[0]);
1691}
1692
1693struct komodo_state *komodo_stateptr(char *symbol,char *dest)
1694{
1695 int32_t baseid;
1696 komodo_nameset(symbol,dest,ASSETCHAINS_SYMBOL);
1697 return(komodo_stateptrget(symbol));
ab918767 1698}
This page took 0.501593 seconds and 4 git commands to generate.