mirror of
https://github.com/sparrowwallet/drongo.git
synced 2024-12-26 01:56:44 +00:00
transaction headers retrieval and edit
This commit is contained in:
parent
566aa2e953
commit
7fb5601de3
3 changed files with 82 additions and 7 deletions
|
@ -24,6 +24,8 @@ public class Transaction extends TransactionPart {
|
||||||
|
|
||||||
private long version;
|
private long version;
|
||||||
private long lockTime;
|
private long lockTime;
|
||||||
|
private boolean segwit;
|
||||||
|
private int segwitVersion;
|
||||||
|
|
||||||
private Sha256Hash cachedTxId;
|
private Sha256Hash cachedTxId;
|
||||||
private Sha256Hash cachedWTxId;
|
private Sha256Hash cachedWTxId;
|
||||||
|
@ -39,10 +41,18 @@ public class Transaction extends TransactionPart {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setVersion(long version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
public long getLockTime() {
|
public long getLockTime() {
|
||||||
return lockTime;
|
return lockTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setLockTime(long lockTime) {
|
||||||
|
this.lockTime = lockTime;
|
||||||
|
}
|
||||||
|
|
||||||
public Sha256Hash getTxId() {
|
public Sha256Hash getTxId() {
|
||||||
if (cachedTxId == null) {
|
if (cachedTxId == null) {
|
||||||
if (!hasWitnesses() && cachedWTxId != null) {
|
if (!hasWitnesses() && cachedWTxId != null) {
|
||||||
|
@ -75,6 +85,18 @@ public class Transaction extends TransactionPart {
|
||||||
return Sha256Hash.wrapReversed(Sha256Hash.hashTwice(stream.toByteArray()));
|
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() {
|
public boolean hasWitnesses() {
|
||||||
for (TransactionInput in : inputs)
|
for (TransactionInput in : inputs)
|
||||||
if (in.hasWitness())
|
if (in.hasWitness())
|
||||||
|
@ -83,7 +105,7 @@ public class Transaction extends TransactionPart {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bitcoinSerializeToStream(OutputStream stream) throws IOException {
|
public void bitcoinSerializeToStream(OutputStream stream) throws IOException {
|
||||||
boolean useSegwit = hasWitnesses();
|
boolean useSegwit = isSegwit();
|
||||||
bitcoinSerializeToStream(stream, useSegwit);
|
bitcoinSerializeToStream(stream, useSegwit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +120,7 @@ public class Transaction extends TransactionPart {
|
||||||
// marker, flag
|
// marker, flag
|
||||||
if (useSegwit) {
|
if (useSegwit) {
|
||||||
stream.write(0);
|
stream.write(0);
|
||||||
stream.write(1);
|
stream.write(segwitVersion);
|
||||||
}
|
}
|
||||||
// txin_count, txins
|
// txin_count, txins
|
||||||
stream.write(new VarInt(inputs.size()).encode());
|
stream.write(new VarInt(inputs.size()).encode());
|
||||||
|
@ -108,7 +130,7 @@ public class Transaction extends TransactionPart {
|
||||||
stream.write(new VarInt(outputs.size()).encode());
|
stream.write(new VarInt(outputs.size()).encode());
|
||||||
for (TransactionOutput out : outputs)
|
for (TransactionOutput out : outputs)
|
||||||
out.bitcoinSerializeToStream(stream);
|
out.bitcoinSerializeToStream(stream);
|
||||||
// script_witnisses
|
// script_witnesses
|
||||||
if (useSegwit) {
|
if (useSegwit) {
|
||||||
for (TransactionInput in : inputs) {
|
for (TransactionInput in : inputs) {
|
||||||
in.getWitness().bitcoinSerializeToStream(stream);
|
in.getWitness().bitcoinSerializeToStream(stream);
|
||||||
|
@ -128,17 +150,18 @@ public class Transaction extends TransactionPart {
|
||||||
version = readUint32();
|
version = readUint32();
|
||||||
// peek at marker
|
// peek at marker
|
||||||
byte marker = rawtx[cursor];
|
byte marker = rawtx[cursor];
|
||||||
boolean useSegwit = marker == 0;
|
segwit = (marker == 0);
|
||||||
// marker, flag
|
// marker, flag
|
||||||
if (useSegwit) {
|
if (segwit) {
|
||||||
readBytes(2);
|
byte[] segwitHeader = readBytes(2);
|
||||||
|
segwitVersion = segwitHeader[1];
|
||||||
}
|
}
|
||||||
// txin_count, txins
|
// txin_count, txins
|
||||||
parseInputs();
|
parseInputs();
|
||||||
// txout_count, txouts
|
// txout_count, txouts
|
||||||
parseOutputs();
|
parseOutputs();
|
||||||
// script_witnesses
|
// script_witnesses
|
||||||
if (useSegwit)
|
if (segwit)
|
||||||
parseWitnesses();
|
parseWitnesses();
|
||||||
// lock_time
|
// lock_time
|
||||||
lockTime = readUint32();
|
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() {
|
public List<TransactionInput> getInputs() {
|
||||||
return Collections.unmodifiableList(inputs);
|
return Collections.unmodifiableList(inputs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,14 @@ public abstract class TransactionPart {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getOffset() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This returns a correct value by parsing the message.
|
* This returns a correct value by parsing the message.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,6 +29,17 @@ public class TransactionWitness {
|
||||||
return pushes.size();
|
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 {
|
protected void bitcoinSerializeToStream(OutputStream stream) throws IOException {
|
||||||
stream.write(new VarInt(pushes.size()).encode());
|
stream.write(new VarInt(pushes.size()).encode());
|
||||||
for (int i = 0; i < pushes.size(); i++) {
|
for (int i = 0; i < pushes.size(); i++) {
|
||||||
|
|
Loading…
Reference in a new issue