mirror of
https://github.com/ok2/coinbin.git
synced 2026-04-18 08:44:03 +02:00
Compare commits
91 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 | ||
|
|
734e6b2eeb | ||
|
|
90a309d4b4 | ||
|
|
abd2191c50 | ||
|
|
bb8abb4ded | ||
|
|
40d514e0f0 | ||
|
|
c3b1a47199 | ||
|
|
ed7d5d6411 | ||
|
|
10e083bd89 | ||
|
|
56fa7b5139 | ||
|
|
e85276dd89 | ||
|
|
c843685662 | ||
|
|
64af126bc5 | ||
|
|
b997751791 | ||
|
|
9bccc5c512 | ||
|
|
217897285e | ||
|
|
b1603821da | ||
|
|
c2ef949dd0 | ||
|
|
ecb18acb0f | ||
|
|
4a4f302fe6 | ||
|
|
4afee020b0 |
17
README.md
17
README.md
@ -1,7 +1,7 @@
|
||||
coinbin
|
||||
=======
|
||||
|
||||
A Open Source Browser Based Bitcoin Wallet. Version 1.3 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,10 +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
|
||||
- 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 1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg to see more development!
|
||||
Donate to 33tht1bKDgZVxb39MnZsWa8oxHXHvUYE4G to see more development!
|
||||
|
||||
@ -32,3 +32,89 @@ body {
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#fees .txi_regular {
|
||||
background: #d3d3d3;
|
||||
}
|
||||
|
||||
#fees .txi_segwit {
|
||||
background: #bae1ff;
|
||||
}
|
||||
|
||||
#fees .txi_multisig {
|
||||
background: #baffc9;
|
||||
}
|
||||
|
||||
#fees .txi_hodl {
|
||||
background: #ffdfba;
|
||||
}
|
||||
|
||||
#fees .txi_unknown {
|
||||
background: #ffb3ba;
|
||||
}
|
||||
|
||||
#fees .txo_p2pkh {
|
||||
background: #E679C8;
|
||||
}
|
||||
|
||||
#fees .txo_p2sh {
|
||||
background: #FAFE92;
|
||||
}
|
||||
|
||||
#fees .txinputs {
|
||||
}
|
||||
|
||||
#fees .txoutputs {
|
||||
}
|
||||
|
||||
.hideOverflow {
|
||||
overflow:hidden;
|
||||
white-space:nowrap;
|
||||
text-overflow:ellipsis;
|
||||
}
|
||||
|
||||
#fees .slider {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
outline: none;
|
||||
opacity: 0.7;
|
||||
-webkit-transition: .2s;
|
||||
transition: opacity .2s;
|
||||
border: 2px dotted #c3c3c3;
|
||||
}
|
||||
|
||||
#fees .sliderbtn {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
#fees .slider:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#fees .slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 0;
|
||||
background: url('https://coinb.in/images/btc32x.png');
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#fees .slider::-moz-range-thumb {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 0;
|
||||
background: url('https://coinb.in/images/btc32x.png');
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#fees .total {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
BIN
images/btc32x.png
Normal file
BIN
images/btc32x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
383
index.html
383
index.html
@ -4,9 +4,9 @@
|
||||
|
||||
<title>Bitcoin Wallet by Coinb.in</title>
|
||||
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
|
||||
<meta name="keywords" content="bitcoin, wallet, multisig, multisignature, address, browser, javascript, js, broadcast, transaction, verify, decode" />
|
||||
<meta name="description" content="A Bitcoin Wallet written in Javascript. Supports Multisig, Custom Transactions, nLockTime and more!" />
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
|
||||
<meta name="keywords" content="bitcoin, wallet, multisig, multisignature, address, browser, segwit, javascript, js, broadcast, transaction, verify, decode" />
|
||||
<meta name="description" content="A Bitcoin Wallet written in Javascript. Supports Multisig, SegWit, Custom Transactions, nLockTime and more!" />
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
@ -74,6 +74,7 @@
|
||||
<li><a href="#about" data-toggle="tab"><span class="glyphicon glyphicon-info-sign"></span> About</a></li>
|
||||
|
||||
<li class="hidden"><a href="#settings" data-toggle="tab"><span class="glyphicon glyphicon-cog"></span> Settings</a></li>
|
||||
<li class="hidden"><a href="#fees" data-toggle="tab"><span class="glyphicon glyphicon-tag"></span> Fees</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -119,12 +120,12 @@
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h3><span class="glyphicon glyphicon-piggy-bank"></span> Wallet</h3>
|
||||
<p>Quick access to an <a href="#wallet">online wallet</a> where only you have access to your own private keys!</p>
|
||||
<p>Quick access to an <a href="#wallet">online wallet</a> where only you have access to your own private keys & can <a href="#fees">calculate your own fee</a>!</p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<h3><span class="glyphicon glyphicon-globe"></span> Addresses</h3>
|
||||
<p>We support <a href="#newAddress">regular addresses</a>, <a href="#newMultiSig">multisig</a>, <a href="#newSegWit">segwit</a> and stealth all with access to your own private keys!</p>
|
||||
<p>We support <a href="#newAddress">regular addresses</a>, <a href="#newMultiSig">multisig</a>, <a href="#newSegWit">segwit / bech32</a> and stealth all with access to your own private keys!</p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
@ -151,6 +152,24 @@
|
||||
<input id="openPass" type="password" class="form-control" placeholder="Password" required>
|
||||
<input id="openPassConfirm" type="password" class="form-control" placeholder="Password confirm" required>
|
||||
<br>
|
||||
|
||||
<div>
|
||||
<a href="javascript:;" class="optionsCollapse"><div class="well well-sm"><span class="glyphicon glyphicon-collapse-down" id="glyphcollapse"></span> Advanced Options</div></a>
|
||||
<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> <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>
|
||||
<p class="checkbox">
|
||||
<label><input type="checkbox" id="walletRBF" class="checkbox-inline" checked> Enable RBF on all transactions, allowing you to manually raise the transaction fee later if required. <span class="text-muted"><i>(recommended)</i></span></label></label>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="openLoginStatus" class="alert alert-danger hidden"></div>
|
||||
<button id="openBtn" class="btn btn-primary" type="submit">Submit</button>
|
||||
</form>
|
||||
@ -165,7 +184,16 @@
|
||||
<div id="walletQrCode"></div> <br>
|
||||
<div>
|
||||
<span id="walletLoader" class="hidden"><img src="images/loader.gif"></span>
|
||||
<span id="walletAddress"></span>
|
||||
<span id="walletAddress"></span>
|
||||
|
||||
<div class="btn-group">
|
||||
<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>
|
||||
</div>
|
||||
<br>
|
||||
<div style="text-align:center; width:350px;">
|
||||
@ -182,6 +210,12 @@
|
||||
<div id="walletKeys" class="hidden">
|
||||
<label>Public Key</label>
|
||||
<input class="form-control pubkey" type="text" readonly>
|
||||
|
||||
<div class="walletSegWitRS hidden">
|
||||
<label>Redeem Script <i>(SegWit)</i></label>
|
||||
<input class="form-control" type="text" readonly>
|
||||
</div>
|
||||
|
||||
<label>Private key</label>
|
||||
<div class="input-group">
|
||||
<input class="form-control privkey" type="password" readonly>
|
||||
@ -190,6 +224,7 @@
|
||||
<button class="showKey btn btn-default" type="button">Show</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<label>Private Key (AES256 encrypted key)</label>
|
||||
<input class="form-control privkeyaes" type="text" readonly>
|
||||
</div>
|
||||
@ -223,8 +258,8 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<label><abbr title="the amount to pay in network miner fees - 0.0004 or more recommended for a faster processing time">Transaction Fee</abbr> <a href="https://bitcoinfees.21.co/" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a></label>
|
||||
<input type="text" class="form-control" value="0.0004" id="txFee">
|
||||
<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.00004000" id="txFee">
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
<label><abbr title="the amount to donate to coinb.in">Donation</abbr></label>
|
||||
@ -303,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>
|
||||
|
||||
@ -339,12 +383,26 @@
|
||||
<h3>Address Options</h3>
|
||||
<p>You can use the advanced options below to generate different kind of keys and addresses.</p>
|
||||
|
||||
<div class="checkbox">
|
||||
<label><input type="checkbox" id="newSegWitBech32addr" class="checkbox-inline" checked> Enable <a href="https://en.bitcoin.it/wiki/Bech32" target="_blank">Bech32</a>?</label>
|
||||
</div>
|
||||
|
||||
<div class="checkbox">
|
||||
<label><input type="checkbox" id="newSegWitBrainwallet" class="checkbox-inline"> Custom Seed or Brain Wallet</label>
|
||||
<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>
|
||||
|
||||
@ -539,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>
|
||||
@ -557,9 +615,9 @@
|
||||
<div class="hidden alert alert-info" id="redeemFromAddress"></div>
|
||||
|
||||
<div>
|
||||
<a href="javascript:;" id="optionsCollapse"><div class="well well-sm"><span class="glyphicon glyphicon-collapse-down" id="glyphcollapse"></span> Advanced Options</div></a>
|
||||
<a href="javascript:;" class="optionsCollapse"><div class="well well-sm"><span class="glyphicon glyphicon-collapse-down" id="glyphcollapse"></span> Advanced Options</div></a>
|
||||
|
||||
<div class="hidden" id="optionsAdvanced">
|
||||
<div class="hidden optionsAdvanced">
|
||||
|
||||
<label>Clear Inputs</label>
|
||||
<p class="checkbox">
|
||||
@ -570,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>
|
||||
|
||||
@ -585,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>
|
||||
@ -685,7 +743,7 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-3">
|
||||
<label><abbr title="What is not spent will be used as a transaction fee">Transaction Fee</abbr> <a href="https://bitcoinfees.21.co/" target="_blank"><span class="glyphicon glyphicon-question-sign"></span></a></label>
|
||||
<label><abbr title="What is not spent will be used as a transaction fee, so remember to add a "change address"">Transaction Fee</abbr> <a href="javascript:;" id="feesestnewtx"><span class="glyphicon glyphicon-question-sign"></span></a></label>
|
||||
<input type="text" id="transactionFee" class="form-control" value="0.0000" readonly>
|
||||
</div>
|
||||
</div>
|
||||
@ -710,6 +768,211 @@
|
||||
<br>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tab-pane tab-content" id="fees">
|
||||
<h2>Bitcoin Fee Calculator</h2>
|
||||
<p>This page will give you a guide on the lowest fee to use to get your transaction included within the next few blocks. It works by predicting the size of a transaction and comparing it to another transaction in a recent block to determine an appropriate fee.</p>
|
||||
|
||||
<div align="center" class="alert alert-info">
|
||||
<h2><span class="glyphicon glyphicon-question-sign"></span> Recommended Fee: <span class="recommendedFee">0.00000000</span> BTC <small> <br> for a transaction of <span class="feeTxSize">0</span> bytes</small></h2>
|
||||
<span class="text-muted"><i><span class="feeSatByte">?</span> Sat/Byte</i></span>
|
||||
</div>
|
||||
|
||||
<div id="txsliders" class="row">
|
||||
<div class="col-md-6 txinputs">
|
||||
|
||||
<div align="center"><b><span class="txtotal total">0</span><br>Inputs</b></div>
|
||||
<div id="txinputstype" align="center" class="small text-muted">
|
||||
<br>
|
||||
<span><span class="txsize">0</span> Bytes</span>
|
||||
</div>
|
||||
|
||||
<h4 class="regular"><abbr title="Spending from a compressed legacy address. p2pkh">Regular</abbr> <small>Compressed</small>
|
||||
<span class="badge inputno" title="Number of Regular Inputs">1</span>
|
||||
<small><span class="bytes">148</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="1" class="slider txinput txi_regular" rel="regular">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<h4 class="segwit"><abbr title="Spending from a segwit address. p2sh">SegWit</abbr>
|
||||
<span class="badge inputno" title="Number of SegWit Inputs">0</span>
|
||||
<small><span class="bytes">0</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="0" class="slider txinput txi_segwit" rel="segwit">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<h4 class="multisig"><abbr title="Spending from a multisig address. p2sh">MultiSig</abbr>
|
||||
<span class="badge inputno" title="Number of MultiSig Inputs">0</span>
|
||||
<small><span class="bytes">0</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="0" class="slider txinput txi_multisig" rel="multisig">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<h4 class="hodl"><abbr title="Spending from a time locked address. p2sh">Hodl</abbr> <small>Time Locked</small>
|
||||
<span class="badge inputno" title="Number of Hodl Inputs">0</span>
|
||||
<small><span class="bytes">0</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="0" class="slider txinput txi_hodl" rel="hodl">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<h4 class="unknown"><abbr title="Spending from an unrecognized input. p2sh">Unknown</abbr>
|
||||
<span class="badge inputno" title="Number of Unknown Inputs">0</span>
|
||||
<small><span class="bytes">0</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="0" class="slider txinput txi_unknown" rel="unknown">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 txoutputs">
|
||||
|
||||
<div align="center"><b><span class="txtotal total">0</span><br>Outputs</b></div>
|
||||
<div id="txoutputtype" align="center" class="small text-muted">
|
||||
<br>
|
||||
<span><span class="txsize">0</span> Bytes</span>
|
||||
</div>
|
||||
|
||||
<h4 class="p2pkh"><abbr title="A pay 2 public key hash. Starts with 1. Used with legacy addresses">Regular</abbr> <small>p2pkh (1...)</small>
|
||||
<span class="badge outputno" title="Number of p2pkh Outputs">2</span>
|
||||
<small><span class="bytes">68</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="2" class="slider txoutput txo_p2pkh" rel="p2pkh">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<h4 class="p2sh"><abbr title="A pay 2 script hash address. Starts with a 3. For example a segwit or multisig address">Regular</abbr> <small>p2sh (3...)</small>
|
||||
<span class="badge outputno" title="Number of p2sh Outputs">0</span>
|
||||
<small><span class="bytes">0</span> bytes</small>
|
||||
<small class="estimate hidden"><em> *estimate</em></small>
|
||||
</h4>
|
||||
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn down" type="button"><span class="glyphicon glyphicon-chevron-left"></span></button></span>
|
||||
<input type="range" min="0" max="100" value="0" class="slider txoutput txo_p2sh" rel="p2sh">
|
||||
<span class="input-group-btn"><button class="btn sliderbtn up" type="button"><span class="glyphicon glyphicon-chevron-right"></span></button></span>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="text-muted">Chargable Transaction Size: <span class="feeTxSize">0</span> bytes</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12 recommended">
|
||||
|
||||
<h3>Blockchain Data <span class="pull-right"><button type="button" id="feeStatsReload" class="btn btn-default btn-sm"><span class="glyphicon glyphicon-refresh"></span></button></span></h3>
|
||||
|
||||
<p>This is based on us comparing your transaction against a very recent transaction found in a very recent block</p>
|
||||
<p><b>Block Height</b>: <span class="blockHeight">?</span></p>
|
||||
<p class="hideOverflow"><b>Block #</b>: <span class="blockHash">?</span></p>
|
||||
<p><b>Block Time</b>: <span class="blockTime">?</span> <span class="blockDateTime text-muted"></span></p>
|
||||
<p class="hideOverflow"><b>Transaction ID</b>: <span class="txId">?</span></p>
|
||||
<p><b>Transaction Size</b>: <span class="txSize">0</span> bytes</p>
|
||||
<p><b>Transaction Fee</b>: <span class="txFee">0.00000000</span></p>
|
||||
<p><b>Satoshi per Byte</b>: <span class="feeSatByte">0</span></p>
|
||||
|
||||
<p>Based on your data and this recently mined transaction we recommend a fee of <b><span class="recommendedFee">0.00000000</span> BTC</b> to get it into the next few blocks</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-12">
|
||||
<a href="javascript:;" id="advancedFeesCollapse">
|
||||
<div class="well well-sm"><span class="glyphicon glyphicon-collapse-down"></span> Advanced Options & Raw Transaction</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row hidden" id="advancedFees">
|
||||
<div class="col-md-12">
|
||||
<p>Enter your unsigned or signed hex encoded transaction below:</p>
|
||||
<textarea class="form-control txhex" style="height:160px"></textarea><br>
|
||||
<button type="button" class="btn btn-primary" id="feesAnalyseBtn">Analyse Transaction</button>
|
||||
|
||||
<hr>
|
||||
|
||||
<h4>Estimate Input Size <small>in bytes</small></h4>
|
||||
|
||||
<div class="form-inline">
|
||||
<div class="form-group">
|
||||
<label for="est_txi_regular">Regular</label>
|
||||
<input type="number" class="form-control" id="est_txi_regular" value="107">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="est_txi_segwit">SegWit</label>
|
||||
<input type="number" class="form-control" id="est_txi_segwit" value="27">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="est_txi_multisig">MultiSig</label>
|
||||
<input type="number" class="form-control" id="est_txi_multisig" value="351">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="est_txi_hodl">Hodl</label>
|
||||
<input type="number" class="form-control" id="est_txi_hodl" value="78">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="est_txi_unknown">Unknown</label>
|
||||
<input type="number" class="form-control" id="est_txi_unknown" value="512">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>Estimate Output Size <small> in bytes</small></h4>
|
||||
<div class="form-inline">
|
||||
<div class="form-group">
|
||||
<label for="est_txo_p2pkh">Regular P2PKH</label>
|
||||
<input type="number" class="form-control" id="est_txo_p2pkh" value="25">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="est_txo_p2sh">Regular P2SH</label>
|
||||
<input type="number" class="form-control" id="est_txo_p2sh" value="23">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane tab-content" id="verify">
|
||||
<h2>Verify <small>transactions and other scripts</small></h2>
|
||||
<div class="row">
|
||||
@ -847,7 +1110,33 @@
|
||||
<div class="hidden verifyData" id="verifyPubKey">
|
||||
<h4>Public key</h4>
|
||||
<p><span style="float:right"><a href="" target="_blank" class="verifyLink" title="Link to this page"><span class="glyphicon glyphicon-link"></span></a></span>The above public key has been encoded to its address</p>
|
||||
<p><b>Address</b>: <input type="text" class="form-control address" readonly></p>
|
||||
<p><b>Legacy Address</b>: <input type="text" class="form-control address" readonly></p>
|
||||
|
||||
<div class="hidden verifyDataSw">
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p><b>P2SH Segwit Address</b>: <input type="text" class="form-control addressSegWit" readonly></p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<p><b>P2SH Segwit Redeem Script</b>: <input type="text" class="form-control addressSegWitRedeemScript" readonly></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p><b>Bech32 Address</b>: <input type="text" class="form-control addressBech32" readonly></p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<p><b>Bech32 Redeem Script</b>: <input type="text" class="form-control addressBech32RedeemScript" readonly></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hidden verifyData" id="verifyHDaddress">
|
||||
@ -904,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>
|
||||
|
||||
@ -1036,8 +1333,8 @@
|
||||
|
||||
<div class="tab-pane tab-content" id="about">
|
||||
<h2>About <small>open source bitcoin wallet</small></h2>
|
||||
<p>Version 1.3</p>
|
||||
<p>Compatible with bitcoin-qt</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>
|
||||
<h3>What is Bitcoin?</h3>
|
||||
@ -1046,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 beleives 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>
|
||||
<p>We recommend that you first check our <a href="https://status.coinb.in/" target="_blank">service status</a> page, 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>
|
||||
<p>Please donate to <a href="bitcoin:1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg">1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg</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">
|
||||
@ -1064,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>
|
||||
@ -1121,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>
|
||||
@ -1137,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>
|
||||
@ -1144,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">
|
||||
@ -1163,7 +1488,7 @@
|
||||
|
||||
<div id="footer">
|
||||
<div class="container text-right">
|
||||
<p class="text-muted">Version 1.3</p>
|
||||
<p class="text-muted">Version 1.6</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
372
js/coin.js
372
js/coin.js
@ -14,14 +14,18 @@
|
||||
coinjs.priv = 0x80;
|
||||
coinjs.multisig = 0x05;
|
||||
coinjs.hdkey = {'prv':0x0488ade4, 'pub':0x0488b21e};
|
||||
coinjs.bech32 = {'charset':'qpzry9x8gf2tvdw0s3jn54khce6mua7l', 'version':0, 'hrp':'bc'};
|
||||
|
||||
coinjs.compressed = false;
|
||||
|
||||
coinjs.hd_derivation = "bip32_derivation";
|
||||
|
||||
/* other vars */
|
||||
coinjs.developer = '1CWHWkTWaq1K5hevimJia3cyinQsrgXUvg'; // 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';
|
||||
|
||||
@ -132,7 +136,13 @@
|
||||
var checksum = r.slice(0,4);
|
||||
var redeemScript = Crypto.util.bytesToHex(s.buffer);
|
||||
var address = coinjs.base58encode(x.concat(checksum));
|
||||
return {'address':address, 'redeemScript':redeemScript};
|
||||
|
||||
if(s.buffer.length > 520){ // too large
|
||||
address = 'invalid';
|
||||
redeemScript = 'invalid';
|
||||
}
|
||||
|
||||
return {'address':address, 'redeemScript':redeemScript, 'size': s.buffer.length};
|
||||
}
|
||||
|
||||
/* new time locked address, provide the pubkey and time necessary to unlock the funds.
|
||||
@ -148,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));
|
||||
@ -178,6 +192,24 @@
|
||||
return {'address':address, 'type':'segwit', 'redeemscript':Crypto.util.bytesToHex(keyhash)};
|
||||
}
|
||||
|
||||
/* create a new segwit bech32 encoded address */
|
||||
coinjs.bech32Address = function(pubkey){
|
||||
var program = ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(pubkey), {asBytes: true}), {asBytes: true});
|
||||
var address = coinjs.bech32_encode(coinjs.bech32.hrp, [coinjs.bech32.version].concat(coinjs.bech32_convert(program, 8, 5, true)));
|
||||
return {'address':address, 'type':'bech32', 'redeemscript':Crypto.util.bytesToHex(program)};
|
||||
}
|
||||
|
||||
/* extract the redeemscript from a bech32 address */
|
||||
coinjs.bech32redeemscript = function(address){
|
||||
var r = false;
|
||||
var decode = coinjs.bech32_decode(address);
|
||||
if(decode){
|
||||
decode.data.shift();
|
||||
return Crypto.util.bytesToHex(coinjs.bech32_convert(decode.data, 5, 8, false));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* provide a privkey and return an WIF */
|
||||
coinjs.privkey2wif = function(h){
|
||||
var r = Crypto.util.hexToBytes(h);
|
||||
@ -277,10 +309,15 @@
|
||||
|
||||
return o;
|
||||
} else {
|
||||
return false;
|
||||
throw "Invalid checksum";
|
||||
}
|
||||
} catch(e) {
|
||||
return false;
|
||||
bech32rs = coinjs.bech32redeemscript(addr);
|
||||
if(bech32rs){
|
||||
return {'type':'bech32', 'redeemscript':bech32rs};
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,6 +347,126 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
coinjs.bech32_polymod = function(values) {
|
||||
var chk = 1;
|
||||
var BECH32_GENERATOR = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
|
||||
for (var p = 0; p < values.length; ++p) {
|
||||
var top = chk >> 25;
|
||||
chk = (chk & 0x1ffffff) << 5 ^ values[p];
|
||||
for (var i = 0; i < 5; ++i) {
|
||||
if ((top >> i) & 1) {
|
||||
chk ^= BECH32_GENERATOR[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return chk;
|
||||
}
|
||||
|
||||
coinjs.bech32_hrpExpand = function(hrp) {
|
||||
var ret = [];
|
||||
var p;
|
||||
for (p = 0; p < hrp.length; ++p) {
|
||||
ret.push(hrp.charCodeAt(p) >> 5);
|
||||
}
|
||||
ret.push(0);
|
||||
for (p = 0; p < hrp.length; ++p) {
|
||||
ret.push(hrp.charCodeAt(p) & 31);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
coinjs. bech32_verifyChecksum = function(hrp, data) {
|
||||
return coinjs.bech32_polymod(coinjs.bech32_hrpExpand(hrp).concat(data)) === 1;
|
||||
}
|
||||
|
||||
coinjs.bech32_createChecksum = function(hrp, data) {
|
||||
var values = coinjs.bech32_hrpExpand(hrp).concat(data).concat([0, 0, 0, 0, 0, 0]);
|
||||
var mod = coinjs.bech32_polymod(values) ^ 1;
|
||||
var ret = [];
|
||||
for (var p = 0; p < 6; ++p) {
|
||||
ret.push((mod >> 5 * (5 - p)) & 31);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
coinjs.bech32_encode = function(hrp, data) {
|
||||
var combined = data.concat(coinjs.bech32_createChecksum(hrp, data));
|
||||
var ret = hrp + '1';
|
||||
for (var p = 0; p < combined.length; ++p) {
|
||||
ret += coinjs.bech32.charset.charAt(combined[p]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
coinjs.bech32_decode = function(bechString) {
|
||||
var p;
|
||||
var has_lower = false;
|
||||
var has_upper = false;
|
||||
for (p = 0; p < bechString.length; ++p) {
|
||||
if (bechString.charCodeAt(p) < 33 || bechString.charCodeAt(p) > 126) {
|
||||
return null;
|
||||
}
|
||||
if (bechString.charCodeAt(p) >= 97 && bechString.charCodeAt(p) <= 122) {
|
||||
has_lower = true;
|
||||
}
|
||||
if (bechString.charCodeAt(p) >= 65 && bechString.charCodeAt(p) <= 90) {
|
||||
has_upper = true;
|
||||
}
|
||||
}
|
||||
if (has_lower && has_upper) {
|
||||
return null;
|
||||
}
|
||||
bechString = bechString.toLowerCase();
|
||||
var pos = bechString.lastIndexOf('1');
|
||||
if (pos < 1 || pos + 7 > bechString.length || bechString.length > 90) {
|
||||
return null;
|
||||
}
|
||||
var hrp = bechString.substring(0, pos);
|
||||
var data = [];
|
||||
for (p = pos + 1; p < bechString.length; ++p) {
|
||||
var d = coinjs.bech32.charset.indexOf(bechString.charAt(p));
|
||||
if (d === -1) {
|
||||
return null;
|
||||
}
|
||||
data.push(d);
|
||||
}
|
||||
if (!coinjs.bech32_verifyChecksum(hrp, data)) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
hrp: hrp,
|
||||
data: data.slice(0, data.length - 6)
|
||||
};
|
||||
}
|
||||
|
||||
coinjs.bech32_convert = function(data, inBits, outBits, pad) {
|
||||
var value = 0;
|
||||
var bits = 0;
|
||||
var maxV = (1 << outBits) - 1;
|
||||
|
||||
var result = [];
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
value = (value << inBits) | data[i];
|
||||
bits += inBits;
|
||||
|
||||
while (bits >= outBits) {
|
||||
bits -= outBits;
|
||||
result.push((value >> bits) & maxV);
|
||||
}
|
||||
}
|
||||
|
||||
if (pad) {
|
||||
if (bits > 0) {
|
||||
result.push((value << (outBits - bits)) & maxV);
|
||||
}
|
||||
} else {
|
||||
if (bits >= inBits) throw new Error('Excess padding');
|
||||
if ((value << (outBits - bits)) & maxV) throw new Error('Non-zero padding');
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
coinjs.testdeterministicK = function() {
|
||||
// https://github.com/bitpay/bitcore/blob/9a5193d8e94b0bd5b8e7f00038e7c0b935405a03/test/crypto/ecdsa.js
|
||||
// Line 21 and 22 specify digest hash and privkey for the first 2 test vectors.
|
||||
@ -483,6 +640,8 @@
|
||||
|
||||
coinjs.compressed = c; // reset to default
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// extend prv/pub key
|
||||
@ -496,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");
|
||||
@ -552,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;
|
||||
}
|
||||
|
||||
@ -617,8 +808,7 @@
|
||||
return o;
|
||||
}
|
||||
|
||||
r.parse();
|
||||
return r;
|
||||
return r.parse();
|
||||
}
|
||||
|
||||
|
||||
@ -696,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__";
|
||||
@ -709,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) {
|
||||
@ -722,7 +917,10 @@
|
||||
r.spendToScript = function(address){
|
||||
var addr = coinjs.addressDecode(address);
|
||||
var s = coinjs.script();
|
||||
if(addr.version==coinjs.multisig){ // multisig address
|
||||
if(addr.type == "bech32"){
|
||||
s.writeOp(0);
|
||||
s.writeBytes(Crypto.util.hexToBytes(addr.redeemscript));
|
||||
} else if(addr.version==coinjs.multisig){ // multisig address
|
||||
s.writeOp(169); //OP_HASH160
|
||||
s.writeBytes(addr.bytes);
|
||||
s.writeOp(135); //OP_EQUAL
|
||||
@ -792,7 +990,7 @@
|
||||
r.lock_time = 0;
|
||||
r.ins = [];
|
||||
r.outs = [];
|
||||
r.witness = [];
|
||||
r.witness = false;
|
||||
r.timestamp = null;
|
||||
r.block = null;
|
||||
|
||||
@ -875,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){
|
||||
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 = {};
|
||||
@ -896,21 +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 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;
|
||||
|
||||
self.addinput(txhash, n, script);
|
||||
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. */
|
||||
|
||||
value += u.getElementsByTagName("value")[0].childNodes[0].nodeValue*1;
|
||||
total++;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
@ -1026,20 +1244,24 @@
|
||||
return {'result':0, 'fail':'redeemscript', 'response':'redeemscript missing or not valid for segwit'};
|
||||
}
|
||||
|
||||
var scriptcode = Crypto.util.hexToBytes(extract['script']);
|
||||
if(scriptcode[0] != 0){
|
||||
return {'result':0, 'fail':'scriptcode', 'response':'redeemscript is not valid'};
|
||||
}
|
||||
|
||||
if(extract['value'] == -1){
|
||||
return {'result':0, 'fail':'value', 'response':'unable to generate a valid segwit hash without a value'};
|
||||
}
|
||||
|
||||
var scriptcode = Crypto.util.hexToBytes(extract['script']);
|
||||
|
||||
// end of redeem script check
|
||||
|
||||
scriptcode = scriptcode.slice(1);
|
||||
scriptcode.unshift(25, 118, 169);
|
||||
scriptcode.push(136, 172);
|
||||
/* P2WPKH */
|
||||
if(scriptcode.length == 20){
|
||||
scriptcode = [0x00,0x14].concat(scriptcode);
|
||||
}
|
||||
|
||||
if(scriptcode.length == 22){
|
||||
scriptcode = scriptcode.slice(1);
|
||||
scriptcode.unshift(25, 118, 169);
|
||||
scriptcode.push(136, 172);
|
||||
}
|
||||
|
||||
var value = coinjs.numToBytes(extract['value'], 8);
|
||||
|
||||
@ -1120,8 +1342,7 @@
|
||||
} else if(this.ins[index].script.chunks.length == 5 && this.ins[index].script.chunks[1] == 177){//OP_CHECKLOCKTIMEVERIFY
|
||||
// hodl script (not signed)
|
||||
return {'type':'hodl', 'signed':'false', 'signatures': 0, 'script': Crypto.util.bytesToHex(this.ins[index].script.buffer)};
|
||||
} else if((this.ins[index].script.chunks.length <= 3 && this.ins[index].script.chunks.length > 0) && this.ins[index].script.chunks[0].length == 22 && this.ins[index].script.chunks[0][0] == 0){
|
||||
// segwit script
|
||||
} else if((this.ins[index].script.chunks.length <= 3 && this.ins[index].script.chunks.length > 0) && ((this.ins[index].script.chunks[0].length == 22 && this.ins[index].script.chunks[0][0] == 0) || (this.ins[index].script.chunks[0].length == 20 && this.ins[index].script.chunks[1] == 0))){
|
||||
var signed = ((this.witness[index]) && this.witness[index].length==2) ? 'true' : 'false';
|
||||
var sigs = (signed == 'true') ? 1 : 0;
|
||||
var value = -1; // no value found
|
||||
@ -1131,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)};
|
||||
@ -1350,30 +1578,61 @@
|
||||
|
||||
var wif2 = coinjs.wif2pubkey(wif);
|
||||
var segwit = coinjs.segwitAddress(wif2['pubkey']);
|
||||
var bech32 = coinjs.bech32Address(wif2['pubkey']);
|
||||
|
||||
if(segwit['redeemscript'] == Crypto.util.bytesToHex(this.ins[index].script.chunks[0])){
|
||||
if((segwit['redeemscript'] == Crypto.util.bytesToHex(this.ins[index].script.chunks[0])) || (bech32['redeemscript'] == Crypto.util.bytesToHex(this.ins[index].script.chunks[0]))){
|
||||
var txhash = this.transactionHashSegWitV0(index, shType);
|
||||
|
||||
if(txhash.result == 1){
|
||||
|
||||
var segwitHash = Crypto.util.hexToBytes(txhash.hash);
|
||||
var signature = this.transactionSig(index, wif, shType, segwitHash);
|
||||
|
||||
|
||||
// remove any non standard data we store, i.e. input value
|
||||
var script = coinjs.script();
|
||||
script.writeBytes(this.ins[index].script.chunks[0]);
|
||||
this.ins[index].script = script;
|
||||
|
||||
if(!coinjs.isArray(this.witness)){
|
||||
this.witness = [];
|
||||
}
|
||||
|
||||
this.witness.push([signature, wif2['pubkey']]);
|
||||
|
||||
/* reorder witness data */
|
||||
/* attempt to reorder witness data as best as we can.
|
||||
data can't be easily validated at this stage as
|
||||
we dont have access to the inputs value and
|
||||
making a web call will be too slow. */
|
||||
|
||||
var witness_order = [];
|
||||
var witness_used = [];
|
||||
for(var i = 0; i < this.ins.length; i++){
|
||||
for(var y = 0; y < this.witness.length; y++){
|
||||
var sw = coinjs.segwitAddress(this.witness[y][1]);
|
||||
if(sw['redeemscript'] == Crypto.util.bytesToHex(this.ins[i].script.chunks[0])){
|
||||
witness_order.push(this.witness[y]);
|
||||
if(!witness_used.includes(y)){
|
||||
var sw = coinjs.segwitAddress(this.witness[y][1]);
|
||||
var b32 = coinjs.bech32Address(this.witness[y][1]);
|
||||
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);
|
||||
|
||||
// bech32, empty redeemscript
|
||||
if(b32['redeemscript'] == rs){
|
||||
this.ins[index].script = coinjs.script();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.witness = witness_order;
|
||||
}
|
||||
}
|
||||
@ -1414,7 +1673,7 @@
|
||||
var buffer = [];
|
||||
buffer = buffer.concat(coinjs.numToBytes(parseInt(this.version),4));
|
||||
|
||||
if(this.witness.length>=1){
|
||||
if(coinjs.isArray(this.witness)){
|
||||
buffer = buffer.concat([0x00, 0x01]);
|
||||
}
|
||||
|
||||
@ -1438,7 +1697,7 @@
|
||||
buffer = buffer.concat(scriptBytes);
|
||||
}
|
||||
|
||||
if(this.witness.length>=1){
|
||||
if((coinjs.isArray(this.witness)) && this.witness.length>=1){
|
||||
for(var i = 0; i < this.witness.length; i++){
|
||||
buffer = buffer.concat(coinjs.numToVarInt(this.witness[i].length));
|
||||
for(var x = 0; x < this.witness[i].length; x++){
|
||||
@ -1721,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) {
|
||||
|
||||
822
js/coinbin.js
822
js/coinbin.js
File diff suppressed because it is too large
Load Diff
14
sha1sum
14
sha1sum
@ -1,9 +1,9 @@
|
||||
---- Version 1.3 2017.09.10 ----
|
||||
---- Version 1.6 2020.10.02 ----
|
||||
77e4519962e2f6a9fc93342137dbb31c33b76b04 ./js/aes.js
|
||||
3a09a8fc0cfe828b57fc798d668234d0490ee1a6 ./js/bootstrap-datetimepicker.min.js
|
||||
253711c6d825de55a8360552573be950da180614 ./js/bootstrap.min.js
|
||||
b98f718f0400fada4e0f15471031f92ce31e2b83 ./js/coinbin.js
|
||||
3e7b9b1a30412f827d4709a53014d0b6f06103f0 ./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
|
||||
@ -21,7 +21,8 @@ ad038e1f39646b68ae666324ed4c2882a8c42474 ./js/qrcode.js
|
||||
255c58c17e63eb54adb3cd02b5c06224c67fc364 ./css/bootstrap-datetimepicker.min.css
|
||||
ed29315e0ffb3f14382431f2724235bf67f44eb3 ./css/bootstrap.min.css
|
||||
fc6b4268fbd57ad95d2b41a1d4d6866f222fbdb2 ./css/bootstrap-theme.min.css
|
||||
4198ed869836ea5727ad6b80bf2df0a9c1a83244 ./css/style.css
|
||||
eb54f374256b75a17f274847b4ca9985fd046f9f ./css/style.css
|
||||
2e3217a3f3b7c2fb30562ab9a4ef9a407ae81897 ./images/btc32x.png
|
||||
8ac24915d59cef71c542e7cb7d7e153f560cba1f ./images/coinbin.gif
|
||||
f2af060f1cadbc9065c8c465c648dc01be67cc12 ./images/loader.gif
|
||||
86b6f62b7853e67d3e635f6512a5a5efc58ea3c3 ./fonts/glyphicons-halflings-regular.eot
|
||||
@ -29,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
|
||||
d8a324a13501cd5705dc26b945fc8088f00907ae ./README.md
|
||||
da6e4cbb4a168a3583086e0997c8c678a7a80925 ./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