3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-01-31 07:12:17 +00:00

Delete some dead code in Script that was confusing people; BitCoinJ does not run scripts.

Remove build.xml as we've switched to Maven.
This commit is contained in:
Mike Hearn 2011-08-05 14:37:48 +00:00
parent 78bdd09189
commit 3498763d18
3 changed files with 0 additions and 185 deletions

View File

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="bitcoinj" default="all">
<target name="init">
<tstamp/>
<mkdir dir="out"/>
<mkdir dir="docs"/>
</target>
<target name="compile" depends="init">
<javac destdir="out" includeantruntime="no">
<src path="src"/>
<src path="tests"/>
<classpath path="lib/junit-4.8.2.jar"/>
<classpath path="lib/slf4j-api-1.6.1.jar"/>
<classpath path="lib/slf4j-simple-1.6.1.jar"/>
</javac>
</target>
<target name="docs" depends="init">
<javadoc sourcepath="src"
excludepackagenames="com.google.bitcoin.bouncycastle.*,com.google.bitcoin.examples.*"
destdir="docs"
additionalparam="-notimestamp"
classpath="lib/slf4j-api-1.6.1.jar"/>
</target>
<target name="test" depends="compile">
<junit showoutput="false">
<classpath path="lib/junit-4.8.2.jar:out"/>
<classpath path="lib/slf4j-api-1.6.1.jar:out"/>
<classpath path="lib/slf4j-simple-1.6.1.jar:out"/>
<batchtest>
<fileset dir="tests"><include name="**/*.java"/></fileset>
<formatter type="brief" usefile="no"/>
</batchtest>
</junit>
</target>
<target name="dist" depends="compile">
<mkdir dir="dist"/>
<jar jarfile="dist/bitcoinj-${DSTAMP}.jar" basedir="out"/>
</target>
<target name="all" depends="dist,docs,test"/>
<target name="clean">
<delete dir="out"/>
<delete dir="dist"/>
<delete dir="docs"/>
</target>
</project>

View File

