From 3ba79f0e3d85a13031a211744f085ff753172b1a Mon Sep 17 00:00:00 2001 From: Daniel Weigl Date: Sun, 3 Jul 2016 19:22:23 +0200 Subject: [PATCH 1/2] Error in serialization for nLockTime values if nLockTime is 1234(decimal) -> thats 4D2(hex) -> The current code splits it beginning from the end into bytes -> [4d, 02], but it should be [4, d2]. Error only occurs if one of the bytes is <16 --- js/coin.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/js/coin.js b/js/coin.js index c7b2efb..1971de9 100644 --- a/js/coin.js +++ b/js/coin.js @@ -148,7 +148,7 @@ } var s = coinjs.script(); - s.writeBytes(Crypto.util.hexToBytes(checklocktimeverify.toString(16)).reverse()); + s.writeBytes(coinjs.numToByteArray(checklocktimeverify).reverse()); s.writeOp(177);//OP_CHECKLOCKTIMEVERIFY s.writeOp(117);//OP_DROP s.writeBytes(Crypto.util.hexToBytes(pubkey)); @@ -687,7 +687,7 @@ // ^ OP_CHECKLOCKTIMEVERIFY OP_DROP OP_CHECKSIG ^ r = {} r.pubkey = Crypto.util.bytesToHex(s.chunks[3]); - r.checklocktimeverify = parseInt(Crypto.util.bytesToHex(s.chunks[0].slice().reverse()), 16); + r.checklocktimeverify = coinjs.bytesToNum(s.chunks[0].slice().reverse()); r.address = coinjs.simpleHodlAddress(r.pubkey, r.checklocktimeverify).address; r.type = "hodl__"; } @@ -1454,6 +1454,14 @@ } } + coinjs.numToByteArray = function(num) { + if (num <= 256) { + return [num]; + } else { + return [num % 256].concat(coinjs.numToByteArray(Math.floor(num / 256))); + } + } + coinjs.numToVarInt = function(num) { if (num < 253) { return [num]; From 347ccf4947fb8006a1b0310f5ebc7564bb3bfa18 Mon Sep 17 00:00:00 2001 From: Daniel Weigl Date: Sun, 3 Jul 2016 19:28:47 +0200 Subject: [PATCH 2/2] Allow HODL transaction to define nLockTime in blockheight or date/time it still has a small UX quirks: the radio buttons dont get restored correctly after page reload --- index.html | 14 +++++++++++++- js/coinbin.js | 32 ++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 759bb70..7892ad7 100644 --- a/index.html +++ b/index.html @@ -408,7 +408,16 @@ -

Enter the date and time required to release the coins:

+

+ Enter the + + + or + + + + required to release the coins: +

@@ -418,6 +427,9 @@
+
diff --git a/js/coinbin.js b/js/coinbin.js index 6d21b7a..7c7ffc4 100644 --- a/js/coinbin.js +++ b/js/coinbin.js @@ -369,6 +369,16 @@ $(document).ready(function() { format: "MM/DD/YYYY HH:mm", }); + $('#timeLockedRbTypeBox input').change(function(){ + if ($('#timeLockedRbTypeDate').is(':checked')){ + $('#timeLockedDateTimePicker').show(); + $('#timeLockedBlockHeight').hide(); + } else { + $('#timeLockedDateTimePicker').hide(); + $('#timeLockedBlockHeight').removeClass('hidden').show(); + } + }); + $("#newTimeLockedAddress").click(function(){ $("#timeLockedData").removeClass('show').addClass('hidden').fadeOut(); @@ -380,14 +390,28 @@ $(document).ready(function() { $('#timeLockedPubKey').parent().addClass('has-error'); } - var date = $('#timeLockedDateTimePicker').data("DateTimePicker").date(); - if(!date || !date.isValid()) { - $('#timeLockedDateTimePicker').parent().addClass('has-error'); + var nLockTime = -1; + + if ($('#timeLockedRbTypeDate').is(':checked')){ + // by date + var date = $('#timeLockedDateTimePicker').data("DateTimePicker").date(); + if(!date || !date.isValid()) { + $('#timeLockedDateTimePicker').parent().addClass('has-error'); + } + nLockTime = date.unix() + if (nLockTime < 500000000) { + $('#timeLockedDateTimePicker').parent().addClass('has-error'); + } + } else { + nLockTime = parseInt($('#timeLockedBlockHeightVal').val(), 10); + if (nLockTime >= 500000000) { + $('#timeLockedDateTimePicker').parent().addClass('has-error'); + } } if(($("#timeLockedPubKey").parent().hasClass('has-error')==false) && $("#timeLockedDateTimePicker").parent().hasClass('has-error')==false){ try { - var hodl = coinjs.simpleHodlAddress($("#timeLockedPubKey").val(), date.unix()); + var hodl = coinjs.simpleHodlAddress($("#timeLockedPubKey").val(), nLockTime); $("#timeLockedData .address").val(hodl['address']); $("#timeLockedData .script").val(hodl['redeemScript']); $("#timeLockedData .scriptUrl").val(document.location.origin+''+document.location.pathname+'?verify='+hodl['redeemScript']+'#verify');