transaction headers retrieval and edit

This commit is contained in:
Craig Raw 2020-03-28 10:44:50 +02:00
parent 566aa2e953
commit 7fb5601de3
3 changed files with 82 additions and 7 deletions

View file

@ -24,6 +24,8 @@ public class Transaction extends TransactionPart {
private long version;
private long lockTime;
private boolean segwit;
private int segwitVersion;
private Sha256Hash cachedTxId;
private Sha256Hash cachedWTxId;
@ -39,10 +41,18 @@ public class Transaction extends TransactionPart {
return version;
}
public void setVersion(long version) {
this.version = version;
}
public long getLockTime() {
return lockTime;
}
public void setLockTime(long lockTime) {
this.lockTime = lockTime;
}
public Sha256Hash getTxId() {
if (cachedTxId == null) {
if (!hasWitnesses() && cachedWTxId != null) {
@ -75,6 +85,18 @@ public class Transaction extends TransactionPart {
return Sha256Hash.wrapReversed(Sha256Hash.hashTwice(stream.toByteArray()));
}
public boolean isSegwit() {
return segwit;
}
public int getSegwitVersion() {
return segwitVersion;
}
public void setSegwitVersion(int segwitVersion) {
this.segwitVersion = segwitVersion;
}
public boolean hasWitnesses() {
for (TransactionInput in : inputs)
if (in.hasWitness())
@ -83,7 +105,7 @@ public class Transaction extends TransactionPart {
}
public void bitcoinSerializeToStream(OutputStream stream) throws IOException {
boolean useSegwit = hasWitnesses();
boolean useSegwit = isSegwit();
bitcoinSerializeToStream(stream, useSegwit);
}
@ -98,7 +120,7 @@ public class Transaction extends TransactionPart {
// marker, flag
if (useSegwit) {
stream.write(0);
stream.write(1);
stream.write(segwitVersion);
}
// txin_count, txins
stream.write(new VarInt(inputs.size()).encode());
@ -108,7 +130,7 @@ public class Transaction extends TransactionPart {
stream.write(new VarInt(outputs.size()).encode());
for (TransactionOutput out : outputs)
out.bitcoinSerializeToStream(stream);
// script_witnisses
// script_witnesses
if (useSegwit) {
for (TransactionInput in : inputs) {
in.getWitness().bitcoinSerializeToStream(stream);
@ -128,17 +150,18 @@ public class Transaction extends TransactionPart {
version = readUint32();
// peek at marker
byte marker = rawtx[cursor];
boolean useSegwit = marker == 0;
segwit = (marker == 0);
// marker, flag
if (useSegwit) {
readBytes(2);
if (segwit) {
byte[] segwitHeader = readBytes(2);
segwitVersion = segwitHeader[1];
}
// txin_count, txins
parseInputs();
// txout_count, txouts
parseOutputs();
// script_witnesses
if (useSegwit)
if (segwit)
parseWitnesses();
// lock_time
lockTime = readUint32();
@ -182,6 +205,39 @@ public class Transaction extends TransactionPart {
}
}
public int getSize() {
return length;
}
public int getVirtualSize() {
int wu = 0;
// version
wu += 4*4;
// marker, flag
if(isSegwit()) {
wu += 2;
}
// txin_count, txins
wu += new VarInt(inputs.size()).getSizeInBytes() * 4;
for (TransactionInput in : inputs)
wu += in.length * 4;
// txout_count, txouts
wu += new VarInt(outputs.size()).getSizeInBytes() * 4;
for (TransactionOutput out : outputs)
wu += out.length * 4;
// script_witnesses
if(isSegwit()) {
for (TransactionInput in : inputs) {
wu += in.getWitness().getLength();
}
}
// lock_time
wu += 4*4;
return (int)Math.ceil((double)wu / 4.0);
}
public List<TransactionInput> getInputs() {
return Collections.unmodifiableList(inputs);
}

View file

@ -38,6 +38,14 @@ public abstract class TransactionPart {
this.parent = parent;
}
public int getOffset() {
return offset;
}
public int getLength() {
return length;
}
/**
* This returns a correct value by parsing the message.
*/

View file

@ -29,6 +29,17 @@ public class TransactionWitness {
return pushes.size();
}
public int getLength() {
int length = new VarInt(pushes.size()).getSizeInBytes();
for (int i = 0; i < pushes.size(); i++) {
byte[] push = pushes.get(i);
length += new VarInt(push.length).getSizeInBytes();
length += push.length;
}
return length;
}
protected void bitcoinSerializeToStream(OutputStream stream) throws IOException {
stream.write(new VarInt(pushes.size()).encode());
for (int i = 0; i < pushes.size(); i++) {