Last active
August 20, 2019 20:03
-
-
Save wintercooled/d0f31033d56251b85bfa662cd83e130a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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