69 Commits

Author SHA1 Message Date
root b4fd55aebe added feature to rebuild a transaction from the txid, useful for RBF and double spending :o. Changed donation address. Released as version 1.6 2020-07-06 21:33:57 +00:00
root f51be92a72 fixed multisig bug as described in issues/212 2020-07-05 20:21:41 +00:00
root 06cf50abb3 removed auto reload wallet feature. users must click or interact with the page. attempt to save on bandwidth. 2020-06-03 17:59:47 +00:00
root 35de4228d8 updated index.html to list link to new host 2020-04-22 20:18:08 +00:00
OutCast3k a4ef169031 update sha1sum 2020-02-23 19:57:33 +00:00
OutCast3k 6bb5e3785a Merge pull request #210 from junderw/patch-1
Don't add padding to P2WSH
2020-02-23 19:55:14 +00:00
OutCast3k a199d3a55c Merge pull request #208 from jmacxx/fix_bech32_address_decoding
fix: some bech32 addresses were not recognised
2020-02-23 19:54:46 +00:00
Jonathan Underwood 7e92530e1a Don't add padding to P2WSH
Fixes #209
2020-02-20 10:12:57 +09:00
Wowee0 f5c2f48efc fix: some bech32 addresses were not recognised 2020-02-12 10:57:15 -06:00
OutCast3k 4f3ceeb3ea update date in sha1sum file 2019-12-28 12:10:39 +00:00
OutCast3k 73369dd253 add file hash of test.html to sha1sum 2019-12-28 12:08:51 +00:00
OutCast3k 6ed0d3e07e Merge pull request #206 from jmacxx/tests
add some self-test routines to coinbin
2019-12-28 12:03:55 +00:00
Wowee0 84304f23ea tests added 2019-12-25 19:30:38 -06:00
OutCast3k 44ba1b3d30 update readme 2019-12-25 22:15:55 +00:00
OutCast3k 5583675390 custom hd key derivation addded 2019-12-25 22:10:55 +00:00
OutCast3k 56cb104ea4 updated sha1sum 2019-12-24 23:01:50 +00:00
OutCast3k c6f70d000e Merge pull request #194 from jmacxx/fix_issue_140
fix Issue 140: error logged to console when switching tabs.
2019-12-24 23:00:22 +00:00
OutCast3k 4836b20fae updated sha1sum 2019-12-24 22:47:28 +00:00
OutCast3k f364ae4b4a Merge pull request #198 from jmacxx/fix_issue_193
fix: RBF always set when redeeming OP_CHECKLOCKTIMEVERIFY
2019-12-24 22:44:43 +00:00
OutCast3k 64cb387247 updated as outcast3k 2019-12-24 21:53:20 +00:00
btc b2a86006cf updated sha1sum file 2019-12-24 21:51:33 +00:00
OutCast3k b5ebaafed8 Merge pull request #202 from junderw/fixScriptNum
Fix script num
2019-12-24 21:49:03 +00:00
kinoshitajona d4f47fce28 Must do OPs with script method 2019-11-14 15:13:51 +09:00
kinoshitajona 5bd3786f94 Fix ScriptNum 2019-11-14 15:07:15 +09:00
Wowee0 b77f3cf06a fix: RBF always set when redeeming OP_CHECKLOCKTIMEVERIFY 2019-10-18 23:19:52 -05:00
Wowee0 b0c6c3a516 fix Uncaught TypeError logged to console when switching Tx Input and Output tabs 2019-09-23 21:01:03 -05:00
OutCast3k a6f5dcf7f0 removed debugger code 2019-09-22 20:32:42 +00:00
OutCast3k cf2a8b01cb update sha1sum file 2019-08-30 17:03:31 +00:00
OutCast3k 261c4ace40 Merge pull request #191 from Wowee0/choose_backend
fix for #189 .. three backend API options for btc/ltc/doge
2019-08-30 17:58:50 +01:00
Wowee0 e18b634c4e fix issue where empty broadcast did not handle the error response appropriately 2019-08-27 11:17:08 -05:00
Wowee0 1f3b878d63 bugfix for blockcypher when address used that has no UTXO 2019-08-22 07:41:36 -05:00
Wowee0 efc16c10fb allow backend API choice between blockcypher/blockchair/chain.so 2019-08-16 16:28:29 -05:00
Wowee0 477ca8890d Merge pull request #1 from OutCast3k/master
sync with OutCast3k/coinbin
2019-06-15 09:18:15 -05:00
OutCast3k e73e8093b3 change made to avoid captcha provided by cloudflare to TOR users 2019-06-05 19:34:45 +00:00
OutCast3k 40ea3230fd removed blockchain.com links 2019-05-28 15:21:58 +00:00
OutCast3k dc416c6521 changes made to paper wallet 2019-05-24 14:44:47 +00:00
OutCast3k fc66bc9423 Merge pull request #127 from olivergregorius/paperwallet
Paperwallet
2019-05-24 15:41:54 +01:00
OutCast3k 1c10bef510 Merge pull request #183 from yottalogical/blockchain-explorer-link
Add Link to Blockchain Explorer after Broadcasting Transaction (Litecoin)
2019-05-06 11:49:48 +01:00
yottalogical b22e79391f Update sha1sum 2019-05-05 12:36:32 -04:00
yottalogical 0be8fd9a97 Add link to blockchain explorer for Chain.so (Litecoin) 2019-05-05 12:30:28 -04:00
OutCast3k 1a364ff770 updated sha1sum file 2019-05-05 09:22:52 +00:00
OutCast3k bc0c72117e Merge pull request #182 from Wowee0/litecoin
re-enabled Litecoin
2019-05-05 10:11:31 +01:00
OutCast3k 13c50cf4b6 Merge pull request #170 from ivy-dong/ivy_remove_redundant_quotation_marks
remove redundant quotation marks
2019-05-05 10:09:08 +01:00
OutCast3k dea1d1b274 Merge pull request #178 from yottalogical/blockchain-explorer-link 2019-05-05 10:07:00 +01:00
Wowee0 e6c70d133b set appropriate hrp for Litecoin SegWit addresses
set chain.so/address/LTC for view of address (previously was referencing BTC block explorer)
2019-04-22 22:09:20 -05:00
Wowee0 10aa011c6e LTC SegWit (pre-bech32) address version changed from 5 to 50 (i.e. 3-addresses changed to M-addresses) 2019-04-20 23:28:40 -05:00
Wowee0 c7a0fda7e5 re-enabled Litecoin 2019-04-19 10:40:59 -05:00
yottalogical c9cfeefc86 Correct month in sha1sum 2019-02-22 18:19:35 -05:00
yottalogical cdf4aa105b Fix variable name in broadcast success message 2019-02-06 15:43:23 -05:00
yottalogical 2fc574dde0 Remove unnecessary linebreak at end 2019-02-06 15:34:25 -05:00
yottalogical f088ec2e52 Update sha1sum 2019-02-06 15:28:04 -05:00
yottalogical 9ccd73808d Capitalize TXID in success message 2019-02-06 15:23:09 -05:00
yottalogical cb81362330 Add link to blockchain explorer for Cryptoid.info (Carboncoin) 2019-02-06 15:21:39 -05:00
yottalogical fcbf25eaec Add link to blockchain explorer for coinb.in (Bitcoin) 2019-02-06 15:20:43 -05:00
yottalogical 2aca9ab28d Add link to blockchain explorer for Blockcypher.com 2019-02-06 14:46:19 -05:00
yottalogical 5c581316fe Add link to blockchain explorer for Chain.so (Bitcoin) 2019-02-06 14:39:48 -05:00
yottalogical ebfb940dd5 Fix typo in comment 2019-02-06 14:32:49 -05:00
yottalogical 3201550d40 Add link to blockchain explorer for Chain.so (Dogecoin) 2019-02-06 14:23:27 -05:00
OutCast3k d88ec3db4b update sha1sum file 2018-12-28 23:49:01 +00:00
OutCast3k 530453a701 improvement to previous timelock address bug fix 2018-12-28 23:42:00 +00:00
OutCast3k 194df37d56 bug fix for time locked addresses. transactions not being built correctly (no loss of funds!!!!) 2018-12-28 23:33:42 +00:00
Ivy Dong 87461b58b8 remove redundant quotation marks 2018-12-16 20:04:27 +08:00
OutCast3k 739aee3c0f couple of bug fixes with transaction building 2018-08-26 20:53:25 +00:00
OutCast3k fd81fafdff segwit signing bug fix 2018-06-19 15:45:21 +00:00
OutCast3k 9bede2aef4 Update sha1sum 2018-06-17 11:37:21 +01:00
OutCast3k 37f4395d9f wallet segwit spend bugfix 2018-06-17 09:22:44 +00:00
OutCast3k 5a65a77bd2 added a bech32 address to the #wallet section of coinb.in 2018-06-11 16:23:18 +00:00
oliverdorn b997751791 Added functionality for printing Paper Wallet 2017-11-25 00:53:00 +01:00
oliverdorn 9bccc5c512 Added Buttons for printing Paper Wallets
Added Buttons for printint Paper Wallets for generated Legacy- and SegWit-Adresses
2017-11-25 00:49:16 +01:00
6 changed files with 855 additions and 139 deletions
+9 -8
View File
@@ -1,7 +1,7 @@
coinbin coinbin
======= =======
A Open Source Browser Based Bitcoin Wallet. Version 1.4 beta by OutCast3k A Open Source Browser Based Bitcoin Wallet. Version 1.6 beta by OutCast3k
Live version available at http://coinb.in/ or http://4zpinp6gdkjfplhk.onion Live version available at http://coinb.in/ or http://4zpinp6gdkjfplhk.onion
@@ -24,12 +24,13 @@ Coinb.in supports a number of key features such as:
- Brain wallet support. - Brain wallet support.
- Compatible with bitcoin-qt - Compatible with bitcoin-qt
- An offical .onion address for tor users. - An offical .onion address for tor users.
- Offline qrcode creator and scanning tool - Offline qrcode creator and scanning tool.
- HD (bip32) support - HD (bip32) support.
- Supports altcoins such as litecoin - Supports altcoins such as litecoin.
- Replace by fee (RBF) Support - Replace by fee (RBF) Support.
- Segwit Support - Segwit Support.
- Bech32 address support - Bech32 address support.
- Fee calculator - https://coinb.in/#fees - Fee calculator - https://coinb.in/#fees
- Transaction rebuild support for RBF and double spending.
Donate to 3K1oFZMks41C7qDYBsr72SYjapLqDuSYuN to see more development! Donate to 33tht1bKDgZVxb39MnZsWa8oxHXHvUYE4G to see more development!
+60 -15
View File
@@ -158,7 +158,9 @@
<div class="hidden optionsAdvanced"> <div class="hidden optionsAdvanced">
<label>Segregated Witness Address</label> <label>Segregated Witness Address</label>
<p class="checkbox"> <p class="checkbox">
<label><input type="checkbox" id="walletSegwit" class="checkbox-inline" checked> Use a segwit address instead of a regular address. <span class="text-muted"><i>(recommended)</i></span></label></label> <label><input type="checkbox" id="walletSegwit" class="checkbox-inline" checked> Use a segwit address instead of a regular address. <span class="text-muted"><i>(recommended)</i></span></label></label> <br>
<label><input type="radio" id="walletSegwitp2sh" class="walletSegwitType" name="walletSegWitType" value="p2sh" checked> p2sh address</label> <br>
<label><input type="radio" id="walletSegwitBech32" class="walletSegwitType" name="walletSegWitType" value="bech32"> bech32 address</label>
</p> </p>
<label>Enable Replace by Fee (RBF)</label> <label>Enable Replace by Fee (RBF)</label>
@@ -188,6 +190,7 @@
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" id="walletToBtn">SegWit <span class="caret"></span></button> <button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" id="walletToBtn">SegWit <span class="caret"></span></button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="javascript:;" id="walletToSegWit">SegWit</a></li> <li><a href="javascript:;" id="walletToSegWit">SegWit</a></li>
<li><a href="javascript:;" id="walletToSegWitBech32">SegWit/Bech32</a></li>
<li><a href="javascript:;" id="walletToLegacy">Legacy</a></li> <li><a href="javascript:;" id="walletToLegacy">Legacy</a></li>
</ul> </ul>
</div> </div>
@@ -256,7 +259,7 @@
<div class="row"> <div class="row">
<div class="col-xs-6"> <div class="col-xs-6">
<label><abbr title="the amount to pay in network miner fee">Transaction Fee</abbr>&nbsp;&nbsp;<a href="javascript:;" id="feesestwallet"><span class="glyphicon glyphicon-question-sign"></span></a></label> <label><abbr title="the amount to pay in network miner fee">Transaction Fee</abbr>&nbsp;&nbsp;<a href="javascript:;" id="feesestwallet"><span class="glyphicon glyphicon-question-sign"></span></a></label>
<input type="text" class="form-control" value="0.0004" id="txFee"> <input type="text" class="form-control" value="0.00004000" id="txFee">
</div> </div>
<div class="col-xs-5"> <div class="col-xs-5">
<label><abbr title="the amount to donate to coinb.in">Donation</abbr></label> <label><abbr title="the amount to donate to coinb.in">Donation</abbr></label>
@@ -335,7 +338,16 @@
</div> </div>
<input type="button" class="btn btn-primary" value="Generate" id="newKeysBtn"> <div class="btn-group">
<input type="button" class="btn btn-primary" value="Generate" id="newKeysBtn">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a href="#" id="newPaperwalletBtn">Print</a></li>
</ul>
</div>
<br> <br>
</div> </div>
@@ -380,7 +392,17 @@
<input type="text" class="form-control hidden" id="brainwalletSegWit"> <input type="text" class="form-control hidden" id="brainwalletSegWit">
</div> </div>
<input type="button" class="btn btn-primary" value="Generate" id="newSegWitKeysBtn"> <div class="btn-group">
<input type="button" class="btn btn-primary" value="Generate" id="newSegWitKeysBtn">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a href="#" id="newSegwitPaperwalletBtn">Print</a></li>
</ul>
</div>
<br> <br>
</div> </div>
@@ -606,7 +628,7 @@
<label>Null Data</label> <span class="text-muted text-normal">(80 byte limit, <i>40 bytes recommended</i>)</span> <label>Null Data</label> <span class="text-muted text-normal">(80 byte limit, <i>40 bytes recommended</i>)</span>
<p class="checkbox"> <p class="checkbox">
<label><input type="checkbox" id="opReturn" class="checkbox-inline"> Allow data to be sent within the transaction and stored in the blockchain by using <a href="https://bitcoin.org/en/developer-guide#null-data" target="_"blank">OP_RETURN</a>.</label> <label><input type="checkbox" id="opReturn" class="checkbox-inline"> Allow data to be sent within the transaction and stored in the blockchain by using <a href="https://bitcoin.org/en/developer-guide#null-data" target="_blank">OP_RETURN</a>.</label>
<div class="text-muted">When using this option you may enter a hex string or address into the address field on the output tab.</div> <div class="text-muted">When using this option you may enter a hex string or address into the address field on the output tab.</div>
</p> </p>
@@ -621,7 +643,7 @@
<label>Replace By Fee (RBF)</label> <label>Replace By Fee (RBF)</label>
<p class="checkbox"> <p class="checkbox">
<label><input type="checkbox" id="txRBF" class="checkbox-inline"> Make this a <a href="https://en.bitcoin.it/wiki/Transaction_replacement" target="_blank">RBF transaction</a>.</label> <label><input type="checkbox" id="txRBF" class="checkbox-inline" checked> Make this a <a href="https://en.bitcoin.it/wiki/Transaction_replacement" target="_blank">RBF transaction</a>.</label>
</p> </p>
<hr> <hr>
@@ -1171,18 +1193,26 @@
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-md-8">
<b>Path</b><br> <b>Path</b><br>
<select class="form-control"> <select class="form-control" id="hdpathtype"">
<option>Simple: m/i</option> <option value="simple">Simple: m/i</option>
<option value="custom">Custom</option>
</select> </select>
<div id="hdpath" class="hidden" style="margin-top:4px">
<span class="input-group">
<input type="text" class="form-control" value="m/0/1"> <br>
<span class="input-group-addon"> / </span>
</span>
</div>
</div> </div>
<div class="col-md-2"> <div class="col-md-2">
<b>Index (Start)</b><br> <b><u>I</u>ndex (Start)</b><br>
<input type="text" class="form-control derivation_index_start" value="0"> <input type="text" class="form-control derivation_index_start" value="0">
</div> </div>
<div class="col-md-2"> <div class="col-md-2">
<b>Index (End)</b><br> <b><u>I</u>ndex (End)</b><br>
<input type="text" class="form-control derivation_index_end" value="1"> <input type="text" class="form-control derivation_index_end" value="1">
</div> </div>
@@ -1303,7 +1333,7 @@
<div class="tab-pane tab-content" id="about"> <div class="tab-pane tab-content" id="about">
<h2>About <small>open source bitcoin wallet</small></h2> <h2>About <small>open source bitcoin wallet</small></h2>
<p>Version 1.4</p> <p>Version 1.6</p>
<p>Compatible with bitcoin core</p> <p>Compatible with bitcoin core</p>
<p>Github <a href="https://github.com/OutCast3k/coinbin/">https://github.com/OutCast3k/coinbin/</a></p> <p>Github <a href="https://github.com/OutCast3k/coinbin/">https://github.com/OutCast3k/coinbin/</a></p>
<p>TOR <a href="http://4zpinp6gdkjfplhk.onion">4zpinp6gdkjfplhk.onion</a></p> <p>TOR <a href="http://4zpinp6gdkjfplhk.onion">4zpinp6gdkjfplhk.onion</a></p>
@@ -1313,12 +1343,13 @@
<h3>Information</h3> <h3>Information</h3>
<p>Coinb.in is a free and open source project released under the MIT license, originally by <a href="https://bitcointalk.org/index.php?action=profile;u=34834" target="_blank">OutCast3k</a> in 2013. Discussion of the project can be found at <a href="https://bitcointalk.org/index.php?topic=390046" target="_blank">bitcointalk.org</a> during its early testing stages when its primary focus was to develop a proof of concept multisig solution in javascript.</p> <p>Coinb.in is a free and open source project released under the MIT license, originally by <a href="https://bitcointalk.org/index.php?action=profile;u=34834" target="_blank">OutCast3k</a> in 2013. Discussion of the project can be found at <a href="https://bitcointalk.org/index.php?topic=390046" target="_blank">bitcointalk.org</a> during its early testing stages when its primary focus was to develop a proof of concept multisig solution in javascript.</p>
<p>Coinb.in is run and funded by the generosity of others in terms of <a href="https://github.com/OutCast3k/coinbin/graphs/contributors" target="_blank">development</a> and hosting.</p> <p>Coinb.in is run and funded by the generosity of others in terms of <a href="https://github.com/OutCast3k/coinbin/graphs/contributors" target="_blank">development</a> and hosting.</p>
<p>Coinb.in is kindly hosted by <a href="https://www.bitvps.com/" target="_blank">BitVPS.com</a>.</p>
<h3>Privacy</h3> <h3>Privacy</h3>
<p>Coinb.in believes strongly in privacy, not only do we support the use of TOR, the site does not collect and store IP or transaction data via our servers nor do we store your bitcoins private key. We do route traffic via cloudflare using an SSL certificate.</p> <p>Coinb.in believes strongly in privacy, not only do we support the use of TOR, the site does not collect and store IP or transaction data via our servers nor do we store your bitcoins private key. We do route traffic via cloudflare using an SSL certificate.</p>
<h3>Support</h3> <h3>Support</h3>
<p>We recommend that you first check our <a href="https://status.coinb.in/" target="_blank">service status</a> page and then <a href="https://blog.coinb.in/" target="_blank">blog</a> page which has multiple <a href="https://blog.coinb.in/guides" target="_blank">guides</a>. However if the problem persists you can contact us by emailing support{at}coinb.in.</p> <p>We recommend that you first check our <a href="https://status.coinb.in/" target="_blank">service status</a> page and then <a href="https://blog.coinb.in/" target="_blank">blog</a> page which has multiple <a href="https://blog.coinb.in/guides" target="_blank">guides</a>. However if the problem persists you can contact us by emailing support{at}coinb.in.</p>
<h3>Donate</h3> <h3>Donate</h3>
<p>Please donate to <a href="bitcoin:3K1oFZMks41C7qDYBsr72SYjapLqDuSYuN">3K1oFZMks41C7qDYBsr72SYjapLqDuSYuN</a> if you found this project useful or want to see more features!</p> <p>Please donate to <a href="bitcoin:33tht1bKDgZVxb39MnZsWa8oxHXHvUYE4G">33tht1bKDgZVxb39MnZsWa8oxHXHvUYE4G</a> if you found this project useful or want to see more features!</p>
</div> </div>
<div class="tab-pane tab-content" id="settings"> <div class="tab-pane tab-content" id="settings">
@@ -1331,7 +1362,8 @@
<p class="text-muted">Select which network you'd like to use for key pair generation.</p> <p class="text-muted">Select which network you'd like to use for key pair generation.</p>
<select class="form-control" id="coinjs_coin"> <select class="form-control" id="coinjs_coin">
<option value="bitcoin_mainnet" rel="0x00;0x80;0x05;0x488b21e;0x488ade4;coinb.in;coinb.in">Bitcoin (mainnet)</option> <option value="bitcoin_mainnet" rel="0x00;0x80;0x05;0x488b21e;0x488ade4;coinb.in;coinb.in">Bitcoin (mainnet)</option>
<option value="dogecoin_mainnet" rel="0x1e;0x9e;0x16;0x0827421e;0x089944e4;chain.so_dogecoin;chain.so_dogecoin">Dogecoin (mainnet)</option> <option value="litecoin_mainnet" rel="0x30;0xb0;0x32;0x019da462;0x019d9cfe;blockcypher_litecoin;blockcypher_litecoin">Litecoin (mainnet)</option>
<option value="dogecoin_mainnet" rel="0x1e;0x9e;0x16;0x0827421e;0x089944e4;blockcypher_dogecoin;blockcypher_dogecoin">Dogecoin (mainnet)</option>
<option value="carboncoin_mainnet" rel="0x2f;0xaf;0x05;0x488b21e;0x488ade4;cryptoid.info_carboncoin;cryptoid.info_carboncoin">Carboncoin (mainnet)</option> <option value="carboncoin_mainnet" rel="0x2f;0xaf;0x05;0x488b21e;0x488ade4;cryptoid.info_carboncoin;cryptoid.info_carboncoin">Carboncoin (mainnet)</option>
<option value="shadowcash_mainnet" rel="0x3f;0xbf;0x7d;0xee80286a;0xee8031e8;false;false">ShadowCash (mainnet)</option> <option value="shadowcash_mainnet" rel="0x3f;0xbf;0x7d;0xee80286a;0xee8031e8;false;false">ShadowCash (mainnet)</option>
<option value="bitcoin_testnet" rel="0x6f;0xef;0xc4;0x043587cf;0x04358394;false;false">Bitcoin (testnet)</option> <option value="bitcoin_testnet" rel="0x6f;0xef;0xc4;0x043587cf;0x04358394;false;false">Bitcoin (testnet)</option>
@@ -1388,8 +1420,14 @@
<p class="text-muted">Select the network you wish to broadcast the transaction via</p> <p class="text-muted">Select the network you wish to broadcast the transaction via</p>
<select class="form-control" id="coinjs_broadcast"> <select class="form-control" id="coinjs_broadcast">
<option value="coinb.in">coinb.in (Bitcoin mainnet)</option> <option value="coinb.in">coinb.in (Bitcoin mainnet)</option>
<option value="chain.so_bitcoinmainnet"> Chain.so (Bitcoin mainnet)</option>
<option value="blockcypher_bitcoinmainnet"> Blockcypher.com (Bitcoin mainnet)</option> <option value="blockcypher_bitcoinmainnet"> Blockcypher.com (Bitcoin mainnet)</option>
<option value="blockcypher_litecoin"> Blockcypher.com (Litecoin)</option>
<option value="blockcypher_dogecoin"> Blockcypher.com (Dogecoin)</option>
<option value="blockchair_bitcoinmainnet"> Blockchair.com (Bitcoin mainnet)</option>
<option value="blockchair_litecoin"> Blockchair.com (Litecoin)</option>
<option value="blockchair_dogecoin"> Blockchair.com (Dogecoin)</option>
<option value="chain.so_bitcoinmainnet"> Chain.so (Bitcoin mainnet)</option>
<option value="chain.so_litecoin"> Chain.so (Litecoin)</option>
<option value="chain.so_dogecoin"> Chain.so (Dogecoin)</option> <option value="chain.so_dogecoin"> Chain.so (Dogecoin)</option>
<option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option> <option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option>
</select> </select>
@@ -1404,6 +1442,13 @@
<p class="text-muted">Select the network you wish to retreive your unspent inputs from</p> <p class="text-muted">Select the network you wish to retreive your unspent inputs from</p>
<select class="form-control" id="coinjs_utxo"> <select class="form-control" id="coinjs_utxo">
<option value="coinb.in">coinb.in (Bitcoin mainnet)</option> <option value="coinb.in">coinb.in (Bitcoin mainnet)</option>
<option value="blockcypher_bitcoinmainnet"> Blockcypher.com (Bitcoin mainnet)</option>
<option value="blockcypher_litecoin"> Blockcypher.com (Litecoin)</option>
<option value="blockcypher_dogecoin"> Blockcypher.com (Dogecoin)</option>
<option value="blockchair_bitcoinmainnet"> Blockchair.com (Bitcoin mainnet)</option>
<option value="blockchair_litecoin"> Blockchair.com (Litecoin)</option>
<option value="blockchair_dogecoin"> Blockchair.com (Dogecoin)</option>
<option value="chain.so_bitcoinmainnet"> Chain.so (Bitcoin mainnet)</option>
<option value="chain.so_litecoin"> Chain.so (Litecoin)</option> <option value="chain.so_litecoin"> Chain.so (Litecoin)</option>
<option value="chain.so_dogecoin"> Chain.so (Dogecoin)</option> <option value="chain.so_dogecoin"> Chain.so (Dogecoin)</option>
<option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option> <option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option>
@@ -1430,7 +1475,7 @@
<div id="footer"> <div id="footer">
<div class="container text-right"> <div class="container text-right">
<p class="text-muted">Version 1.4</p> <p class="text-muted">Version 1.6</p>
</div> </div>
</div> </div>
+97 -17
View File
@@ -19,10 +19,11 @@
coinjs.compressed = false; coinjs.compressed = false;
/* other vars */ /* other vars */
coinjs.developer = '3K1oFZMks41C7qDYBsr72SYjapLqDuSYuN'; //bitcoin coinjs.developer = '33tht1bKDgZVxb39MnZsWa8oxHXHvUYE4G'; //bitcoin
/* bit(coinb.in) api vars */ /* bit(coinb.in) api vars */
coinjs.host = ('https:'==document.location.protocol?'https://':'http://')+'coinb.in/api/'; coinjs.hostname = ((document.location.hostname.split(".")[(document.location.hostname.split(".")).length-1]) == 'onion') ? '4zpinp6gdkjfplhk.onion' : 'coinb.in';
coinjs.host = ('https:'==document.location.protocol?'https://':'http://')+coinjs.hostname+'/api/';
coinjs.uid = '1'; coinjs.uid = '1';
coinjs.key = '12345678901234567890123456789012'; coinjs.key = '12345678901234567890123456789012';
@@ -155,7 +156,11 @@
} }
var s = coinjs.script(); var s = coinjs.script();
s.writeBytes(coinjs.numToByteArray(checklocktimeverify)); if (checklocktimeverify <= 16 && checklocktimeverify >= 1) {
s.writeOp(0x50 + checklocktimeverify);//OP_1 to OP_16 for minimal encoding
} else {
s.writeBytes(coinjs.numToScriptNumBytes(checklocktimeverify));
}
s.writeOp(177);//OP_CHECKLOCKTIMEVERIFY s.writeOp(177);//OP_CHECKLOCKTIMEVERIFY
s.writeOp(117);//OP_DROP s.writeOp(117);//OP_DROP
s.writeBytes(Crypto.util.hexToBytes(pubkey)); s.writeBytes(Crypto.util.hexToBytes(pubkey));
@@ -198,7 +203,7 @@
var decode = coinjs.bech32_decode(address); var decode = coinjs.bech32_decode(address);
if(decode){ if(decode){
decode.data.shift(); decode.data.shift();
return Crypto.util.bytesToHex(coinjs.bech32_convert(decode.data, 5, 8, true)); return Crypto.util.bytesToHex(coinjs.bech32_convert(decode.data, 5, 8, false));
} }
return r; return r;
} }
@@ -302,7 +307,7 @@
return o; return o;
} else { } else {
return false; throw "Invalid checksum";
} }
} catch(e) { } catch(e) {
bech32rs = coinjs.bech32redeemscript(addr); bech32rs = coinjs.bech32redeemscript(addr);
@@ -633,6 +638,8 @@
coinjs.compressed = c; // reset to default coinjs.compressed = c; // reset to default
} }
return r;
} }
// extend prv/pub key // extend prv/pub key
@@ -646,8 +653,37 @@
'pubkey':this.keys.pubkey}); 'pubkey':this.keys.pubkey});
} }
// derive from path
r.derive_path = function(path) {
if( path == 'm' || path == 'M' || path == 'm\'' || path == 'M\'' ) return this;
var p = path.split('/');
var hdp = coinjs.clone(this); // clone hd path
for( var i in p ) {
if((( i == 0 ) && c != 'm') || i == 'remove'){
continue;
}
var c = p[i];
var use_private = (c.length > 1) && (c[c.length-1] == '\'');
var child_index = parseInt(use_private ? c.slice(0, c.length - 1) : c) & 0x7fffffff;
if(use_private)
child_index += 0x80000000;
hdp = hdp.derive(child_index);
var key = ((hdp.keys_extended.privkey) && hdp.keys_extended.privkey!='') ? hdp.keys_extended.privkey : hdp.keys_extended.pubkey;
hdp = coinjs.hd(key);
}
return hdp;
}
// derive key from index // derive key from index
r.derive = function(i){ r.derive = function(i){
i = (i)?i:0; i = (i)?i:0;
var blob = (Crypto.util.hexToBytes(this.keys.pubkey)).concat(coinjs.numToBytes(i,4).reverse()); var blob = (Crypto.util.hexToBytes(this.keys.pubkey)).concat(coinjs.numToBytes(i,4).reverse());
@@ -702,7 +738,6 @@
o.parent_fingerprint = (ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(r.keys.pubkey),{asBytes:true}),{asBytes:true})).slice(0,4); o.parent_fingerprint = (ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(r.keys.pubkey),{asBytes:true}),{asBytes:true})).slice(0,4);
o.keys_extended = o.extend(); o.keys_extended = o.extend();
return o; return o;
} }
@@ -767,8 +802,7 @@
return o; return o;
} }
r.parse(); return r.parse();
return r;
} }
@@ -846,6 +880,9 @@
var multi = coinjs.pubkeys2MultisigAddress(pubkeys, r.signaturesRequired); var multi = coinjs.pubkeys2MultisigAddress(pubkeys, r.signaturesRequired);
r.address = multi['address']; r.address = multi['address'];
r.type = 'multisig__'; // using __ for now to differentiat from the other object .type == "multisig" r.type = 'multisig__'; // using __ for now to differentiat from the other object .type == "multisig"
var rs = Crypto.util.bytesToHex(s.buffer);
r.redeemscript = rs;
} else if((s.chunks.length==2) && (s.buffer[0] == 0 && s.buffer[1] == 20)){ // SEGWIT } else if((s.chunks.length==2) && (s.buffer[0] == 0 && s.buffer[1] == 20)){ // SEGWIT
r = {}; r = {};
r.type = "segwit__"; r.type = "segwit__";
@@ -859,6 +896,8 @@
r.pubkey = Crypto.util.bytesToHex(s.chunks[3]); r.pubkey = Crypto.util.bytesToHex(s.chunks[3]);
r.checklocktimeverify = coinjs.bytesToNum(s.chunks[0].slice()); r.checklocktimeverify = coinjs.bytesToNum(s.chunks[0].slice());
r.address = coinjs.simpleHodlAddress(r.pubkey, r.checklocktimeverify).address; r.address = coinjs.simpleHodlAddress(r.pubkey, r.checklocktimeverify).address;
var rs = Crypto.util.bytesToHex(s.buffer);
r.redeemscript = rs;
r.type = "hodl__"; r.type = "hodl__";
} }
} catch(e) { } catch(e) {
@@ -1028,12 +1067,16 @@
coinjs.ajax(coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=addresses&request=unspent&address='+address+'&r='+Math.random(), callback, "GET"); coinjs.ajax(coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=addresses&request=unspent&address='+address+'&r='+Math.random(), callback, "GET");
} }
/* list transaction data */
r.getTransaction = function(txid, callback) {
coinjs.ajax(coinjs.host+'?uid='+coinjs.uid+'&key='+coinjs.key+'&setmodule=bitcoin&request=gettransaction&txid='+txid+'&r='+Math.random(), callback, "GET");
}
/* add unspent to transaction */ /* add unspent to transaction */
r.addUnspent = function(address, callback, script, segwit, sequence){ r.addUnspent = function(address, callback, script, segwit, sequence){
var self = this; var self = this;
this.listUnspent(address, function(data){ this.listUnspent(address, function(data){
var s = coinjs.script(); var s = coinjs.script();
var pubkeyScript = s.pubkeyHash(address);
var value = 0; var value = 0;
var total = 0; var total = 0;
var x = {}; var x = {};
@@ -1298,7 +1341,14 @@
return {'type':'segwit', 'signed':signed, 'signatures': sigs, 'script': Crypto.util.bytesToHex(this.ins[index].script.chunks[0]), 'value': value}; return {'type':'segwit', 'signed':signed, 'signatures': sigs, 'script': Crypto.util.bytesToHex(this.ins[index].script.chunks[0]), 'value': value};
} else if (this.ins[index].script.chunks[0]==0 && this.ins[index].script.chunks[this.ins[index].script.chunks.length-1][this.ins[index].script.chunks[this.ins[index].script.chunks.length-1].length-1]==174) { // OP_CHECKMULTISIG } else if (this.ins[index].script.chunks[0]==0 && this.ins[index].script.chunks[this.ins[index].script.chunks.length-1][this.ins[index].script.chunks[this.ins[index].script.chunks.length-1].length-1]==174) { // OP_CHECKMULTISIG
// multisig script, with signature(s) included // multisig script, with signature(s) included
return {'type':'multisig', 'signed':'true', 'signatures':this.ins[index].script.chunks.length-2, 'script': Crypto.util.bytesToHex(this.ins[index].script.chunks[this.ins[index].script.chunks.length-1])}; sigcount = 0;
for(i=1; i<this.ins[index].script.chunks.length-1;i++){
if(this.ins[index].script.chunks[i]!=0){
sigcount++;
}
}
return {'type':'multisig', 'signed':'true', 'signatures':sigcount, 'script': Crypto.util.bytesToHex(this.ins[index].script.chunks[this.ins[index].script.chunks.length-1])};
} else if (this.ins[index].script.chunks[0]>=80 && this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]==174) { // OP_CHECKMULTISIG } else if (this.ins[index].script.chunks[0]>=80 && this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]==174) { // OP_CHECKMULTISIG
// multisig script, without signature! // multisig script, without signature!
return {'type':'multisig', 'signed':'false', 'signatures':0, 'script': Crypto.util.bytesToHex(this.ins[index].script.buffer)}; return {'type':'multisig', 'signed':'false', 'signatures':0, 'script': Crypto.util.bytesToHex(this.ins[index].script.buffer)};
@@ -1550,10 +1600,20 @@
if(!witness_used.includes(y)){ if(!witness_used.includes(y)){
var sw = coinjs.segwitAddress(this.witness[y][1]); var sw = coinjs.segwitAddress(this.witness[y][1]);
var b32 = coinjs.bech32Address(this.witness[y][1]); var b32 = coinjs.bech32Address(this.witness[y][1]);
if((sw['redeemscript'] == Crypto.util.bytesToHex(this.ins[i].script.chunks[0])) || (b32['redeemscript'] == Crypto.util.bytesToHex(this.ins[i].script.chunks[0]))){ var rs = '';
if(this.ins[i].script.chunks.length>=1){
rs = Crypto.util.bytesToHex(this.ins[i].script.chunks[0]);
} else if (this.ins[i].script.chunks.length==0){
rs = b32['redeemscript'];
}
if((sw['redeemscript'] == rs) || (b32['redeemscript'] == rs)){
witness_order.push(this.witness[y]); witness_order.push(this.witness[y]);
witness_used.push(y); witness_used.push(y);
if(b32['redeemscript'] == Crypto.util.bytesToHex(this.ins[i].script.chunks[0])){
// bech32, empty redeemscript
if(b32['redeemscript'] == rs){
this.ins[index].script = coinjs.script(); this.ins[index].script = coinjs.script();
} }
break; break;
@@ -1561,6 +1621,7 @@
} }
} }
} }
this.witness = witness_order; this.witness = witness_order;
} }
} }
@@ -1908,12 +1969,31 @@
} }
} }
coinjs.numToByteArray = function(num) { function scriptNumSize(i) {
if (num <= 256) { return i > 0x7fffffff ? 5
return [num]; : i > 0x7fffff ? 4
} else { : i > 0x7fff ? 3
return [num % 256].concat(coinjs.numToByteArray(Math.floor(num / 256))); : i > 0x7f ? 2
: i > 0x00 ? 1
: 0;
}
coinjs.numToScriptNumBytes = function(_number) {
var value = Math.abs(_number);
var size = scriptNumSize(value);
var result = [];
for (var i = 0; i < size; ++i) {
result.push(0);
} }
var negative = _number < 0;
for (i = 0; i < size; ++i) {
result[i] = value & 0xff;
value = Math.floor(value / 256);
}
if (negative) {
result[size - 1] |= 0x80;
}
return result;
} }
coinjs.numToVarInt = function(num) { coinjs.numToVarInt = function(num) {
+304 -94
View File
@@ -37,11 +37,17 @@ $(document).ready(function() {
$("#walletKeys .walletSegWitRS").addClass("hidden"); $("#walletKeys .walletSegWitRS").addClass("hidden");
if($("#walletSegwit").is(":checked")){ if($("#walletSegwit").is(":checked")){
var sw = coinjs.segwitAddress(pubkey); if($("#walletSegwitBech32").is(":checked")){
address = sw.address; var sw = coinjs.bech32Address(pubkey);
address = sw.address;
} else {
var sw = coinjs.segwitAddress(pubkey);
address = sw.address;
}
$("#walletKeys .walletSegWitRS").removeClass("hidden"); $("#walletKeys .walletSegWitRS").removeClass("hidden");
$("#walletKeys .walletSegWitRS input:text").val(sw.redeemscript); $("#walletKeys .walletSegWitRS input:text").val(sw.redeemscript);
} }
$("#walletAddress").html(address); $("#walletAddress").html(address);
@@ -59,7 +65,6 @@ $(document).ready(function() {
$("#openWallet").removeClass("hidden").show(); $("#openWallet").removeClass("hidden").show();
walletBalance(); walletBalance();
checkBalanceLoop();
} else { } else {
$("#openLoginStatus").html("Your passwords do not match!").removeClass("hidden").fadeOut().fadeIn(); $("#openLoginStatus").html("Your passwords do not match!").removeClass("hidden").fadeOut().fadeIn();
} }
@@ -94,9 +99,25 @@ $(document).ready(function() {
$("#openLoginStatus").html("").hide(); $("#openLoginStatus").html("").hide();
}); });
$("#walletSegwit").click(function(){
if($(this).is(":checked")){
$(".walletSegwitType").attr('disabled',false);
} else {
$(".walletSegwitType").attr('disabled',true);
}
});
$("#walletToSegWit").click(function(){ $("#walletToSegWit").click(function(){
$("#walletToBtn").html('SegWit <span class="caret"></span>'); $("#walletToBtn").html('SegWit <span class="caret"></span>');
$("#walletSegwit")[0].checked = true; $("#walletSegwit")[0].checked = true;
$("#walletSegwitp2sh")[0].checked = true;
$("#openBtn").click();
});
$("#walletToSegWitBech32").click(function(){
$("#walletToBtn").html('Bech32 <span class="caret"></span>');
$("#walletSegwit")[0].checked = true;
$("#walletSegwitBech32")[0].checked = true;
$("#openBtn").click(); $("#openBtn").click();
}); });
@@ -106,13 +127,12 @@ $(document).ready(function() {
$("#openBtn").click(); $("#openBtn").click();
}); });
$("#walletShowKeys").click(function(){ $("#walletShowKeys").click(function(){
$("#walletKeys").removeClass("hidden"); $("#walletKeys").removeClass("hidden");
$("#walletSpend").removeClass("hidden").addClass("hidden"); $("#walletSpend").removeClass("hidden").addClass("hidden");
}); });
$("#walletBalance").click(function(){ $("#walletBalance, #walletAddress, #walletQrCode").click(function(){
walletBalance(); walletBalance();
}); });
@@ -142,11 +162,15 @@ $(document).ready(function() {
var script = false; var script = false;
if($("#walletSegwit").is(":checked")){ if($("#walletSegwit").is(":checked")){
var sw = coinjs.segwitAddress($("#walletKeys .pubkey").val()); if($("#walletSegwitBech32").is(":checked")){
var sw = coinjs.bech32Address($("#walletKeys .pubkey").val());
} else {
var sw = coinjs.segwitAddress($("#walletKeys .pubkey").val());
}
script = sw.redeemscript; script = sw.redeemscript;
} }
var sequence = false; var sequence = 0xffffffff-1;
if($("#walletRBF").is(":checked")){ if($("#walletRBF").is(":checked")){
sequence = 0xffffffff-2; sequence = 0xffffffff-2;
} }
@@ -272,28 +296,20 @@ $(document).ready(function() {
}); });
function walletBalance(){ function walletBalance(){
var tx = coinjs.transaction(); if($("#walletLoader").hasClass("hidden")){
$("#walletLoader").removeClass("hidden"); var tx = coinjs.transaction();
coinjs.addressBalance($("#walletAddress").html(),function(data){ $("#walletLoader").removeClass("hidden");
if($(data).find("result").text()==1){ coinjs.addressBalance($("#walletAddress").html(),function(data){
var v = $(data).find("balance").text()/100000000; if($(data).find("result").text()==1){
$("#walletBalance").html(v+" BTC").attr('rel',v).fadeOut().fadeIn(); var v = $(data).find("balance").text()/100000000;
} else { $("#walletBalance").html(v+" BTC").attr('rel',v).fadeOut().fadeIn();
} else {
$("#walletBalance").html("0.00 BTC").attr('rel',v).fadeOut().fadeIn(); $("#walletBalance").html("0.00 BTC").attr('rel',v).fadeOut().fadeIn();
} }
$("#walletLoader").addClass("hidden"); $("#walletLoader").addClass("hidden");
}); });
} }
function checkBalanceLoop(){
clearTimeout(wallet_timer);
wallet_timer = setTimeout(function(){
if($("#walletLoader").hasClass("hidden")){
walletBalance();
}
checkBalanceLoop();
},45000);
} }
/* new -> address code */ /* new -> address code */
@@ -319,7 +335,22 @@ $(document).ready(function() {
$("#aes256passStatus").removeClass("hidden"); $("#aes256passStatus").removeClass("hidden");
} }
$("#newPrivKeyEnc").val(CryptoJS.AES.encrypt(coin.wif, $("#aes256pass").val())+''); $("#newPrivKeyEnc").val(CryptoJS.AES.encrypt(coin.wif, $("#aes256pass").val())+'');
});
$("#newPaperwalletBtn").click(function(){
if($("#newBitcoinAddress").val()==""){
$("#newKeysBtn").click();
}
var paperwallet = window.open();
paperwallet.document.write('<h2>BTC PaperWallet</h2><hr><div style="margin-top: 5px; margin-bottom: 5px"><div><h3 style="margin-top: 0">Address (Share)</h3></div><div style="text-align: center;"><div id="qraddress"></div><p>'+$("#newBitcoinAddress").val()+'</p></div></div><hr><div style="margin-top: 5px; margin-bottom: 5px"><div><h3 style="margin-top: 0">Public Key</h3></div><div style="text-align: center;"><div id="qrpubkey"></div><p>'+$("#newPubKey").val()+'</p></div></div><hr><div style="margin-top: 5px; margin-bottom: 5px"><div><h3 style="margin-top: 0">Private Key (KEEP SECRET!)</h3></div><div style="text-align: center;"><div id="qrprivkey"></div><p>'+$("#newPrivKey").val()+'</p></div></div>');
paperwallet.document.close();
paperwallet.focus();
new QRCode(paperwallet.document.getElementById("qraddress"), {text: $("#newBitcoinAddress").val(), width: 125, height: 125});
new QRCode(paperwallet.document.getElementById("qrpubkey"), {text: $("#newPubKey").val(), width: 125, height: 125});
new QRCode(paperwallet.document.getElementById("qrprivkey"), {text: $("#newPrivKey").val(), width: 125, height: 125});
paperwallet.print();
paperwallet.close();
}); });
$("#newBrainwallet").click(function(){ $("#newBrainwallet").click(function(){
@@ -367,6 +398,22 @@ $(document).ready(function() {
coinjs.compressed = compressed; coinjs.compressed = compressed;
}); });
$("#newSegwitPaperwalletBtn").click(function(){
if($("#newSegWitAddress").val()==""){
$("#newSegWitKeysBtn").click();
}
var paperwallet = window.open();
paperwallet.document.write('<h2>BTC SegWit PaperWallet</h2><hr><div style="margin-top: 5px; margin-bottom: 5px"><div><h3 style="margin-top: 0">Address (Share)</h3></div><div style="text-align: center;"><div id="qraddress"></div><p>'+$("#newSegWitAddress").val()+'</p></div></div><hr><div style="margin-top: 5px; margin-bottom: 5px"><div><h3 style="margin-top: 0">Public Key</h3></div><div style="text-align: center;"><div id="qrpubkey"></div><p>'+$("#newSegWitPubKey").val()+'</p></div></div><hr><div style="margin-top: 5px; margin-bottom: 5px"><div><h3 style="margin-top: 0">Redeem Script</h3></div><div style="text-align: center;"><div id="qrredeem"></div><p>'+$("#newSegWitRedeemScript").val()+'</p></div></div><hr><div style="margin-top: 5px; margin-bottom: 5px"><div><h3 style="margin-top: 0">Private Key (KEEP SECRET!)</h3></div><div style="text-align: center;"><div id="qrprivkey"></div><p>'+$("#newSegWitPrivKey").val()+'</p></div></div>');
paperwallet.document.close();
paperwallet.focus();
new QRCode(paperwallet.document.getElementById("qraddress"), {text: $("#newSegWitAddress").val(), width: 110, height: 110});
new QRCode(paperwallet.document.getElementById("qrpubkey"), {text: $("#newSegWitPubKey").val(), width: 110, height: 110});
new QRCode(paperwallet.document.getElementById("qrredeem"), {text: $("#newSegWitRedeemScript").val(), width: 110, height: 110});
new QRCode(paperwallet.document.getElementById("qrprivkey"), {text: $("#newSegWitPrivKey").val(), width: 110, height: 110});
paperwallet.print();
paperwallet.close();
});
/* new -> multisig code */ /* new -> multisig code */
@@ -600,7 +647,7 @@ $(document).ready(function() {
} }
if(!$(o).hasClass("has-error")){ if(!$(o).hasClass("has-error")){
var seq = null; var seq = 0xffffffff-1;
if($("#txRBF").is(":checked")){ if($("#txRBF").is(":checked")){
seq = 0xffffffff-2; seq = 0xffffffff-2;
} }
@@ -699,24 +746,24 @@ $(document).ready(function() {
$.each($("#walletSpendTo .output"), function(i,o){ $.each($("#walletSpendTo .output"), function(i,o){
var addr = $('.addressTo',o); var addr = $('.addressTo',o);
var ad = coinjs.addressDecode(addr.val()); var ad = coinjs.addressDecode(addr.val());
if (ad.version == coinjs.multisig){ // p2sh if (ad.version == coinjs.pub){ // p2pkh
$("#fees .txo_p2sh").val(($("#fees .txo_p2sh").val()*1)+1);
$("#fees .txo_p2sh").trigger('input');
} else { // p2pkh
$("#fees .txo_p2pkh").val(($("#fees .txo_p2pkh").val()*1)+1); $("#fees .txo_p2pkh").val(($("#fees .txo_p2pkh").val()*1)+1);
$("#fees .txo_p2pkh").trigger('input'); $("#fees .txo_p2pkh").trigger('input');
} else { // p2psh
$("#fees .txo_p2sh").val(($("#fees .txo_p2sh").val()*1)+1);
$("#fees .txo_p2sh").trigger('input');
} }
}); });
if(($("#developerDonation").val()*1)>0){ if(($("#developerDonation").val()*1)>0){
var addr = coinjs.developer; var addr = coinjs.developer;
var ad = coinjs.addressDecode(addr); var ad = coinjs.addressDecode(addr);
if (ad.version == coinjs.multisig){ // p2sh if (ad.version == coinjs.pub){ // p2pkh
$("#fees .txo_p2pkh").val(($("#fees .txo_p2pkh").val()*1)+1);
$("#fees .txo_p2pkh").trigger('input');
} else { // p2psh
$("#fees .txo_p2sh").val(($("#fees .txo_p2sh").val()*1)+1); $("#fees .txo_p2sh").val(($("#fees .txo_p2sh").val()*1)+1);
$("#fees .txo_p2sh").trigger('input'); $("#fees .txo_p2sh").trigger('input');
} else { // p2pkh
$("#fees .txo_p2pkh").val(($("#fees .txo_p2pkh").val()*1)+1);
$("#fees .txo_p2pkh").trigger('input');
} }
} }
@@ -829,12 +876,12 @@ $(document).ready(function() {
/* redeem from button code */ /* redeem from button code */
$("#redeemFromBtn").click(function(){ $("#redeemFromBtn").click(function(){
var redeem = redeemingFrom($("#redeemFrom").val()); var redeem = redeemingFrom($("#redeemFrom").val());
$("#redeemFromStatus, #redeemFromAddress").addClass('hidden'); $("#redeemFromStatus, #redeemFromAddress").addClass('hidden');
if(redeem.from=='multisigAddress'){ if(redeem.from=='multisigAddress'){
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> You should use the redeem script, not the multisig address!'); $("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> You should use the redeem script, not its address!');
return false; return false;
} }
@@ -851,11 +898,32 @@ $(document).ready(function() {
var host = $(this).attr('rel'); var host = $(this).attr('rel');
// api: blockcypher blockchair chain.so
// network name "btc" "bitcoin" "BTC"
// network name "ltc" "litecoin" "LTC"
// network name "doge" "dogecoin" "DOGE"
if(host=='chain.so_litecoin'){ if(host=='chain.so_bitcoinmainnet'){
listUnspentChainso_Litecoin(redeem); listUnspentChainso(redeem, "BTC");
} else if(host=='chain.so_litecoin'){
listUnspentChainso(redeem, "LTC");
} else if(host=='chain.so_dogecoin'){ } else if(host=='chain.so_dogecoin'){
listUnspentChainso_Dogecoin(redeem); listUnspentChainso(redeem, "DOGE");
} else if(host=='blockcypher_bitcoinmainnet'){
listUnspentBlockcypher(redeem, "btc");
} else if(host=='blockcypher_litecoin'){
listUnspentBlockcypher(redeem, "ltc");
} else if(host=='blockcypher_dogecoin'){
listUnspentBlockcypher(redeem, "doge");
} else if(host=='blockchair_bitcoinmainnet'){
listUnspentBlockchair(redeem, "bitcoin");
} else if(host=='blockchair_litecoin'){
listUnspentBlockchair(redeem, "litecoin");
} else if(host=='blockchair_dogecoin'){
listUnspentBlockchair(redeem, "dogecoin");
} else if(host=='cryptoid.info_carboncoin'){ } else if(host=='cryptoid.info_carboncoin'){
listUnspentCryptoidinfo_Carboncoin(redeem); listUnspentCryptoidinfo_Carboncoin(redeem);
} else { } else {
@@ -864,8 +932,8 @@ $(document).ready(function() {
if($("#redeemFromStatus").hasClass("hidden")) { if($("#redeemFromStatus").hasClass("hidden")) {
// An ethical dilemma: Should we automatically set nLockTime? // An ethical dilemma: Should we automatically set nLockTime?
if(redeem.from == 'redeemScript' && redeem.decodedRs.type == "hodl__") { if(redeem.from == 'redeemScript' && redeem.type == "hodl__") {
$("#nLockTime").val(redeem.decodedRs.checklocktimeverify); $("#nLockTime").val(redeem.decodescript.checklocktimeverify);
} else { } else {
$("#nLockTime").val(0); $("#nLockTime").val(0);
} }
@@ -901,11 +969,19 @@ $(document).ready(function() {
r.addr = decodeRs['address']; r.addr = decodeRs['address'];
r.from = 'redeemScript'; r.from = 'redeemScript';
r.decodedRs = decodeRs.redeemscript; r.decodedRs = decodeRs.redeemscript;
r.type = decodeRs['type'];
r.redeemscript = true; r.redeemscript = true;
r.decodescript = decodeRs;
} else { // something else } else { // something else
r.addr = ''; if(string.match(/^[a-f0-9]{64}$/i)){
r.from = 'other'; r.addr = string;
r.redeemscript = false; r.from = 'txid';
r.redeemscript = false;
} else {
r.addr = '';
r.from = 'other';
r.redeemscript = false;
}
} }
} }
return r; return r;
@@ -972,9 +1048,61 @@ $(document).ready(function() {
} }
} }
/* global function to add inputs to page */
function addInput(address, amount) {
if($("#recipients .recipient:last .address:last").val() != ""){
$("#recipients .addressAddTo:first").click();
};
$("#recipients .address:last").val(address);
$("#recipients .amount:last").val(amount);
}
/* default function to retreive unspent outputs*/ /* default function to retreive unspent outputs*/
function listUnspentDefault(redeem){ function listUnspentDefault(redeem){
var tx = coinjs.transaction(); var tx = coinjs.transaction();
// unspent from transaction; double spend and RBF.
if(redeem.from == 'txid'){
tx.getTransaction(redeem.addr, function(data){
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Attempted to rebuild transaction id <a href="'+explorer_tx+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
$.each($(data).find("inputs").children(), function(i,o){
var tx = $(o).find("txid").text();
var n = $(o).find("output_no").text();
var amount = (($(o).find("value").text()*1)).toFixed(8);
var script = coinjs.script();
var s = script.spendToScript($(o).find("address").text());
var scr = Crypto.util.bytesToHex(s.buffer);
addOutput(tx, n, scr, amount);
});
$("#recipients .addressRemoveTo").click();
$("#recipients .address").val("");
$("#recipients .amount").val("");
$.each($(data).find("outputs").children(), function(i,o){
addInput($(o).find("address").text(), $(o).find("value").text());
});
$("#redeemFromBtn").html("Load").attr('disabled',false);
totalInputAmount();
validateOutputAmount();
});
return;
}
// unspent from address
tx.listUnspent(redeem.addr, function(data){ tx.listUnspent(redeem.addr, function(data){
if(redeem.addr) { if(redeem.addr) {
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>'); $("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
@@ -997,25 +1125,27 @@ $(document).ready(function() {
} }
/* retrieve unspent data from chainso for litecoin */ /* retrieve unspent data from blockcypher */
function listUnspentChainso_Litecoin(redeem){ function listUnspentBlockcypher(redeem,network){
$.ajax ({ $.ajax ({
type: "GET", type: "GET",
url: "https://chain.so/api/v2/get_tx_unspent/ltc/"+redeem.addr, url: "https://api.blockcypher.com/v1/"+network+"/main/addrs/"+redeem.addr+"?includeScript=true&unspentOnly=true",
dataType: "json", dataType: "json",
error: function(data) { error: function(data) {
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!'); $("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!');
}, },
success: function(data) { success: function(data) {
if((data.status && data.data) && data.status=='success'){ if (data.address) { // address field will always be present, txrefs is only present if there are UTXOs
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>'); $("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
for(var i in data.data.txs){ for(var i in data.txrefs){
var o = data.data.txs[i]; var o = data.txrefs[i];
var tx = ((o.txid).match(/.{1,2}/g).reverse()).join("")+''; var tx = ((""+o.tx_hash).match(/.{1,2}/g).reverse()).join("")+'';
var n = o.output_no; if(tx.match(/^[a-f0-9]+$/)){
var script = (redeem.redeemscript==true) ? redeem.decodedRs : o.script_hex; var n = o.tx_output_n;
var amount = o.value; var script = (redeem.redeemscript==true) ? redeem.decodedRs : o.script;
addOutput(tx, n, script, amount); var amount = ((o.value.toString()*1)/100000000).toFixed(8);
addOutput(tx, n, script, amount);
}
} }
} else { } else {
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs.'); $("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs.');
@@ -1062,19 +1192,54 @@ $(document).ready(function() {
} }
/* retrieve unspent data from chain.so for dogecoin */
function listUnspentChainso_Dogecoin(redeem){ /* retrieve unspent data from blockchair */
function listUnspentBlockchair(redeem,network){
$.ajax ({ $.ajax ({
type: "GET", type: "GET",
url: "https://chain.so/api/v2/get_tx_unspent/doge/"+redeem.addr, url: "https://api.blockchair.com/"+network+"/dashboards/address/"+redeem.addr,
dataType: "json",
error: function(data) {
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!');
},
success: function(data) {
if((data.context && data.data) && data.context.code =='200'){
$("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
var all_info = data.data[redeem.addr];
for(var i in all_info.utxo){
var o = all_info.utxo[i];
var tx = ((""+o.transaction_hash).match(/.{1,2}/g).reverse()).join("")+'';
if(tx.match(/^[a-f0-9]+$/)){
var n = o.index;
var script = (redeem.redeemscript==true) ? redeem.decodedRs : all_info.address.script_hex;
var amount = ((o.value.toString()*1)/100000000).toFixed(8);
addOutput(tx, n, script, amount);
}
}
} else {
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs.');
}
},
complete: function(data, status) {
$("#redeemFromBtn").html("Load").attr('disabled',false);
totalInputAmount();
}
});
}
/* retrieve unspent data from chainso */
function listUnspentChainso(redeem, network){
$.ajax ({
type: "GET",
url: "https://chain.so/api/v2/get_tx_unspent/"+network+"/"+redeem.addr,
dataType: "json", dataType: "json",
error: function(data) { error: function(data) {
$("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!'); $("#redeemFromStatus").removeClass('hidden').html('<span class="glyphicon glyphicon-exclamation-sign"></span> Unexpected error, unable to retrieve unspent outputs!');
}, },
success: function(data) { success: function(data) {
if((data.status && data.data) && data.status=='success'){ if((data.status && data.data) && data.status=='success'){
$("#redeemFromAddress").removeClass('hidden').html( $("#redeemFromAddress").removeClass('hidden').html('<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
'<span class="glyphicon glyphicon-info-sign"></span> Retrieved unspent inputs from address <a href="'+explorer_addr+redeem.addr+'" target="_blank">'+redeem.addr+'</a>');
for(var i in data.data.txs){ for(var i in data.data.txs){
var o = data.data.txs[i]; var o = data.data.txs[i];
var tx = ((""+o.txid).match(/.{1,2}/g).reverse()).join("")+''; var tx = ((""+o.txid).match(/.{1,2}/g).reverse()).join("")+'';
@@ -1096,6 +1261,7 @@ $(document).ready(function() {
}); });
} }
/* math to calculate the inputs and outputs */ /* math to calculate the inputs and outputs */
function totalInputAmount(){ function totalInputAmount(){
@@ -1155,7 +1321,7 @@ $(document).ready(function() {
rawSubmitDefault(this); rawSubmitDefault(this);
}); });
// broadcast transaction vai coinbin (default) // broadcast transaction via coinbin (default)
function rawSubmitDefault(btn){ function rawSubmitDefault(btn){
var thisbtn = btn; var thisbtn = btn;
$(thisbtn).val('Please wait, loading...').attr('disabled',true); $(thisbtn).val('Please wait, loading...').attr('disabled',true);
@@ -1170,8 +1336,7 @@ $(document).ready(function() {
success: function(data) { success: function(data) {
$("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden'); $("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden');
if($(data).find("result").text()==1){ if($(data).find("result").text()==1){
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger'); $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' TXID: ' + $(data).find("txid").text() + '<br> <a href="https://coinb.in/tx/' + $(data).find("txid").text() + '" target="_blank">View on Blockchain</a>');
$("#rawTransactionStatus").html('txid: '+$(data).find("txid").text());
} else { } else {
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span> '); $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span> ');
} }
@@ -1197,8 +1362,7 @@ $(document).ready(function() {
success: function(data) { success: function(data) {
$("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden'); $("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden');
if($(data).find("result").text()==1){ if($(data).find("result").text()==1){
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger'); $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' TXID: ' + $(data).find("txid").text() + '<br> <a href="https://chainz.cryptoid.info/carbon/tx.dws?' + $(data).find("txid").text() + '" target="_blank">View on Blockchain Explorer</a>');
$("#rawTransactionStatus").html('txid: '+$(data).find("txid").text());
} else { } else {
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span> '); $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span> ');
} }
@@ -1211,11 +1375,11 @@ $(document).ready(function() {
} }
// broadcast transaction via chain.so (mainnet) // broadcast transaction via chain.so (mainnet)
function rawSubmitChainso_BitcoinMainnet(thisbtn){ function rawSubmitChainso(thisbtn, network){
$(thisbtn).val('Please wait, loading...').attr('disabled',true); $(thisbtn).val('Please wait, loading...').attr('disabled',true);
$.ajax ({ $.ajax ({
type: "POST", type: "POST",
url: "https://chain.so/api/v2/send_tx/BTC/", url: "https://chain.so/api/v2/send_tx/"+network+"/",
data: {"tx_hex":$("#rawTransaction").val()}, data: {"tx_hex":$("#rawTransaction").val()},
dataType: "json", dataType: "json",
error: function(data) { error: function(data) {
@@ -1227,7 +1391,7 @@ $(document).ready(function() {
}, },
success: function(data) { success: function(data) {
if(data.status && data.data.txid){ if(data.status && data.data.txid){
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.data.txid); $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' TXID: ' + data.data.txid + '<br> <a href="https://chain.so/tx/'+network+'/' + data.data.txid + '" target="_blank">View on Blockchain Explorer</a>');
} else { } else {
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>'); $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
} }
@@ -1240,22 +1404,20 @@ $(document).ready(function() {
} }
// broadcast transaction via blockcypher.com (mainnet) // broadcast transaction via blockcypher.com (mainnet)
function rawSubmitblockcypher_BitcoinMainnet(thisbtn){ function rawSubmitblockcypher(thisbtn, network){
$(thisbtn).val('Please wait, loading...').attr('disabled',true); $(thisbtn).val('Please wait, loading...').attr('disabled',true);
$.ajax ({ $.ajax ({
type: "POST", type: "POST",
url: "https://api.blockcypher.com/v1/btc/main/txs/push", url: "https://api.blockcypher.com/v1/"+network+"/main/txs/push",
data: JSON.stringify({"tx":$("#rawTransaction").val()}), data: JSON.stringify({"tx":$("#rawTransaction").val()}),
error: function(data) { error: function(data) {
var obj = $.parseJSON(data.responseText); var r = 'Failed to broadcast: error code=' + data.status.toString() + ' ' + data.statusText;
var r = ' ';
r += (obj.error) ? obj.error : '';
r = (r!='') ? r : ' Failed to broadcast'; // build response
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>'); $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
}, },
success: function(data) { success: function(data) {
if((data.tx) && data.tx.hash){ if((data.tx) && data.tx.hash){
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: '+data.tx.hash); $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden")
.html(' TXID: ' + data.tx.hash + '<br> <a href="https://live.blockcypher.com/'+network+'/tx/' + data.tx.hash + '" target="_blank">View on Blockchain Explorer</a>');
} else { } else {
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>'); $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
} }
@@ -1267,27 +1429,24 @@ $(document).ready(function() {
}); });
} }
// broadcast transaction via blockchair
// broadcast transaction via chain.so for dogecoin function rawSubmitblockchair(thisbtn, network){
function rawSubmitchainso_dogecoin(thisbtn){
$(thisbtn).val('Please wait, loading...').attr('disabled',true); $(thisbtn).val('Please wait, loading...').attr('disabled',true);
$.ajax ({ $.ajax ({
type: "POST", type: "POST",
url: "https://chain.so/api/v2/send_tx/DOGE", url: "https://api.blockchair.com/"+network+"/push/transaction",
data: {"tx_hex":$("#rawTransaction").val()}, data: {"data":$("#rawTransaction").val()},
dataType: "json", dataType: "json",
error: function(data) { error: function(data) {
var obj = $.parseJSON(data.responseText); var r = 'Failed to broadcast: error code=' + data.status.toString() + ' ' + data.statusText;
var r = ' ';
r += (obj.data.tx_hex) ? ' '+obj.data.tx_hex : '';
r = (r!='') ? r : ' Failed to broadcast'; // build response
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>'); $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
// console.error(JSON.stringify(data, null, 4)); // console.error(JSON.stringify(data, null, 4));
}, },
success: function(data) { success: function(data) {
// console.info(JSON.stringify(data, null, 4)); // console.info(JSON.stringify(data, null, 4));
if((data.status && data.data) && data.status=='success'){ if((data.context && data.data) && data.context.code=='200'){
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: ' + data.data.txid); $("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden")
.html(' TXID: ' + data.data.transaction_hash + '<br> <a href="https://blockchair.com/'+network+'/transaction/' + data.data.transaction_hash + '" target="_blank">View on Blockchain Explorer</a>');
} else { } else {
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>'); $("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
} }
@@ -1549,7 +1708,11 @@ $(document).ready(function() {
var html = ''; var html = '';
$("#verifyHDaddress .derived_data table tbody").html(""); $("#verifyHDaddress .derived_data table tbody").html("");
for(var i=index_start;i<=index_end;i++){ for(var i=index_start;i<=index_end;i++){
var derived = hd.derive(i); if($("#hdpathtype option:selected").val()=='simple'){
var derived = hd.derive(i);
} else {
var derived = hd.derive_path(($("#hdpath input").val().replace(/\/+$/, ""))+'/'+i);
}
html += '<tr>'; html += '<tr>';
html += '<td>'+i+'</td>'; html += '<td>'+i+'</td>';
html += '<td><input type="text" class="form-control" value="'+derived.keys.address+'" readonly></td>'; html += '<td><input type="text" class="form-control" value="'+derived.keys.address+'" readonly></td>';
@@ -1562,6 +1725,15 @@ $(document).ready(function() {
} }
$("#hdpathtype").change(function(){
if($(this).val()=='simple'){
$("#hdpath").removeClass().addClass("hidden");
} else {
$("#hdpath").removeClass();
}
});
/* sign code */ /* sign code */
$("#signBtn").click(function(){ $("#signBtn").click(function(){
@@ -1692,7 +1864,7 @@ $(document).ready(function() {
$('a[data-toggle="tab"]').on('click', function(e) { $('a[data-toggle="tab"]').on('click', function(e) {
e.preventDefault(); e.preventDefault();
if(e.target){ if(e.target && $(e.target).attr('href')) {
history.pushState(null, null, '#'+$(e.target).attr('href').substr(1)); history.pushState(null, null, '#'+$(e.target).attr('href').substr(1));
} }
}); });
@@ -1747,6 +1919,14 @@ $(document).ready(function() {
configureBroadcast(); configureBroadcast();
configureGetUnspentTx(); configureGetUnspentTx();
if (coinjs.pub == 0x30){ // LTC
explorer_addr = "https://chain.so/address/LTC/";
coinjs.bech32.hrp = "ltc";
}
else if (coinjs.pub == 0x1e){ // DOGE
explorer_addr = "https://chain.so/address/DOGE/";
}
$("#statusSettings").addClass("alert-success").removeClass("hidden").html("<span class=\"glyphicon glyphicon-ok\"></span> Settings updates successfully").fadeOut().fadeIn(); $("#statusSettings").addClass("alert-success").removeClass("hidden").html("<span class=\"glyphicon glyphicon-ok\"></span> Settings updates successfully").fadeOut().fadeIn();
} else { } else {
$("#statusSettings").addClass("alert-danger").removeClass("hidden").html("There is an error with one or more of your settings"); $("#statusSettings").addClass("alert-danger").removeClass("hidden").html("There is an error with one or more of your settings");
@@ -1792,18 +1972,48 @@ $(document).ready(function() {
function configureBroadcast(){ function configureBroadcast(){
var host = $("#coinjs_broadcast option:selected").val(); var host = $("#coinjs_broadcast option:selected").val();
// api: blockcypher blockchair chain.so
// network name "btc" "bitcoin" "BTC"
// network name "ltc" "litecoin" "LTC"
// network name "doge" "dogecoin" "DOGE"
$("#rawSubmitBtn").unbind(""); $("#rawSubmitBtn").unbind("");
if(host=="chain.so_bitcoinmainnet"){ if(host=="chain.so_bitcoinmainnet"){
$("#rawSubmitBtn").click(function(){ $("#rawSubmitBtn").click(function(){
rawSubmitChainso_BitcoinMainnet(this); rawSubmitChainso(this, "BTC");
});
} else if(host=="chain.so_litecoin"){
$("#rawSubmitBtn").click(function(){
rawSubmitchainso(this, "LTC");
}); });
} else if(host=="chain.so_dogecoin"){ } else if(host=="chain.so_dogecoin"){
$("#rawSubmitBtn").click(function(){ $("#rawSubmitBtn").click(function(){
rawSubmitchainso_dogecoin(this); rawSubmitchainso(this, "DOGE");
}); });
} else if(host=="blockcypher_bitcoinmainnet"){ } else if(host=="blockcypher_bitcoinmainnet"){
$("#rawSubmitBtn").click(function(){ $("#rawSubmitBtn").click(function(){
rawSubmitblockcypher_BitcoinMainnet(this); rawSubmitblockcypher(this, "btc");
});
} else if(host=="blockcypher_litecoin"){
$("#rawSubmitBtn").click(function(){
rawSubmitblockcypher(this, "ltc");
});
} else if(host=="blockcypher_dogecoin"){
$("#rawSubmitBtn").click(function(){
rawSubmitblockcypher(this, "doge");
});
} else if(host=="blockchair_bitcoinmainnet"){
$("#rawSubmitBtn").click(function(){
rawSubmitblockchair(this, "bitcoin");
});
} else if(host=="blockchair_litecoin"){
$("#rawSubmitBtn").click(function(){
rawSubmitblockchair(this, "litecoin");
});
} else if(host=="blockchair_dogecoin"){
$("#rawSubmitBtn").click(function(){
rawSubmitblockchair(this, "dogecoin");
}); });
} else if(host=="cryptoid.info_carboncoin"){ } else if(host=="cryptoid.info_carboncoin"){
$("#rawSubmitBtn").click(function(){ $("#rawSubmitBtn").click(function(){
+6 -5
View File
@@ -1,9 +1,9 @@
---- Version 1.4 2018.05.27 --- ---- Version 1.6 2020.07.06 ----
77e4519962e2f6a9fc93342137dbb31c33b76b04 ./js/aes.js 77e4519962e2f6a9fc93342137dbb31c33b76b04 ./js/aes.js
3a09a8fc0cfe828b57fc798d668234d0490ee1a6 ./js/bootstrap-datetimepicker.min.js 3a09a8fc0cfe828b57fc798d668234d0490ee1a6 ./js/bootstrap-datetimepicker.min.js
253711c6d825de55a8360552573be950da180614 ./js/bootstrap.min.js 253711c6d825de55a8360552573be950da180614 ./js/bootstrap.min.js
dda26795fcd22541612067d44cf72ecae62f092b ./js/coinbin.js 7dd75e07389808d57261bca630a5bab55ce9faef ./js/coinbin.js
eec3c5f1c5f69a34205613f6bf62ff9cc5a8d07a ./js/coin.js 228cdcf29d33a5eadd360e85a6220e4853ee4590 ./js/coin.js
988565bc2cb402d63ed5c5fd7ff47c4278efc2c5 ./js/collapse.js 988565bc2cb402d63ed5c5fd7ff47c4278efc2c5 ./js/collapse.js
9ba5ede3d7f9d4c8fd623395f196adfdcf7e970f ./js/crypto-min.js 9ba5ede3d7f9d4c8fd623395f196adfdcf7e970f ./js/crypto-min.js
f7c09f2f5a721371e7d478050119f7e2d58e3ef9 ./js/crypto-sha256-hmac.js f7c09f2f5a721371e7d478050119f7e2d58e3ef9 ./js/crypto-sha256-hmac.js
@@ -30,5 +30,6 @@ ca35b697d99cae4d1b60f2d60fcd37771987eb07 ./fonts/glyphicons-halflings-regular.w
de51a8494180a6db074af2dee2383f0a363c5b08 ./fonts/glyphicons-halflings-regular.svg de51a8494180a6db074af2dee2383f0a363c5b08 ./fonts/glyphicons-halflings-regular.svg
278e49a86e634da6f2a02f3b47dd9d2a8f26210f ./fonts/glyphicons-halflings-regular.woff 278e49a86e634da6f2a02f3b47dd9d2a8f26210f ./fonts/glyphicons-halflings-regular.woff
44bc1850f570972267b169ae18f1cb06b611ffa2 ./fonts/glyphicons-halflings-regular.ttf 44bc1850f570972267b169ae18f1cb06b611ffa2 ./fonts/glyphicons-halflings-regular.ttf
c024021c71cba503979a859d23cbf7a88b570d82 ./README.md ee481606d8d48f402d152fa632ba9e5f9da7f169 ./README.md
208b64a1ef61aaceec82f06515e4f7cf046793f6 ./index.html 5054e03cff2cfcd1ce5296fe2659ca2d46d64fe4 ./index.html
7130b64e3ef4cf6f2f1550e902f081c58dc053de ./test.html
+379
View File
@@ -0,0 +1,379 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<!-- =================================================================== -->
<head>
<title>TESTING COINBIN</title>
<link rel="stylesheet" href="css/bootstrap.min.css" media="screen">
<link rel="stylesheet" href="css/bootstrap-datetimepicker.min.css">
<link rel="stylesheet" href="css/style.css" media="screen">
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/moment.min.js"></script>
<script type="text/javascript" src="js/transition.js"></script>
<script type="text/javascript" src="js/collapse.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/bootstrap-datetimepicker.min.js"></script>
<script type="text/javascript" src="js/crypto-min.js"></script>
<script type="text/javascript" src="js/crypto-sha256.js"></script>
<script type="text/javascript" src="js/crypto-sha256-hmac.js"></script>
<script type="text/javascript" src="js/sha512.js"></script>
<script type="text/javascript" src="js/ripemd160.js"></script>
<script type="text/javascript" src="js/aes.js"></script>
<script type="text/javascript" src="js/jsbn.js"></script>
<script type="text/javascript" src="js/ellipticcurve.js"></script>
<script type="text/javascript" src="js/coin.js"></script>
</head>
<!-- =================================================================== -->
<body>
<!-- =================================================================== -->
<div id="fwrap">
<!-- Fixed navbar -->
<div id="header" class="navbar navbar-default " role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="#home" class="navbar-brand" id="homeBtn"><img src="images/coinbin.gif" style="height:25px;margin-top:-5px"></a>
</div>
</div>
</div>
<div id="content" class="container">
<div class="tab-content">
<div class="tab-pane tab-content active" id="home">
<br />
<button id="test1Btn" class="btn btn-primary" type="submit">Run Coinbin Test Suite</button>
<br />
<textarea rows=20 cols=86 id="testResults"></textarea>
</div>
</div> <!-- content -->
</div> <!-- wrap -->
</div> <!-- navbar -->
</div> <!-- container -->
</body>
<script type="text/javascript">
$(document).ready(function() {
}); // end of document.ready
$("#test1Btn").click(function(){
{
var testName = "hex private key to compressed address";
var testInput = "0000000000000000000000000000000000000000000000000000000000000001";
var testExpected = "1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH";
coinjs.compressed = true;
var pubkeyHex = coinjs.newPubkey(testInput);
var testOutput = coinjs.pubkey2address(pubkeyHex, coinjs.pub);
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "hex private key to uncompressed address";
var testInput = "0000000000000000000000000000000000000000000000000000000000000001";
var testExpected = "1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm";
coinjs.compressed = false;
var pubkeyHex = coinjs.newPubkey(testInput);
var testOutput = coinjs.pubkey2address(pubkeyHex, coinjs.pub);
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "WIF uncompressed private key to address";
var testInput = "5J1LYLWqNxJBTwdGAmzYnpkqqSuFu48fsHv8jgojFMV2Z8exk9L";
var testExpected ="16SK7HnxBMRxSpLhhdf8RYcqv8MPJiSF6Q";
coinjs.compressed = false;
var testOutput = coinjs.wif2address(testInput).address;
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "raw private key to uncompressed base58check WIF private key";
var testInput = "62A87AD3272B41E67108FEA10C57BA6ED609F2F7A2264A83B690CD45707090D1";
var testExpected = "5JZjfs5wJv1gNkJXCmYpyj6VxciqPkwmK4yHW8zMmPN1PW7Hk7F";
coinjs.compressed = false;
var testOutput = coinjs.privkey2wif(testInput);
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "raw private key to compressed base58check WIF private key";
var testInput = "62A87AD3272B41E67108FEA10C57BA6ED609F2F7A2264A83B690CD45707090D1";
var testExpected = "KzXVLY4ni4yznz8LJwdUmNoGpUfebSxiakXRqcGAeuhihzaVe3Rz";
coinjs.compressed = true;
var testOutput = coinjs.privkey2wif(testInput);
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "hex ripemd160 hash of public key, to base58check address";
var testInput = "62E907B15CBF27D5425399EBF6F0FB50EBB88F18";
var testExpected = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa";
var testOutput = coinjs.scripthash2address(testInput);
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "base58check address, to hex ripemd160 hash of public key";
var testInput = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa";
var testExpected = "62e907b15cbf27d5425399ebf6f0fb50ebb88f18";
var bytes = coinjs.base58decode(testInput);
var front = bytes.slice(1, bytes.length-4);
var testOutput = Crypto.util.bytesToHex(front);
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "convert 'Hash 160' to address";
var testInput = "119b098e2e980a229e139a9ed01a469e518e6f26";
var testExpected = "12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX";
var testOutput = coinjs.scripthash2address(testInput);
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "convert 'SHA256' to address";
var testInput = "904b8a01c68095a9e825d28082c04b75b1f56277648256985717620e8913b79b";
var testExpected = "1JNC98D5LZbrGHFR8shDwiqLPGfpg15BUM";
var r = ripemd160(Crypto.util.hexToBytes(testInput));
r.unshift(coinjs.pub);
var hash = Crypto.SHA256(Crypto.SHA256(r, {asBytes: true}), {asBytes: true});
var checksum = hash.slice(0, 4);
var testOutput = coinjs.base58encode(r.concat(checksum));
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "convert WIF private key to address bech32";
var testInput = "L3GzRAGwCqfSNFr6g1NQm7edn29DgAKZJ6owUBqYELpP6Kbim5kM";
var testExpected = "bc1qhmc0vk4xzr37ayv7tlyhns7x4dk04tyvflk8ey";
var pubkey = coinjs.wif2pubkey(testInput);
var testOutput = coinjs.bech32Address(pubkey.pubkey).address;
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "bech32 address, to hex ripemd160 hash of public key";
var testInput = "bc1qhmc0vk4xzr37ayv7tlyhns7x4dk04tyvflk8ey";
var testExpected = "bef0f65aa610e3ee919e5fc979c3c6ab6cfaac8c";
var testOutput = coinjs.bech32redeemscript(testInput);
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "prefix1 - WIF compressed private key to address (bitcoin)";
var testInput = "Kx4VFK8gXu4qBv73x9b1KFnWYqKekkprYyfX9QhFUMQhrTUooXKc";
var testExpected = "1NFeCVtA3zuCUAmYheRvfyABnSZCHfrR3j";
var testOutput = coinjs.wif2address(testInput).address;
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "prefix2 - WIF compressed private key to address (bitcoin-testnet)";
var testInput = "92Wn1EBgiwDNT8SC7WMZfcSk2y3mQkLUPAQtwMNYZQGAzCFUTdu";
var testExpected = "mxToLbBqPcSNnqPCSnrYjFv172TFPLjVNf";
var saved = pushNetworkVars("btc-testnet");
var testOutput = coinjs.wif2address(testInput).address;
popNetworkVars(saved);
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "prefix3 - WIF compressed private key to address (litecoin)";
var testInput = "6vVAeKejJRV5wgrAqtqi7eQsS4Zf79nkw8xuYntU3JwHCiexYaJ";
var testExpected = "LMzBLYQG2opHvMBihMQgJBboxunoj5pssC";
var saved = pushNetworkVars("ltc-mainnet");
var testOutput = coinjs.wif2address(testInput).address;
popNetworkVars(saved);
addTestOutput(testName, testOutput, testExpected);
}
{
var testName = "prefix4 - WIF compressed private key to address (dogecoin)";
var testInput = "6KayMYAEQfFACQhZUzbBpFhvGzDWSmRtaY9NrPQGig9qVzRCzQf";
var testExpected = "DHEPGdnS46dHT79tkfm5DyhGAbQj4Xi8Ni";
var saved = pushNetworkVars("doge-mainnet");
var testOutput = coinjs.wif2address(testInput).address;
popNetworkVars(saved);
addTestOutput(testName, testOutput, testExpected);
}
{
// this test comes from https://bitcoindev.network/guides/bitcoinjs-lib/bitcoin-script-puzzles/
var testName = "P2SH redeem script to address (bitcoin testnet)";
var testInput = "935587";
var testExpected = "2N7WfHK1ftrTdhWej8rnFNR7guhvhfGWwFR";
var saved = pushNetworkVars("btc-testnet");
var hash = Crypto.SHA256(Crypto.util.hexToBytes(testInput), {asBytes: true});
var r = ripemd160(hash);
r.unshift(coinjs.multisig);
var hash = Crypto.SHA256(Crypto.SHA256(r, {asBytes: true}), {asBytes: true});
var checksum = hash.slice(0, 4);
var testOutput = coinjs.base58encode(r.concat(checksum));
addTestOutput(testName, testOutput, testExpected);
popNetworkVars(saved);
}
{
// this test comes from https://bitcoindev.network/guides/bitcoinjs-lib/bitcoin-script-puzzles/
var testName = "P2WSH redeem script to address (bitcoin testnet)";
var testInput = "935587";
var testExpected = "bcrt1qpt7c23c0wep9e8up4ywn070w3tqz3828ngy34aj8slsfxrh08ddq2d2pyu";
var hash = Crypto.SHA256(Crypto.util.hexToBytes(testInput), {asBytes: true});
var testOutput = coinjs.bech32_encode(/*coinjs.bech32.hrp*/"bcrt", [coinjs.bech32.version].concat(coinjs.bech32_convert(hash, 8, 5, true)));
addTestOutput(testName, testOutput, testExpected);
}
{
// data from https://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx (runeks)
var testName = "basic transaction building bitcoin";
var testExpectedUnsigned = "0100000001eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2010000001976a914010966776006953d5567439e5e39f86a0d273bee88acffffffff01605af405000000001976a914097072524438d003d23a2f23edb65aae1bb3e46988ac00000000";
var testExpectedSigned = "0100000001eccf7e3034189b851985d871f91384b8ee357cd47c3024736e5676eb2debb3f2010000008a4730440220299fffaf20745458111e7826e5c2cca3b78dd27c97e0a513aab807f0d724103402203247498cfb019bbbd3d629814c8703e974f177478f6fde53503a9b1088852fad01410450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6ffffffff01605af405000000001976a914097072524438d003d23a2f23edb65aae1bb3e46988ac00000000";
var privKeyHex = "18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725";
var inputTx = "f2b3eb2deb76566e7324307cd47c35eeb88413f971d88519859b1834307ecfec";
var inputScript = "76a914010966776006953d5567439e5e39f86a0d273bee88ac";
var inputN = 1;
var address0 = "097072524438d003d23a2f23edb65aae1bb3e469";
var amount = 0.999;
coinjs.compressed = false;
var r = coinjs.transaction();
var wif = coinjs.privkey2wif(privKeyHex);
var address1 = coinjs.scripthash2address(address0);
r.addinput(inputTx, inputN, inputScript, 0xffffffff/*sequence*/);
r.addoutput(address1, amount);
var testOutputUnsigned = r.serialize();
debugger;
r.sign(wif, 1/*sighashtype*/);
var testOutputSigned = r.serialize();
addTestOutput(testName+" (unsigned)", testOutputUnsigned, testExpectedUnsigned);
addTestOutput(testName+" (signed)", testOutputSigned, testExpectedSigned);
}
{
// bitcoin testnet transaction https://tbtc.bitaps.com/04bbae5806d2b8fb17ed9339f42c6f6d731191a974b975d2e1df8e7601e90f6f
var saved = pushNetworkVars("btc-testnet");
var testName = "basic transaction building bitcoin-testnet";
var testExpectedUnsigned = "0100000001c72eabf9f208cacc908538e2609bbe665ffda680e2a6c39475941389dd5b14de000000001976a914b9e16a03bbf40ebb78cbc35e22d72a695f27624088acffffffff01703a0f00000000001976a914a447681601eef322926c0b3de5dfbb4157bbe40988ac00000000";
var testExpectedSigned = "0100000001c72eabf9f208cacc908538e2609bbe665ffda680e2a6c39475941389dd5b14de000000008b483045022100d909d4d3d2b540891c102d06fc8eaf1e9b914b93ea28626990666554a75b369102205a73b38071eab5b0acb8381c1454e7d998c80cd6d229645231b6bc1fb024d1d70141046fad107ba21fae3f047096152d0298291168bc0cb6b834f7cc77510dcb41839206b936649623988f7ca58c6104a22105c5b398912ded514685ebd0d8ac4011c2ffffffff01703a0f00000000001976a914a447681601eef322926c0b3de5dfbb4157bbe40988ac00000000";
var wif = "92Wn1EBgiwDNT8SC7WMZfcSk2y3mQkLUPAQtwMNYZQGAzCFUTdu";
var inputTx = "de145bdd8913947594c3a6e280a6fd5f66be9b60e2388590ccca08f2f9ab2ec7";
var inputScript = "76a914b9e16a03bbf40ebb78cbc35e22d72a695f27624088ac";
var inputN = 0;
var address1 = "mvVaevwNK2SdNj9kcugh29HbSLPhv7xszY";
var amount = 0.00998;
coinjs.compressed = true;
var r = coinjs.transaction();
r.addinput(inputTx, inputN, inputScript, 0xffffffff/*sequence*/);
r.addoutput(address1, amount);
var warnings = new Array;
var testOutputUnsigned = r.serialize();
r.sign(wif, 1/*sighashtype*/, warnings);
var testOutputSigned = r.serialize();
popNetworkVars(saved);
addTestOutput(testName+" (unsigned)", testOutputUnsigned, testExpectedUnsigned);
addTestOutput(testName+" (signed)", testOutputSigned, testExpectedSigned);
}
// create a lot of timelock scripts, compare them to known ones created using bitcoinjs-lib
// focus on edge cases like described in https://github.com/OutCast3k/coinbin/issues/201
// ranges 80-ff, 8000-ffff, 800000-ffffff, 80000000-ffffffff.
{
var testExpected = "HODL_depositAddress: 2NAx7Sx9B6epdUGyPeUEAU2tJiPectEym4F HODL_redeemScript: 050000008000b175210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac\n" +
"HODL_depositAddress: 2N5VZkAjtGerFUrc3bKjuK3whVEyaoKQceg HODL_redeemScript: 0400000008b175210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac\n" +
"HODL_depositAddress: 2MyN366sJLwXTMVMsMTHxi1bSJBwZwmNsQ4 HODL_redeemScript: 0400008000b175210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac\n" +
"HODL_depositAddress: 2NFjqkVBLKXjFLGPDpSoBTbhVsccUrqhRLW HODL_redeemScript: 03000008b175210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac\n" +
"HODL_depositAddress: 2N555b2vUzCJ5t8DryLYTw6vggH87SrK14b HODL_redeemScript: 03008000b175210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac\n" +
"HODL_depositAddress: 2N31s67tdRuaVfQipgkozEXd9jAt4saniH5 HODL_redeemScript: 020008b175210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac\n" +
"HODL_depositAddress: 2N9vLAD9f1WqFiJXinC9oCxDhypz36ZzaT7 HODL_redeemScript: 028000b175210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac\n" +
"HODL_depositAddress: 2MxRBGmDkNK44wCw2NMNq12UKxuPmkN8Wrx HODL_redeemScript: 58b175210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ac\n";
var testOutput = "";
var saved = pushNetworkVars("btc-testnet");
var testName = "timelocks";
var timeLock = 0x80000000;
while (timeLock > 0) {
//var timeLock = Math.pow(2,n)-1;
//var timeLock = 16777215;
var wif = "cMahea7zqjxrtgAbB7LSGbcQUr1uX1ojuat9jZodMN87JcbXMTcA"; // TESTNET pubKey="0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", addr="mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r"
var pubkey = coinjs.wif2pubkey(wif);
var myHodl = coinjs.simpleHodlAddress(pubkey.pubkey, timeLock);
testOutput += 'HODL_depositAddress: ' + myHodl.address + ' ';
testOutput += 'HODL_redeemScript: ' + myHodl.redeemScript + '\n';
timeLock = (timeLock >>> 4);
}
popNetworkVars(saved);
addTestOutput(testName, testOutput, testExpected);
}
});
function addTestOutput(testName, testOutput, testExpected) {
var testResult = "Fail ❌";
if (testOutput == testExpected) { testResult = "Pass ✓"; }
document.getElementById('testResults').value += testName + " : " + testResult + "\n";
}
function popNetworkVars(saved) {
coinjs.pub = saved.pub;
coinjs.priv = saved.priv;
coinjs.multisig = saved.multisig;
}
function pushNetworkVars(network) {
var savedParams = {
'pub':coinjs.pub,
'priv':coinjs.priv,
'multisig':coinjs.multisig
};
if (network == "btc-mainnet") {
coinjs.pub = 0x00;
coinjs.priv = 0x80;
coinjs.multisig = 0x05;
}
if (network == "btc-testnet") {
coinjs.pub = 0x6f;
coinjs.priv = 0xef;
coinjs.multisig = 0xc4;
}
if (network == "ltc-mainnet") {
coinjs.pub = 0x30;
coinjs.priv = 0xb0;
coinjs.multisig = 0x32;
}
if (network == "ltc-testnet") {
coinjs.pub = 0x6f;
coinjs.priv = 0xef;
coinjs.multisig = 0x3a4;
}
if (network == "doge-mainnet") {
coinjs.pub = 0x1e;
coinjs.priv = 0x9e;
coinjs.multisig = 0x16;
}
return savedParams;
}
</script>
</html>