mirror of
https://github.com/ok2/coinbin.git
synced 2026-04-18 08:44:03 +02:00
Compare commits
73 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c8ee40a9a | ||
|
|
9a0175e18f | ||
|
|
507b44f719 | ||
|
|
c868cf984e | ||
|
|
b4fd55aebe | ||
|
|
f51be92a72 | ||
|
|
06cf50abb3 | ||
|
|
35de4228d8 | ||
|
|
a4ef169031 | ||
|
|
6bb5e3785a | ||
|
|
a199d3a55c | ||
|
|
7e92530e1a | ||
|
|
f5c2f48efc | ||
|
|
4f3ceeb3ea | ||
|
|
73369dd253 | ||
|
|
6ed0d3e07e | ||
|
|
84304f23ea | ||
|
|
44ba1b3d30 | ||
|
|
5583675390 | ||
|
|
56cb104ea4 | ||
|
|
c6f70d000e | ||
|
|
4836b20fae | ||
|
|
f364ae4b4a | ||
|
|
64cb387247 | ||
|
|
b2a86006cf | ||
|
|
b5ebaafed8 | ||
|
|
d4f47fce28 | ||
|
|
5bd3786f94 | ||
|
|
b77f3cf06a | ||
|
|
b0c6c3a516 | ||
|
|
a6f5dcf7f0 | ||
|
|
cf2a8b01cb | ||
|
|
261c4ace40 | ||
|
|
e18b634c4e | ||
|
|
1f3b878d63 | ||
|
|
efc16c10fb | ||
|
|
477ca8890d | ||
|
|
e73e8093b3 | ||
|
|
40ea3230fd | ||
|
|
dc416c6521 | ||
|
|
fc66bc9423 | ||
|
|
1c10bef510 | ||
|
|
b22e79391f | ||
|
|
0be8fd9a97 | ||
|
|
1a364ff770 | ||
|
|
bc0c72117e | ||
|
|
13c50cf4b6 | ||
|
|
dea1d1b274 | ||
|
|
e6c70d133b | ||
|
|
10aa011c6e | ||
|
|
c7a0fda7e5 | ||
|
|
c9cfeefc86 | ||
|
|
cdf4aa105b | ||
|
|
2fc574dde0 | ||
|
|
f088ec2e52 | ||
|
|
9ccd73808d | ||
|
|
cb81362330 | ||
|
|
fcbf25eaec | ||
|
|
2aca9ab28d | ||
|
|
5c581316fe | ||
|
|
ebfb940dd5 | ||
|
|
3201550d40 | ||
|
|
d88ec3db4b | ||
|
|
530453a701 | ||
|
|
194df37d56 | ||
|
|
87461b58b8 | ||
|
|
739aee3c0f | ||
|
|
fd81fafdff | ||
|
|
9bede2aef4 | ||
|
|
37f4395d9f | ||
|
|
5a65a77bd2 | ||
|
|
b997751791 | ||
|
|
9bccc5c512 |
17
README.md
17
README.md
@ -1,7 +1,7 @@
|
||||
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
|
||||
|
||||
@ -24,12 +24,13 @@ Coinb.in supports a number of key features such as:
|
||||
- Brain wallet support.
|
||||
- Compatible with bitcoin-qt
|
||||
- An offical .onion address for tor users.
|
||||
- Offline qrcode creator and scanning tool
|
||||
- HD (bip32) support
|
||||
- Supports altcoins such as litecoin
|
||||
- Replace by fee (RBF) Support
|
||||
- Segwit Support
|
||||
- Bech32 address support
|
||||
- Offline qrcode creator and scanning tool.
|
||||
- HD (bip32) support.
|
||||
- Supports altcoins such as litecoin.
|
||||
- Replace by fee (RBF) Support.
|
||||
- Segwit Support.
|
||||
- Bech32 address support.
|
||||
- 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!
|
||||
|
||||
90
index.html
90
index.html
@ -158,7 +158,9 @@
|
||||
<div class="hidden optionsAdvanced">
|
||||
<label>Segregated Witness Address</label>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
<ul class="dropdown-menu">
|
||||
<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>
|
||||
</ul>
|
||||
</div>
|
||||
@ -256,7 +259,7 @@
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<label><abbr title="the amount to pay in network miner fee">Transaction Fee</abbr> <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 class="col-xs-5">
|
||||
<label><abbr title="the amount to donate to coinb.in">Donation</abbr></label>
|
||||
@ -335,7 +338,16 @@
|
||||
|
||||
</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>
|
||||
</div>
|
||||
|
||||
@ -380,7 +392,17 @@
|
||||
<input type="text" class="form-control hidden" id="brainwalletSegWit">
|
||||
</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>
|
||||
</div>
|
||||
|
||||
@ -575,7 +597,7 @@
|
||||
<h2>Transaction <small>Create a new transaction</small></h2>
|
||||
<p>Use this page to create a raw transaction</p>
|
||||
|
||||
<b>Address, WIF key or Redeem Script</b>:
|
||||
<b>Address, WIF key, Redeem Script or Transaction ID</b>:
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-info qrcodeScanner" type="button" data-toggle="modal" data-target="#modalQrcodeScanner" forward-result="#redeemFrom"><span class="glyphicon glyphicon-camera"></span></button>
|
||||
@ -606,7 +628,7 @@
|
||||
|
||||
<label>Null Data</label> <span class="text-muted text-normal">(80 byte limit, <i>40 bytes recommended</i>)</span>
|
||||
<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>
|
||||
</p>
|
||||
|
||||
@ -621,7 +643,7 @@
|
||||
|
||||
<label>Replace By Fee (RBF)</label>
|
||||
<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>
|
||||
|
||||
<hr>
|
||||
@ -1171,18 +1193,26 @@
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<b>Path</b><br>
|
||||
<select class="form-control">
|
||||
<option>Simple: m/i</option>
|
||||
<select class="form-control" id="hdpathtype">
|
||||
<option value="simple">Simple: m/i</option>
|
||||
<option value="custom">Custom</option>
|
||||
</select>
|
||||
|
||||
<div id="hdpath" class="hidden" style="margin-top:4px">
|
||||
<span class="input-group">
|
||||
<input type="text" class="form-control" value="m/0/1" title="WARNING: see #settings page when using hardened paths!"> <br>
|
||||
<span class="input-group-addon"> / </span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
</div>
|
||||
|
||||
<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">
|
||||
</div>
|
||||
|
||||
@ -1303,7 +1333,7 @@
|
||||
|
||||
<div class="tab-pane tab-content" id="about">
|
||||
<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>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>
|
||||
@ -1313,12 +1343,13 @@
|
||||
<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 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>
|
||||
<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>
|
||||
<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>
|
||||
<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 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>
|
||||
<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="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="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>
|
||||
@ -1388,8 +1420,14 @@
|
||||
<p class="text-muted">Select the network you wish to broadcast the transaction via</p>
|
||||
<select class="form-control" id="coinjs_broadcast">
|
||||
<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_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="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option>
|
||||
</select>
|
||||
@ -1404,6 +1442,13 @@
|
||||
<p class="text-muted">Select the network you wish to retreive your unspent inputs from</p>
|
||||
<select class="form-control" id="coinjs_utxo">
|
||||
<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_dogecoin"> Chain.so (Dogecoin)</option>
|
||||
<option value="cryptoid.info_carboncoin"> Cryptoid.info (Carboncoin)</option>
|
||||
@ -1411,6 +1456,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<b>HD wallet hardened path derivation</b>: <br>
|
||||
<p class="text-muted">The path derivation for hardened paths was calculated wrong in earlier versions of coinb.in. Please select the old path derivation to recover HD wallet keys generated with older version of coinb.in.</p>
|
||||
<select class="form-control" id="coinjs_derivation">
|
||||
<option value="bip32_derivation">BIP32 compliant derivation</option>
|
||||
<option value="coinbin_broken">Old (broken) coinb.in path derivation</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div id="statusSettings" class="hidden alert">
|
||||
@ -1430,7 +1488,7 @@
|
||||
|
||||
<div id="footer">
|
||||
<div class="container text-right">
|
||||
<p class="text-muted">Version 1.4</p>
|
||||
<p class="text-muted">Version 1.6</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
165
js/coin.js
165
js/coin.js
@ -18,11 +18,14 @@
|
||||
|
||||
coinjs.compressed = false;
|
||||
|
||||
coinjs.hd_derivation = "bip32_derivation";
|
||||
|
||||
/* other vars */
|
||||
coinjs.developer = '3K1oFZMks41C7qDYBsr72SYjapLqDuSYuN'; //bitcoin
|
||||
coinjs.developer = '33tht1bKDgZVxb39MnZsWa8oxHXHvUYE4G'; //bitcoin
|
||||
|
||||
/* 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.key = '12345678901234567890123456789012';
|
||||
|
||||
@ -155,7 +158,11 @@
|
||||
}
|
||||
|
||||
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(117);//OP_DROP
|
||||
s.writeBytes(Crypto.util.hexToBytes(pubkey));
|
||||
@ -198,7 +205,7 @@
|
||||
var decode = coinjs.bech32_decode(address);
|
||||
if(decode){
|
||||
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;
|
||||
}
|
||||
@ -302,7 +309,7 @@
|
||||
|
||||
return o;
|
||||
} else {
|
||||
return false;
|
||||
throw "Invalid checksum";
|
||||
}
|
||||
} catch(e) {
|
||||
bech32rs = coinjs.bech32redeemscript(addr);
|
||||
@ -633,6 +640,8 @@
|
||||
|
||||
coinjs.compressed = c; // reset to default
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// extend prv/pub key
|
||||
@ -646,10 +655,43 @@
|
||||
'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
|
||||
r.derive = function(i){
|
||||
|
||||
i = (i)?i:0;
|
||||
var blob = (Crypto.util.hexToBytes(this.keys.pubkey)).concat(coinjs.numToBytes(i,4).reverse());
|
||||
if ((i >= 0x80000000) && (coinjs.hd_derivation == "bip32_derivation")) {
|
||||
var blob = (Crypto.util.hexToBytes("00").concat(Crypto.util.hexToBytes(this.keys.privkey)).concat(coinjs.numToBytes(i,4).reverse()));
|
||||
} else {
|
||||
var blob = (Crypto.util.hexToBytes(this.keys.pubkey)).concat(coinjs.numToBytes(i,4).reverse());
|
||||
}
|
||||
|
||||
var j = new jsSHA(Crypto.util.bytesToHex(blob), 'HEX');
|
||||
var hash = j.getHMAC(Crypto.util.bytesToHex(r.chain_code), "HEX", "SHA-512", "HEX");
|
||||
@ -702,7 +744,6 @@
|
||||
|
||||
o.parent_fingerprint = (ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(r.keys.pubkey),{asBytes:true}),{asBytes:true})).slice(0,4);
|
||||
o.keys_extended = o.extend();
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
@ -767,8 +808,7 @@
|
||||
return o;
|
||||
}
|
||||
|
||||
r.parse();
|
||||
return r;
|
||||
return r.parse();
|
||||
}
|
||||
|
||||
|
||||
@ -846,6 +886,9 @@
|
||||
var multi = coinjs.pubkeys2MultisigAddress(pubkeys, r.signaturesRequired);
|
||||
r.address = multi['address'];
|
||||
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
|
||||
r = {};
|
||||
r.type = "segwit__";
|
||||
@ -859,6 +902,8 @@
|
||||
r.pubkey = Crypto.util.bytesToHex(s.chunks[3]);
|
||||
r.checklocktimeverify = coinjs.bytesToNum(s.chunks[0].slice());
|
||||
r.address = coinjs.simpleHodlAddress(r.pubkey, r.checklocktimeverify).address;
|
||||
var rs = Crypto.util.bytesToHex(s.buffer);
|
||||
r.redeemscript = rs;
|
||||
r.type = "hodl__";
|
||||
}
|
||||
} catch(e) {
|
||||
@ -1028,12 +1073,16 @@
|
||||
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 */
|
||||
r.addUnspent = function(address, callback, script, segwit, sequence){
|
||||
var self = this;
|
||||
this.listUnspent(address, function(data){
|
||||
var s = coinjs.script();
|
||||
var pubkeyScript = s.pubkeyHash(address);
|
||||
var value = 0;
|
||||
var total = 0;
|
||||
var x = {};
|
||||
@ -1049,32 +1098,37 @@
|
||||
|
||||
var unspent = xmlDoc.getElementsByTagName("unspent")[0];
|
||||
|
||||
for(i=1;i<=unspent.childElementCount;i++){
|
||||
var u = xmlDoc.getElementsByTagName("unspent_"+i)[0]
|
||||
var txhash = (u.getElementsByTagName("tx_hash")[0].childNodes[0].nodeValue).match(/.{1,2}/g).reverse().join("")+'';
|
||||
var n = u.getElementsByTagName("tx_output_n")[0].childNodes[0].nodeValue;
|
||||
var scr = script || u.getElementsByTagName("script")[0].childNodes[0].nodeValue;
|
||||
if(unspent){
|
||||
for(i=1;i<=unspent.childElementCount;i++){
|
||||
var u = xmlDoc.getElementsByTagName("unspent_"+i)[0]
|
||||
var txhash = (u.getElementsByTagName("tx_hash")[0].childNodes[0].nodeValue).match(/.{1,2}/g).reverse().join("")+'';
|
||||
var n = u.getElementsByTagName("tx_output_n")[0].childNodes[0].nodeValue;
|
||||
var scr = script || u.getElementsByTagName("script")[0].childNodes[0].nodeValue;
|
||||
|
||||
if(segwit){
|
||||
/* this is a small hack to include the value with the redeemscript to make the signing procedure smoother.
|
||||
It is not standard and removed during the signing procedure. */
|
||||
if(segwit){
|
||||
/* this is a small hack to include the value with the redeemscript to make the signing procedure smoother.
|
||||
It is not standard and removed during the signing procedure. */
|
||||
|
||||
s = coinjs.script();
|
||||
s.writeBytes(Crypto.util.hexToBytes(script));
|
||||
s.writeOp(0);
|
||||
s.writeBytes(coinjs.numToBytes(u.getElementsByTagName("value")[0].childNodes[0].nodeValue*1, 8));
|
||||
scr = Crypto.util.bytesToHex(s.buffer);
|
||||
s = coinjs.script();
|
||||
s.writeBytes(Crypto.util.hexToBytes(script));
|
||||
s.writeOp(0);
|
||||
s.writeBytes(coinjs.numToBytes(u.getElementsByTagName("value")[0].childNodes[0].nodeValue*1, 8));
|
||||
scr = Crypto.util.bytesToHex(s.buffer);
|
||||
}
|
||||
|
||||
var seq = sequence || false;
|
||||
self.addinput(txhash, n, scr, seq);
|
||||
value += u.getElementsByTagName("value")[0].childNodes[0].nodeValue*1;
|
||||
total++;
|
||||
}
|
||||
|
||||
var seq = sequence || false;
|
||||
self.addinput(txhash, n, scr, seq);
|
||||
value += u.getElementsByTagName("value")[0].childNodes[0].nodeValue*1;
|
||||
total++;
|
||||
}
|
||||
|
||||
x.unspent = $(xmlDoc).find("unspent");
|
||||
x.result = xmlDoc.getElementsByTagName("result")[0].childNodes[0].nodeValue;
|
||||
x.unspent = unspent;
|
||||
x.value = value;
|
||||
x.total = total;
|
||||
x.response = xmlDoc.getElementsByTagName("response")[0].childNodes[0].nodeValue;
|
||||
|
||||
return callback(x);
|
||||
});
|
||||
}
|
||||
@ -1298,7 +1352,14 @@
|
||||
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
|
||||
// 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
|
||||
// multisig script, without signature!
|
||||
return {'type':'multisig', 'signed':'false', 'signatures':0, 'script': Crypto.util.bytesToHex(this.ins[index].script.buffer)};
|
||||
@ -1550,10 +1611,20 @@
|
||||
if(!witness_used.includes(y)){
|
||||
var sw = coinjs.segwitAddress(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_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();
|
||||
}
|
||||
break;
|
||||
@ -1561,6 +1632,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.witness = witness_order;
|
||||
}
|
||||
}
|
||||
@ -1908,12 +1980,31 @@
|
||||
}
|
||||
}
|
||||
|
||||
coinjs.numToByteArray = function(num) {
|
||||
if (num <= 256) {
|
||||
return [num];
|
||||
} else {
|
||||
return [num % 256].concat(coinjs.numToByteArray(Math.floor(num / 256)));
|
||||
function scriptNumSize(i) {
|
||||
return i > 0x7fffffff ? 5
|
||||
: i > 0x7fffff ? 4
|
||||
: i > 0x7fff ? 3
|
||||
: 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) {
|
||||
|
||||
411
js/coinbin.js
411
js/coinbin.js
@ -37,11 +37,17 @@ $(document).ready(function() {
|
||||
|
||||
$("#walletKeys .walletSegWitRS").addClass("hidden");
|
||||
if($("#walletSegwit").is(":checked")){
|
||||
var sw = coinjs.segwitAddress(pubkey);
|
||||
address = sw.address;
|
||||
if($("#walletSegwitBech32").is(":checked")){
|
||||
var sw = coinjs.bech32Address(pubkey);
|
||||
address = sw.address;
|
||||
} else {
|
||||
|
||||
var sw = coinjs.segwitAddress(pubkey);
|
||||
address = sw.address;
|
||||
}
|
||||
|
||||
$("#walletKeys .walletSegWitRS").removeClass("hidden");
|
||||
$("#walletKeys .walletSegWitRS input:text").val(sw.redeemscript);
|
||||
$("#walletKeys .walletSegWitRS input:text").val(sw.redeemscript);
|
||||
}
|
||||
|
||||
$("#walletAddress").html(address);
|
||||
@ -59,7 +65,6 @@ $(document).ready(function() {
|
||||
$("#openWallet").removeClass("hidden").show();
|
||||
|
||||
walletBalance();
|
||||
checkBalanceLoop();
|
||||
} else {
|
||||
$("#openLoginStatus").html("Your passwords do not match!").removeClass("hidden").fadeOut().fadeIn();
|
||||
}
|
||||
@ -94,9 +99,25 @@ $(document).ready(function() {
|
||||
$("#openLoginStatus").html("").hide();
|
||||
});
|
||||
|
||||
$("#walletSegwit").click(function(){
|
||||
if($(this).is(":checked")){
|
||||
$(".walletSegwitType").attr('disabled',false);
|
||||
} else {
|
||||
$(".walletSegwitType").attr('disabled',true);
|
||||
}
|
||||
});
|
||||
|
||||
$("#walletToSegWit").click(function(){
|
||||
$("#walletToBtn").html('SegWit <span class="caret"></span>');
|
||||
$("#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();
|
||||
});
|
||||
|
||||
@ -106,13 +127,12 @@ $(document).ready(function() {
|
||||
$("#openBtn").click();
|
||||
});
|
||||
|
||||
|
||||
$("#walletShowKeys").click(function(){
|
||||
$("#walletKeys").removeClass("hidden");
|
||||
$("#walletSpend").removeClass("hidden").addClass("hidden");
|
||||
});
|
||||
|
||||
$("#walletBalance").click(function(){
|
||||
$("#walletBalance, #walletAddress, #walletQrCode").click(function(){
|
||||
walletBalance();
|
||||
});
|
||||
|
||||
@ -142,11 +162,15 @@ $(document).ready(function() {
|
||||
|
||||
var script = false;
|
||||
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;
|
||||
}
|
||||
|
||||
var sequence = false;
|
||||
var sequence = 0xffffffff-1;
|
||||
if($("#walletRBF").is(":checked")){
|
||||
sequence = 0xffffffff-2;
|
||||
}
|
||||
@ -272,28 +296,20 @@ $(document).ready(function() {
|
||||
});
|
||||
|
||||
function walletBalance(){
|
||||
var tx = coinjs.transaction();
|
||||
$("#walletLoader").removeClass("hidden");
|
||||
coinjs.addressBalance($("#walletAddress").html(),function(data){
|
||||
if($(data).find("result").text()==1){
|
||||
var v = $(data).find("balance").text()/100000000;
|
||||
$("#walletBalance").html(v+" BTC").attr('rel',v).fadeOut().fadeIn();
|
||||
} else {
|
||||
if($("#walletLoader").hasClass("hidden")){
|
||||
var tx = coinjs.transaction();
|
||||
$("#walletLoader").removeClass("hidden");
|
||||
coinjs.addressBalance($("#walletAddress").html(),function(data){
|
||||
if($(data).find("result").text()==1){
|
||||
var v = $(data).find("balance").text()/100000000;
|
||||
$("#walletBalance").html(v+" BTC").attr('rel',v).fadeOut().fadeIn();
|
||||
} else {
|
||||
$("#walletBalance").html("0.00 BTC").attr('rel',v).fadeOut().fadeIn();
|
||||
}
|
||||
}
|
||||
|
||||
$("#walletLoader").addClass("hidden");
|
||||
});
|
||||
}
|
||||
|
||||
function checkBalanceLoop(){
|
||||
clearTimeout(wallet_timer);
|
||||
wallet_timer = setTimeout(function(){
|
||||
if($("#walletLoader").hasClass("hidden")){
|
||||
walletBalance();
|
||||
}
|
||||
checkBalanceLoop();
|
||||
},45000);
|
||||
$("#walletLoader").addClass("hidden");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* new -> address code */
|
||||
@ -319,7 +335,22 @@ $(document).ready(function() {
|
||||
$("#aes256passStatus").removeClass("hidden");
|
||||
}
|
||||
$("#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(){
|
||||
@ -367,6 +398,22 @@ $(document).ready(function() {
|
||||
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 */
|
||||
|
||||
@ -600,7 +647,7 @@ $(document).ready(function() {
|
||||
}
|
||||
|
||||
if(!$(o).hasClass("has-error")){
|
||||
var seq = null;
|
||||
var seq = 0xffffffff-1;
|
||||
if($("#txRBF").is(":checked")){
|
||||
seq = 0xffffffff-2;
|
||||
}
|
||||
@ -699,24 +746,24 @@ $(document).ready(function() {
|
||||
$.each($("#walletSpendTo .output"), function(i,o){
|
||||
var addr = $('.addressTo',o);
|
||||
var ad = coinjs.addressDecode(addr.val());
|
||||
if (ad.version == coinjs.multisig){ // p2sh
|
||||
$("#fees .txo_p2sh").val(($("#fees .txo_p2sh").val()*1)+1);
|
||||
$("#fees .txo_p2sh").trigger('input');
|
||||
} else { // p2pkh
|
||||
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").trigger('input');
|
||||
}
|
||||
});
|
||||
|
||||
if(($("#developerDonation").val()*1)>0){
|
||||
var addr = coinjs.developer;
|
||||
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").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 */
|
||||
|
||||
$("#redeemFromBtn").click(function(){
|
||||
var redeem = redeemingFrom($("#redeemFrom").val());
|
||||
var redeem = redeemingFrom($("#redeemFrom").val());
|
||||
|
||||
$("#redeemFromStatus, #redeemFromAddress").addClass('hidden');
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -851,11 +898,32 @@ $(document).ready(function() {
|
||||
|
||||
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'){
|
||||
listUnspentChainso_Litecoin(redeem);
|
||||
if(host=='chain.so_bitcoinmainnet'){
|
||||
listUnspentChainso(redeem, "BTC");
|
||||
} else if(host=='chain.so_litecoin'){
|
||||
listUnspentChainso(redeem, "LTC");
|
||||
} 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'){
|
||||
listUnspentCryptoidinfo_Carboncoin(redeem);
|
||||
} else {
|
||||
@ -864,8 +932,8 @@ $(document).ready(function() {
|
||||
|
||||
if($("#redeemFromStatus").hasClass("hidden")) {
|
||||
// An ethical dilemma: Should we automatically set nLockTime?
|
||||
if(redeem.from == 'redeemScript' && redeem.decodedRs.type == "hodl__") {
|
||||
$("#nLockTime").val(redeem.decodedRs.checklocktimeverify);
|
||||
if(redeem.from == 'redeemScript' && redeem.type == "hodl__") {
|
||||
$("#nLockTime").val(redeem.decodescript.checklocktimeverify);
|
||||
} else {
|
||||
$("#nLockTime").val(0);
|
||||
}
|
||||
@ -901,11 +969,19 @@ $(document).ready(function() {
|
||||
r.addr = decodeRs['address'];
|
||||
r.from = 'redeemScript';
|
||||
r.decodedRs = decodeRs.redeemscript;
|
||||
r.type = decodeRs['type'];
|
||||
r.redeemscript = true;
|
||||
r.decodescript = decodeRs;
|
||||
} else { // something else
|
||||
r.addr = '';
|
||||
r.from = 'other';
|
||||
r.redeemscript = false;
|
||||
if(string.match(/^[a-f0-9]{64}$/i)){
|
||||
r.addr = string;
|
||||
r.from = 'txid';
|
||||
r.redeemscript = false;
|
||||
} else {
|
||||
r.addr = '';
|
||||
r.from = 'other';
|
||||
r.redeemscript = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
@ -972,9 +1048,59 @@ $(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*/
|
||||
function listUnspentDefault(redeem){
|
||||
|
||||
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 scr = $(o).find("script").text();
|
||||
|
||||
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){
|
||||
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>');
|
||||
@ -997,25 +1123,27 @@ $(document).ready(function() {
|
||||
}
|
||||
|
||||
|
||||
/* retrieve unspent data from chainso for litecoin */
|
||||
function listUnspentChainso_Litecoin(redeem){
|
||||
/* retrieve unspent data from blockcypher */
|
||||
function listUnspentBlockcypher(redeem,network){
|
||||
$.ajax ({
|
||||
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",
|
||||
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.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>');
|
||||
for(var i in data.data.txs){
|
||||
var o = data.data.txs[i];
|
||||
var tx = ((o.txid).match(/.{1,2}/g).reverse()).join("")+'';
|
||||
var n = o.output_no;
|
||||
var script = (redeem.redeemscript==true) ? redeem.decodedRs : o.script_hex;
|
||||
var amount = o.value;
|
||||
addOutput(tx, n, script, amount);
|
||||
for(var i in data.txrefs){
|
||||
var o = data.txrefs[i];
|
||||
var tx = ((""+o.tx_hash).match(/.{1,2}/g).reverse()).join("")+'';
|
||||
if(tx.match(/^[a-f0-9]+$/)){
|
||||
var n = o.tx_output_n;
|
||||
var script = (redeem.redeemscript==true) ? redeem.decodedRs : o.script;
|
||||
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.');
|
||||
@ -1062,19 +1190,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 ({
|
||||
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",
|
||||
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.status && data.data) && data.status=='success'){
|
||||
$("#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){
|
||||
var o = data.data.txs[i];
|
||||
var tx = ((""+o.txid).match(/.{1,2}/g).reverse()).join("")+'';
|
||||
@ -1096,6 +1259,7 @@ $(document).ready(function() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* math to calculate the inputs and outputs */
|
||||
|
||||
function totalInputAmount(){
|
||||
@ -1155,7 +1319,7 @@ $(document).ready(function() {
|
||||
rawSubmitDefault(this);
|
||||
});
|
||||
|
||||
// broadcast transaction vai coinbin (default)
|
||||
// broadcast transaction via coinbin (default)
|
||||
function rawSubmitDefault(btn){
|
||||
var thisbtn = btn;
|
||||
$(thisbtn).val('Please wait, loading...').attr('disabled',true);
|
||||
@ -1170,8 +1334,7 @@ $(document).ready(function() {
|
||||
success: function(data) {
|
||||
$("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden');
|
||||
if($(data).find("result").text()==1){
|
||||
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger');
|
||||
$("#rawTransactionStatus").html('txid: '+$(data).find("txid").text());
|
||||
$("#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>');
|
||||
} else {
|
||||
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span> ');
|
||||
}
|
||||
@ -1197,8 +1360,7 @@ $(document).ready(function() {
|
||||
success: function(data) {
|
||||
$("#rawTransactionStatus").html(unescape($(data).find("response").text()).replace(/\+/g,' ')).removeClass('hidden');
|
||||
if($(data).find("result").text()==1){
|
||||
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger');
|
||||
$("#rawTransactionStatus").html('txid: '+$(data).find("txid").text());
|
||||
$("#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>');
|
||||
} else {
|
||||
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span> ');
|
||||
}
|
||||
@ -1211,11 +1373,11 @@ $(document).ready(function() {
|
||||
}
|
||||
|
||||
// broadcast transaction via chain.so (mainnet)
|
||||
function rawSubmitChainso_BitcoinMainnet(thisbtn){
|
||||
function rawSubmitChainso(thisbtn, network){
|
||||
$(thisbtn).val('Please wait, loading...').attr('disabled',true);
|
||||
$.ajax ({
|
||||
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()},
|
||||
dataType: "json",
|
||||
error: function(data) {
|
||||
@ -1227,7 +1389,7 @@ $(document).ready(function() {
|
||||
},
|
||||
success: function(data) {
|
||||
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 {
|
||||
$("#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 +1402,20 @@ $(document).ready(function() {
|
||||
}
|
||||
|
||||
// broadcast transaction via blockcypher.com (mainnet)
|
||||
function rawSubmitblockcypher_BitcoinMainnet(thisbtn){
|
||||
function rawSubmitblockcypher(thisbtn, network){
|
||||
$(thisbtn).val('Please wait, loading...').attr('disabled',true);
|
||||
$.ajax ({
|
||||
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()}),
|
||||
error: function(data) {
|
||||
var obj = $.parseJSON(data.responseText);
|
||||
var r = ' ';
|
||||
r += (obj.error) ? obj.error : '';
|
||||
r = (r!='') ? r : ' Failed to broadcast'; // build response
|
||||
var r = 'Failed to broadcast: error code=' + data.status.toString() + ' ' + data.statusText;
|
||||
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(r).prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
|
||||
},
|
||||
success: function(data) {
|
||||
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 {
|
||||
$("#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 +1427,24 @@ $(document).ready(function() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// broadcast transaction via chain.so for dogecoin
|
||||
function rawSubmitchainso_dogecoin(thisbtn){
|
||||
// broadcast transaction via blockchair
|
||||
function rawSubmitblockchair(thisbtn, network){
|
||||
$(thisbtn).val('Please wait, loading...').attr('disabled',true);
|
||||
$.ajax ({
|
||||
type: "POST",
|
||||
url: "https://chain.so/api/v2/send_tx/DOGE",
|
||||
data: {"tx_hex":$("#rawTransaction").val()},
|
||||
url: "https://api.blockchair.com/"+network+"/push/transaction",
|
||||
data: {"data":$("#rawTransaction").val()},
|
||||
dataType: "json",
|
||||
error: function(data) {
|
||||
var obj = $.parseJSON(data.responseText);
|
||||
var r = ' ';
|
||||
r += (obj.data.tx_hex) ? ' '+obj.data.tx_hex : '';
|
||||
r = (r!='') ? r : ' Failed to broadcast'; // build response
|
||||
var r = 'Failed to broadcast: error code=' + data.status.toString() + ' ' + data.statusText;
|
||||
$("#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));
|
||||
},
|
||||
success: function(data) {
|
||||
// console.info(JSON.stringify(data, null, 4));
|
||||
if((data.status && data.data) && data.status=='success'){
|
||||
$("#rawTransactionStatus").addClass('alert-success').removeClass('alert-danger').removeClass("hidden").html(' Txid: ' + data.data.txid);
|
||||
if((data.context && data.data) && data.context.code=='200'){
|
||||
$("#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 {
|
||||
$("#rawTransactionStatus").addClass('alert-danger').removeClass('alert-success').removeClass("hidden").html(' Unexpected error, please try again').prepend('<span class="glyphicon glyphicon-exclamation-sign"></span>');
|
||||
}
|
||||
@ -1544,12 +1701,24 @@ $(document).ready(function() {
|
||||
|
||||
function deriveHDaddress() {
|
||||
var hd = coinjs.hd($("#verifyHDaddress .hdKey").html());
|
||||
var index_start = $("#verifyHDaddress .derivation_index_start").val()*1;
|
||||
var index_end = $("#verifyHDaddress .derivation_index_end").val()*1;
|
||||
var index_start = $("#verifyHDaddress .derivation_index_start").val();
|
||||
if ((index_start.length > 1) && (index_start[index_start.length - 1] == '\'')) {
|
||||
var use_private_index = '\'';
|
||||
index_start = index_start.replace(/[']/, "") * 1;
|
||||
} else {
|
||||
var use_private_index = '';
|
||||
index_start = index_start.replace(/[']/, "") * 1;
|
||||
}
|
||||
var index_end = $("#verifyHDaddress .derivation_index_end").val().replace(/[']/, "") * 1;
|
||||
$("#verifyHDaddress .derivation_index_end").val(index_end + use_private_index);
|
||||
var html = '';
|
||||
$("#verifyHDaddress .derived_data table tbody").html("");
|
||||
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+use_private_index);
|
||||
}
|
||||
html += '<tr>';
|
||||
html += '<td>'+i+'</td>';
|
||||
html += '<td><input type="text" class="form-control" value="'+derived.keys.address+'" readonly></td>';
|
||||
@ -1562,6 +1731,15 @@ $(document).ready(function() {
|
||||
}
|
||||
|
||||
|
||||
$("#hdpathtype").change(function(){
|
||||
if($(this).val()=='simple'){
|
||||
$("#hdpath").removeClass().addClass("hidden");
|
||||
} else {
|
||||
$("#hdpath").removeClass();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/* sign code */
|
||||
|
||||
$("#signBtn").click(function(){
|
||||
@ -1692,7 +1870,7 @@ $(document).ready(function() {
|
||||
|
||||
$('a[data-toggle="tab"]').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
if(e.target){
|
||||
if(e.target && $(e.target).attr('href')) {
|
||||
history.pushState(null, null, '#'+$(e.target).attr('href').substr(1));
|
||||
}
|
||||
});
|
||||
@ -1744,9 +1922,19 @@ $(document).ready(function() {
|
||||
coinjs.hdkey.pub = $("#coinjs_hdpub").val()*1;
|
||||
coinjs.hdkey.prv = $("#coinjs_hdprv").val()*1;
|
||||
|
||||
coinjs.hd_derivation = $("#coinjs_derivation").val();
|
||||
|
||||
configureBroadcast();
|
||||
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();
|
||||
} else {
|
||||
$("#statusSettings").addClass("alert-danger").removeClass("hidden").html("There is an error with one or more of your settings");
|
||||
@ -1781,6 +1969,7 @@ $(document).ready(function() {
|
||||
$("#coinjs_multisig").val(o[2]);
|
||||
$("#coinjs_hdpub").val(o[3]);
|
||||
$("#coinjs_hdprv").val(o[4]);
|
||||
$("#coinjs_derivation").val(o[7]);
|
||||
|
||||
// hide/show custom screen
|
||||
if($("option:selected",this).val()=="custom"){
|
||||
@ -1792,18 +1981,48 @@ $(document).ready(function() {
|
||||
|
||||
function configureBroadcast(){
|
||||
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("");
|
||||
if(host=="chain.so_bitcoinmainnet"){
|
||||
$("#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"){
|
||||
$("#rawSubmitBtn").click(function(){
|
||||
rawSubmitchainso_dogecoin(this);
|
||||
rawSubmitchainso(this, "DOGE");
|
||||
});
|
||||
} else if(host=="blockcypher_bitcoinmainnet"){
|
||||
$("#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"){
|
||||
$("#rawSubmitBtn").click(function(){
|
||||
|
||||
11
sha1sum
11
sha1sum
@ -1,9 +1,9 @@
|
||||
---- Version 1.4 2018.05.27 ---
|
||||
---- Version 1.6 2020.10.02 ----
|
||||
77e4519962e2f6a9fc93342137dbb31c33b76b04 ./js/aes.js
|
||||
3a09a8fc0cfe828b57fc798d668234d0490ee1a6 ./js/bootstrap-datetimepicker.min.js
|
||||
253711c6d825de55a8360552573be950da180614 ./js/bootstrap.min.js
|
||||
dda26795fcd22541612067d44cf72ecae62f092b ./js/coinbin.js
|
||||
eec3c5f1c5f69a34205613f6bf62ff9cc5a8d07a ./js/coin.js
|
||||
cb5717166bf1c99abbd75a06013067c4a5897d5a ./js/coinbin.js
|
||||
911fb7bdba24269029f27659e4040cd991b2307c ./js/coin.js
|
||||
988565bc2cb402d63ed5c5fd7ff47c4278efc2c5 ./js/collapse.js
|
||||
9ba5ede3d7f9d4c8fd623395f196adfdcf7e970f ./js/crypto-min.js
|
||||
f7c09f2f5a721371e7d478050119f7e2d58e3ef9 ./js/crypto-sha256-hmac.js
|
||||
@ -30,5 +30,6 @@ ca35b697d99cae4d1b60f2d60fcd37771987eb07 ./fonts/glyphicons-halflings-regular.w
|
||||
de51a8494180a6db074af2dee2383f0a363c5b08 ./fonts/glyphicons-halflings-regular.svg
|
||||
278e49a86e634da6f2a02f3b47dd9d2a8f26210f ./fonts/glyphicons-halflings-regular.woff
|
||||
44bc1850f570972267b169ae18f1cb06b611ffa2 ./fonts/glyphicons-halflings-regular.ttf
|
||||
c024021c71cba503979a859d23cbf7a88b570d82 ./README.md
|
||||
208b64a1ef61aaceec82f06515e4f7cf046793f6 ./index.html
|
||||
ee481606d8d48f402d152fa632ba9e5f9da7f169 ./README.md
|
||||
a706e95f6436ee4a31dc26b17a9ac8ab1f0d3750 ./index.html
|
||||
7130b64e3ef4cf6f2f1550e902f081c58dc053de ./test.html
|
||||
|
||||
379
test.html
Normal file
379
test.html
Normal 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>
|
||||
Loading…
x
Reference in New Issue
Block a user