individual tx input and output hex highlighting

This commit is contained in:
Craig Raw 2020-04-02 17:11:19 +02:00
parent c05fe42261
commit 1806b11f6d
11 changed files with 170 additions and 69 deletions

View file

@ -13,6 +13,10 @@ public class InputForm extends TransactionForm {
this.transactionInput = transactionInput;
}
public TransactionInput getTransactionInput() {
return transactionInput;
}
public Node getContents() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("input.fxml"));
Node node = loader.load();

View file

@ -13,6 +13,10 @@ public class OutputForm extends TransactionForm {
this.transactionOutput = transactionOutput;
}
public TransactionOutput getTransactionOutput() {
return transactionOutput;
}
public Node getContents() throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("output.fxml"));
Node node = loader.load();

View file

@ -33,6 +33,8 @@ public class TransactionController implements Initializable, TransactionListener
private Transaction transaction;
private PSBT psbt;
private int selectedInputIndex = -1;
private int selectedOutputIndex = -1;
@Override
public void initialize(URL location, ResourceBundle resources) {
@ -94,6 +96,18 @@ public class TransactionController implements Initializable, TransactionListener
Parent parent = (Parent)node;
txhex.getStylesheets().clear();
txhex.getStylesheets().addAll(parent.getStylesheets());
selectedInputIndex = -1;
selectedOutputIndex = -1;
if(transactionForm instanceof InputForm) {
InputForm inputForm = (InputForm)transactionForm;
selectedInputIndex = inputForm.getTransactionInput().getIndex();
} else if(transactionForm instanceof OutputForm) {
OutputForm outputForm = (OutputForm)transactionForm;
selectedOutputIndex = outputForm.getTransactionOutput().getIndex();
}
refreshTxHex();
}
} catch (IOException e) {
throw new IllegalStateException("Can't find pane", e);
@ -132,13 +146,14 @@ public class TransactionController implements Initializable, TransactionListener
cursor = addText(hex, cursor, numInputs.getSizeInBytes()*2, "num-inputs");
//Inputs
for(TransactionInput input : transaction.getInputs()) {
cursor = addText(hex, cursor, 32*2, "input-hash");
cursor = addText(hex, cursor, 4*2, "input-index");
for (int i = 0; i < transaction.getInputs().size(); i++) {
TransactionInput input = transaction.getInputs().get(i);
cursor = addText(hex, cursor, 32*2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "hash"));
cursor = addText(hex, cursor, 4*2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "index"));
VarInt scriptLen = new VarInt(input.getScriptBytes().length);
cursor = addText(hex, cursor, scriptLen.getSizeInBytes()*2, "input-sigscript-length");
cursor = addText(hex, cursor, (int)scriptLen.value*2, "input-sigscript");
cursor = addText(hex, cursor, 4*2, "input-sequence");
cursor = addText(hex, cursor, scriptLen.getSizeInBytes()*2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "sigscript-length"));
cursor = addText(hex, cursor, (int)scriptLen.value*2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "sigscript"));
cursor = addText(hex, cursor, 4*2, "input-" + getIndexedStyleClass(i, selectedInputIndex, "sequence"));
}
//Number of outputs
@ -146,11 +161,12 @@ public class TransactionController implements Initializable, TransactionListener
cursor = addText(hex, cursor, numOutputs.getSizeInBytes()*2, "num-outputs");
//Outputs
for(TransactionOutput output : transaction.getOutputs()) {
cursor = addText(hex, cursor, 8*2, "output-value");
for (int i = 0; i < transaction.getOutputs().size(); i++) {
TransactionOutput output = transaction.getOutputs().get(i);
cursor = addText(hex, cursor, 8*2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "value"));
VarInt scriptLen = new VarInt(output.getScriptBytes().length);
cursor = addText(hex, cursor, scriptLen.getSizeInBytes()*2, "output-pubkeyscript-length");
cursor = addText(hex, cursor, (int)scriptLen.value*2, "output-pubkeyscript");
cursor = addText(hex, cursor, scriptLen.getSizeInBytes()*2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "pubkeyscript-length"));
cursor = addText(hex, cursor, (int)scriptLen.value*2, "output-" + getIndexedStyleClass(i, selectedOutputIndex, "pubkeyscript"));
}
if(transaction.hasWitnesses()) {
@ -169,8 +185,16 @@ public class TransactionController implements Initializable, TransactionListener
}
}
private int addText(String hex, int cursor, int length, String description) {
txhex.append(hex.substring(cursor, cursor+=length), description + "-color");
private String getIndexedStyleClass(int iterableIndex, int selectedIndex, String styleClass) {
if(selectedIndex == -1 || selectedIndex == iterableIndex) {
return styleClass;
}
return "other";
}
private int addText(String hex, int cursor, int length, String styleClass) {
txhex.append(hex.substring(cursor, cursor+=length), styleClass);
return cursor;
}

View file

@ -1,18 +1,18 @@
.version-color { -fx-fill: #986801 }
.segwit-marker-color { -fx-fill: #000000 }
.segwit-flag-color { -fx-fill: #4078f2 }
.version { -fx-fill: #986801 }
.segwit-marker { -fx-fill: #000000 }
.segwit-flag { -fx-fill: #4078f2 }
.num-inputs-color { -fx-fill: #ca1243 }
.input-hash-color { -fx-fill: #0184bc }
.input-index-color { -fx-fill: #0184bc }
.input-sigscript-length-color { -fx-fill: #0184bc }
.input-sigscript-color { -fx-fill: #0184bc }
.input-sequence-color { -fx-fill: #0184bc }
.num-inputs { -fx-fill: #ca1243 }
.input-hash { -fx-fill: #0184bc }
.input-index { -fx-fill: #0184bc }
.input-sigscript-length { -fx-fill: #0184bc }
.input-sigscript { -fx-fill: #0184bc }
.input-sequence { -fx-fill: #0184bc }
.num-outputs-color { -fx-fill: #ca1243 }
.output-value-color { -fx-fill: #50a14f }
.output-pubkeyscript-length-color { -fx-fill: #50a14f }
.output-pubkeyscript-color { -fx-fill: #50a14f }
.num-outputs { -fx-fill: #ca1243 }
.output-value { -fx-fill: #50a14f }
.output-pubkeyscript-length { -fx-fill: #50a14f }
.output-pubkeyscript { -fx-fill: #50a14f }
.witnesses-color { -fx-fill: #a626a4 }
.locktime-color { -fx-fill: #986801 }
.witnesses { -fx-fill: #a626a4 }
.locktime { -fx-fill: #986801 }

View file

@ -0,0 +1,21 @@
.version { -fx-fill: #e5e5e6 }
.segwit-marker { -fx-fill: #e5e5e6 }
.segwit-flag { -fx-fill: #e5e5e6 }
.num-inputs { -fx-fill: #e5e5e6 }
.input-other { -fx-fill: #e5e5e6 }
.input-hash { -fx-fill: #0184bc }
.input-index { -fx-fill: #000000 }
.input-sigscript-length { -fx-fill: #a626a4 }
.input-sigscript { -fx-fill: #50a14f }
.input-sequence { -fx-fill: #986801 }
.num-outputs { -fx-fill: #e5e5e6 }
.output-value { -fx-fill: #e5e5e6 }
.output-pubkeyscript-length { -fx-fill: #e5e5e6 }
.output-pubkeyscript { -fx-fill: #e5e5e6 }
.witnesses { -fx-fill: #e5e5e6 }
.locktime { -fx-fill: #e5e5e6 }

View file

@ -5,10 +5,42 @@
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import tornadofx.control.Form?>
<?import tornadofx.control.Fieldset?>
<?import tornadofx.control.Field?>
<?import javafx.geometry.Insets?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="com.sparrowwallet.sparrow.transaction.InputController"
prefHeight="400.0" prefWidth="600.0">
<GridPane alignment="TOP_CENTER" hgap="10.0" prefHeight="500.0" prefWidth="600.0" stylesheets="@input.css, @../general.css" vgap="10.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.transaction.InputController">
<padding>
<Insets bottom="25.0" left="25.0" right="25.0" top="25.0" />
</padding>
<columnConstraints>
<ColumnConstraints maxWidth="Infinity" minWidth="290" prefWidth="290">
</ColumnConstraints>
<ColumnConstraints maxWidth="Infinity" minWidth="290" prefWidth="290">
</ColumnConstraints>
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<Form GridPane.columnIndex="0" GridPane.rowIndex="0">
<Fieldset inputGrow="SOMETIMES" text="Inputs">
<Field text="Count:">
<TextField fx:id="count" editable="false" minWidth="520" prefWidth="520" styleClass="copyable-label" />
</Field>
<Field text="Total:">
<TextField fx:id="total" editable="false" minWidth="520" prefWidth="520" styleClass="copyable-label" />
</Field>
</Fieldset>
</Form>
</AnchorPane>
<Form GridPane.columnIndex="1" GridPane.rowIndex="0">
<Fieldset inputGrow="SOMETIMES" text="Signatures">
<Field text="Status:">
<TextField fx:id="signatures" editable="false" minWidth="520" prefWidth="520" styleClass="copyable-label" />
</Field>
</Fieldset>
</Form>
<Separator GridPane.columnIndex="0" GridPane.rowIndex="1" GridPane.columnSpan="2" styleClass="form-separator"/>
</GridPane>

View file

@ -1,21 +1,21 @@
.version-color { -fx-fill: #e5e5e6 }
.segwit-marker-color { -fx-fill: #e5e5e6 }
.segwit-flag-color { -fx-fill: #e5e5e6 }
.version { -fx-fill: #e5e5e6 }
.segwit-marker { -fx-fill: #e5e5e6 }
.segwit-flag { -fx-fill: #e5e5e6 }
.num-inputs-color { -fx-fill: #ca1243 }
.input-hash-color { -fx-fill: #0184bc }
.input-index-color { -fx-fill: #000000 }
.input-sigscript-length-color { -fx-fill: #a626a4 }
.input-sigscript-color { -fx-fill: #50a14f }
.input-sequence-color { -fx-fill: #986801 }
.num-inputs { -fx-fill: #ca1243 }
.input-hash { -fx-fill: #0184bc }
.input-index { -fx-fill: #000000 }
.input-sigscript-length { -fx-fill: #a626a4 }
.input-sigscript { -fx-fill: #50a14f }
.input-sequence { -fx-fill: #986801 }
.num-outputs-color { -fx-fill: #e5e5e6 }
.output-value-color { -fx-fill: #e5e5e6 }
.output-pubkeyscript-length-color { -fx-fill: #e5e5e6 }
.output-pubkeyscript-color { -fx-fill: #e5e5e6 }
.num-outputs { -fx-fill: #e5e5e6 }
.output-value { -fx-fill: #e5e5e6 }
.output-pubkeyscript-length { -fx-fill: #e5e5e6 }
.output-pubkeyscript { -fx-fill: #e5e5e6 }
.witnesses-color { -fx-fill: #e5e5e6 }
.locktime-color { -fx-fill: #e5e5e6 }
.witnesses { -fx-fill: #e5e5e6 }
.locktime { -fx-fill: #e5e5e6 }
.chart-legend-item{
-fx-font-family: Courier;

View file

@ -4,8 +4,8 @@
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import tornadofx.control.*?>
<?import javafx.scene.chart.PieChart?>
<GridPane alignment="TOP_CENTER" hgap="10.0" prefHeight="500.0" prefWidth="600.0" stylesheets="@inputs.css, @../general.css" vgap="10.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.transaction.InputsController">
<padding>
<Insets bottom="25.0" left="25.0" right="25.0" top="25.0" />

View file

@ -0,0 +1,20 @@
.version { -fx-fill: #e5e5e6 }
.segwit-marker { -fx-fill: #e5e5e6 }
.segwit-flag { -fx-fill: #e5e5e6 }
.num-inputs { -fx-fill: #e5e5e6 }
.input-hash { -fx-fill: #e5e5e6 }
.input-index { -fx-fill: #e5e5e6 }
.input-sigscript-length { -fx-fill: #e5e5e6 }
.input-sigscript { -fx-fill: #e5e5e6 }
.input-sequence { -fx-fill: #e5e5e6 }
.num-outputs { -fx-fill: #e5e5e6 }
.output-other { -fx-fill: #e5e5e6 }
.output-value { -fx-fill: #000000 }
.output-pubkeyscript-length { -fx-fill: #a626a4 }
.output-pubkeyscript { -fx-fill: #50a14f }
.witnesses { -fx-fill: #e5e5e6 }
.locktime { -fx-fill: #e5e5e6 }

View file

@ -6,9 +6,5 @@
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="com.sparrowwallet.sparrow.transaction.OutputController"
prefHeight="400.0" prefWidth="600.0">
</AnchorPane>
<GridPane alignment="TOP_CENTER" hgap="10.0" prefHeight="500.0" prefWidth="600.0" stylesheets="@output.css, @../general.css" vgap="10.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.sparrowwallet.sparrow.transaction.OutputController">
</GridPane>

View file

@ -1,21 +1,21 @@
.version-color { -fx-fill: #e5e5e6 }
.segwit-marker-color { -fx-fill: #e5e5e6 }
.segwit-flag-color { -fx-fill: #e5e5e6 }
.version { -fx-fill: #e5e5e6 }
.segwit-marker { -fx-fill: #e5e5e6 }
.segwit-flag { -fx-fill: #e5e5e6 }
.num-inputs-color { -fx-fill: #e5e5e6 }
.input-hash-color { -fx-fill: #e5e5e6 }
.input-index-color { -fx-fill: #e5e5e6 }
.input-sigscript-length-color { -fx-fill: #e5e5e6 }
.input-sigscript-color { -fx-fill: #e5e5e6 }
.input-sequence-color { -fx-fill: #e5e5e6 }
.num-inputs { -fx-fill: #e5e5e6 }
.input-hash { -fx-fill: #e5e5e6 }
.input-index { -fx-fill: #e5e5e6 }
.input-sigscript-length { -fx-fill: #e5e5e6 }
.input-sigscript { -fx-fill: #e5e5e6 }
.input-sequence { -fx-fill: #e5e5e6 }
.num-outputs-color { -fx-fill: #ca1243 }
.output-value-color { -fx-fill: #000000 }
.output-pubkeyscript-length-color { -fx-fill: #a626a4 }
.output-pubkeyscript-color { -fx-fill: #50a14f }
.num-outputs { -fx-fill: #ca1243 }
.output-value { -fx-fill: #000000 }
.output-pubkeyscript-length { -fx-fill: #a626a4 }
.output-pubkeyscript { -fx-fill: #50a14f }
.witnesses-color { -fx-fill: #e5e5e6 }
.locktime-color { -fx-fill: #e5e5e6 }
.witnesses { -fx-fill: #e5e5e6 }
.locktime { -fx-fill: #e5e5e6 }
.chart-legend-item{
-fx-font-family: Courier;