@ -54,23 +54,11 @@ public class Script {
byte[] program; byte[] program;
private int cursor; private int cursor;
// The stack consists of an ordered series of data buffers growing from zero up.
private final Stack<byte[]> stack;
// The program is a set of byte[]s where each element is either [opcode] or [data, data, data ...] // The program is a set of byte[]s where each element is either [opcode] or [data, data, data ...]
private List<byte[]> chunks; private List<byte[]> chunks;
private boolean tracing;
byte[] programCopy; // TODO: remove this byte[] programCopy; // TODO: remove this
private final NetworkParameters params; private final NetworkParameters params;
/** Concatenates two scripts to form a new one. This is used when verifying transactions. */
public static Script join(Script a, Script b) throws ScriptException {
assert a.params == b.params;
byte[] fullProg = new byte[a.programCopy.length + b.programCopy.length];
System.arraycopy(a.programCopy, 0, fullProg, 0, a.programCopy.length);
System.arraycopy(b.programCopy, 0, fullProg, a.programCopy.length, b.programCopy.length);
return new Script(a.params, fullProg, 0, fullProg.length);
}
/** /**
* Construct a Script using the given network parameters and a range of the programBytes array. * Construct a Script using the given network parameters and a range of the programBytes array.
* @param params Network parameters. * @param params Network parameters.
@ -81,15 +69,9 @@ public class Script {
*/ */
public Script(NetworkParameters params, byte[] programBytes, int offset, int length) throws ScriptException { public Script(NetworkParameters params, byte[] programBytes, int offset, int length) throws ScriptException {
this.params = params; this.params = params;
stack = new Stack<byte[]>();
parse(programBytes, offset, length); parse(programBytes, offset, length);
} }
/** If true, running a program will log its instructions. */
public void setTracing(boolean value) {
this.tracing = value;
}
/** Returns the program opcodes as a string, for example "[1234] DUP HAHS160" */ /** Returns the program opcodes as a string, for example "[1234] DUP HAHS160" */
public String toString() { public String toString() {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
@ -240,7 +222,6 @@ public class Script {
return new Address(params, Utils.sha256hash160(getPubKey())); return new Address(params, Utils.sha256hash160(getPubKey()));
} }
/** /**
* Gets the destination address from this script, if it's in the required form (see getPubKey). * Gets the destination address from this script, if it's in the required form (see getPubKey).
* @throws ScriptException * @throws ScriptException
@ -248,110 +229,6 @@ public class Script {
public Address getToAddress() throws ScriptException { public Address getToAddress() throws ScriptException {
return new Address(params, getPubKeyHash()); return new Address(params, getPubKeyHash());
} }
/**
* Runs the script with the given Transaction as the "context". Some operations like CHECKSIG
* require a transaction to operate on (eg to hash). The context transaction is typically
* the transaction having its inputs verified, ie the one where the scriptSig comes from.
*/
public boolean run(Transaction context) throws ScriptException {
for (byte[] chunk : chunks) {
if (chunk.length == 1) {
int opcode = 0xFF & chunk[0];
switch (opcode) {
case OP_DUP: opDup(); break;
case OP_HASH160: opHash160(); break;
case OP_EQUALVERIFY: opEqualVerify(); break;
case OP_CHECKSIG: opCheckSig(context); break;
default:
log.debug("Unknown/unimplemented opcode: {}", opcode);
}
} else {
// Data block, push it onto the stack.
log.debug("Push {}", Utils.bytesToHexString(chunk));
stack.add(chunk);
}
}
byte[] result = stack.pop();
if (result.length != 1)
throw new ScriptException("Script left junk at the top of the stack: " + Utils.bytesToHexString(result));
return result[0] == 1;
}
void logStack() {
for (int i = 0; i < stack.size(); i++) {
log.debug("Stack[{}]: {}",i , Utils.bytesToHexString(stack.get(i)));
}
}
// WARNING: Unfinished and untested!
@SuppressWarnings("unused")
private void opCheckSig( Transaction context) throws ScriptException {
byte[] pubkey = stack.pop();
byte[] sigAndHashType = stack.pop();
// The signature has an extra byte on the end to indicate the type of hash. The signature
// is over the contents of the program, minus the signature itself of course.
byte hashType = sigAndHashType[sigAndHashType.length - 1];
// The high bit of the hashType byte is set to indicate "anyone can pay".
boolean anyoneCanPay = hashType < 0;
// Mask out the top bit.
hashType &= (byte)-1 >>> 1;
Transaction.SigHash sigHash;
switch (hashType) {
case 1: sigHash = SigHash.ALL; break;
case 2: sigHash = SigHash.NONE; break;
case 3: sigHash = SigHash.SINGLE; break;
default:
// TODO: This should probably not be an exception.
throw new ScriptException("Unknown sighash byte: " + sigAndHashType[sigAndHashType.length - 1]);
}
byte[] sig = new byte[sigAndHashType.length - 1];
System.arraycopy(sigAndHashType, 0, sig, 0, sig.length);
log.debug("CHECKSIG: hashtype={} anyoneCanPay={}", sigHash, anyoneCanPay);
if (context == null) {
// TODO: Fix the unit tests to run scripts in transaction context then remove this.
pushBool(true);
return;
}
// TODO: Implement me!
// Transaction tx = context.simplify(sigHash, 0, anyoneCanPay);
// The steps to do so are as follows:
// - Use the hashtype to fiddle the transaction as appropriate
// - Serialize the transaction and hash it
// - Use EC code to verify the hash matches the signature
pushBool(true);
}
@SuppressWarnings({"SameParameterValue"})
private void pushBool(boolean val) {
stack.push(new byte[] { val ? (byte)1 : (byte)0 });
}
private void opEqualVerify() throws ScriptException {
log.debug("EQUALVERIFY");
byte[] a = stack.pop();
byte[] b = stack.pop();
if (!Arrays.areEqual(a, b))
throw new ScriptException("EQUALVERIFY failed: " + Utils.bytesToHexString(a) + " vs " +
Utils.bytesToHexString(b));
}
/** Replaces the top item in the stack with a hash160 of it */
private void opHash160() {
byte[] buf = stack.pop();
byte[] hash = Utils.sha256hash160(buf);
stack.add(hash);
log.debug("HASH160: output is {}", Utils.bytesToHexString(hash));
}
/** Duplicates the top item on the stack */
private void opDup() {
log.debug("DUP");
stack.add(Arrays.clone(stack.lastElement()));
}
////////////////////// Interface for writing scripts from scratch //////////////////////////////// ////////////////////// Interface for writing scripts from scratch ////////////////////////////////

View File

@ -37,7 +37,6 @@ public class ScriptTest {
public void testScriptSig() throws Exception { public void testScriptSig() throws Exception {
byte[] sigProgBytes = Hex.decode(sigProg); byte[] sigProgBytes = Hex.decode(sigProg);
Script script = new Script(params, sigProgBytes, 0, sigProgBytes.length); Script script = new Script(params, sigProgBytes, 0, sigProgBytes.length);
script.setTracing(true);
// Test we can extract the from address. // Test we can extract the from address.
byte[] hash160 = Utils.sha256hash160(script.getPubKey()); byte[] hash160 = Utils.sha256hash160(script.getPubKey());
Address a = new Address(params, hash160); Address a = new Address(params, hash160);
@ -51,22 +50,12 @@ public class ScriptTest {
Script pubkey = new Script(params, pubkeyBytes, 0, pubkeyBytes.length); Script pubkey = new Script(params, pubkeyBytes, 0, pubkeyBytes.length);
Address toAddr = new Address(params, pubkey.getPubKeyHash()); Address toAddr = new Address(params, pubkey.getPubKeyHash());
assertEquals("mkFQohBpy2HDXrCwyMrYL5RtfrmeiuuPY2", toAddr.toString()); assertEquals("mkFQohBpy2HDXrCwyMrYL5RtfrmeiuuPY2", toAddr.toString());
// To verify a transaction as legitimate, both scripts are concatenated and then the whole
// thing is run. So check we can do that.
byte[] sigBytes = Hex.decode(sigProg);
Script sig = new Script(params, sigBytes, 0, sigBytes.length);
Script allScript = Script.join(sig, pubkey);
allScript.setTracing(true);
assertTrue(allScript.run(null));
allScript.logStack();
} }
@Test @Test
public void testIp() throws Exception { public void testIp() throws Exception {
byte[] bytes = Hex.decode("41043e96222332ea7848323c08116dddafbfa917b8e37f0bdf63841628267148588a09a43540942d58d49717ad3fabfe14978cf4f0a8b84d2435dad16e9aa4d7f935ac"); byte[] bytes = Hex.decode("41043e96222332ea7848323c08116dddafbfa917b8e37f0bdf63841628267148588a09a43540942d58d49717ad3fabfe14978cf4f0a8b84d2435dad16e9aa4d7f935ac");
Script s = new Script(params, bytes, 0, bytes.length); Script s = new Script(params, bytes, 0, bytes.length);
s.setTracing(true);
assertTrue(s.isSentToIP()); assertTrue(s.isSentToIP());
} }
} }