diff --git a/core/src/main/java/com/google/bitcoin/core/Message.java b/core/src/main/java/com/google/bitcoin/core/Message.java index 384d972d..1dd72b17 100644 --- a/core/src/main/java/com/google/bitcoin/core/Message.java +++ b/core/src/main/java/com/google/bitcoin/core/Message.java @@ -410,6 +410,11 @@ public abstract class Message implements Serializable { return new Sha256Hash(hash); } + long readInt64() { + long u = Utils.readInt64(bytes, cursor); + cursor += 8; + return u; + } BigInteger readUint64() { // Java does not have an unsigned 64 bit type. So scrape it off the wire then flip. diff --git a/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java b/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java index 0c4154e9..89d80971 100644 --- a/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java +++ b/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java @@ -131,7 +131,11 @@ public class TransactionOutput extends ChildMessage implements Serializable { } protected void parseLite() { - value = readUint64(); + // TODO: There is no reason to use BigInteger for values, they are always smaller than 21 million * COIN + // The only reason to use BigInteger would be to properly read values from the reference implementation, however + // the reference implementation uses signed 64-bit integers for its values as well (though it probably shouldn't) + long outputValue = readInt64(); + value = BigInteger.valueOf(outputValue); scriptLen = (int) readVarInt(); length = cursor - offset + scriptLen; } diff --git a/core/src/main/java/com/google/bitcoin/core/Utils.java b/core/src/main/java/com/google/bitcoin/core/Utils.java index 2d350901..e14555c5 100644 --- a/core/src/main/java/com/google/bitcoin/core/Utils.java +++ b/core/src/main/java/com/google/bitcoin/core/Utils.java @@ -238,6 +238,17 @@ public class Utils { ((bytes[offset++] & 0xFFL) << 16) | ((bytes[offset] & 0xFFL) << 24); } + + public static long readInt64(byte[] bytes, int offset) { + return ((bytes[offset++] & 0xFFL) << 0) | + ((bytes[offset++] & 0xFFL) << 8) | + ((bytes[offset++] & 0xFFL) << 16) | + ((bytes[offset++] & 0xFFL) << 24) | + ((bytes[offset++] & 0xFFL) << 32) | + ((bytes[offset++] & 0xFFL) << 40) | + ((bytes[offset++] & 0xFFL) << 48) | + ((bytes[offset] & 0xFFL) << 56); + } public static long readUint32BE(byte[] bytes, int offset) { return ((bytes[offset + 0] & 0xFFL) << 24) |