How to use bitcoinj to implement multisig transactions
Bitcoin is the dawn of the exciting blockchain technology. Although using bitcoin directly to build blockchain applications is somewhat obscure, it still can build many vivid applications based on smart contracts -- https://en.bitcoin.it/wiki/Contract. Among others, multisig technology is the cornerstone to leverage bitcoin to implement those features.
The following tutorial will show how to use a popular Java bitcoin library to build transactions inherently multisig-based.
Basically, it demonstrates three steps to go through whole workflow.
In order to build applications sitting on testnet, we should leverage following websites to assist development:
The former one is to get some free coins, the latter one is for checking if transactions are confirmed and accepted by blockchain.
Essentially, multisignature (multisig) refers to requiring more than one key to authorize a Bitcoin transaction. It is generally used to divide up responsibility for possession of bitcoins. For more information, please refer to https://en.bitcoin.it/wiki/Multisignature
As the class name suggested, it has dual functions. Running first time will create a new wallet to store coins locally, afterwards, it checks all details inside that newly created wallet. By running this application first time, you'll get following alike output:
Pay attention to the wallet's current receive address, we'll use this address to get some free coins from testnet faucet: https://testnet.manu.backend.hamburg/faucet, put the current receive address in the address input box and hit the give me some coins button. After a while, let's run CheckingWallet again:
At this moment, we've received 1.30 BTC as indicated by UNSPENT transaction: 818721a12db6d9b2876cced77999c0aa36295e2089e1a18f1aba6f586f906f3c.
As a side note: two files are also created locally -- wallet.wallet and wallet.spvchain. These files store wallet and blockchain information locally, do not delete them when executing applications!
This FundingTransaction application can run independently, there're two steps comprised -- create an multisig address and send coins to the multisig address. Our case is a 2 of 3 multisig address, which means the address is generated by three keys and in order to redeem the fund at this address any two keys should present to sign. The createMultisigAddress method tells all the details, which also generates the output's ScriptPubKey, the multisig address is implicitly contained inside ScriptPubKey. In the method sendCoinsToMultisigAddress, a transaction that moves some fund out of the coins received in the previous step to the newly generated multisig address is constructed and broadcasted. After running this application and wait for a while to let this transaction mined and confirmed, we can run CheckingWallet again:
(you can also go to testnet explorer website listed above to check progress)
We can find a new UNSPENT transaction generated and confirmed, the outpoint of this transaction tells us that previous received coins are origin of transaction input and one of output is sending 0.02 BTC to the multisig address.
All right, we've done the step moving some coins from an original address to a multisig address!
It consists of several key methods:
Run this application, then wait for a while to let the transaction mined and confirmed. To confirm the sending is done and dusted, let's run CheckingWallet again:
You can find, in transaction 984d090af0afb0e371f535ba03ba6daac42ac37408b4ee7e2300403d133a1eb7, our multisig output is spent by f81af0eda458e7109c709982a3ce1e8ea455af94b89fda373da02e6c3fb120b0. Checking corresponding transaction, we find this transaction is mined and confirmed. Eventually, we successfully moved 0.01 BTC from the multisig address to another address in the wallet -- mkrr59Mrtff3JVoDcfX3bjy4LEFTVyqQQX
You can also verify the progress via testnet explorer website.
The following tutorial will show how to use a popular Java bitcoin library to build transactions inherently multisig-based.
Basically, it demonstrates three steps to go through whole workflow.
- Prepare coins.
- Send coins to a multisig address.
- Spend coins at this multisig address.
In order to build applications sitting on testnet, we should leverage following websites to assist development:
The former one is to get some free coins, the latter one is for checking if transactions are confirmed and accepted by blockchain.
Essentially, multisignature (multisig) refers to requiring more than one key to authorize a Bitcoin transaction. It is generally used to divide up responsibility for possession of bitcoins. For more information, please refer to https://en.bitcoin.it/wiki/Multisignature
Prepare coins
To begin with, we must have some coins to move around after all bitcoin is all about how to circulate money. Let's prepare a wallet locally to receive some coins to play with. The code would looks like this: import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.wallet.Wallet;
import java.io.File;
public class CheckingWallet {
public static void main(String[] args) {
TestNet3Params params = TestNet3Params.get();
WalletAppKit appKit = new WalletAppKit(params, new File("."), "wallet"); //create a new wallet or load an existing wallet.
appKit.startAsync();
appKit.awaitRunning();
System.out.println("Network connected!");
Wallet wallet = appKit.wallet();
System.out.println("Wallet's current receive address: " + wallet.currentReceiveAddress());
System.out.println("Wallet contents: " + wallet);
}
}
As the class name suggested, it has dual functions. Running first time will create a new wallet to store coins locally, afterwards, it checks all details inside that newly created wallet. By running this application first time, you'll get following alike output:
Network connected!
Wallet's current receive address: mw4J3xZqoXy5heforQqwv6KyGddU3oagGE
Wallet contents: Wallet containing 0.00 BTC (spendable: 0.00 BTC) in:
0 pending transactions
0 unspent transactions
0 spent transactions
0 dead transactions
Last seen best block: 1348772 (2018-07-01T23:28:29Z): 00000000000001db3d8051dbdfceb088b7a41a904ff2c3cd4a82bd696d3fe20d
Keys:
Earliest creation time: 2018-07-01T23:43:30Z
Seed birthday: 1530488610 [2018-07-01T23:43:30Z]
Key to watch: tpubD8xnQctrUtegeLVkDMy6sEebcbq9TJjNVCbuswUv1XUsBzmMCZAcVWbTufgDs6NmF9BnnGiAZTkv6FQnoXEkKgocQyEXzYQe92bKbUj8oRR
addr:mw4J3xZqoXy5heforQqwv6KyGddU3oagGE hash160:aa77461c3d60ed5fe10f366943e683acd0246d8d (M/0H/0/0)
Pay attention to the wallet's current receive address, we'll use this address to get some free coins from testnet faucet: https://testnet.manu.backend.hamburg/faucet, put the current receive address in the address input box and hit the give me some coins button. After a while, let's run CheckingWallet again:
Network connected!
Wallet's current receive address: mkrr59Mrtff3JVoDcfX3bjy4LEFTVyqQQX
Wallet contents: Wallet containing 1.30 BTC (spendable: 1.30 BTC) in:
0 pending transactions
1 unspent transactions
0 spent transactions
0 dead transactions
Last seen best block: 1348795 (2018-07-02T02:21:13Z): 000000000000023c0d533a0bc81f00f49280c425382cfd5178aaab92327acaec
Keys:
Earliest creation time: 2018-07-01T23:43:30Z
Seed birthday: 1530488610 [2018-07-01T23:43:30Z]
Key to watch: tpubD8xnQctrUtegeLVkDMy6sEebcbq9TJjNVCbuswUv1XUsBzmMCZAcVWbTufgDs6NmF9BnnGiAZTkv6FQnoXEkKgocQyEXzYQe92bKbUj8oRR
addr:mw4J3xZqoXy5heforQqwv6KyGddU3oagGE hash160:aa77461c3d60ed5fe10f366943e683acd0246d8d (M/0H/0/0)
addr:mkrr59Mrtff3JVoDcfX3bjy4LEFTVyqQQX hash160:3a9bc0f9ff2048c3668caed35eb0e3f3b8498669 (M/0H/0/1)
>>> UNSPENT:
1.30 BTC total value (sends 0.00 BTC and receives 1.30 BTC)
confidence: Appeared in best chain at height 1348778, depth 18. Source: NETWORK
818721a12db6d9b2876cced77999c0aa36295e2089e1a18f1aba6f586f906f3c
updated: 2018-07-02T00:38:02Z
version 2
time locked until block 1348692
in PUSHDATA(71)[304402203bd81b7bd9ff413752e7a79104aff2b5eb3b256db318b4e5887ac36182efd7e4022073dc50b0c254ced6a8fdafff121ffbc980c8dd060c22879fdfa56934d3d5740001] PUSHDATA(33)[02c5462ac8c6e90a929f8fe32f77a5333d3d35f6d07482847c9742582e24951a97]
outpoint:2aef0a373f8272333f386a019d8987f66db38a2af06b33980e1ddf764ca5d67d:1
sequence:fffffffe
out DUP HASH160 PUSHDATA(20)[aa77461c3d60ed5fe10f366943e683acd0246d8d] EQUALVERIFY CHECKSIG 1.30 BTC
out DUP HASH160 PUSHDATA(20)[af65b0a6a7144413c0a55090410beb6da010582a] EQUALVERIFY CHECKSIG 30.65906828 BTC
prps UNKNOWN
At this moment, we've received 1.30 BTC as indicated by UNSPENT transaction: 818721a12db6d9b2876cced77999c0aa36295e2089e1a18f1aba6f586f906f3c.
As a side note: two files are also created locally -- wallet.wallet and wallet.spvchain. These files store wallet and blockchain information locally, do not delete them when executing applications!
Send coins to a multisig address
Now that we've got coins in our wallet, we need send some coins to a multisig address. Let's create another application: import org.bitcoinj.core.*;
import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.script.Script;
import org.bitcoinj.script.ScriptBuilder;
import org.bitcoinj.wallet.SendRequest;
import org.bitcoinj.wallet.Wallet;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class FundingTransaction {
private TestNet3Params params = TestNet3Params.get();
private WalletAppKit appKit;
private Wallet wallet;
private Script payingToMultisigTxoutScript;
public FundingTransaction() {
appKit = new WalletAppKit(params, new File("."), "wallet"); //Loading existing wallet
appKit.startAsync();
appKit.awaitRunning();
System.out.println("Network connected!");
wallet = appKit.wallet();
}
public static void main(String[] args) throws InterruptedException, InsufficientMoneyException, ExecutionException {
FundingTransaction ft = new FundingTransaction();
ft.createMultisigAddress();
ft.sendCoinsToMultisigAddress();
}
private void createMultisigAddress() {
List<ECKey> keys = Arrays.asList(new ECKey(), new ECKey(), new ECKey());
wallet.importKeys(keys);
//the below is redeem script
payingToMultisigTxoutScript = ScriptBuilder.createMultiSigOutputScript(2, keys); //2 of 3 multisig
System.out.println("Is sent to multisig: " + payingToMultisigTxoutScript.isSentToMultiSig());
System.out.println("redeemScript: " + payingToMultisigTxoutScript);
}
private void sendCoinsToMultisigAddress() throws InsufficientMoneyException, ExecutionException, InterruptedException {
Transaction payingToMultisigTx = new Transaction(params);
Coin value = Coin.valueOf(0, 2); // send 2 cents of BTC
payingToMultisigTx.addOutput(value, payingToMultisigTxoutScript);
SendRequest request = SendRequest.forTx(payingToMultisigTx);
wallet.completeTx(request);
PeerGroup peerGroup = appKit.peerGroup();
peerGroup.broadcastTransaction(request.tx).broadcast().get();
System.out.println("Paying to multisig transaction broadcasted!");
}
}
This FundingTransaction application can run independently, there're two steps comprised -- create an multisig address and send coins to the multisig address. Our case is a 2 of 3 multisig address, which means the address is generated by three keys and in order to redeem the fund at this address any two keys should present to sign. The createMultisigAddress method tells all the details, which also generates the output's ScriptPubKey, the multisig address is implicitly contained inside ScriptPubKey. In the method sendCoinsToMultisigAddress, a transaction that moves some fund out of the coins received in the previous step to the newly generated multisig address is constructed and broadcasted. After running this application and wait for a while to let this transaction mined and confirmed, we can run CheckingWallet again:
(you can also go to testnet explorer website listed above to check progress)
Network connected!
Wallet's current receive address: mkrr59Mrtff3JVoDcfX3bjy4LEFTVyqQQX
Wallet contents: Wallet containing 1.279693 BTC (spendable: 1.279693 BTC) in:
0 pending transactions
1 unspent transactions
1 spent transactions
0 dead transactions
Last seen best block: 1349027 (2018-07-02T21:21:57Z): 00000000000002489c61f19f41da84475daed022ebdf0bdb2951dc90d24ac604
Keys:
Earliest creation time: 2018-07-01T23:43:30Z
addr:mnTLZeWSAF2fwNyALhynuDKqsaN6HiAQfN hash160:4c19ce4515ec6734cedac8998ae8a2ceae39e9c4 creationTimeSeconds:1530503906
addr:n2uYLzr4eYaVpuVDvwF3bZhH8ckAe8z4Bo hash160:eaa0377dc04bda2db95b02c2dec1d01947412925 creationTimeSeconds:1530503906
addr:mtmpz9Q95MAvHy5R7Eb62AHbFMn9LReAaT hash160:9169c60868c568822007b080e4b2e088be6b5552 creationTimeSeconds:1530503906
Seed birthday: 1530488610 [2018-07-01T23:43:30Z]
Key to watch: tpubD8xnQctrUtegeLVkDMy6sEebcbq9TJjNVCbuswUv1XUsBzmMCZAcVWbTufgDs6NmF9BnnGiAZTkv6FQnoXEkKgocQyEXzYQe92bKbUj8oRR
addr:mw4J3xZqoXy5heforQqwv6KyGddU3oagGE hash160:aa77461c3d60ed5fe10f366943e683acd0246d8d (M/0H/0/0)
addr:mkrr59Mrtff3JVoDcfX3bjy4LEFTVyqQQX hash160:3a9bc0f9ff2048c3668caed35eb0e3f3b8498669 (M/0H/0/1)
addr:mqQuPkRfbsKwXXatqzjBrbvFVEpmDCLnis hash160:6c8c56fad7a3c899f425c5d0ab67b217c3e74175 (M/0H/1/0)
addr:n4fTrg9H3bSLcvYPAHygarnTPf8RvaBCCP hash160:fde6e5f0cbfbf8d99be308e24b488e1aa6cb0e54 (M/0H/1/1)
>>> UNSPENT:
-0.020307 BTC total value (sends 1.30 BTC and receives 1.279693 BTC)
confidence: Appeared in best chain at height 1348809, depth 219. Source: NETWORK
984d090af0afb0e371f535ba03ba6daac42ac37408b4ee7e2300403d133a1eb7
updated: 2018-07-02T03:58:32Z
in PUSHDATA(72)[3045022100911bf3219462de5279a71221ed4042bd50e203aeb7fae09c4617ee2fdf8417f0022061d2a41b917e9a01a24da2f6edacdada8ce6491bb5d56b05350848ce10af597801] PUSHDATA(33)[02bd51003c6a6fa7c236c4704b2a6bc3c4256ba8512ae35b3d09653a2e971ec59c] 1.30 BTC
outpoint:818721a12db6d9b2876cced77999c0aa36295e2089e1a18f1aba6f586f906f3c:0 hash160:aa77461c3d60ed5fe10f366943e683acd0246d8d
out 2 PUSHDATA(33)[0233896a708d3ac3f4f871abe26b3b38f32bcb4402b3fe12046278376fbc770625] PUSHDATA(33)[037f9ebcc6412702be3c0dcca071c612a8414f6f3cbea12a81c76edf2f17f6f231] PUSHDATA(33)[028516c2b2407a985ede41676c3e5ad328b9e99cb928d7042cc79014fe68632eaf] 3 CHECKMULTISIG 0.02 BTC
out DUP HASH160 PUSHDATA(20)[6c8c56fad7a3c899f425c5d0ab67b217c3e74175] EQUALVERIFY CHECKSIG 1.279693 BTC
fee 0.00100326 BTC/kB, 0.000307 BTC for 306 bytes
prps USER_PAYMENT
>>> SPENT:
1.30 BTC total value (sends 0.00 BTC and receives 1.30 BTC)
confidence: Appeared in best chain at height 1348778, depth 250. Source: NETWORK
818721a12db6d9b2876cced77999c0aa36295e2089e1a18f1aba6f586f906f3c
updated: 2018-07-02T00:38:02Z
version 2
time locked until block 1348692
in PUSHDATA(71)[304402203bd81b7bd9ff413752e7a79104aff2b5eb3b256db318b4e5887ac36182efd7e4022073dc50b0c254ced6a8fdafff121ffbc980c8dd060c22879fdfa56934d3d5740001] PUSHDATA(33)[02c5462ac8c6e90a929f8fe32f77a5333d3d35f6d07482847c9742582e24951a97]
outpoint:2aef0a373f8272333f386a019d8987f66db38a2af06b33980e1ddf764ca5d67d:1
sequence:fffffffe
out DUP HASH160 PUSHDATA(20)[aa77461c3d60ed5fe10f366943e683acd0246d8d] EQUALVERIFY CHECKSIG 1.30 BTC Spent by 984d090af0afb0e371f535ba03ba6daac42ac37408b4ee7e2300403d133a1eb7
out DUP HASH160 PUSHDATA(20)[af65b0a6a7144413c0a55090410beb6da010582a] EQUALVERIFY CHECKSIG 30.65906828 BTC
prps UNKNOWN
We can find a new UNSPENT transaction generated and confirmed, the outpoint of this transaction tells us that previous received coins are origin of transaction input and one of output is sending 0.02 BTC to the multisig address.
All right, we've done the step moving some coins from an original address to a multisig address!
Spend coins at this multisig address
In the last step, we'll create an application to redeem the coins stored in the multisig address used in the previous step. In order to redeem the coins at a multisig address, we must request multiple key holders to sign the redeeming transaction. The application would look like this: import org.bitcoinj.core.*;
import org.bitcoinj.crypto.TransactionSignature;
import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.script.Script;
import org.bitcoinj.script.ScriptBuilder;
import org.bitcoinj.wallet.Wallet;
import java.io.File;
import java.util.concurrent.ExecutionException;
import static com.google.common.base.Preconditions.checkState;
public class RedeemingTransaction {
private TestNet3Params params = TestNet3Params.get();
private WalletAppKit appKit;
private Wallet wallet;
private TransactionOutput multisigOutput;
private Transaction redeemingMultisigTx1;
private Transaction redeemingMultisigTx2;
private TransactionInput redeemMultisigTxInput;
private ECKey.ECDSASignature partyASignature;
private ECKey.ECDSASignature partyBSignature;
public RedeemingTransaction() {
appKit = new WalletAppKit(params, new File("."), "wallet");
appKit.startAsync();
appKit.awaitRunning();
System.out.println("Network connected!");
wallet = appKit.wallet();
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
RedeemingTransaction rt = new RedeemingTransaction();
rt.createRawTransactionForMultisigRedeemingByA();
rt.signRawTransactionForMultisigRedeemingByA();
rt.createRawTransactionForMultisigRedeemingByB();
rt.signRawTransactionForMultisigRedeemingByB();
rt.createAndBroadcastMultisigRedeemingTx();
}
private void createRawTransactionForMultisigRedeemingByA() {
redeemingMultisigTx1 = new Transaction(params);
multisigOutput = wallet.getUnspents().get(0).getParentTransaction().getOutputs().stream().filter(unspent -> unspent.getScriptPubKey().isSentToMultiSig()).findFirst().get();
System.out.println("multisigOutput: " + multisigOutput);
redeemingMultisigTx1.addInput(multisigOutput);
Coin value = multisigOutput.getValue();
wallet = appKit.wallet();
Address finalAddress = wallet.currentReceiveAddress();
redeemingMultisigTx1.addOutput(value.div(2), finalAddress); //leave some mining fee
System.out.println("Send to final address: " + finalAddress);
}
private void signRawTransactionForMultisigRedeemingByA() {
Script payingToMultisigTxoutScriptPubKey = multisigOutput.getScriptPubKey();
System.out.println("payingToMultisigTxoutScriptPubKey: " + payingToMultisigTxoutScriptPubKey);
checkState(payingToMultisigTxoutScriptPubKey.isSentToMultiSig());
Sha256Hash sighash = redeemingMultisigTx1.hashForSignature(0, payingToMultisigTxoutScriptPubKey, Transaction.SigHash.ALL, false);
partyASignature = wallet.getImportedKeys().get(0).sign(sighash);
}
private void createRawTransactionForMultisigRedeemingByB() {
redeemingMultisigTx2 = new Transaction(params);
redeemMultisigTxInput = redeemingMultisigTx2.addInput(multisigOutput);
Coin value = multisigOutput.getValue();
wallet = appKit.wallet();
Address finalAddress = wallet.currentReceiveAddress();
redeemingMultisigTx2.addOutput(value.div(2), finalAddress);
System.out.println("Send to final address: " + finalAddress);
}
private void signRawTransactionForMultisigRedeemingByB() {
Script payingToMultisigTxoutScriptPubKey = multisigOutput.getScriptPubKey();
Sha256Hash sighash = redeemingMultisigTx2.hashForSignature(0, payingToMultisigTxoutScriptPubKey, Transaction.SigHash.ALL, false);
partyBSignature = wallet.getImportedKeys().get(1).sign(sighash);
}
private void createAndBroadcastMultisigRedeemingTx() throws ExecutionException, InterruptedException {
TransactionSignature signatureA = new TransactionSignature(partyASignature, Transaction.SigHash.ALL, false);
TransactionSignature signatureB = new TransactionSignature(partyBSignature, Transaction.SigHash.ALL, false);
Script inputScript = ScriptBuilder.createMultiSigInputScript(signatureA, signatureB);
System.out.println("redeeming Tx input script: " + inputScript);
redeemMultisigTxInput.setScriptSig(inputScript);
redeemMultisigTxInput.verify(multisigOutput);
PeerGroup peerGroup = appKit.peerGroup();
peerGroup.broadcastTransaction(redeemingMultisigTx2).broadcast().get();
System.out.println("Multisig redeeming transaction broadcasted!");
}
}
It consists of several key methods:
- createRawTransactionForMultisigRedeemingByA
- signRawTransactionForMultisigRedeemingByA
- createRawTransactionForMultisigRedeemingByB
- signRawTransactionForMultisigRedeemingByB
Run this application, then wait for a while to let the transaction mined and confirmed. To confirm the sending is done and dusted, let's run CheckingWallet again:
Network connected!
Wallet's current receive address: mkQ78nnJvZ8RKBbGAxTcmJXjw7rRgHmw7W
Wallet contents: Wallet containing 1.289693 BTC (spendable: 1.289693 BTC) in:
0 pending transactions
2 unspent transactions
1 spent transactions
0 dead transactions
Last seen best block: 1349055 (2018-07-03T01:07:07Z): 00000000000002e948be15d30d9c3242715cf274c208a2aee9df14b62987ee0a
Keys:
Earliest creation time: 2018-07-01T23:43:30Z
addr:mnTLZeWSAF2fwNyALhynuDKqsaN6HiAQfN hash160:4c19ce4515ec6734cedac8998ae8a2ceae39e9c4 creationTimeSeconds:1530503906
addr:n2uYLzr4eYaVpuVDvwF3bZhH8ckAe8z4Bo hash160:eaa0377dc04bda2db95b02c2dec1d01947412925 creationTimeSeconds:1530503906
addr:mtmpz9Q95MAvHy5R7Eb62AHbFMn9LReAaT hash160:9169c60868c568822007b080e4b2e088be6b5552 creationTimeSeconds:1530503906
Seed birthday: 1530488610 [2018-07-01T23:43:30Z]
Key to watch: tpubD8xnQctrUtegeLVkDMy6sEebcbq9TJjNVCbuswUv1XUsBzmMCZAcVWbTufgDs6NmF9BnnGiAZTkv6FQnoXEkKgocQyEXzYQe92bKbUj8oRR
addr:mw4J3xZqoXy5heforQqwv6KyGddU3oagGE hash160:aa77461c3d60ed5fe10f366943e683acd0246d8d (M/0H/0/0)
addr:mkrr59Mrtff3JVoDcfX3bjy4LEFTVyqQQX hash160:3a9bc0f9ff2048c3668caed35eb0e3f3b8498669 (M/0H/0/1)
addr:mkQ78nnJvZ8RKBbGAxTcmJXjw7rRgHmw7W hash160:358d18bff1dcf68c5f242cc6d1acfe191289cf5b (M/0H/0/2)
addr:mqQuPkRfbsKwXXatqzjBrbvFVEpmDCLnis hash160:6c8c56fad7a3c899f425c5d0ab67b217c3e74175 (M/0H/1/0)
addr:n4fTrg9H3bSLcvYPAHygarnTPf8RvaBCCP hash160:fde6e5f0cbfbf8d99be308e24b488e1aa6cb0e54 (M/0H/1/1)
>>> UNSPENT:
0.01 BTC total value (sends 0.00 BTC and receives 0.01 BTC)
confidence: Seen by 3 peers (most recently: 2018-07-03T00:49:10Z). Appeared in best chain at height 1349050, depth 6. Source: NETWORK
f81af0eda458e7109c709982a3ce1e8ea455af94b89fda373da02e6c3fb120b0
updated: 2018-07-03T00:49:10Z
in 0[] PUSHDATA(71)[304402201eb74f5e52610f817e939279ff44a03e906f08613c3d84124f3e583f238c34aa022067d065b63ed3a28c71ee481d0e108bec007900d2de677ec7b0e692d2d66c00f201] PUSHDATA(71)[304402205276cfe52278e7d5f33e3b4d93685b9e15ec8151a331710a6b58c1609e9640770220240c763147fdf16d1199f57f0605d7086b41924c27b3e23435440d8a587de02201] 0.02 BTC
outpoint:984d090af0afb0e371f535ba03ba6daac42ac37408b4ee7e2300403d133a1eb7:0
out DUP HASH160 PUSHDATA(20)[3a9bc0f9ff2048c3668caed35eb0e3f3b8498669] EQUALVERIFY CHECKSIG 0.01 BTC
fee 0.04347826 BTC/kB, 0.01 BTC for 230 bytes
prps UNKNOWN
-0.020307 BTC total value (sends 1.30 BTC and receives 1.279693 BTC)
confidence: Appeared in best chain at height 1348809, depth 247. Source: NETWORK
984d090af0afb0e371f535ba03ba6daac42ac37408b4ee7e2300403d133a1eb7
updated: 2018-07-02T03:58:32Z
in PUSHDATA(72)[3045022100911bf3219462de5279a71221ed4042bd50e203aeb7fae09c4617ee2fdf8417f0022061d2a41b917e9a01a24da2f6edacdada8ce6491bb5d56b05350848ce10af597801] PUSHDATA(33)[02bd51003c6a6fa7c236c4704b2a6bc3c4256ba8512ae35b3d09653a2e971ec59c] 1.30 BTC
outpoint:818721a12db6d9b2876cced77999c0aa36295e2089e1a18f1aba6f586f906f3c:0 hash160:aa77461c3d60ed5fe10f366943e683acd0246d8d
out 2 PUSHDATA(33)[0233896a708d3ac3f4f871abe26b3b38f32bcb4402b3fe12046278376fbc770625] PUSHDATA(33)[037f9ebcc6412702be3c0dcca071c612a8414f6f3cbea12a81c76edf2f17f6f231] PUSHDATA(33)[028516c2b2407a985ede41676c3e5ad328b9e99cb928d7042cc79014fe68632eaf] 3 CHECKMULTISIG 0.02 BTC Spent by f81af0eda458e7109c709982a3ce1e8ea455af94b89fda373da02e6c3fb120b0
out DUP HASH160 PUSHDATA(20)[6c8c56fad7a3c899f425c5d0ab67b217c3e74175] EQUALVERIFY CHECKSIG 1.279693 BTC
fee 0.00100326 BTC/kB, 0.000307 BTC for 306 bytes
prps USER_PAYMENT
>>> SPENT:
1.30 BTC total value (sends 0.00 BTC and receives 1.30 BTC)
confidence: Appeared in best chain at height 1348778, depth 278. Source: NETWORK
818721a12db6d9b2876cced77999c0aa36295e2089e1a18f1aba6f586f906f3c
updated: 2018-07-02T00:38:02Z
version 2
time locked until block 1348692
in PUSHDATA(71)[304402203bd81b7bd9ff413752e7a79104aff2b5eb3b256db318b4e5887ac36182efd7e4022073dc50b0c254ced6a8fdafff121ffbc980c8dd060c22879fdfa56934d3d5740001] PUSHDATA(33)[02c5462ac8c6e90a929f8fe32f77a5333d3d35f6d07482847c9742582e24951a97]
outpoint:2aef0a373f8272333f386a019d8987f66db38a2af06b33980e1ddf764ca5d67d:1
sequence:fffffffe
out DUP HASH160 PUSHDATA(20)[aa77461c3d60ed5fe10f366943e683acd0246d8d] EQUALVERIFY CHECKSIG 1.30 BTC Spent by 984d090af0afb0e371f535ba03ba6daac42ac37408b4ee7e2300403d133a1eb7
out DUP HASH160 PUSHDATA(20)[af65b0a6a7144413c0a55090410beb6da010582a] EQUALVERIFY CHECKSIG 30.65906828 BTC
prps UNKNOWN
You can find, in transaction 984d090af0afb0e371f535ba03ba6daac42ac37408b4ee7e2300403d133a1eb7, our multisig output is spent by f81af0eda458e7109c709982a3ce1e8ea455af94b89fda373da02e6c3fb120b0. Checking corresponding transaction, we find this transaction is mined and confirmed. Eventually, we successfully moved 0.01 BTC from the multisig address to another address in the wallet -- mkrr59Mrtff3JVoDcfX3bjy4LEFTVyqQQX
You can also verify the progress via testnet explorer website.
Hiiii....Thanks for sharing Great information....Nice post....Keep move on....
ReplyDeleteBlockchain Training in Hyderabad
Nice Blog.
ReplyDeleteI've gone through the details that you mentioned in the blog regarding Bitcoin and blockchain. The way you defined it is really great and is understandable to each and every person who is looking for the bitcoin and its trading concept. Thanks for sharing such a great article, I was looking to
hire dedicated blockchain development company and found this blog.
Thanks for sharing such a great blog.
hire dedicated blockchain developers
ethereum blockchain development