From 775af907ae42b4bfa29e92ccad203b80a54c0669 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 23 Apr 2013 17:57:16 +0200 Subject: [PATCH] Widen the scoping on a few methods in preparation for moving the Script class. --- .../java/com/google/bitcoin/core/Script.java | 33 ++++++++++++++++--- .../com/google/bitcoin/core/Transaction.java | 8 ++--- .../java/com/google/bitcoin/core/Utils.java | 4 +-- .../com/google/bitcoin/core/WalletTest.java | 4 +-- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/core/Script.java b/core/src/main/java/com/google/bitcoin/core/Script.java index 05d3ba91..6d366d4e 100644 --- a/core/src/main/java/com/google/bitcoin/core/Script.java +++ b/core/src/main/java/com/google/bitcoin/core/Script.java @@ -17,6 +17,7 @@ package com.google.bitcoin.core; +import com.google.common.collect.Lists; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.crypto.digests.RIPEMD160Digest; @@ -56,18 +57,33 @@ public class Script { * An element that is either an opcode or a raw byte array (signature, pubkey, etc). */ public static class Chunk { - public boolean isOpCode; + private boolean isOpCode; public byte[] data; - public int startLocationInProgram; + private int startLocationInProgram; + + public Chunk(boolean isOpCode, byte[] data) { + this(isOpCode, data, -1); + } + public Chunk(boolean isOpCode, byte[] data, int startLocationInProgram) { this.isOpCode = isOpCode; this.data = data; this.startLocationInProgram = startLocationInProgram; } + public boolean equalsOpCode(int opCode) { return isOpCode && data.length == 1 && (0xFF & data[0]) == opCode; } + public boolean isOpCode() { + return isOpCode; + } + + public int getStartLocationInProgram() { + checkState(startLocationInProgram >= 0); + return startLocationInProgram; + } + public void write(OutputStream stream) throws IOException { if (isOpCode) { checkState(data.length == 1); @@ -98,8 +114,10 @@ public class Script { // must preserve the exact bytes that we read off the wire, along with the parsed form. protected byte[] program; - // Only for internal use - private Script() {} + /** Creates an empty script that serializes to nothing. */ + public Script() { + chunks = Lists.newArrayList(); + } /** * Construct a Script that copies and wraps the programBytes array. The array is parsed and checked for syntactic @@ -146,6 +164,11 @@ public class Script { } } + /** Returns an immutable list of the scripts parsed form. */ + public List getChunks() { + return Collections.unmodifiableList(chunks); + } + /** *

To run a script, first we parse it which breaks it up into chunks representing pushes of data or logical * opcodes. Then we can run the parsed chunks.

@@ -1056,7 +1079,7 @@ public class Script { stack.add(Utils.doubleDigest(stack.pollLast())); break; case OP_CODESEPARATOR: - lastCodeSepLocation = chunk.startLocationInProgram + 1; + lastCodeSepLocation = chunk.getStartLocationInProgram() + 1; break; case OP_CHECKSIG: case OP_CHECKSIGVERIFY: diff --git a/core/src/main/java/com/google/bitcoin/core/Transaction.java b/core/src/main/java/com/google/bitcoin/core/Transaction.java index 9b2d5f9c..16917574 100644 --- a/core/src/main/java/com/google/bitcoin/core/Transaction.java +++ b/core/src/main/java/com/google/bitcoin/core/Transaction.java @@ -599,11 +599,11 @@ public class Transaction extends ChildMessage implements Serializable { try { Script scriptSig = in.getScriptSig(); - if (scriptSig.chunks.size() == 2) + if (scriptSig.getChunks().size() == 2) s.append(scriptSig.getFromAddress(params).toString()); - else if (scriptSig.chunks.size() == 1) { + else if (scriptSig.getChunks().size() == 1) { s.append("[sig:"); - s.append(bytesToHexString(scriptSig.chunks.get(0).data)); + s.append(bytesToHexString(scriptSig.getChunks().get(0).data)); s.append("]"); } else s.append("???"); @@ -813,7 +813,7 @@ public class Transaction extends ChildMessage implements Serializable { * This is required for signatures which use a sigHashType which cannot be represented using SigHash and anyoneCanPay * See transaction c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73, which has sigHashType 0 */ - synchronized Sha256Hash hashTransactionForSignature(int inputIndex, byte[] connectedScript, + public synchronized Sha256Hash hashTransactionForSignature(int inputIndex, byte[] connectedScript, byte sigHashType) throws ScriptException { // TODO: This whole separate method should be un-necessary if we fix how we deserialize sighash flags. 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 f1a06ea2..b9d3effd 100644 --- a/core/src/main/java/com/google/bitcoin/core/Utils.java +++ b/core/src/main/java/com/google/bitcoin/core/Utils.java @@ -347,7 +347,7 @@ public class Utils { * the number in big endian format (with a sign bit). * @param hasLength can be set to false if the given array is missing the 4 byte length field */ - static BigInteger decodeMPI(byte[] mpi, boolean hasLength) { + public static BigInteger decodeMPI(byte[] mpi, boolean hasLength) { byte[] buf; if (hasLength) { int length = (int) readUint32BE(mpi, 0); @@ -370,7 +370,7 @@ public class Utils { * the number in big endian format (with a sign bit). * @param includeLength indicates whether the 4 byte length field should be included */ - static byte[] encodeMPI(BigInteger value, boolean includeLength) { + public static byte[] encodeMPI(BigInteger value, boolean includeLength) { if (value.equals(BigInteger.ZERO)) { if (!includeLength) return new byte[] {}; diff --git a/core/src/test/java/com/google/bitcoin/core/WalletTest.java b/core/src/test/java/com/google/bitcoin/core/WalletTest.java index 5b1ec0ce..9e56cc7f 100644 --- a/core/src/test/java/com/google/bitcoin/core/WalletTest.java +++ b/core/src/test/java/com/google/bitcoin/core/WalletTest.java @@ -853,8 +853,8 @@ public class WalletTest extends TestWithWallet { Transaction t2 = wallet.createSend(new ECKey().toAddress(params), value); assertNotNull(t2); // TODO: This code is messy, improve the Script class and fixinate! - assertEquals(t2.toString(), 1, t2.getInputs().get(0).getScriptSig().chunks.size()); - assertTrue(t2.getInputs().get(0).getScriptSig().chunks.get(0).data.length > 50); + assertEquals(t2.toString(), 1, t2.getInputs().get(0).getScriptSig().getChunks().size()); + assertTrue(t2.getInputs().get(0).getScriptSig().getChunks().get(0).data.length > 50); log.info(t2.toString(chain)); }