better sighash support for the gui, plus bug fixes and testing

This commit is contained in:
OutCast3k 2017-02-17 15:38:24 +00:00
parent d12b9d9072
commit 1f9d9e97c2
4 changed files with 105 additions and 57 deletions

View file

@ -884,6 +884,7 @@
<div class="tab-pane tab-content" id="sign">
<h2>Sign Transaction <small>once a transaction has been verified</small></h2>
<p>Once you have <a href="#verify">verified</a> a transaction you can sign and then <a href="#broadcast">broadcast</a> it into the network.</p>
<div class="row">
<div class="col-md-12">
<label for="signPrivateKey">Private key</label>
@ -905,6 +906,33 @@
</div>
<br>
<a href="javascript:;" id="signAdvancedCollapse">
<div class="well well-sm"><span class="glyphicon glyphicon-collapse-down"></span> Advanced Options</div>
</a>
<div id="signAdvanced" class="hidden">
<div class="row">
<div class="col-md-12">
<label for="sighashType">Sig Hash Type</label>
<select id="sighashType" class="form-control">
<option value="1" rel="SIGHASH_ALL: Signs all the inputs and outputs, protecting everything against modification.">ALL (default)</option>
<option value="2" rel="SIGHASH_NONE: Signs all of the inputs but none of the outputs, allowing anyone to change where the satoshis are going unless other signatures using other signature hash flags protect the outputs.">NONE</option>
<option value="3" rel="SIGHASH_SINGLE: The only output signed is the one corresponding to this input, ensuring nobody can change your part of the transaction but allowing other signers to change their part of the transaction.">SINGLE</option>
<option value="129" rel="SIGHASH_ALL|SIGHASH_ANYONECANPAY: Signs all of the outputs but only this one input, it allows anyone to add or remove other inputs, so anyone can contribute additional satoshis but they cannot change how many satoshis are sent nor where they go.">ALL|ANYONECANPAY</option>
<option value="130" rel="SIGHASH_NONE|SIGHASH_ANYONECANPAY: Signs only this one input and allows anyone to add or remove other inputs or outputs, so anyone who gets a copy of this input can spend it however they'd like.">NONE|ANYONECANPAY</option>
<option value="131" rel="SIGHASH_SINGLE|SIGHASH_ANYONECANPAY: Signs this one input and its corresponding output. Allows anyone to add or remove other inputs.">SINGLE|ANYONECANPAY</option>
</select>
</div>
</div>
<br>
<div class="alert alert-info" id="sighashTypeInfo">
SIGHASH_ALL: The default, signs all the inputs and outputs, protecting everything except the signature scripts against modification.
</div>
</div>
<div class="alert alert-danger hidden" id="signedDataError">
<span class="glyphicon glyphicon-exclamation-sign"></span> There is a problem with one or more of your inputs, please check and try again
</div>

View file

