Liquid Transaction Example
Liquid transaction example in Java
The example below shows you how to create and run an example in Java that builds a Liquid transaction and signs it.
Create file named liquid_tx_example.java
in libwally-core/src/swig_java/src/com/blockstream/test/
The contents of the file are shown below. Copy them into the file and save it.
package com.blockstream.test;
import com.blockstream.libwally.Wally;
public class liquid_tx_example {
public liquid_tx_example() { }
/**
* Example of stages in creating a transaction, using dummy hex values.
* Adds two inputs and one output.
* Signs the inputs.
*
* @System.out the signed transaction hex
*/
public void build_and_sign_transaction() {
/*
* Create a transaction
* --------------------
*/
final String tx_in_hex = "0000000000000000000000000000000000000000000000000000000000000000";
final byte[] tx_in_byte = Wally.hex_to_bytes(tx_in_hex);
final String tx_out_hex = "0000000000000000000000000000000000000000000000000000000000000000";
final byte[] tx_out_byte = Wally.hex_to_bytes(tx_out_hex);
final String script_hex = "0000";
final byte[] script_byte = Wally.hex_to_bytes(script_hex);
final String witness_script_hex = "000000";
final byte[] witness_script_byte = Wally.hex_to_bytes(witness_script_hex);
final String nonce_hex = "0000000000000000000000000000000000000000000000000000000000000000";
final byte[] nonce_byte = Wally.hex_to_bytes(nonce_hex);
final String entropy_hex = "0000000000000000000000000000000000000000000000000000000000000000";
final byte[] entropy_byte = Wally.hex_to_bytes(entropy_hex);
final Object witness = Wally.tx_witness_stack_init(5L);
Wally.tx_witness_stack_add(witness, witness_script_byte);
// This is currently required by tx_elements_input_init - this is a bug that is being addressed.
final Object pegin_witness = Wally.tx_witness_stack_init(5L);
Wally.tx_witness_stack_add(pegin_witness, witness_script_byte);
final long sequence = 0xffffffffL;
// Version, locktime, inputs, outputs:
final Object tx = Wally.tx_init(2, 0, 2, 1);
final Object tx_input01 = Wally.tx_elements_input_init(tx_in_byte, 0L, sequence, script_byte, witness, nonce_byte, entropy_byte, null, null, null, null, pegin_witness);
final Object tx_input02 = Wally.tx_elements_input_init(tx_in_byte, 2L, sequence, script_byte, witness, nonce_byte, entropy_byte, null, null, null, null, pegin_witness);
final byte[] ct_value_byte = Wally.tx_confidential_value_from_satoshi(10000L, null);
final Object tx_output = Wally.tx_elements_output_init(script_byte, null, ct_value_byte, null, null, null);
Wally.tx_add_input(tx, tx_input01);
Wally.tx_add_input(tx, tx_input02);
Wally.tx_add_output(tx, tx_output);
final byte[] input_witness01 = Wally.tx_input_get_witness(tx_input01, 0);
final byte[] input_witness02 = Wally.tx_input_get_witness(tx_input02, 0);
String tx_hex = "";
tx_hex = Wally.tx_to_hex(tx, Wally.WALLY_TX_FLAG_USE_WITNESS);
System.out.println("UNSIGNED TX HEX: " + tx_hex);
/*
* Sign the transaction
* --------------------
*/
byte[] sig_hash01 = Wally.tx_get_elements_signature_hash(tx, 0L, script_byte, ct_value_byte, Wally.WALLY_SIGHASH_ALL, Wally.WALLY_TX_FLAG_USE_WITNESS, null);
byte[] sig_hash02 = Wally.tx_get_elements_signature_hash(tx, 1L, script_byte, ct_value_byte, Wally.WALLY_SIGHASH_ALL, Wally.WALLY_TX_FLAG_USE_WITNESS, null);
// Example bip32 key
final byte[] seed = h("000102030405060708090a0b0c0d0e0f");
final Object seedKey = Wally.bip32_key_from_seed(seed, Wally.BIP32_VER_MAIN_PRIVATE, 0);
final Object derivedKey = Wally.bip32_key_from_parent(seedKey, 0, Wally.BIP32_FLAG_KEY_PRIVATE);
final byte[] private_key_bytes = Wally.bip32_key_get_priv_key(derivedKey);
final byte[] public_key_bytes = Wally.bip32_key_get_pub_key(derivedKey);
final byte[] signature01 = Wally.ec_sig_from_bytes(private_key_bytes, sig_hash01, Wally.EC_FLAG_ECDSA);
final byte[] signature02 = Wally.ec_sig_from_bytes(private_key_bytes, sig_hash02, Wally.EC_FLAG_ECDSA);
Wally.ec_sig_verify(public_key_bytes, sig_hash01, Wally.EC_FLAG_ECDSA, signature01);
Wally.ec_sig_verify(public_key_bytes, sig_hash02, Wally.EC_FLAG_ECDSA, signature02);
Wally.tx_set_input_script(tx, 0L, signature01);
Wally.tx_set_input_script(tx, 1L, signature02);
tx_hex = Wally.tx_to_hex(tx, Wally.WALLY_TX_FLAG_USE_WITNESS);
System.out.println("SIGNED TX HEX: " + tx_hex);
// Cleanup
Wally.bip32_key_free(derivedKey);
Wally.bip32_key_free(seedKey);
Wally.cleanup();
}
private String h(final byte[] bytes) { return Wally.hex_from_bytes(bytes); }
private byte[] h(final String hex) { return Wally.hex_to_bytes(hex); }
public static void main(final String[] args) {
System.out.println("EXAMPLE");
final liquid_tx_example example = new liquid_tx_example();
example.build_and_sign_transaction();
}
}
From the libwally-core/src
directory, compile the code and then run it:
cd swig_java/src
javac com/blockstream/test/liquid_tx_example.java
cd ..
cd ..
LD_LIBRARY_PATH=.libs java -Djava.library.path=.libs -classpath swig_java/src com.blockstream.test.liquid_tx_example
For more details on signing see libwally-core/src/swig_java/src/com/blockstream/test/test_bip32.java
.
Using other Libwally functions
You can find all the Libwally functions on https://wally.readthedocs.io.
To use one, look up your chosen function on https://wally.readthedocs.io
To see the arguments you need to provide to use the function in Java:
- Refer to the similar function (e.g. wally_tx_init_alloc is wally_tx_init) in Wally.java
- Note the arguments you must provide (some are not needed) and call the function from Java.
For example using tx_elements_input_init as an example:
Readthedocs lists 21 arguments whereas Wally.java
lists 12:
jarg1, jarg3, jarg4, jarg5, jarg7, jarg8, jarg10, jarg12, jarg14, jarg16, jarg18, jarg20
.
Meaning that you do not need to provide the following readthedocs arguments in order to call the function from Java:
2 (txhash_len), 6, 9, 11, 13, 15, 17, 19, 21
Updated almost 2 years ago