diff --git a/src/core_read.cpp b/src/core_read.cpp
--- a/src/core_read.cpp
+++ b/src/core_read.cpp
@@ -49,7 +49,9 @@
                             boost::algorithm::token_compress_on);
 
     size_t push_size = 0, next_push_size = 0;
-    size_t script_size = 0;
+    size_t script_size = 0, size_change = 0;
+    // Deal with PUSHDATA1 operation with some more hacks.
+    size_t push_data_size = 0;
 
     for (const auto &w : words) {
         if (w.empty()) {
@@ -63,8 +65,8 @@
 
         // Make sure we keep track of the size of push operations.
         push_size = next_push_size;
-        next_push_size = 0;
 
+        // Decimal numbers
         if (all(w, boost::algorithm::is_digit()) ||
             (boost::algorithm::starts_with(w, "-") &&
              all(std::string(w.begin() + 1, w.end()),
@@ -75,6 +77,7 @@
             goto next;
         }
 
+        // Hex Data
         if (boost::algorithm::starts_with(w, "0x") &&
             (w.begin() + 2 != w.end())) {
             if (!IsHex(std::string(w.begin() + 2, w.end()))) {
@@ -87,11 +90,6 @@
             // Raw hex data, inserted NOT pushed onto stack:
             std::vector<uint8_t> raw =
                 ParseHex(std::string(w.begin() + 2, w.end()));
-            // If we have what looks like an immediate push, figure out its
-            // size.
-            if (!push_size && raw.size() == 1 && raw[0] < OP_PUSHDATA1) {
-                next_push_size = raw[0];
-            }
 
             result.insert(result.end(), raw.begin(), raw.end());
             goto next;
@@ -111,30 +109,67 @@
             // opcode, e.g. OP_ADD or ADD:
             opcodetype op = mapOpNames[w];
 
+            result << op;
+            goto next;
+        }
+
+        throw std::runtime_error("Error parsing script: " + s);
+
+    next:
+        next_push_size = 0;
+        size_change = result.size() - script_size;
+
+        // If push_size is set, ensure have added the right amount of stuff.
+        if (push_size != 0 && size_change != push_size) {
+            throw std::runtime_error("Wrong number of bytes being pushed.");
+        }
+
+        // If push_size is set, and we have push_data_size set, then we have a
+        // PUSHDATAX opcode.  We need to read it's push size as a LE value for
+        // the next iteration of this loop.
+        if (push_size != 0 && push_data_size != 0) {
+            auto offset = &result[script_size];
+
+            // Push data size is not a CScriptNum (Because it is
+            // 2's-complement instead of 1's complement).  We need to use
+            // ReadLE(N) instead of converting to a CScriptNum.
+            if (push_data_size == 1) {
+                next_push_size = *offset;
+            } else if (push_data_size == 2) {
+                next_push_size = ReadLE16(offset);
+            } else if (push_data_size == 4) {
+                next_push_size = ReadLE32(offset);
+            }
+
+            push_data_size = 0;
+        }
+
+        // If push_size is unset, but size_change is 1, that means we have an
+        // opcode in the form of `0x00`.  We will check to see if it is a push
+        // operation and set state accordingly
+        if (push_size == 0 && size_change == 1) {
+            opcodetype op = opcodetype(*result.rbegin());
+
+            // If we have what looks like an immediate push, figure out its
+            // size.
+            if (op < OP_PUSHDATA1) {
+                next_push_size = op;
+                continue;
+            }
+
             switch (op) {
                 case OP_PUSHDATA1:
-                    next_push_size = 1;
+                    push_data_size = next_push_size = 1;
                     break;
                 case OP_PUSHDATA2:
-                    next_push_size = 2;
+                    push_data_size = next_push_size = 2;
                     break;
                 case OP_PUSHDATA4:
-                    next_push_size = 4;
+                    push_data_size = next_push_size = 4;
                     break;
                 default:
                     break;
             }
-
-            result << op;
-            goto next;
-        }
-
-        throw std::runtime_error("Error parsing script: " + s);
-
-    next:
-        size_t size_change = result.size() - script_size;
-        if (push_size && size_change != push_size) {
-            throw std::runtime_error("Wrong number of bytes being pushed.");
         }
     }
 
diff --git a/src/test/core_io_tests.cpp b/src/test/core_io_tests.cpp
--- a/src/test/core_io_tests.cpp
+++ b/src/test/core_io_tests.cpp
@@ -25,6 +25,44 @@
     }
 }
 
+static void PrintLE(std::ostringstream &testString, size_t bytes,
+                    size_t pushLength) {
+    testString << "0x";
+    while (bytes != 0) {
+        testString << std::setfill('0') << std::setw(2) << std::hex
+                   << pushLength % 256;
+        pushLength /= 256;
+        bytes--;
+    }
+}
+
+static std::string TestPushOpcode(size_t pushWidth, size_t pushLength,
+                                  size_t actualLength) {
+    std::ostringstream testString;
+
+    switch (pushWidth) {
+        case 1:
+            testString << "PUSHDATA1 ";
+            break;
+        case 2:
+            testString << "PUSHDATA2 ";
+            break;
+        case 4:
+            testString << "PUSHDATA4 ";
+            break;
+        default:
+            assert(false);
+    }
+    PrintLE(testString, pushWidth, pushLength);
+    testString << " 0x";
+
+    for (size_t i = 0; i < actualLength; i++) {
+        testString << "01";
+    }
+
+    return testString.str();
+}
+
 BOOST_AUTO_TEST_CASE(parse_push_test) {
     BOOST_CHECK_NO_THROW(ParseScript("0x01 0x01"));
     BOOST_CHECK_NO_THROW(ParseScript("0x01 XOR"));
@@ -42,6 +80,64 @@
     BOOST_CHECK_THROW(ParseScript("0x02 ''"), std::runtime_error);
     BOOST_CHECK_THROW(ParseScript("0x02 0x010101"), std::runtime_error);
     BOOST_CHECK_THROW(ParseScript("0x02 'ab'"), std::runtime_error);
+
+    // Note sizes are LE encoded.  Also, some of these values are not
+    // minimally encoded intentionally -- nor are they being required to be
+    // minimally encoded.
+    BOOST_CHECK_NO_THROW(ParseScript("PUSHDATA4 0x02000000 0x0101"));
+    BOOST_CHECK_THROW(ParseScript("PUSHDATA4 0x03000000 0x0101"),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript("PUSHDATA4 0x02000000 0x010101"),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript("PUSHDATA4 0x020000 0x0101"),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript("PUSHDATA4 0x0200000000 0x0101"),
+                      std::runtime_error);
+
+    BOOST_CHECK_NO_THROW(ParseScript("PUSHDATA2 0x0200 0x0101"));
+    BOOST_CHECK_THROW(ParseScript("PUSHDATA2 0x0300 0x0101"),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript("PUSHDATA2 0x030000 0x0101"),
+                      std::runtime_error);
+    BOOST_CHECK_NO_THROW(ParseScript("PUSHDATA1 0x02 0x0101"));
+    BOOST_CHECK_THROW(ParseScript("PUSHDATA1 0x02 0x010101"),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript("PUSHDATA1 0x0200 0x010101"),
+                      std::runtime_error);
+
+    // Ensure the test generator is doing what we think it is.
+    std::ostringstream testString;
+    PrintLE(testString, 04, 0x8001);
+    BOOST_CHECK_EQUAL(testString.str(), "0x01800000");
+    BOOST_CHECK_EQUAL(TestPushOpcode(1, 2, 2), "PUSHDATA1 0x02 0x0101");
+    BOOST_CHECK_EQUAL(TestPushOpcode(2, 2, 2), "PUSHDATA2 0x0200 0x0101");
+    BOOST_CHECK_EQUAL(TestPushOpcode(4, 2, 2), "PUSHDATA4 0x02000000 0x0101");
+
+    // Ensure pushdata handling is not using 1's complement
+    BOOST_CHECK_NO_THROW(ParseScript(TestPushOpcode(1, 0xC8, 0xC8)));
+    BOOST_CHECK_THROW(ParseScript(TestPushOpcode(1, 0xC8, 0xC9)),
+                      std::runtime_error);
+
+    BOOST_CHECK_NO_THROW(ParseScript(TestPushOpcode(2, 0x8000, 0x8000)));
+    BOOST_CHECK_THROW(ParseScript(TestPushOpcode(2, 0x8000, 0x8001)),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript(TestPushOpcode(2, 0x8001, 0x8000)),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript(TestPushOpcode(2, 0x80, 0x81)),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript(TestPushOpcode(2, 0x80, 0x7F)),
+                      std::runtime_error);
+
+    // Can't build something too long.
+    BOOST_CHECK_NO_THROW(ParseScript(TestPushOpcode(4, 0x8000, 0x8000)));
+    BOOST_CHECK_THROW(ParseScript(TestPushOpcode(4, 0x8000, 0x8001)),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript(TestPushOpcode(4, 0x8001, 0x8000)),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript(TestPushOpcode(4, 0x80, 0x81)),
+                      std::runtime_error);
+    BOOST_CHECK_THROW(ParseScript(TestPushOpcode(4, 0x80, 0x7F)),
+                      std::runtime_error);
 }
 
 BOOST_AUTO_TEST_SUITE_END()