Beispiel #1
0
		public void Step() {
			byte next = Execution.Pop();
			bool branchIsRunning = RunBranch.Items.All(b => b);

			if(branchIsRunning) {
				if(Opcodes.IsFastPush(next)) {
					Main.Push(Execution.Pop(next));
				}
				else {
					switch((Op)next) {
					case Op.False:
						Main.Push(false);
						break;
					case Op.PushData1:
						int i = new SignedInt(Execution.Pop()).Value;
						Main.Push(Execution.Pop(i));
						break;
					case Op.PushData2:
						Main.Push(Execution.Pop(new SignedInt(Execution.Pop(2)).Value));
						break;
					case Op.PushData4:
						Main.Push(Execution.Pop(new SignedInt(Execution.Pop(4)).Value));
						break;
					case Op.Negate1:
						Main.Push(-1);
						break;
					case Op.True:
						Main.Push(true);
						break;
					case Op.Num2:
						Main.Push(2);
						break;
					case Op.Num3:
						Main.Push(3);
						break;
					case Op.Num4:
						Main.Push(4);
						break;
					case Op.Num5:
						Main.Push(5);
						break;
					case Op.Num6:
						Main.Push(6);
						break;
					case Op.Num7:
						Main.Push(7);
						break;
					case Op.Num8:
						Main.Push(8);
						break;
					case Op.Num9:
						Main.Push(9);
						break;
					case Op.Num10:
						Main.Push(10);
						break;
					case Op.Num11:
						Main.Push(11);
						break;
					case Op.Num12:
						Main.Push(12);
						break;
					case Op.Num13:
						Main.Push(13);
						break;
					case Op.Num14:
						Main.Push(14);
						break;
					case Op.Num15:
						Main.Push(15);
						break;
					case Op.Num16:
						Main.Push(16);
						break;

					case Op.Verify:
						if(!Main.PopTruth())
							throw new Exception();
						break;
					case Op.Return:
						throw new Exception();

					case Op.ToAltStack:
						Alt.Push(Main.Pop());
						break;
					case Op.FromAltStack:
						Main.Push(Alt.Pop());
						break;
					case Op.IfDup:
						if(Main.IsTrue)
							Main.Push(Main[0]);
						break;
					case Op.Depth:
						Main.Push(Main.Count);
						break;
					case Op.Drop:
						Main.Pop();
						break;
					case Op.Dup:
						Main.Push(Main[0]);
						break;
					case Op.Nip:
						Main.RemoveAt(1);
						break;
					case Op.Over:
						Main.Push(Main[1]);
						break;
					case Op.Pick:
						Main.Push(Main[Main.PopInt()]);
						break;
					case Op.Roll:
						int index = Main.PopInt();
						byte[] roll = Main[index];
						Main.RemoveAt(index);
						Main.Push(roll);
						break;
					case Op.Rot:
						byte[][] rot = Main.Pop(3);
						Main.Push(new byte[][] { rot[0], rot[2], rot[1] });
						break;
					case Op.Swap:
						byte[][] swap = Main.Pop(2);
						Main.Push(new byte[][] { swap[0], swap[1] });
						break;
					case Op.Tuck:
						byte[][] tuck = Main.Pop(2);
						Main.Push(new byte[][] { tuck[0], tuck[1], tuck[0] });
						break;
					case Op.Drop2:
						Main.Pop(2);
						break;
					case Op.Dup2:
						Main.Push(new byte[][] { Main[1], Main[0] });
						break;
					case Op.Dup3:
						Main.Push(new byte[][] { Main[2], Main[1], Main[0] });
						break;
					case Op.Over2:
						Main.Push(new byte[][] { Main[3], Main[2] });
						break;
					case Op.Rot2:
						byte[][] rot2 = Main.Pop(6);
						Main.Push(new byte[][] { rot2[1], rot2[0], rot2[5], rot2[4], rot2[3], rot2[2] });
						break;
					case Op.Swap2:
						byte[][] swap2 = Main.Pop(4);
						Main.Push(new byte[][] { swap2[2], swap2[3], swap2[0], swap2[1] });
						break;

					case Op.Size:
						throw new NotImplementedException();

					case Op.Equal:
						Main.Push(Main[0].SequenceEqual(Main[1]));
						break;
					case Op.EqualVerify:
						Main.Push(Main[0] == Main[1]);
						goto case Op.Verify;
					case Op.Add1:
						Main.Push(Main.PopInt() + 1);
						break;
					case Op.Sub1:
						Main.Push(Main.PopInt() - 1);
						break;
					case Op.Negate:
						Main.Push(-Main.PopInt());
						break;
					case Op.Abs:
						Main.Push(Math.Abs(Main.PopInt()));
						break;
					case Op.Not:
						Main.Push(Main.PopInt() == 0 ? 1 : 0);
						break;
					case Op.NotEqual0:
						Main.Push(Main.PopInt() == 0 ? 0 : 1);
						break;
					case Op.Add:
						Main.Push(Main.PopInt() + Main.PopInt());
						break;
					case Op.Sub:
						int b = Main.PopInt();
						Main.Push(Main.PopInt() - b);
						break;
					case Op.BoolAnd:
						Main.Push(Main.PopBool() && Main.PopBool());
						break;
					case Op.BoolOr:
						Main.Push(Main.PopBool() || Main.PopBool());
						break;
					case Op.NumEqual:
						Main.Push(Main.PopInt() == Main.PopInt());
						break;
					case Op.NumEqualVerify:
						Main.Push(Main.PopInt() == Main.PopInt());
						goto case Op.Verify;
					case Op.NumNotEqual:
						Main.Push(Main.PopInt() != Main.PopInt());
						break;
					case Op.LessThan:
						Main.Push(Main.PopInt() < Main.PopInt());
						break;
					case Op.GreaterThan:
						Main.Push(Main.PopInt() > Main.PopInt());
						break;
					case Op.LessThanOrEqual:
						Main.Push(Main.PopInt() <= Main.PopInt());
						break;
					case Op.GreaterThanOrEqual:
						Main.Push(Main.PopInt() >= Main.PopInt());
						break;
					case Op.Min:
						Main.Push(Math.Min(Main.PopInt(), Main.PopInt()));
						break;
					case Op.Max:
						Main.Push(Math.Max(Main.PopInt(), Main.PopInt()));
						break;
					case Op.Within:
						int max = Main.PopInt();
						int min = Main.PopInt();
						int x = Main.PopInt();
						Main.Push(min <= x && x < max);
						break;

					case Op.RIPEMD160:
						Main.Push(RIPEMD160.Hash(Main.Pop()));
						break;
					case Op.SHA1:
						Main.Push(SHA1.Hash(Main.Pop()));
						break;
					case Op.SHA256:
						Main.Push(SHA256.Hash(Main.Pop()));
						break;
					case Op.Hash160:
						Main.Push(Digest.Hash<RIPEMD160, SHA256>(Main.Pop()));
						break;
					case Op.Hash256:
						Main.Push(Digest.Hash<SHA256, SHA256>(Main.Pop()));
						break;
					case Op.CodeSeparator:
						lastSeparatorIndex = _start.Count - Execution.Count;
						break;
					case Op.CheckSig:
//						Main.Push(Transaction.SigIsValid(Main.Pop(), Main.Pop(), SubScript, InputIndex));
						throw new NotImplementedException();
					case Op.CheckSigVerify:
						throw new NotImplementedException();
					case Op.CheckMultiSig:
						throw new NotImplementedException();
					case Op.CheckMultiSigVerify:
						throw new NotImplementedException();

					case Op.Reserved:
					case Op.Ver:
					case Op.Reserved1:
					case Op.Reserved2:
						throw new Exception(String.Format("Invalid script! (opcode {0} used)", (Op)next));

						
					case Op.If:
					case Op.NotIf:
					case Op.Else:
					case Op.EndIf:
						goto case Op.Nop;
					
					case Op.Nop:
					case Op.Nop1:
					case Op.Nop2:
					case Op.Nop3:
					case Op.Nop4:
					case Op.Nop5:
					case Op.Nop6:
					case Op.Nop7:
					case Op.Nop8:
					case Op.Nop9:
					case Op.Nop10:
						break;

					default:
						throw new Exception(String.Format("{0} is an invalid opcode", next));
					}
				}
			}

			switch((Op)next) {
			case Op.If:
				RunBranch.Push(branchIsRunning && Main.PopBool());
				break;
			case Op.NotIf:
				RunBranch.Push(branchIsRunning && !Main.PopBool());
				break;
			case Op.Else:
				RunBranch.Push(!RunBranch.Pop() && !branchIsRunning);
				break;
			case Op.EndIf:
				RunBranch.Pop();
				break;
			case Op.VerIf:
			case Op.VerNotIf:
				throw new Exception(String.Format("Invalid script! (opcode {0} included)", (Op)next));
			}
		}
Beispiel #2
0
		public override string ToString() {
			var dataStack = new Stack<byte>(_start);
			var unpacked = new List<string>();

			while(dataStack.Count > 0) {
				byte next = dataStack.Pop();

				if(Opcodes.IsPush(next)) {
					int toPush = 0;

					if(Opcodes.IsFastPush(next))
						toPush = next;
					else if(next == (byte)Op.PushData1)
						toPush = new SignedInt(dataStack.Pop()).Value;
					else if(next == (byte)Op.PushData2)
						toPush = new SignedInt(dataStack.Pop(2)).Value;
					else if(next == (byte)Op.PushData4)
						toPush = new SignedInt(dataStack.Pop(4)).Value;

					unpacked.Add(BinaryHelpers.ByteArrayToHex(dataStack.Pop(toPush)).ToUpper());
				}

				else {
					unpacked.Add(Opcodes.Strings.FirstOrDefault(x => x.Value == (Op)next).Key ?? next.ToString());
				}
			}

			return String.Join(" ", unpacked);
		}