3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 18:55:52 +00:00

In UTXO property scriptBytes changed to class Script.

Property addressType deleted.
FullPrunedBlockChain code re-formatted, changed UTXO class usage.
This commit is contained in:
Loco 2015-04-29 13:16:51 +03:00 committed by Mike Hearn
parent 4e8f1bb153
commit bee1873e1a
4 changed files with 83 additions and 103 deletions

View File

@ -47,7 +47,9 @@ import static com.google.common.base.Preconditions.checkState;
public class FullPrunedBlockChain extends AbstractBlockChain { public class FullPrunedBlockChain extends AbstractBlockChain {
private static final Logger log = LoggerFactory.getLogger(FullPrunedBlockChain.class); private static final Logger log = LoggerFactory.getLogger(FullPrunedBlockChain.class);
/** Keeps a map of block hashes to StoredBlocks. */ /**
* Keeps a map of block hashes to StoredBlocks.
*/
protected final FullPrunedBlockStore blockStore; protected final FullPrunedBlockStore blockStore;
// Whether or not to execute scriptPubKeys before accepting a transaction (i.e. check signatures). // Whether or not to execute scriptPubKeys before accepting a transaction (i.e. check signatures).
@ -70,12 +72,16 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
this(Context.getOrCreate(params), wallet, blockStore); this(Context.getOrCreate(params), wallet, blockStore);
} }
/** Constructs a block chain connected to the given store. */ /**
* Constructs a block chain connected to the given store.
*/
public FullPrunedBlockChain(Context context, FullPrunedBlockStore blockStore) throws BlockStoreException { public FullPrunedBlockChain(Context context, FullPrunedBlockStore blockStore) throws BlockStoreException {
this(context, new ArrayList<BlockChainListener>(), blockStore); this(context, new ArrayList<BlockChainListener>(), blockStore);
} }
/** See {@link #FullPrunedBlockChain(Context, Wallet, FullPrunedBlockStore)} */ /**
* See {@link #FullPrunedBlockChain(Context, Wallet, FullPrunedBlockStore)}
*/
public FullPrunedBlockChain(NetworkParameters params, FullPrunedBlockStore blockStore) throws BlockStoreException { public FullPrunedBlockChain(NetworkParameters params, FullPrunedBlockStore blockStore) throws BlockStoreException {
this(Context.getOrCreate(params), blockStore); this(Context.getOrCreate(params), blockStore);
} }
@ -90,7 +96,9 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
this.chainHead = blockStore.getVerifiedChainHead(); this.chainHead = blockStore.getVerifiedChainHead();
} }
/** See {@link #FullPrunedBlockChain(Context, List, FullPrunedBlockStore)} */ /**
* See {@link #FullPrunedBlockChain(Context, List, FullPrunedBlockStore)}
*/
public FullPrunedBlockChain(NetworkParameters params, List<BlockChainListener> listeners, public FullPrunedBlockChain(NetworkParameters params, List<BlockChainListener> listeners,
FullPrunedBlockStore blockStore) throws BlockStoreException { FullPrunedBlockStore blockStore) throws BlockStoreException {
this(Context.getOrCreate(params), listeners, blockStore); this(Context.getOrCreate(params), listeners, blockStore);
@ -133,26 +141,30 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
this.runScripts = value; this.runScripts = value;
} }
//TODO: Remove lots of duplicated code in the two connectTransactions // TODO: Remove lots of duplicated code in the two connectTransactions
// TODO: execute in order of largest transaction (by input count) first // TODO: execute in order of largest transaction (by input count) first
ExecutorService scriptVerificationExecutor = Executors.newFixedThreadPool( ExecutorService scriptVerificationExecutor = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors(), new ContextPropagatingThreadFactory("Script verification")); Runtime.getRuntime().availableProcessors(), new ContextPropagatingThreadFactory("Script verification"));
/** A job submitted to the executor which verifies signatures. */ /**
* A job submitted to the executor which verifies signatures.
*/
private static class Verifier implements Callable<VerificationException> { private static class Verifier implements Callable<VerificationException> {
final Transaction tx; final Transaction tx;
final List<Script> prevOutScripts; final List<Script> prevOutScripts;
final Set<VerifyFlag> verifyFlags; final Set<VerifyFlag> verifyFlags;
public Verifier(final Transaction tx, final List<Script> prevOutScripts, final Set<VerifyFlag> verifyFlags) { public Verifier(final Transaction tx, final List<Script> prevOutScripts, final Set<VerifyFlag> verifyFlags) {
this.tx = tx; this.prevOutScripts = prevOutScripts; this.verifyFlags = verifyFlags; this.tx = tx;
this.prevOutScripts = prevOutScripts;
this.verifyFlags = verifyFlags;
} }
@Nullable @Nullable
@Override @Override
public VerificationException call() throws Exception { public VerificationException call() throws Exception {
try{ try {
ListIterator<Script> prevOutIt = prevOutScripts.listIterator(); ListIterator<Script> prevOutIt = prevOutScripts.listIterator();
for (int index = 0; index < tx.getInputs().size(); index++) { for (int index = 0; index < tx.getInputs().size(); index++) {
tx.getInputs().get(index).getScriptSig().correctlySpends(tx, index, prevOutIt.next(), verifyFlags); tx.getInputs().get(index).getScriptSig().correctlySpends(tx, index, prevOutIt.next(), verifyFlags);
@ -164,18 +176,20 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
} }
} }
/** Get the {@link Script} from the script bytes or null if it doesn't parse. */ /**
@Nullable * Get the {@link Script} from the script bytes or null if it doesn't parse.
*/
private Script getScript(byte[] scriptBytes) { private Script getScript(byte[] scriptBytes) {
try { try {
return new Script(scriptBytes); return new Script(scriptBytes);
} catch (Exception e) { } catch (Exception e) {
return null; return new Script(new byte[0]);
} }
} }
/** /**
* Get the address from the {@link Script} if it exists otherwise return empty string "". * Get the address from the {@link Script} if it exists otherwise return empty string "".
*
* @param script The script. * @param script The script.
* @return The address. * @return The address.
*/ */
@ -190,18 +204,6 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
return address; return address;
} }
/**
* Get the {@link Script.ScriptType} of this script.
* @param script The script.
* @return The script type.
*/
private Script.ScriptType getScriptType(@Nullable Script script) {
if (script != null) {
return script.getScriptType();
}
return Script.ScriptType.NO_TYPE;
}
@Override @Override
protected TransactionOutputChanges connectTransactions(int height, Block block) protected TransactionOutputChanges connectTransactions(int height, Block block)
throws VerificationException, BlockStoreException { throws VerificationException, BlockStoreException {
@ -252,7 +254,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
for (int index = 0; index < tx.getInputs().size(); index++) { for (int index = 0; index < tx.getInputs().size(); index++) {
TransactionInput in = tx.getInputs().get(index); TransactionInput in = tx.getInputs().get(index);
UTXO prevOut = blockStore.getTransactionOutput(in.getOutpoint().getHash(), UTXO prevOut = blockStore.getTransactionOutput(in.getOutpoint().getHash(),
in.getOutpoint().getIndex()); in.getOutpoint().getIndex());
if (prevOut == null) if (prevOut == null)
throw new VerificationException("Attempted to spend a non-existent or already spent output!"); throw new VerificationException("Attempted to spend a non-existent or already spent output!");
// Coinbases can't be spent until they mature, to avoid re-orgs destroying entire transaction // Coinbases can't be spent until they mature, to avoid re-orgs destroying entire transaction
@ -266,16 +268,13 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
// TODO: Check we're not spending the genesis transaction here. Satoshis code won't allow it. // TODO: Check we're not spending the genesis transaction here. Satoshis code won't allow it.
valueIn = valueIn.add(prevOut.getValue()); valueIn = valueIn.add(prevOut.getValue());
if (verifyFlags.contains(VerifyFlag.P2SH)) { if (verifyFlags.contains(VerifyFlag.P2SH)) {
if (new Script(prevOut.getScriptBytes()).isPayToScriptHash()) if (prevOut.getScript().isPayToScriptHash())
sigOps += Script.getP2SHSigOpCount(in.getScriptBytes()); sigOps += Script.getP2SHSigOpCount(in.getScriptBytes());
if (sigOps > Block.MAX_BLOCK_SIGOPS) if (sigOps > Block.MAX_BLOCK_SIGOPS)
throw new VerificationException("Too many P2SH SigOps in block"); throw new VerificationException("Too many P2SH SigOps in block");
} }
prevOutScripts.add(new Script(prevOut.getScriptBytes())); prevOutScripts.add(prevOut.getScript());
//in.getScriptSig().correctlySpends(tx, index, new Script(params, prevOut.getScriptBytes(), 0, prevOut.getScriptBytes().length));
blockStore.removeUnspentTransactionOutput(prevOut); blockStore.removeUnspentTransactionOutput(prevOut);
txOutsSpent.add(prevOut); txOutsSpent.add(prevOut);
} }
@ -289,9 +288,8 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
out.getIndex(), out.getIndex(),
out.getValue(), out.getValue(),
height, isCoinBase, height, isCoinBase,
out.getScriptBytes(), script,
getScriptAddress(script), getScriptAddress(script));
getScriptType(script).ordinal());
blockStore.addUnspentTransactionOutput(newOut); blockStore.addUnspentTransactionOutput(newOut);
txOutsCreated.add(newOut); txOutsCreated.add(newOut);
} }
@ -369,7 +367,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
if (newBlock.getHeader().getTimeSeconds() >= NetworkParameters.BIP16_ENFORCE_TIME) if (newBlock.getHeader().getTimeSeconds() >= NetworkParameters.BIP16_ENFORCE_TIME)
verifyFlags.add(VerifyFlag.P2SH); verifyFlags.add(VerifyFlag.P2SH);
if (!params.isCheckpoint(newBlock.getHeight())) { if (!params.isCheckpoint(newBlock.getHeight())) {
for(Transaction tx : transactions) { for (Transaction tx : transactions) {
Sha256Hash hash = tx.getHash(); Sha256Hash hash = tx.getHash();
if (blockStore.hasUnspentOutputs(hash, tx.getOutputs().size())) if (blockStore.hasUnspentOutputs(hash, tx.getOutputs().size()))
throw new VerificationException("Block failed BIP30 test!"); throw new VerificationException("Block failed BIP30 test!");
@ -381,7 +379,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
if (scriptVerificationExecutor.isShutdown()) if (scriptVerificationExecutor.isShutdown())
scriptVerificationExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); scriptVerificationExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
List<Future<VerificationException>> listScriptVerificationResults = new ArrayList<Future<VerificationException>>(transactions.size()); List<Future<VerificationException>> listScriptVerificationResults = new ArrayList<Future<VerificationException>>(transactions.size());
for(final Transaction tx : transactions) { for (final Transaction tx : transactions) {
boolean isCoinBase = tx.isCoinBase(); boolean isCoinBase = tx.isCoinBase();
Coin valueIn = Coin.ZERO; Coin valueIn = Coin.ZERO;
Coin valueOut = Coin.ZERO; Coin valueOut = Coin.ZERO;
@ -390,21 +388,20 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
for (int index = 0; index < tx.getInputs().size(); index++) { for (int index = 0; index < tx.getInputs().size(); index++) {
final TransactionInput in = tx.getInputs().get(index); final TransactionInput in = tx.getInputs().get(index);
final UTXO prevOut = blockStore.getTransactionOutput(in.getOutpoint().getHash(), final UTXO prevOut = blockStore.getTransactionOutput(in.getOutpoint().getHash(),
in.getOutpoint().getIndex()); in.getOutpoint().getIndex());
if (prevOut == null) if (prevOut == null)
throw new VerificationException("Attempted spend of a non-existent or already spent output!"); throw new VerificationException("Attempted spend of a non-existent or already spent output!");
if (prevOut.isCoinbase() && newBlock.getHeight() - prevOut.getHeight() < params.getSpendableCoinbaseDepth()) if (prevOut.isCoinbase() && newBlock.getHeight() - prevOut.getHeight() < params.getSpendableCoinbaseDepth())
throw new VerificationException("Tried to spend coinbase at depth " + (newBlock.getHeight() - prevOut.getHeight())); throw new VerificationException("Tried to spend coinbase at depth " + (newBlock.getHeight() - prevOut.getHeight()));
valueIn = valueIn.add(prevOut.getValue()); valueIn = valueIn.add(prevOut.getValue());
if (verifyFlags.contains(VerifyFlag.P2SH)) { if (verifyFlags.contains(VerifyFlag.P2SH)) {
Script script = new Script(prevOut.getScriptBytes()); if (prevOut.getScript().isPayToScriptHash())
if (script.isPayToScriptHash())
sigOps += Script.getP2SHSigOpCount(in.getScriptBytes()); sigOps += Script.getP2SHSigOpCount(in.getScriptBytes());
if (sigOps > Block.MAX_BLOCK_SIGOPS) if (sigOps > Block.MAX_BLOCK_SIGOPS)
throw new VerificationException("Too many P2SH SigOps in block"); throw new VerificationException("Too many P2SH SigOps in block");
} }
prevOutScripts.add(new Script(prevOut.getScriptBytes())); prevOutScripts.add(prevOut.getScript());
blockStore.removeUnspentTransactionOutput(prevOut); blockStore.removeUnspentTransactionOutput(prevOut);
txOutsSpent.add(prevOut); txOutsSpent.add(prevOut);
@ -419,9 +416,8 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
out.getValue(), out.getValue(),
newBlock.getHeight(), newBlock.getHeight(),
isCoinBase, isCoinBase,
out.getScriptBytes(), script,
getScriptAddress(script), getScriptAddress(script));
getScriptType(script).ordinal());
blockStore.addUnspentTransactionOutput(newOut); blockStore.addUnspentTransactionOutput(newOut);
txOutsCreated.add(newOut); txOutsCreated.add(newOut);
} }
@ -464,7 +460,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
} else { } else {
txOutChanges = block.getTxOutChanges(); txOutChanges = block.getTxOutChanges();
if (!params.isCheckpoint(newBlock.getHeight())) if (!params.isCheckpoint(newBlock.getHeight()))
for(UTXO out : txOutChanges.txOutsCreated) { for (UTXO out : txOutChanges.txOutsCreated) {
Sha256Hash hash = out.getHash(); Sha256Hash hash = out.getHash();
if (blockStore.getTransactionOutput(hash, out.getIndex()) != null) if (blockStore.getTransactionOutput(hash, out.getIndex()) != null)
throw new VerificationException("Block failed BIP30 test!"); throw new VerificationException("Block failed BIP30 test!");
@ -498,9 +494,9 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
StoredUndoableBlock undoBlock = blockStore.getUndoBlock(oldBlock.getHeader().getHash()); StoredUndoableBlock undoBlock = blockStore.getUndoBlock(oldBlock.getHeader().getHash());
if (undoBlock == null) throw new PrunedException(oldBlock.getHeader().getHash()); if (undoBlock == null) throw new PrunedException(oldBlock.getHeader().getHash());
TransactionOutputChanges txOutChanges = undoBlock.getTxOutChanges(); TransactionOutputChanges txOutChanges = undoBlock.getTxOutChanges();
for(UTXO out : txOutChanges.txOutsSpent) for (UTXO out : txOutChanges.txOutsSpent)
blockStore.addUnspentTransactionOutput(out); blockStore.addUnspentTransactionOutput(out);
for(UTXO out : txOutChanges.txOutsCreated) for (UTXO out : txOutChanges.txOutsCreated)
blockStore.removeUnspentTransactionOutput(out); blockStore.removeUnspentTransactionOutput(out);
} catch (PrunedException e) { } catch (PrunedException e) {
blockStore.abortDatabaseBatchWrite(); blockStore.abortDatabaseBatchWrite();

View File

@ -1,12 +1,12 @@
/** /**
* Copyright 2012 Matt Corallo. * Copyright 2012 Matt Corallo.
* * <p/>
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* * <p/>
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* * <p/>
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -16,6 +16,7 @@
package org.bitcoinj.core; package org.bitcoinj.core;
import org.bitcoinj.script.Script;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -36,7 +37,7 @@ public class UTXO implements Serializable {
* this output. * this output.
*/ */
private Coin value; private Coin value;
private byte[] scriptBytes; private Script script;
/** Hash of the transaction to which we refer. */ /** Hash of the transaction to which we refer. */
private Sha256Hash hash; private Sha256Hash hash;
@ -48,8 +49,6 @@ public class UTXO implements Serializable {
private boolean coinbase; private boolean coinbase;
/** The address of this output */ /** The address of this output */
private String address; private String address;
/** The type of this address */
private int addressType;
/** /**
* Creates a stored transaction output. * Creates a stored transaction output.
@ -58,22 +57,20 @@ public class UTXO implements Serializable {
* @param value The value available. * @param value The value available.
* @param height The height this output was created in. * @param height The height this output was created in.
* @param coinbase The coinbase flag. * @param coinbase The coinbase flag.
* @param scriptBytes The script bytes.
*/ */
public UTXO(Sha256Hash hash, public UTXO(Sha256Hash hash,
long index, long index,
Coin value, Coin value,
int height, int height,
boolean coinbase, boolean coinbase,
byte[] scriptBytes) { Script script) {
this.hash = hash; this.hash = hash;
this.index = index; this.index = index;
this.value = value; this.value = value;
this.height = height; this.height = height;
this.scriptBytes = scriptBytes; this.script = script;
this.coinbase = coinbase; this.coinbase = coinbase;
this.address = ""; this.address = "";
this.addressType = 0;
} }
/** /**
@ -83,21 +80,17 @@ public class UTXO implements Serializable {
* @param value The value available. * @param value The value available.
* @param height The height this output was created in. * @param height The height this output was created in.
* @param coinbase The coinbase flag. * @param coinbase The coinbase flag.
* @param scriptBytes The script bytes.
* @param address The address. * @param address The address.
* @param addressType The address type.
*/ */
public UTXO(Sha256Hash hash, public UTXO(Sha256Hash hash,
long index, long index,
Coin value, Coin value,
int height, int height,
boolean coinbase, boolean coinbase,
byte[] scriptBytes, Script script,
String address, String address) {
int addressType) { this(hash, index, value, height, coinbase, script);
this(hash, index, value, height, coinbase, scriptBytes);
this.address = address; this.address = address;
this.addressType = addressType;
} }
public UTXO(InputStream in) throws IOException { public UTXO(InputStream in) throws IOException {
@ -110,9 +103,10 @@ public class UTXO implements Serializable {
((in.read() & 0xFF) << 8) | ((in.read() & 0xFF) << 8) |
((in.read() & 0xFF) << 16) | ((in.read() & 0xFF) << 16) |
((in.read() & 0xFF) << 24); ((in.read() & 0xFF) << 24);
scriptBytes = new byte[scriptBytesLength]; byte[] scriptBytes = new byte[scriptBytesLength];
if (in.read(scriptBytes) != scriptBytesLength) if (in.read(scriptBytes) != scriptBytesLength)
throw new EOFException(); throw new EOFException();
script = new Script(scriptBytes);
byte[] hashBytes = new byte[32]; byte[] hashBytes = new byte[32];
if (in.read(hashBytes) != 32) if (in.read(hashBytes) != 32)
@ -147,11 +141,11 @@ public class UTXO implements Serializable {
} }
/** /**
* The backing script bytes which can be turned into a Script object. * The Script object which you can use to get address, script bytes or script type.
* @return the scriptBytes. * @return the script.
*/ */
public byte[] getScriptBytes() { public Script getScript() {
return scriptBytes; return script;
} }
/** /**
@ -191,15 +185,7 @@ public class UTXO implements Serializable {
* @return The address. * @return The address.
*/ */
public String getAddress() { public String getAddress() {
return address; return address;
}
/**
* The type of the address.
* @return The address type.
*/
public int getAddressType() {
return addressType;
} }
@Override @Override
@ -209,7 +195,7 @@ public class UTXO implements Serializable {
@Override @Override
public int hashCode() { public int hashCode() {
return hash.hashCode() + (int)index; return hash.hashCode() + (int) index;
} }
@Override @Override
@ -224,6 +210,7 @@ public class UTXO implements Serializable {
public void serializeToStream(OutputStream bos) throws IOException { public void serializeToStream(OutputStream bos) throws IOException {
Utils.uint64ToByteStreamLE(BigInteger.valueOf(value.value), bos); Utils.uint64ToByteStreamLE(BigInteger.valueOf(value.value), bos);
byte[] scriptBytes = script.getProgram();
bos.write(0xFF & scriptBytes.length >> 0); bos.write(0xFF & scriptBytes.length >> 0);
bos.write(0xFF & scriptBytes.length >> 8); bos.write(0xFF & scriptBytes.length >> 8);
bos.write(0xFF & (scriptBytes.length >> 16)); bos.write(0xFF & (scriptBytes.length >> 16));
@ -239,7 +226,7 @@ public class UTXO implements Serializable {
bos.write(0xFF & (height >> 24)); bos.write(0xFF & (height >> 24));
byte[] coinbaseByte = new byte[1]; byte[] coinbaseByte = new byte[1];
if(coinbase) { if (coinbase) {
coinbaseByte[0] = 1; coinbaseByte[0] = 1;
} else { } else {
coinbaseByte[0] = 0; coinbaseByte[0] = 0;

View File

@ -4006,7 +4006,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
* @param output The stored output (free standing). * @param output The stored output (free standing).
*/ */
public FreeStandingTransactionOutput(NetworkParameters params, UTXO output, int chainHeight) { public FreeStandingTransactionOutput(NetworkParameters params, UTXO output, int chainHeight) {
super(params, null, output.getValue(), output.getScriptBytes()); super(params, null, output.getValue(), output.getScript().getProgram());
this.output = output; this.output = output;
this.chainHeight = chainHeight; this.chainHeight = chainHeight;
} }

View File

@ -19,6 +19,7 @@ package org.bitcoinj.store;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.bitcoinj.core.*; import org.bitcoinj.core.*;
import org.bitcoinj.script.Script;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -929,15 +930,13 @@ public abstract class DatabaseFullPrunedBlockStore implements FullPrunedBlockSto
byte[] scriptBytes = results.getBytes(3); byte[] scriptBytes = results.getBytes(3);
boolean coinbase = results.getBoolean(4); boolean coinbase = results.getBoolean(4);
String address = results.getString(5); String address = results.getString(5);
int addressType = results.getInt(6);
UTXO txout = new UTXO(hash, UTXO txout = new UTXO(hash,
index, index,
value, value,
height, height,
coinbase, coinbase,
scriptBytes, new Script(scriptBytes),
address, address);
addressType);
return txout; return txout;
} catch (SQLException ex) { } catch (SQLException ex) {
throw new BlockStoreException(ex); throw new BlockStoreException(ex);
@ -963,9 +962,9 @@ public abstract class DatabaseFullPrunedBlockStore implements FullPrunedBlockSto
s.setInt(2, (int) out.getIndex()); s.setInt(2, (int) out.getIndex());
s.setInt(3, out.getHeight()); s.setInt(3, out.getHeight());
s.setLong(4, out.getValue().value); s.setLong(4, out.getValue().value);
s.setBytes(5, out.getScriptBytes()); s.setBytes(5, out.getScript().getProgram());
s.setString(6, out.getAddress()); s.setString(6, out.getAddress());
s.setInt(7, out.getAddressType()); s.setInt(7, out.getScript().getScriptType().ordinal());
s.setBoolean(8, out.isCoinbase()); s.setBoolean(8, out.isCoinbase());
s.executeUpdate(); s.executeUpdate();
s.close(); s.close();
@ -1173,15 +1172,13 @@ public abstract class DatabaseFullPrunedBlockStore implements FullPrunedBlockSto
int index = rs.getInt(5); int index = rs.getInt(5);
boolean coinbase = rs.getBoolean(6); boolean coinbase = rs.getBoolean(6);
String toAddress = rs.getString(7); String toAddress = rs.getString(7);
int addressType = rs.getInt(8);
UTXO output = new UTXO(hash, UTXO output = new UTXO(hash,
index, index,
amount, amount,
height, height,
coinbase, coinbase,
scriptBytes, new Script(scriptBytes),
toAddress, toAddress);
addressType);
outputs.add(output); outputs.add(output);
} }
} }