@ -916,23 +916,26 @@
var clone = coinjs.clone(this);
var shType = sigHashType || 1;
/* black out all other ins, except this one */
for (var i = 0; i < clone.ins.length; i++) {
if(index!=i){
clone.ins[i].script = coinjs.script();
}
}
var extract = this.extractScriptKey(index);
clone.ins[index].script = coinjs.script(extract['script']);
if((clone.ins) && clone.ins[index]){
/* black out all other ins, except this one */
for (var i = 0; i < clone.ins.length; i++) {
if(index!=i){
clone.ins[i].script = coinjs.script();
}
}
/* SIGHASH : For more info on sig hashs see https://en.bitcoin.it/wiki/OP_CHECKSIG
and https://bitcoin.org/en/developer-guide#signature-hash-type */
/* SIGHASH : For more info on sig hashs see https://en.bitcoin.it/wiki/OP_CHECKSIG
and https://bitcoin.org/en/developer-guide#signature-hash-type */
if(shType == 1){
//SIGHASH_ALL 0x01 #t
//SIGHASH_ALL 0x01
} else if(shType == 2){
//SIGHASH_NONE 0x02 #t
//SIGHASH_NONE 0x02
clone.outs = [];
for (var i = 0; i < clone.ins.length; i++) {
if(index!=i){
@ -941,39 +944,42 @@
}
} else if(shType == 3){
//SIGHASH_SINGLE 0x03 #t
for (var i = 0; i < clone.outs.length; i++) {
if(index!=i){
clone.outs[i].value = new BigInteger('' + Math.round((0) * 1e8), 10);
clone.outs[i].script = coinjs.script();
}
//SIGHASH_SINGLE 0x03
clone.outs.length = index + 1;
for(var i = 0; i < index; i++){
clone.outs[i].value = -1;
clone.outs[i].script.buffer = [];
}
} else if(shType >= 128){
//SIGHASH_ANYONECANPAY 0x80 #t
clone.ins = [this.ins[index]];
clone.ins[0].script = this.ins[index].script;
if(shType>128){
if(shType==129){
// SIGHASH_ALL + SIGHASH_ANYONECANPAY
} else if(shType==130){
// SIGHASH_NONE + SIGHASH_ANYONECANPAY #t
clone.outs = [];
} else if(shType==131){
// SIGHASH_SINGLE + SIGHASH_ANYONECANPAY
for (var i = 0; i < clone.outs.length; i++) {
if(index!=i){
clone.outs[i].value = new BigInteger('' + Math.round((0) * 1e8), 10);
clone.outs[i].script = coinjs.script();
}
}
for (var i = 0; i < clone.ins.length; i++) {
if(index!=i){
clone.ins[i].sequence = 0;
}
}
} else if (shType >= 128){
//SIGHASH_ANYONECANPAY 0x80
clone.ins = [clone.ins[index]];
if(shType==129){
// SIGHASH_ALL + SIGHASH_ANYONECANPAY
} else if(shType==130){
// SIGHASH_NONE + SIGHASH_ANYONECANPAY
clone.outs = [];
} else if(shType==131){
// SIGHASH_SINGLE + SIGHASH_ANYONECANPAY
clone.outs.length = index + 1;
for(var i = 0; i < index; i++){
clone.outs[i].value = -1;
clone.outs[i].script.buffer = [];
}
}
}
var extract = this.extractScriptKey(index);
clone.ins[index].script = coinjs.script(extract['script']);
var buffer = Crypto.util.hexToBytes(clone.serialize());
buffer = buffer.concat(coinjs.numToBytes(parseInt(shType), 4));
var hash = Crypto.SHA256(buffer, {asBytes: true});
@ -1185,29 +1191,28 @@
}
var redeemScript = (this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]==174) ? this.ins[index].script.buffer : this.ins[index].script.chunks[this.ins[index].script.chunks.length-1];
var pubkeyList = scriptListPubkey(coinjs.script(redeemScript));
var sigsList = scriptListSigs(this.ins[index].script);
var shType = sigHashType || 1;
var sighash = Crypto.util.hexToBytes(this.transactionHash(index, shType));
var signature = Crypto.util.hexToBytes(this.transactionSig(index, wif, shType));
sigsList[coinjs.countObject(sigsList)+1] = signature;
var s = coinjs.script();
s.writeOp(0);
if(this.ins[index].script.chunks[this.ins[index].script.chunks.length-1]==174){
s.writeBytes(signature);
} 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){
var pubkeyList = scriptListPubkey(coinjs.script(redeemScript));
var sigsList = scriptListSigs(this.ins[index].script);
sigsList[coinjs.countObject(sigsList)+1] = signature;
for(x in pubkeyList){
for(y in sigsList){
if(coinjs.verifySignature(sighash, sigsList[y], pubkeyList[x])){
s.writeBytes(sigsList[y]);
}
for(x in pubkeyList){
for(y in sigsList){
this.ins[index].script.buffer = redeemScript;
sighash = Crypto.util.hexToBytes(this.transactionHash(index, sigsList[y].slice(-1)[0]*1));
if(coinjs.verifySignature(sighash, sigsList[y], pubkeyList[x])){
s.writeBytes(sigsList[y]);
}
}
}
s.writeBytes(redeemScript);
@ -1505,6 +1510,8 @@
if (typeof bytes === "undefined") bytes = 8;
if (bytes == 0) {
return [];
} else if (num == -1){
return Crypto.util.hexToBytes("ffffffffffffffff");
} else {
return [num % 256].concat(coinjs.numToBytes(Math.floor(num / 256),bytes-1));
}

View file

@ -1488,7 +1488,7 @@ $(document).ready(function() {
var tx = coinjs.transaction();
var t = tx.deserialize(script.val());
var signed = t.sign(wifkey.val());
var signed = t.sign(wifkey.val(), $("#sighashType option:selected").val());
$("#signedData textarea").val(signed);
$("#signedData .txSize").html(t.size());
$("#signedData").removeClass('hidden').fadeIn();
@ -1501,6 +1501,19 @@ $(document).ready(function() {
}
});
$("#sighashType").change(function(){
$("#sighashTypeInfo").html($("option:selected",this).attr('rel')).fadeOut().fadeIn();
});
$("#signAdvancedCollapse").click(function(){
if($("#signAdvanced").hasClass('hidden')){
$("span",this).removeClass('glyphicon-collapse-down').addClass('glyphicon-collapse-up');
$("#signAdvanced").removeClass("hidden");
} else {
$("span",this).removeClass('glyphicon-collapse-up').addClass('glyphicon-collapse-down');
$("#signAdvanced").addClass("hidden");
}
});
/* page load code */

View file

@ -1,9 +1,9 @@
---- Version 1.2 2017.02.10 ----
---- Version 1.2 2017.02.17 ----
77e4519962e2f6a9fc93342137dbb31c33b76b04 ./js/aes.js
3a09a8fc0cfe828b57fc798d668234d0490ee1a6 ./js/bootstrap-datetimepicker.min.js
253711c6d825de55a8360552573be950da180614 ./js/bootstrap.min.js
bbc88d46bbc8a10def8336a5deb1902863539d46 ./js/coinbin.js
c16f136373fb4df3d04bff0e65e07635fa1812b6 ./js/coin.js
0ee30f1dc9e38c62e99022e185706969ccfd14f1 ./js/coinbin.js
f23a41e5bf56b98790c68502feae569459a60341 ./js/coin.js
988565bc2cb402d63ed5c5fd7ff47c4278efc2c5 ./js/collapse.js
9ba5ede3d7f9d4c8fd623395f196adfdcf7e970f ./js/crypto-min.js
f7c09f2f5a721371e7d478050119f7e2d58e3ef9 ./js/crypto-sha256-hmac.js
@ -30,4 +30,4 @@ de51a8494180a6db074af2dee2383f0a363c5b08 ./fonts/glyphicons-halflings-regular.s
278e49a86e634da6f2a02f3b47dd9d2a8f26210f ./fonts/glyphicons-halflings-regular.woff
44bc1850f570972267b169ae18f1cb06b611ffa2 ./fonts/glyphicons-halflings-regular.ttf
b4d3a33913a0877684909f7edf8b79bf9192b0a7 ./README.md
e4f5289b5d3d626405bb071560e58d53622208b5 ./index.html
3b0c0def7addfffad28a8d83f6a279ca7ceff5f7 ./index.html