raw
experimental-genesis    1 //  /****************************\
experimental-genesis 2 // * EXPERIMENTAL BRANCH. *
experimental-genesis 3 // * FOR LABORATORY USE ONLY. *
experimental-genesis 4 // ********************************
experimental-genesis 5 // ************
experimental-genesis 6 // **************
experimental-genesis 7 // ****************
experimental-genesis 8 // **** **** ****
experimental-genesis 9 // *** *** ***
experimental-genesis 10 // *** *** ***
experimental-genesis 11 // *** * * **
experimental-genesis 12 // ******** ********
experimental-genesis 13 // ******* ******
experimental-genesis 14 // *** **
experimental-genesis 15 // * ******* **
experimental-genesis 16 // ** * * * * *
experimental-genesis 17 // ** * * ***
experimental-genesis 18 // **** * * * * ****
experimental-genesis 19 // **** *** * * ** ***
experimental-genesis 20 // **** ********* ******
experimental-genesis 21 // ******* ***** *******
experimental-genesis 22 // ********* ****** **
experimental-genesis 23 // ** ****** ******
experimental-genesis 24 // ** ******* **
experimental-genesis 25 // ** ******* ***
experimental-genesis 26 // **** ******** ************
experimental-genesis 27 // ************ ************
experimental-genesis 28 // ******** *******
experimental-genesis 29 // ****** ****
experimental-genesis 30 // *** ***
experimental-genesis 31 // ********************************
experimental-genesis 32 // Copyright (c) 2009-2010 Satoshi Nakamoto
experimental-genesis 33 // Copyright (c) 2011 The Bitcoin developers
experimental-genesis 34 // Distributed under the MIT/X11 software license, see the accompanying
experimental-genesis 35 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
experimental-genesis 36 #include "headers.h"
experimental-genesis 37
experimental-genesis 38 using namespace std;
experimental-genesis 39 using namespace boost;
experimental-genesis 40
experimental-genesis 41 bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
experimental-genesis 42
experimental-genesis 43
experimental-genesis 44
experimental-genesis 45 typedef vector<unsigned char> valtype;
experimental-genesis 46 static const valtype vchFalse(0);
experimental-genesis 47 static const valtype vchZero(0);
experimental-genesis 48 static const valtype vchTrue(1, 1);
experimental-genesis 49 static const CBigNum bnZero(0);
experimental-genesis 50 static const CBigNum bnOne(1);
experimental-genesis 51 static const CBigNum bnFalse(0);
experimental-genesis 52 static const CBigNum bnTrue(1);
experimental-genesis 53 static const size_t nMaxNumSize = 4;
experimental-genesis 54
experimental-genesis 55
experimental-genesis 56 CBigNum CastToBigNum(const valtype& vch)
experimental-genesis 57 {
experimental-genesis 58 if (vch.size() > nMaxNumSize)
experimental-genesis 59 throw runtime_error("CastToBigNum() : overflow");
experimental-genesis 60 // Get rid of extra leading zeros
experimental-genesis 61 return CBigNum(CBigNum(vch).getvch());
experimental-genesis 62 }
experimental-genesis 63
experimental-genesis 64 bool CastToBool(const valtype& vch)
experimental-genesis 65 {
experimental-genesis 66 for (int i = 0; i < vch.size(); i++)
experimental-genesis 67 {
experimental-genesis 68 if (vch[i] != 0)
experimental-genesis 69 {
experimental-genesis 70 // Can be negative zero
experimental-genesis 71 if (i == vch.size()-1 && vch[i] == 0x80)
experimental-genesis 72 return false;
experimental-genesis 73 return true;
experimental-genesis 74 }
experimental-genesis 75 }
experimental-genesis 76 return false;
experimental-genesis 77 }
experimental-genesis 78
experimental-genesis 79 void MakeSameSize(valtype& vch1, valtype& vch2)
experimental-genesis 80 {
experimental-genesis 81 // Lengthen the shorter one
experimental-genesis 82 if (vch1.size() < vch2.size())
experimental-genesis 83 vch1.resize(vch2.size(), 0);
experimental-genesis 84 if (vch2.size() < vch1.size())
experimental-genesis 85 vch2.resize(vch1.size(), 0);
experimental-genesis 86 }
experimental-genesis 87
experimental-genesis 88
experimental-genesis 89
experimental-genesis 90 //
experimental-genesis 91 // Script is a stack machine (like Forth) that evaluates a predicate
experimental-genesis 92 // returning a bool indicating valid or not. There are no loops.
experimental-genesis 93 //
experimental-genesis 94 #define stacktop(i) (stack.at(stack.size()+(i)))
experimental-genesis 95 #define altstacktop(i) (altstack.at(altstack.size()+(i)))
experimental-genesis 96 static inline void popstack(vector<valtype>& stack)
experimental-genesis 97 {
experimental-genesis 98 if (stack.empty())
experimental-genesis 99 throw runtime_error("popstack() : stack empty");
experimental-genesis 100 stack.pop_back();
experimental-genesis 101 }
experimental-genesis 102
experimental-genesis 103
experimental-genesis 104 bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType)
experimental-genesis 105 {
experimental-genesis 106 CAutoBN_CTX pctx;
experimental-genesis 107 CScript::const_iterator pc = script.begin();
experimental-genesis 108 CScript::const_iterator pend = script.end();
experimental-genesis 109 CScript::const_iterator pbegincodehash = script.begin();
experimental-genesis 110 opcodetype opcode;
experimental-genesis 111 valtype vchPushValue;
experimental-genesis 112 vector<bool> vfExec;
experimental-genesis 113 vector<valtype> altstack;
experimental-genesis 114 if (script.size() > 10000)
experimental-genesis 115 return false;
experimental-genesis 116 int nOpCount = 0;
experimental-genesis 117
experimental-genesis 118
experimental-genesis 119 try
experimental-genesis 120 {
experimental-genesis 121 while (pc < pend)
experimental-genesis 122 {
experimental-genesis 123 bool fExec = !count(vfExec.begin(), vfExec.end(), false);
experimental-genesis 124
experimental-genesis 125 //
experimental-genesis 126 // Read instruction
experimental-genesis 127 //
experimental-genesis 128 if (!script.GetOp(pc, opcode, vchPushValue))
experimental-genesis 129 return false;
experimental-genesis 130 if (vchPushValue.size() > 520)
experimental-genesis 131 return false;
experimental-genesis 132 if (opcode > OP_16 && ++nOpCount > 201)
experimental-genesis 133 return false;
experimental-genesis 134
experimental-genesis 135 if (opcode == OP_CAT ||
experimental-genesis 136 opcode == OP_SUBSTR ||
experimental-genesis 137 opcode == OP_LEFT ||
experimental-genesis 138 opcode == OP_RIGHT ||
experimental-genesis 139 opcode == OP_INVERT ||
experimental-genesis 140 opcode == OP_AND ||
experimental-genesis 141 opcode == OP_OR ||
experimental-genesis 142 opcode == OP_XOR ||
experimental-genesis 143 opcode == OP_2MUL ||
experimental-genesis 144 opcode == OP_2DIV ||
experimental-genesis 145 opcode == OP_MUL ||
experimental-genesis 146 opcode == OP_DIV ||
experimental-genesis 147 opcode == OP_MOD ||
experimental-genesis 148 opcode == OP_LSHIFT ||
experimental-genesis 149 opcode == OP_RSHIFT)
experimental-genesis 150 return false;
experimental-genesis 151
experimental-genesis 152 if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4)
experimental-genesis 153 stack.push_back(vchPushValue);
experimental-genesis 154 else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))
experimental-genesis 155 switch (opcode)
experimental-genesis 156 {
experimental-genesis 157 //
experimental-genesis 158 // Push value
experimental-genesis 159 //
experimental-genesis 160 case OP_1NEGATE:
experimental-genesis 161 case OP_1:
experimental-genesis 162 case OP_2:
experimental-genesis 163 case OP_3:
experimental-genesis 164 case OP_4:
experimental-genesis 165 case OP_5:
experimental-genesis 166 case OP_6:
experimental-genesis 167 case OP_7:
experimental-genesis 168 case OP_8:
experimental-genesis 169 case OP_9:
experimental-genesis 170 case OP_10:
experimental-genesis 171 case OP_11:
experimental-genesis 172 case OP_12:
experimental-genesis 173 case OP_13:
experimental-genesis 174 case OP_14:
experimental-genesis 175 case OP_15:
experimental-genesis 176 case OP_16:
experimental-genesis 177 {
experimental-genesis 178 // ( -- value)
experimental-genesis 179 CBigNum bn((int)opcode - (int)(OP_1 - 1));
experimental-genesis 180 stack.push_back(bn.getvch());
experimental-genesis 181 }
experimental-genesis 182 break;
experimental-genesis 183
experimental-genesis 184
experimental-genesis 185 //
experimental-genesis 186 // Control
experimental-genesis 187 //
experimental-genesis 188 case OP_NOP:
experimental-genesis 189 case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5:
experimental-genesis 190 case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10:
experimental-genesis 191 break;
experimental-genesis 192
experimental-genesis 193 case OP_IF:
experimental-genesis 194 case OP_NOTIF:
experimental-genesis 195 {
experimental-genesis 196 // <expression> if [statements] [else [statements]] endif
experimental-genesis 197 bool fValue = false;
experimental-genesis 198 if (fExec)
experimental-genesis 199 {
experimental-genesis 200 if (stack.size() < 1)
experimental-genesis 201 return false;
experimental-genesis 202 valtype& vch = stacktop(-1);
experimental-genesis 203 fValue = CastToBool(vch);
experimental-genesis 204 if (opcode == OP_NOTIF)
experimental-genesis 205 fValue = !fValue;
experimental-genesis 206 popstack(stack);
experimental-genesis 207 }
experimental-genesis 208 vfExec.push_back(fValue);
experimental-genesis 209 }
experimental-genesis 210 break;
experimental-genesis 211
experimental-genesis 212 case OP_ELSE:
experimental-genesis 213 {
experimental-genesis 214 if (vfExec.empty())
experimental-genesis 215 return false;
experimental-genesis 216 vfExec.back() = !vfExec.back();
experimental-genesis 217 }
experimental-genesis 218 break;
experimental-genesis 219
experimental-genesis 220 case OP_ENDIF:
experimental-genesis 221 {
experimental-genesis 222 if (vfExec.empty())
experimental-genesis 223 return false;
experimental-genesis 224 vfExec.pop_back();
experimental-genesis 225 }
experimental-genesis 226 break;
experimental-genesis 227
experimental-genesis 228 case OP_VERIFY:
experimental-genesis 229 {
experimental-genesis 230 // (true -- ) or
experimental-genesis 231 // (false -- false) and return
experimental-genesis 232 if (stack.size() < 1)
experimental-genesis 233 return false;
experimental-genesis 234 bool fValue = CastToBool(stacktop(-1));
experimental-genesis 235 if (fValue)
experimental-genesis 236 popstack(stack);
experimental-genesis 237 else
experimental-genesis 238 return false;
experimental-genesis 239 }
experimental-genesis 240 break;
experimental-genesis 241
experimental-genesis 242 case OP_RETURN:
experimental-genesis 243 {
experimental-genesis 244 return false;
experimental-genesis 245 }
experimental-genesis 246 break;
experimental-genesis 247
experimental-genesis 248
experimental-genesis 249 //
experimental-genesis 250 // Stack ops
experimental-genesis 251 //
experimental-genesis 252 case OP_TOALTSTACK:
experimental-genesis 253 {
experimental-genesis 254 if (stack.size() < 1)
experimental-genesis 255 return false;
experimental-genesis 256 altstack.push_back(stacktop(-1));
experimental-genesis 257 popstack(stack);
experimental-genesis 258 }
experimental-genesis 259 break;
experimental-genesis 260
experimental-genesis 261 case OP_FROMALTSTACK:
experimental-genesis 262 {
experimental-genesis 263 if (altstack.size() < 1)
experimental-genesis 264 return false;
experimental-genesis 265 stack.push_back(altstacktop(-1));
experimental-genesis 266 popstack(altstack);
experimental-genesis 267 }
experimental-genesis 268 break;
experimental-genesis 269
experimental-genesis 270 case OP_2DROP:
experimental-genesis 271 {
experimental-genesis 272 // (x1 x2 -- )
experimental-genesis 273 if (stack.size() < 2)
experimental-genesis 274 return false;
experimental-genesis 275 popstack(stack);
experimental-genesis 276 popstack(stack);
experimental-genesis 277 }
experimental-genesis 278 break;
experimental-genesis 279
experimental-genesis 280 case OP_2DUP:
experimental-genesis 281 {
experimental-genesis 282 // (x1 x2 -- x1 x2 x1 x2)
experimental-genesis 283 if (stack.size() < 2)
experimental-genesis 284 return false;
experimental-genesis 285 valtype vch1 = stacktop(-2);
experimental-genesis 286 valtype vch2 = stacktop(-1);
experimental-genesis 287 stack.push_back(vch1);
experimental-genesis 288 stack.push_back(vch2);
experimental-genesis 289 }
experimental-genesis 290 break;
experimental-genesis 291
experimental-genesis 292 case OP_3DUP:
experimental-genesis 293 {
experimental-genesis 294 // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)
experimental-genesis 295 if (stack.size() < 3)
experimental-genesis 296 return false;
experimental-genesis 297 valtype vch1 = stacktop(-3);
experimental-genesis 298 valtype vch2 = stacktop(-2);
experimental-genesis 299 valtype vch3 = stacktop(-1);
experimental-genesis 300 stack.push_back(vch1);
experimental-genesis 301 stack.push_back(vch2);
experimental-genesis 302 stack.push_back(vch3);
experimental-genesis 303 }
experimental-genesis 304 break;
experimental-genesis 305
experimental-genesis 306 case OP_2OVER:
experimental-genesis 307 {
experimental-genesis 308 // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)
experimental-genesis 309 if (stack.size() < 4)
experimental-genesis 310 return false;
experimental-genesis 311 valtype vch1 = stacktop(-4);
experimental-genesis 312 valtype vch2 = stacktop(-3);
experimental-genesis 313 stack.push_back(vch1);
experimental-genesis 314 stack.push_back(vch2);
experimental-genesis 315 }
experimental-genesis 316 break;
experimental-genesis 317
experimental-genesis 318 case OP_2ROT:
experimental-genesis 319 {
experimental-genesis 320 // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)
experimental-genesis 321 if (stack.size() < 6)
experimental-genesis 322 return false;
experimental-genesis 323 valtype vch1 = stacktop(-6);
experimental-genesis 324 valtype vch2 = stacktop(-5);
experimental-genesis 325 stack.erase(stack.end()-6, stack.end()-4);
experimental-genesis 326 stack.push_back(vch1);
experimental-genesis 327 stack.push_back(vch2);
experimental-genesis 328 }
experimental-genesis 329 break;
experimental-genesis 330
experimental-genesis 331 case OP_2SWAP:
experimental-genesis 332 {
experimental-genesis 333 // (x1 x2 x3 x4 -- x3 x4 x1 x2)
experimental-genesis 334 if (stack.size() < 4)
experimental-genesis 335 return false;
experimental-genesis 336 swap(stacktop(-4), stacktop(-2));
experimental-genesis 337 swap(stacktop(-3), stacktop(-1));
experimental-genesis 338 }
experimental-genesis 339 break;
experimental-genesis 340
experimental-genesis 341 case OP_IFDUP:
experimental-genesis 342 {
experimental-genesis 343 // (x - 0 | x x)
experimental-genesis 344 if (stack.size() < 1)
experimental-genesis 345 return false;
experimental-genesis 346 valtype vch = stacktop(-1);
experimental-genesis 347 if (CastToBool(vch))
experimental-genesis 348 stack.push_back(vch);
experimental-genesis 349 }
experimental-genesis 350 break;
experimental-genesis 351
experimental-genesis 352 case OP_DEPTH:
experimental-genesis 353 {
experimental-genesis 354 // -- stacksize
experimental-genesis 355 CBigNum bn(stack.size());
experimental-genesis 356 stack.push_back(bn.getvch());
experimental-genesis 357 }
experimental-genesis 358 break;
experimental-genesis 359
experimental-genesis 360 case OP_DROP:
experimental-genesis 361 {
experimental-genesis 362 // (x -- )
experimental-genesis 363 if (stack.size() < 1)
experimental-genesis 364 return false;
experimental-genesis 365 popstack(stack);
experimental-genesis 366 }
experimental-genesis 367 break;
experimental-genesis 368
experimental-genesis 369 case OP_DUP:
experimental-genesis 370 {
experimental-genesis 371 // (x -- x x)
experimental-genesis 372 if (stack.size() < 1)
experimental-genesis 373 return false;
experimental-genesis 374 valtype vch = stacktop(-1);
experimental-genesis 375 stack.push_back(vch);
experimental-genesis 376 }
experimental-genesis 377 break;
experimental-genesis 378
experimental-genesis 379 case OP_NIP:
experimental-genesis 380 {
experimental-genesis 381 // (x1 x2 -- x2)
experimental-genesis 382 if (stack.size() < 2)
experimental-genesis 383 return false;
experimental-genesis 384 stack.erase(stack.end() - 2);
experimental-genesis 385 }
experimental-genesis 386 break;
experimental-genesis 387
experimental-genesis 388 case OP_OVER:
experimental-genesis 389 {
experimental-genesis 390 // (x1 x2 -- x1 x2 x1)
experimental-genesis 391 if (stack.size() < 2)
experimental-genesis 392 return false;
experimental-genesis 393 valtype vch = stacktop(-2);
experimental-genesis 394 stack.push_back(vch);
experimental-genesis 395 }
experimental-genesis 396 break;
experimental-genesis 397
experimental-genesis 398 case OP_PICK:
experimental-genesis 399 case OP_ROLL:
experimental-genesis 400 {
experimental-genesis 401 // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)
experimental-genesis 402 // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)
experimental-genesis 403 if (stack.size() < 2)
experimental-genesis 404 return false;
experimental-genesis 405 int n = CastToBigNum(stacktop(-1)).getint();
experimental-genesis 406 popstack(stack);
experimental-genesis 407 if (n < 0 || n >= stack.size())
experimental-genesis 408 return false;
experimental-genesis 409 valtype vch = stacktop(-n-1);
experimental-genesis 410 if (opcode == OP_ROLL)
experimental-genesis 411 stack.erase(stack.end()-n-1);
experimental-genesis 412 stack.push_back(vch);
experimental-genesis 413 }
experimental-genesis 414 break;
experimental-genesis 415
experimental-genesis 416 case OP_ROT:
experimental-genesis 417 {
experimental-genesis 418 // (x1 x2 x3 -- x2 x3 x1)
experimental-genesis 419 // x2 x1 x3 after first swap
experimental-genesis 420 // x2 x3 x1 after second swap
experimental-genesis 421 if (stack.size() < 3)
experimental-genesis 422 return false;
experimental-genesis 423 swap(stacktop(-3), stacktop(-2));
experimental-genesis 424 swap(stacktop(-2), stacktop(-1));
experimental-genesis 425 }
experimental-genesis 426 break;
experimental-genesis 427
experimental-genesis 428 case OP_SWAP:
experimental-genesis 429 {
experimental-genesis 430 // (x1 x2 -- x2 x1)
experimental-genesis 431 if (stack.size() < 2)
experimental-genesis 432 return false;
experimental-genesis 433 swap(stacktop(-2), stacktop(-1));
experimental-genesis 434 }
experimental-genesis 435 break;
experimental-genesis 436
experimental-genesis 437 case OP_TUCK:
experimental-genesis 438 {
experimental-genesis 439 // (x1 x2 -- x2 x1 x2)
experimental-genesis 440 if (stack.size() < 2)
experimental-genesis 441 return false;
experimental-genesis 442 valtype vch = stacktop(-1);
experimental-genesis 443 stack.insert(stack.end()-2, vch);
experimental-genesis 444 }
experimental-genesis 445 break;
experimental-genesis 446
experimental-genesis 447
experimental-genesis 448 //
experimental-genesis 449 // Splice ops
experimental-genesis 450 //
experimental-genesis 451 case OP_CAT:
experimental-genesis 452 {
experimental-genesis 453 // (x1 x2 -- out)
experimental-genesis 454 if (stack.size() < 2)
experimental-genesis 455 return false;
experimental-genesis 456 valtype& vch1 = stacktop(-2);
experimental-genesis 457 valtype& vch2 = stacktop(-1);
experimental-genesis 458 vch1.insert(vch1.end(), vch2.begin(), vch2.end());
experimental-genesis 459 popstack(stack);
experimental-genesis 460 if (stacktop(-1).size() > 520)
experimental-genesis 461 return false;
experimental-genesis 462 }
experimental-genesis 463 break;
experimental-genesis 464
experimental-genesis 465 case OP_SUBSTR:
experimental-genesis 466 {
experimental-genesis 467 // (in begin size -- out)
experimental-genesis 468 if (stack.size() < 3)
experimental-genesis 469 return false;
experimental-genesis 470 valtype& vch = stacktop(-3);
experimental-genesis 471 int nBegin = CastToBigNum(stacktop(-2)).getint();
experimental-genesis 472 int nEnd = nBegin + CastToBigNum(stacktop(-1)).getint();
experimental-genesis 473 if (nBegin < 0 || nEnd < nBegin)
experimental-genesis 474 return false;
experimental-genesis 475 if (nBegin > vch.size())
experimental-genesis 476 nBegin = vch.size();
experimental-genesis 477 if (nEnd > vch.size())
experimental-genesis 478 nEnd = vch.size();
experimental-genesis 479 vch.erase(vch.begin() + nEnd, vch.end());
experimental-genesis 480 vch.erase(vch.begin(), vch.begin() + nBegin);
experimental-genesis 481 popstack(stack);
experimental-genesis 482 popstack(stack);
experimental-genesis 483 }
experimental-genesis 484 break;
experimental-genesis 485
experimental-genesis 486 case OP_LEFT:
experimental-genesis 487 case OP_RIGHT:
experimental-genesis 488 {
experimental-genesis 489 // (in size -- out)
experimental-genesis 490 if (stack.size() < 2)
experimental-genesis 491 return false;
experimental-genesis 492 valtype& vch = stacktop(-2);
experimental-genesis 493 int nSize = CastToBigNum(stacktop(-1)).getint();
experimental-genesis 494 if (nSize < 0)
experimental-genesis 495 return false;
experimental-genesis 496 if (nSize > vch.size())
experimental-genesis 497 nSize = vch.size();
experimental-genesis 498 if (opcode == OP_LEFT)
experimental-genesis 499 vch.erase(vch.begin() + nSize, vch.end());
experimental-genesis 500 else
experimental-genesis 501 vch.erase(vch.begin(), vch.end() - nSize);
experimental-genesis 502 popstack(stack);
experimental-genesis 503 }
experimental-genesis 504 break;
experimental-genesis 505
experimental-genesis 506 case OP_SIZE:
experimental-genesis 507 {
experimental-genesis 508 // (in -- in size)
experimental-genesis 509 if (stack.size() < 1)
experimental-genesis 510 return false;
experimental-genesis 511 CBigNum bn(stacktop(-1).size());
experimental-genesis 512 stack.push_back(bn.getvch());
experimental-genesis 513 }
experimental-genesis 514 break;
experimental-genesis 515
experimental-genesis 516
experimental-genesis 517 //
experimental-genesis 518 // Bitwise logic
experimental-genesis 519 //
experimental-genesis 520 case OP_INVERT:
experimental-genesis 521 {
experimental-genesis 522 // (in - out)
experimental-genesis 523 if (stack.size() < 1)
experimental-genesis 524 return false;
experimental-genesis 525 valtype& vch = stacktop(-1);
experimental-genesis 526 for (int i = 0; i < vch.size(); i++)
experimental-genesis 527 vch[i] = ~vch[i];
experimental-genesis 528 }
experimental-genesis 529 break;
experimental-genesis 530
experimental-genesis 531 case OP_AND:
experimental-genesis 532 case OP_OR:
experimental-genesis 533 case OP_XOR:
experimental-genesis 534 {
experimental-genesis 535 // (x1 x2 - out)
experimental-genesis 536 if (stack.size() < 2)
experimental-genesis 537 return false;
experimental-genesis 538 valtype& vch1 = stacktop(-2);
experimental-genesis 539 valtype& vch2 = stacktop(-1);
experimental-genesis 540 MakeSameSize(vch1, vch2);
experimental-genesis 541 if (opcode == OP_AND)
experimental-genesis 542 {
experimental-genesis 543 for (int i = 0; i < vch1.size(); i++)
experimental-genesis 544 vch1[i] &= vch2[i];
experimental-genesis 545 }
experimental-genesis 546 else if (opcode == OP_OR)
experimental-genesis 547 {
experimental-genesis 548 for (int i = 0; i < vch1.size(); i++)
experimental-genesis 549 vch1[i] |= vch2[i];
experimental-genesis 550 }
experimental-genesis 551 else if (opcode == OP_XOR)
experimental-genesis 552 {
experimental-genesis 553 for (int i = 0; i < vch1.size(); i++)
experimental-genesis 554 vch1[i] ^= vch2[i];
experimental-genesis 555 }
experimental-genesis 556 popstack(stack);
experimental-genesis 557 }
experimental-genesis 558 break;
experimental-genesis 559
experimental-genesis 560 case OP_EQUAL:
experimental-genesis 561 case OP_EQUALVERIFY:
experimental-genesis 562 //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL
experimental-genesis 563 {
experimental-genesis 564 // (x1 x2 - bool)
experimental-genesis 565 if (stack.size() < 2)
experimental-genesis 566 return false;
experimental-genesis 567 valtype& vch1 = stacktop(-2);
experimental-genesis 568 valtype& vch2 = stacktop(-1);
experimental-genesis 569 bool fEqual = (vch1 == vch2);
experimental-genesis 570 // OP_NOTEQUAL is disabled because it would be too easy to say
experimental-genesis 571 // something like n != 1 and have some wiseguy pass in 1 with extra
experimental-genesis 572 // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)
experimental-genesis 573 //if (opcode == OP_NOTEQUAL)
experimental-genesis 574 // fEqual = !fEqual;
experimental-genesis 575 popstack(stack);
experimental-genesis 576 popstack(stack);
experimental-genesis 577 stack.push_back(fEqual ? vchTrue : vchFalse);
experimental-genesis 578 if (opcode == OP_EQUALVERIFY)
experimental-genesis 579 {
experimental-genesis 580 if (fEqual)
experimental-genesis 581 popstack(stack);
experimental-genesis 582 else
experimental-genesis 583 return false;
experimental-genesis 584 }
experimental-genesis 585 }
experimental-genesis 586 break;
experimental-genesis 587
experimental-genesis 588
experimental-genesis 589 //
experimental-genesis 590 // Numeric
experimental-genesis 591 //
experimental-genesis 592 case OP_1ADD:
experimental-genesis 593 case OP_1SUB:
experimental-genesis 594 case OP_2MUL:
experimental-genesis 595 case OP_2DIV:
experimental-genesis 596 case OP_NEGATE:
experimental-genesis 597 case OP_ABS:
experimental-genesis 598 case OP_NOT:
experimental-genesis 599 case OP_0NOTEQUAL:
experimental-genesis 600 {
experimental-genesis 601 // (in -- out)
experimental-genesis 602 if (stack.size() < 1)
experimental-genesis 603 return false;
experimental-genesis 604 CBigNum bn = CastToBigNum(stacktop(-1));
experimental-genesis 605 switch (opcode)
experimental-genesis 606 {
experimental-genesis 607 case OP_1ADD: bn += bnOne; break;
experimental-genesis 608 case OP_1SUB: bn -= bnOne; break;
experimental-genesis 609 case OP_2MUL: bn <<= 1; break;
experimental-genesis 610 case OP_2DIV: bn >>= 1; break;
experimental-genesis 611 case OP_NEGATE: bn = -bn; break;
experimental-genesis 612 case OP_ABS: if (bn < bnZero) bn = -bn; break;
experimental-genesis 613 case OP_NOT: bn = (bn == bnZero); break;
experimental-genesis 614 case OP_0NOTEQUAL: bn = (bn != bnZero); break;
experimental-genesis 615 default: assert(!"invalid opcode"); break;
experimental-genesis 616 }
experimental-genesis 617 popstack(stack);
experimental-genesis 618 stack.push_back(bn.getvch());
experimental-genesis 619 }
experimental-genesis 620 break;
experimental-genesis 621
experimental-genesis 622 case OP_ADD:
experimental-genesis 623 case OP_SUB:
experimental-genesis 624 case OP_MUL:
experimental-genesis 625 case OP_DIV:
experimental-genesis 626 case OP_MOD:
experimental-genesis 627 case OP_LSHIFT:
experimental-genesis 628 case OP_RSHIFT:
experimental-genesis 629 case OP_BOOLAND:
experimental-genesis 630 case OP_BOOLOR:
experimental-genesis 631 case OP_NUMEQUAL:
experimental-genesis 632 case OP_NUMEQUALVERIFY:
experimental-genesis 633 case OP_NUMNOTEQUAL:
experimental-genesis 634 case OP_LESSTHAN:
experimental-genesis 635 case OP_GREATERTHAN:
experimental-genesis 636 case OP_LESSTHANOREQUAL:
experimental-genesis 637 case OP_GREATERTHANOREQUAL:
experimental-genesis 638 case OP_MIN:
experimental-genesis 639 case OP_MAX:
experimental-genesis 640 {
experimental-genesis 641 // (x1 x2 -- out)
experimental-genesis 642 if (stack.size() < 2)
experimental-genesis 643 return false;
experimental-genesis 644 CBigNum bn1 = CastToBigNum(stacktop(-2));
experimental-genesis 645 CBigNum bn2 = CastToBigNum(stacktop(-1));
experimental-genesis 646 CBigNum bn;
experimental-genesis 647 switch (opcode)
experimental-genesis 648 {
experimental-genesis 649 case OP_ADD:
experimental-genesis 650 bn = bn1 + bn2;
experimental-genesis 651 break;
experimental-genesis 652
experimental-genesis 653 case OP_SUB:
experimental-genesis 654 bn = bn1 - bn2;
experimental-genesis 655 break;
experimental-genesis 656
experimental-genesis 657 case OP_MUL:
experimental-genesis 658 if (!BN_mul(&bn, &bn1, &bn2, pctx))
experimental-genesis 659 return false;
experimental-genesis 660 break;
experimental-genesis 661
experimental-genesis 662 case OP_DIV:
experimental-genesis 663 if (!BN_div(&bn, NULL, &bn1, &bn2, pctx))
experimental-genesis 664 return false;
experimental-genesis 665 break;
experimental-genesis 666
experimental-genesis 667 case OP_MOD:
experimental-genesis 668 if (!BN_mod(&bn, &bn1, &bn2, pctx))
experimental-genesis 669 return false;
experimental-genesis 670 break;
experimental-genesis 671
experimental-genesis 672 case OP_LSHIFT:
experimental-genesis 673 if (bn2 < bnZero || bn2 > CBigNum(2048))
experimental-genesis 674 return false;
experimental-genesis 675 bn = bn1 << bn2.getulong();
experimental-genesis 676 break;
experimental-genesis 677
experimental-genesis 678 case OP_RSHIFT:
experimental-genesis 679 if (bn2 < bnZero || bn2 > CBigNum(2048))
experimental-genesis 680 return false;
experimental-genesis 681 bn = bn1 >> bn2.getulong();
experimental-genesis 682 break;
experimental-genesis 683
experimental-genesis 684 case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break;
experimental-genesis 685 case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break;
experimental-genesis 686 case OP_NUMEQUAL: bn = (bn1 == bn2); break;
experimental-genesis 687 case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break;
experimental-genesis 688 case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break;
experimental-genesis 689 case OP_LESSTHAN: bn = (bn1 < bn2); break;
experimental-genesis 690 case OP_GREATERTHAN: bn = (bn1 > bn2); break;
experimental-genesis 691 case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break;
experimental-genesis 692 case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break;
experimental-genesis 693 case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break;
experimental-genesis 694 case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break;
experimental-genesis 695 default: assert(!"invalid opcode"); break;
experimental-genesis 696 }
experimental-genesis 697 popstack(stack);
experimental-genesis 698 popstack(stack);
experimental-genesis 699 stack.push_back(bn.getvch());
experimental-genesis 700
experimental-genesis 701 if (opcode == OP_NUMEQUALVERIFY)
experimental-genesis 702 {
experimental-genesis 703 if (CastToBool(stacktop(-1)))
experimental-genesis 704 popstack(stack);
experimental-genesis 705 else
experimental-genesis 706 return false;
experimental-genesis 707 }
experimental-genesis 708 }
experimental-genesis 709 break;
experimental-genesis 710
experimental-genesis 711 case OP_WITHIN:
experimental-genesis 712 {
experimental-genesis 713 // (x min max -- out)
experimental-genesis 714 if (stack.size() < 3)
experimental-genesis 715 return false;
experimental-genesis 716 CBigNum bn1 = CastToBigNum(stacktop(-3));
experimental-genesis 717 CBigNum bn2 = CastToBigNum(stacktop(-2));
experimental-genesis 718 CBigNum bn3 = CastToBigNum(stacktop(-1));
experimental-genesis 719 bool fValue = (bn2 <= bn1 && bn1 < bn3);
experimental-genesis 720 popstack(stack);
experimental-genesis 721 popstack(stack);
experimental-genesis 722 popstack(stack);
experimental-genesis 723 stack.push_back(fValue ? vchTrue : vchFalse);
experimental-genesis 724 }
experimental-genesis 725 break;
experimental-genesis 726
experimental-genesis 727
experimental-genesis 728 //
experimental-genesis 729 // Crypto
experimental-genesis 730 //
experimental-genesis 731 case OP_RIPEMD160:
experimental-genesis 732 case OP_SHA1:
experimental-genesis 733 case OP_SHA256:
experimental-genesis 734 case OP_HASH160:
experimental-genesis 735 case OP_HASH256:
experimental-genesis 736 {
experimental-genesis 737 // (in -- hash)
experimental-genesis 738 if (stack.size() < 1)
experimental-genesis 739 return false;
experimental-genesis 740 valtype& vch = stacktop(-1);
experimental-genesis 741 valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);
experimental-genesis 742 if (opcode == OP_RIPEMD160)
experimental-genesis 743 RIPEMD160(&vch[0], vch.size(), &vchHash[0]);
experimental-genesis 744 else if (opcode == OP_SHA1)
experimental-genesis 745 SHA1(&vch[0], vch.size(), &vchHash[0]);
experimental-genesis 746 else if (opcode == OP_SHA256)
experimental-genesis 747 SHA256(&vch[0], vch.size(), &vchHash[0]);
experimental-genesis 748 else if (opcode == OP_HASH160)
experimental-genesis 749 {
experimental-genesis 750 uint160 hash160 = Hash160(vch);
experimental-genesis 751 memcpy(&vchHash[0], &hash160, sizeof(hash160));
experimental-genesis 752 }
experimental-genesis 753 else if (opcode == OP_HASH256)
experimental-genesis 754 {
experimental-genesis 755 uint256 hash = Hash(vch.begin(), vch.end());
experimental-genesis 756 memcpy(&vchHash[0], &hash, sizeof(hash));
experimental-genesis 757 }
experimental-genesis 758 popstack(stack);
experimental-genesis 759 stack.push_back(vchHash);
experimental-genesis 760 }
experimental-genesis 761 break;
experimental-genesis 762
experimental-genesis 763 case OP_CODESEPARATOR:
experimental-genesis 764 {
experimental-genesis 765 // Hash starts after the code separator
experimental-genesis 766 pbegincodehash = pc;
experimental-genesis 767 }
experimental-genesis 768 break;
experimental-genesis 769
experimental-genesis 770 case OP_CHECKSIG:
experimental-genesis 771 case OP_CHECKSIGVERIFY:
experimental-genesis 772 {
experimental-genesis 773 // (sig pubkey -- bool)
experimental-genesis 774 if (stack.size() < 2)
experimental-genesis 775 return false;
experimental-genesis 776
experimental-genesis 777 valtype& vchSig = stacktop(-2);
experimental-genesis 778 valtype& vchPubKey = stacktop(-1);
experimental-genesis 779
experimental-genesis 780 ////// debug print
experimental-genesis 781 //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n");
experimental-genesis 782 //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n");
experimental-genesis 783
experimental-genesis 784 // Subset of script starting at the most recent codeseparator
experimental-genesis 785 CScript scriptCode(pbegincodehash, pend);
experimental-genesis 786
experimental-genesis 787 // Drop the signature, since there's no way for a signature to sign itself
experimental-genesis 788 scriptCode.FindAndDelete(CScript(vchSig));
experimental-genesis 789
experimental-genesis 790 bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType);
experimental-genesis 791
experimental-genesis 792 popstack(stack);
experimental-genesis 793 popstack(stack);
experimental-genesis 794 stack.push_back(fSuccess ? vchTrue : vchFalse);
experimental-genesis 795 if (opcode == OP_CHECKSIGVERIFY)
experimental-genesis 796 {
experimental-genesis 797 if (fSuccess)
experimental-genesis 798 popstack(stack);
experimental-genesis 799 else
experimental-genesis 800 return false;
experimental-genesis 801 }
experimental-genesis 802 }
experimental-genesis 803 break;
experimental-genesis 804
experimental-genesis 805 case OP_CHECKMULTISIG:
experimental-genesis 806 case OP_CHECKMULTISIGVERIFY:
experimental-genesis 807 {
experimental-genesis 808 // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)
experimental-genesis 809
experimental-genesis 810 int i = 1;
experimental-genesis 811 if (stack.size() < i)
experimental-genesis 812 return false;
experimental-genesis 813
experimental-genesis 814 int nKeysCount = CastToBigNum(stacktop(-i)).getint();
experimental-genesis 815 if (nKeysCount < 0 || nKeysCount > 20)
experimental-genesis 816 return false;
experimental-genesis 817 nOpCount += nKeysCount;
experimental-genesis 818 if (nOpCount > 201)
experimental-genesis 819 return false;
experimental-genesis 820 int ikey = ++i;
experimental-genesis 821 i += nKeysCount;
experimental-genesis 822 if (stack.size() < i)
experimental-genesis 823 return false;
experimental-genesis 824
experimental-genesis 825 int nSigsCount = CastToBigNum(stacktop(-i)).getint();
experimental-genesis 826 if (nSigsCount < 0 || nSigsCount > nKeysCount)
experimental-genesis 827 return false;
experimental-genesis 828 int isig = ++i;
experimental-genesis 829 i += nSigsCount;
experimental-genesis 830 if (stack.size() < i)
experimental-genesis 831 return false;
experimental-genesis 832
experimental-genesis 833 // Subset of script starting at the most recent codeseparator
experimental-genesis 834 CScript scriptCode(pbegincodehash, pend);
experimental-genesis 835
experimental-genesis 836 // Drop the signatures, since there's no way for a signature to sign itself
experimental-genesis 837 for (int k = 0; k < nSigsCount; k++)
experimental-genesis 838 {
experimental-genesis 839 valtype& vchSig = stacktop(-isig-k);
experimental-genesis 840 scriptCode.FindAndDelete(CScript(vchSig));
experimental-genesis 841 }
experimental-genesis 842
experimental-genesis 843 bool fSuccess = true;
experimental-genesis 844 while (fSuccess && nSigsCount > 0)
experimental-genesis 845 {
experimental-genesis 846 valtype& vchSig = stacktop(-isig);
experimental-genesis 847 valtype& vchPubKey = stacktop(-ikey);
experimental-genesis 848
experimental-genesis 849 // Check signature
experimental-genesis 850 if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType))
experimental-genesis 851 {
experimental-genesis 852 isig++;
experimental-genesis 853 nSigsCount--;
experimental-genesis 854 }
experimental-genesis 855 ikey++;
experimental-genesis 856 nKeysCount--;
experimental-genesis 857
experimental-genesis 858 // If there are more signatures left than keys left,
experimental-genesis 859 // then too many signatures have failed
experimental-genesis 860 if (nSigsCount > nKeysCount)
experimental-genesis 861 fSuccess = false;
experimental-genesis 862 }
experimental-genesis 863
experimental-genesis 864 while (i-- > 0)
experimental-genesis 865 popstack(stack);
experimental-genesis 866 stack.push_back(fSuccess ? vchTrue : vchFalse);
experimental-genesis 867
experimental-genesis 868 if (opcode == OP_CHECKMULTISIGVERIFY)
experimental-genesis 869 {
experimental-genesis 870 if (fSuccess)
experimental-genesis 871 popstack(stack);
experimental-genesis 872 else
experimental-genesis 873 return false;
experimental-genesis 874 }
experimental-genesis 875 }
experimental-genesis 876 break;
experimental-genesis 877
experimental-genesis 878 default:
experimental-genesis 879 return false;
experimental-genesis 880 }
experimental-genesis 881
experimental-genesis 882 // Size limits
experimental-genesis 883 if (stack.size() + altstack.size() > 1000)
experimental-genesis 884 return false;
experimental-genesis 885 }
experimental-genesis 886 }
experimental-genesis 887 catch (...)
experimental-genesis 888 {
experimental-genesis 889 return false;
experimental-genesis 890 }
experimental-genesis 891
experimental-genesis 892
experimental-genesis 893 if (!vfExec.empty())
experimental-genesis 894 return false;
experimental-genesis 895
experimental-genesis 896 return true;
experimental-genesis 897 }
experimental-genesis 898
experimental-genesis 899
experimental-genesis 900
experimental-genesis 901
experimental-genesis 902
experimental-genesis 903
experimental-genesis 904
experimental-genesis 905
experimental-genesis 906
experimental-genesis 907 uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
experimental-genesis 908 {
experimental-genesis 909 if (nIn >= txTo.vin.size())
experimental-genesis 910 {
experimental-genesis 911 printf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
experimental-genesis 912 return 1;
experimental-genesis 913 }
experimental-genesis 914 CTransaction txTmp(txTo);
experimental-genesis 915
experimental-genesis 916 // In case concatenating two scripts ends up with two codeseparators,
experimental-genesis 917 // or an extra one at the end, this prevents all those possible incompatibilities.
experimental-genesis 918 scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR));
experimental-genesis 919
experimental-genesis 920 // Blank out other inputs' signatures
experimental-genesis 921 for (int i = 0; i < txTmp.vin.size(); i++)
experimental-genesis 922 txTmp.vin[i].scriptSig = CScript();
experimental-genesis 923 txTmp.vin[nIn].scriptSig = scriptCode;
experimental-genesis 924
experimental-genesis 925 // Blank out some of the outputs
experimental-genesis 926 if ((nHashType & 0x1f) == SIGHASH_NONE)
experimental-genesis 927 {
experimental-genesis 928 // Wildcard payee
experimental-genesis 929 txTmp.vout.clear();
experimental-genesis 930
experimental-genesis 931 // Let the others update at will
experimental-genesis 932 for (int i = 0; i < txTmp.vin.size(); i++)
experimental-genesis 933 if (i != nIn)
experimental-genesis 934 txTmp.vin[i].nSequence = 0;
experimental-genesis 935 }
experimental-genesis 936 else if ((nHashType & 0x1f) == SIGHASH_SINGLE)
experimental-genesis 937 {
experimental-genesis 938 // Only lockin the txout payee at same index as txin
experimental-genesis 939 unsigned int nOut = nIn;
experimental-genesis 940 if (nOut >= txTmp.vout.size())
experimental-genesis 941 {
experimental-genesis 942 printf("ERROR: SignatureHash() : nOut=%d out of range\n", nOut);
experimental-genesis 943 return 1;
experimental-genesis 944 }
experimental-genesis 945 txTmp.vout.resize(nOut+1);
experimental-genesis 946 for (int i = 0; i < nOut; i++)
experimental-genesis 947 txTmp.vout[i].SetNull();
experimental-genesis 948
experimental-genesis 949 // Let the others update at will
experimental-genesis 950 for (int i = 0; i < txTmp.vin.size(); i++)
experimental-genesis 951 if (i != nIn)
experimental-genesis 952 txTmp.vin[i].nSequence = 0;
experimental-genesis 953 }
experimental-genesis 954
experimental-genesis 955 // Blank out other inputs completely, not recommended for open transactions
experimental-genesis 956 if (nHashType & SIGHASH_ANYONECANPAY)
experimental-genesis 957 {
experimental-genesis 958 txTmp.vin[0] = txTmp.vin[nIn];
experimental-genesis 959 txTmp.vin.resize(1);
experimental-genesis 960 }
experimental-genesis 961
experimental-genesis 962 // Serialize and hash
experimental-genesis 963 CDataStream ss(SER_GETHASH);
experimental-genesis 964 ss.reserve(10000);
experimental-genesis 965 ss << txTmp << nHashType;
experimental-genesis 966 return Hash(ss.begin(), ss.end());
experimental-genesis 967 }
experimental-genesis 968
experimental-genesis 969
experimental-genesis 970 bool CheckSig(vector<unsigned char> vchSig, vector<unsigned char> vchPubKey, CScript scriptCode,
experimental-genesis 971 const CTransaction& txTo, unsigned int nIn, int nHashType)
experimental-genesis 972 {
experimental-genesis 973 CKey key;
experimental-genesis 974 if (!key.SetPubKey(vchPubKey))
experimental-genesis 975 return false;
experimental-genesis 976
experimental-genesis 977 // Hash type is one byte tacked on to the end of the signature
experimental-genesis 978 if (vchSig.empty())
experimental-genesis 979 return false;
experimental-genesis 980 if (nHashType == 0)
experimental-genesis 981 nHashType = vchSig.back();
experimental-genesis 982 else if (nHashType != vchSig.back())
experimental-genesis 983 return false;
experimental-genesis 984 vchSig.pop_back();
experimental-genesis 985
experimental-genesis 986 return key.Verify(SignatureHash(scriptCode, txTo, nIn, nHashType), vchSig);
experimental-genesis 987 }
experimental-genesis 988
experimental-genesis 989
experimental-genesis 990
experimental-genesis 991
experimental-genesis 992
experimental-genesis 993
experimental-genesis 994
experimental-genesis 995
experimental-genesis 996
experimental-genesis 997
experimental-genesis 998 bool Solver(const CScript& scriptPubKey, vector<pair<opcodetype, valtype> >& vSolutionRet)
experimental-genesis 999 {
experimental-genesis 1000 // Templates
experimental-genesis 1001 static vector<CScript> vTemplates;
experimental-genesis 1002 if (vTemplates.empty())
experimental-genesis 1003 {
experimental-genesis 1004 // Standard tx, sender provides pubkey, receiver adds signature
experimental-genesis 1005 vTemplates.push_back(CScript() << OP_PUBKEY << OP_CHECKSIG);
experimental-genesis 1006
experimental-genesis 1007 // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
experimental-genesis 1008 vTemplates.push_back(CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG);
experimental-genesis 1009 }
experimental-genesis 1010
experimental-genesis 1011 // Scan templates
experimental-genesis 1012 const CScript& script1 = scriptPubKey;
experimental-genesis 1013 BOOST_FOREACH(const CScript& script2, vTemplates)
experimental-genesis 1014 {
experimental-genesis 1015 vSolutionRet.clear();
experimental-genesis 1016 opcodetype opcode1, opcode2;
experimental-genesis 1017 vector<unsigned char> vch1, vch2;
experimental-genesis 1018
experimental-genesis 1019 // Compare
experimental-genesis 1020 CScript::const_iterator pc1 = script1.begin();
experimental-genesis 1021 CScript::const_iterator pc2 = script2.begin();
experimental-genesis 1022 loop
experimental-genesis 1023 {
experimental-genesis 1024 if (pc1 == script1.end() && pc2 == script2.end())
experimental-genesis 1025 {
experimental-genesis 1026 // Found a match
experimental-genesis 1027 reverse(vSolutionRet.begin(), vSolutionRet.end());
experimental-genesis 1028 return true;
experimental-genesis 1029 }
experimental-genesis 1030 if (!script1.GetOp(pc1, opcode1, vch1))
experimental-genesis 1031 break;
experimental-genesis 1032 if (!script2.GetOp(pc2, opcode2, vch2))
experimental-genesis 1033 break;
experimental-genesis 1034 if (opcode2 == OP_PUBKEY)
experimental-genesis 1035 {
experimental-genesis 1036 if (vch1.size() < 33 || vch1.size() > 120)
experimental-genesis 1037 break;
experimental-genesis 1038 vSolutionRet.push_back(make_pair(opcode2, vch1));
experimental-genesis 1039 }
experimental-genesis 1040 else if (opcode2 == OP_PUBKEYHASH)
experimental-genesis 1041 {
experimental-genesis 1042 if (vch1.size() != sizeof(uint160))
experimental-genesis 1043 break;
experimental-genesis 1044 vSolutionRet.push_back(make_pair(opcode2, vch1));
experimental-genesis 1045 }
experimental-genesis 1046 else if (opcode1 != opcode2 || vch1 != vch2)
experimental-genesis 1047 {
experimental-genesis 1048 break;
experimental-genesis 1049 }
experimental-genesis 1050 }
experimental-genesis 1051 }
experimental-genesis 1052
experimental-genesis 1053 vSolutionRet.clear();
experimental-genesis 1054 return false;
experimental-genesis 1055 }
experimental-genesis 1056
experimental-genesis 1057
experimental-genesis 1058 bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType, CScript& scriptSigRet)
experimental-genesis 1059 {
experimental-genesis 1060 scriptSigRet.clear();
experimental-genesis 1061
experimental-genesis 1062 vector<pair<opcodetype, valtype> > vSolution;
experimental-genesis 1063 if (!Solver(scriptPubKey, vSolution))
experimental-genesis 1064 return false;
experimental-genesis 1065
experimental-genesis 1066 // Compile solution
experimental-genesis 1067 BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
experimental-genesis 1068 {
experimental-genesis 1069 if (item.first == OP_PUBKEY)
experimental-genesis 1070 {
experimental-genesis 1071 // Sign
experimental-genesis 1072 const valtype& vchPubKey = item.second;
experimental-genesis 1073 CKey key;
experimental-genesis 1074 if (!keystore.GetKey(Hash160(vchPubKey), key))
experimental-genesis 1075 return false;
experimental-genesis 1076 if (key.GetPubKey() != vchPubKey)
experimental-genesis 1077 return false;
experimental-genesis 1078 if (hash != 0)
experimental-genesis 1079 {
experimental-genesis 1080 vector<unsigned char> vchSig;
experimental-genesis 1081 if (!key.Sign(hash, vchSig))
experimental-genesis 1082 return false;
experimental-genesis 1083 vchSig.push_back((unsigned char)nHashType);
experimental-genesis 1084 scriptSigRet << vchSig;
experimental-genesis 1085 }
experimental-genesis 1086 }
experimental-genesis 1087 else if (item.first == OP_PUBKEYHASH)
experimental-genesis 1088 {
experimental-genesis 1089 // Sign and give pubkey
experimental-genesis 1090 CKey key;
experimental-genesis 1091 if (!keystore.GetKey(uint160(item.second), key))
experimental-genesis 1092 return false;
experimental-genesis 1093 if (hash != 0)
experimental-genesis 1094 {
experimental-genesis 1095 vector<unsigned char> vchSig;
experimental-genesis 1096 if (!key.Sign(hash, vchSig))
experimental-genesis 1097 return false;
experimental-genesis 1098 vchSig.push_back((unsigned char)nHashType);
experimental-genesis 1099 scriptSigRet << vchSig << key.GetPubKey();
experimental-genesis 1100 }
experimental-genesis 1101 }
experimental-genesis 1102 else
experimental-genesis 1103 {
experimental-genesis 1104 return false;
experimental-genesis 1105 }
experimental-genesis 1106 }
experimental-genesis 1107
experimental-genesis 1108 return true;
experimental-genesis 1109 }
experimental-genesis 1110
experimental-genesis 1111
experimental-genesis 1112 bool IsStandard(const CScript& scriptPubKey)
experimental-genesis 1113 {
experimental-genesis 1114 vector<pair<opcodetype, valtype> > vSolution;
experimental-genesis 1115 return Solver(scriptPubKey, vSolution);
experimental-genesis 1116 }
experimental-genesis 1117
experimental-genesis 1118
experimental-genesis 1119 bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
experimental-genesis 1120 {
experimental-genesis 1121 vector<pair<opcodetype, valtype> > vSolution;
experimental-genesis 1122 if (!Solver(scriptPubKey, vSolution))
experimental-genesis 1123 return false;
experimental-genesis 1124
experimental-genesis 1125 // Compile solution
experimental-genesis 1126 BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
experimental-genesis 1127 {
experimental-genesis 1128 if (item.first == OP_PUBKEY)
experimental-genesis 1129 {
experimental-genesis 1130 const valtype& vchPubKey = item.second;
experimental-genesis 1131 vector<unsigned char> vchPubKeyFound;
experimental-genesis 1132 if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound))
experimental-genesis 1133 return false;
experimental-genesis 1134 if (vchPubKeyFound != vchPubKey)
experimental-genesis 1135 return false;
experimental-genesis 1136 }
experimental-genesis 1137 else if (item.first == OP_PUBKEYHASH)
experimental-genesis 1138 {
experimental-genesis 1139 if (!keystore.HaveKey(uint160(item.second)))
experimental-genesis 1140 return false;
experimental-genesis 1141 }
experimental-genesis 1142 else
experimental-genesis 1143 {
experimental-genesis 1144 return false;
experimental-genesis 1145 }
experimental-genesis 1146 }
experimental-genesis 1147
experimental-genesis 1148 return true;
experimental-genesis 1149 }
experimental-genesis 1150
experimental-genesis 1151 bool static ExtractAddressInner(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
experimental-genesis 1152 {
experimental-genesis 1153 vector<pair<opcodetype, valtype> > vSolution;
experimental-genesis 1154 if (!Solver(scriptPubKey, vSolution))
experimental-genesis 1155 return false;
experimental-genesis 1156
experimental-genesis 1157 BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
experimental-genesis 1158 {
experimental-genesis 1159 if (item.first == OP_PUBKEY)
experimental-genesis 1160 addressRet.SetPubKey(item.second);
experimental-genesis 1161 else if (item.first == OP_PUBKEYHASH)
experimental-genesis 1162 addressRet.SetHash160((uint160)item.second);
experimental-genesis 1163 if (keystore == NULL || keystore->HaveKey(addressRet))
experimental-genesis 1164 return true;
experimental-genesis 1165 }
experimental-genesis 1166
experimental-genesis 1167 return false;
experimental-genesis 1168 }
experimental-genesis 1169
experimental-genesis 1170
experimental-genesis 1171 bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
experimental-genesis 1172 {
experimental-genesis 1173 if (keystore)
experimental-genesis 1174 return ExtractAddressInner(scriptPubKey, keystore, addressRet);
experimental-genesis 1175 else
experimental-genesis 1176 return ExtractAddressInner(scriptPubKey, NULL, addressRet);
experimental-genesis 1177 return false;
experimental-genesis 1178 }
experimental-genesis 1179
experimental-genesis 1180
experimental-genesis 1181 bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int nHashType)
experimental-genesis 1182 {
experimental-genesis 1183 vector<vector<unsigned char> > stack;
experimental-genesis 1184 if (!EvalScript(stack, scriptSig, txTo, nIn, nHashType))
experimental-genesis 1185 return false;
experimental-genesis 1186 if (!EvalScript(stack, scriptPubKey, txTo, nIn, nHashType))
experimental-genesis 1187 return false;
experimental-genesis 1188 if (stack.empty())
experimental-genesis 1189 return false;
experimental-genesis 1190 return CastToBool(stack.back());
experimental-genesis 1191 }
experimental-genesis 1192
experimental-genesis 1193
experimental-genesis 1194 bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType, CScript scriptPrereq)
experimental-genesis 1195 {
experimental-genesis 1196 assert(nIn < txTo.vin.size());
experimental-genesis 1197 CTxIn& txin = txTo.vin[nIn];
experimental-genesis 1198 assert(txin.prevout.n < txFrom.vout.size());
experimental-genesis 1199 const CTxOut& txout = txFrom.vout[txin.prevout.n];
experimental-genesis 1200
experimental-genesis 1201 // Leave out the signature from the hash, since a signature can't sign itself.
experimental-genesis 1202 // The checksig op will also drop the signatures from its hash.
experimental-genesis 1203 uint256 hash = SignatureHash(scriptPrereq + txout.scriptPubKey, txTo, nIn, nHashType);
experimental-genesis 1204
experimental-genesis 1205 if (!Solver(keystore, txout.scriptPubKey, hash, nHashType, txin.scriptSig))
experimental-genesis 1206 return false;
experimental-genesis 1207
experimental-genesis 1208 txin.scriptSig = scriptPrereq + txin.scriptSig;
experimental-genesis 1209
experimental-genesis 1210 // Test solution
experimental-genesis 1211 if (scriptPrereq.empty())
experimental-genesis 1212 if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, 0))
experimental-genesis 1213 return false;
experimental-genesis 1214
experimental-genesis 1215 return true;
experimental-genesis 1216 }
experimental-genesis 1217
experimental-genesis 1218
experimental-genesis 1219 bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType)
experimental-genesis 1220 {
experimental-genesis 1221 assert(nIn < txTo.vin.size());
experimental-genesis 1222 const CTxIn& txin = txTo.vin[nIn];
experimental-genesis 1223 if (txin.prevout.n >= txFrom.vout.size())
experimental-genesis 1224 return false;
experimental-genesis 1225 const CTxOut& txout = txFrom.vout[txin.prevout.n];
experimental-genesis 1226
experimental-genesis 1227 if (txin.prevout.hash != txFrom.GetHash())
experimental-genesis 1228 return false;
experimental-genesis 1229
experimental-genesis 1230 if (!VerifyScript(txin.scriptSig, txout.scriptPubKey, txTo, nIn, nHashType))
experimental-genesis 1231 return false;
experimental-genesis 1232
experimental-genesis 1233 return true;
experimental-genesis 1234 }