Skip to content

Instantly share code, notes, and snippets.

@wintercooled
Last active August 20, 2019 20:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wintercooled/d0f31033d56251b85bfa662cd83e130a to your computer and use it in GitHub Desktop.
Save wintercooled/d0f31033d56251b85bfa662cd83e130a to your computer and use it in GitHub Desktop.
package com.blockstream.test;
import com.blockstream.libwally.Wally;
public class btse_example {
public btse_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("BTSE EXAMPLE MH 01.03");
final btse_example btse = new btse_example();
btse.build_and_sign_transaction();
}
}
/**
* REFERENCES
*
* Libwally on GitHub
* ------------------
* You need the latest (as of 14th August 2019) code from https://github.com/ElementsProject/libwally-core to run this example.
*
*
* How to compile libwally for Java use
* ------------------------------------
* https://gist.github.com/wintercooled/0296f17b0ca8e4eac425bf6c289075a6
*
*
* To compile and run this example
* -------------------------------
* Create file named btse_example.java in libwally-core/src/swig_java/src/com/blockstream/test/
* Compile:
* ~/libwally-core $ javac ./src/swig_java/src/com/blockstream/test/btse_example.java
* Run:
* ~/libwally-core/src $ LD_LIBRARY_PATH=.libs java -Djava.library.path=.libs -classpath swig_java/src com.blockstream.test.btse_example
*
*
* To use a function listed on //https://wally.readthedocs.io
* ----------------------------------------------------------
* 1. Look up a function on //https://wally.readthedocs.io
* 2. 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)
*
* For example using tx_elements_input_init:
* - readthedocs has 21 arguments:
* - https://wally.readthedocs.io/en/release_0.7.3/transaction/?highlight=tx_elements_input_init#c.wally_tx_elements_input_init_alloc
* - Wally.java has 12: jarg1, jarg3, jarg4, jarg5, jarg7, jarg8, jarg10, jarg12, jarg14, jarg16, jarg18, jarg20);
* - Meaning that you do not need to provide the readthedocs arguments: 2 (txhash_len), 6, 9, 11, 13, 15, 17, 19, 21.
*
*
* Signing
* -------
* See libwally-core/src/swig_java/src/com/blockstream/test/test_bip32.java for more info
*
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment