Fix transaction signing
This commit is contained in:
parent
5a300e785f
commit
84aabe20a9
@ -439,10 +439,11 @@ class TX {
|
|||||||
* @param {Amount} value - Previous output value.
|
* @param {Amount} value - Previous output value.
|
||||||
* @param {SighashType} type - Sighash type.
|
* @param {SighashType} type - Sighash type.
|
||||||
* @param {Number} version - Sighash version (0=legacy, 1=segwit).
|
* @param {Number} version - Sighash version (0=legacy, 1=segwit).
|
||||||
|
* @param {Boolean} [includeFloData=true] - Should floData be included in the signature Hash
|
||||||
* @returns {Buffer} Signature hash.
|
* @returns {Buffer} Signature hash.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
signatureHash(index, prev, value, type, version) {
|
signatureHash(index, prev, value, type, version, includeFloData = true) {
|
||||||
assert(index >= 0 && index < this.inputs.length);
|
assert(index >= 0 && index < this.inputs.length);
|
||||||
assert(prev instanceof Script);
|
assert(prev instanceof Script);
|
||||||
assert(typeof value === 'number');
|
assert(typeof value === 'number');
|
||||||
@ -450,11 +451,11 @@ class TX {
|
|||||||
|
|
||||||
// Traditional sighashing
|
// Traditional sighashing
|
||||||
if (version === 0)
|
if (version === 0)
|
||||||
return this.signatureHashV0(index, prev, type);
|
return this.signatureHashV0(index, prev, type, includeFloData);
|
||||||
|
|
||||||
// Segwit sighashing
|
// Segwit sighashing
|
||||||
if (version === 1)
|
if (version === 1)
|
||||||
return this.signatureHashV1(index, prev, value, type);
|
return this.signatureHashV1(index, prev, value, type, includeFloData);
|
||||||
|
|
||||||
throw new Error('Unknown sighash version.');
|
throw new Error('Unknown sighash version.');
|
||||||
}
|
}
|
||||||
@ -465,10 +466,11 @@ class TX {
|
|||||||
* @param {Number} index
|
* @param {Number} index
|
||||||
* @param {Script} prev
|
* @param {Script} prev
|
||||||
* @param {SighashType} type
|
* @param {SighashType} type
|
||||||
|
* @param {Boolean} [includeFloData=true] - Should floData be included in the signature Hash
|
||||||
* @returns {Buffer}
|
* @returns {Buffer}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
signatureHashV0(index, prev, type) {
|
signatureHashV0(index, prev, type, includeFloData = true) {
|
||||||
if ((type & 0x1f) === hashType.SINGLE) {
|
if ((type & 0x1f) === hashType.SINGLE) {
|
||||||
// Bitcoind used to return 1 as an error code:
|
// Bitcoind used to return 1 as an error code:
|
||||||
// it ended up being treated like a hash.
|
// it ended up being treated like a hash.
|
||||||
@ -483,7 +485,7 @@ class TX {
|
|||||||
prev = prev.removeSeparators();
|
prev = prev.removeSeparators();
|
||||||
|
|
||||||
// Calculate buffer size.
|
// Calculate buffer size.
|
||||||
const size = this.hashSize(index, prev, type);
|
const size = this.hashSize(index, prev, type, includeFloData);
|
||||||
const bw = bio.pool(size);
|
const bw = bio.pool(size);
|
||||||
|
|
||||||
bw.writeU32(this.version);
|
bw.writeU32(this.version);
|
||||||
@ -574,14 +576,10 @@ class TX {
|
|||||||
|
|
||||||
bw.writeU32(this.locktime);
|
bw.writeU32(this.locktime);
|
||||||
|
|
||||||
var fOmitTxComment = !!(type & hashType.OMIT_TX_COMMENT);
|
if (this.version >= 2 && includeFloData) {
|
||||||
|
|
||||||
if (this.version >= 2 && !fOmitTxComment) {
|
|
||||||
bw.writeVarBytes(Buffer.from(this.strFloData));
|
bw.writeVarBytes(Buffer.from(this.strFloData));
|
||||||
}
|
}
|
||||||
|
|
||||||
type &= ~hashType.OMIT_TX_COMMENT;
|
|
||||||
|
|
||||||
// Append the hash type.
|
// Append the hash type.
|
||||||
bw.writeU32(type);
|
bw.writeU32(type);
|
||||||
|
|
||||||
@ -597,7 +595,7 @@ class TX {
|
|||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hashSize(index, prev, type) {
|
hashSize(index, prev, type, includeFloData = true) {
|
||||||
let size = 0;
|
let size = 0;
|
||||||
|
|
||||||
size += 4;
|
size += 4;
|
||||||
@ -631,17 +629,11 @@ class TX {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fOmitTxComment = !!(type & hashType.OMIT_TX_COMMENT);
|
if (includeFloData){
|
||||||
|
|
||||||
if (!fOmitTxComment){
|
|
||||||
let bufferLength = Buffer.from(this.strFloData).length;
|
let bufferLength = Buffer.from(this.strFloData).length;
|
||||||
|
|
||||||
if (this.strFloData.length > 0){
|
size += encoding.sizeVarint(bufferLength);
|
||||||
size += encoding.sizeVarint(bufferLength);
|
size += bufferLength
|
||||||
size += bufferLength
|
|
||||||
} else {
|
|
||||||
size += encoding.sizeVarint(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size += 8;
|
size += 8;
|
||||||
@ -656,10 +648,11 @@ class TX {
|
|||||||
* @param {Script} prev
|
* @param {Script} prev
|
||||||
* @param {Amount} value
|
* @param {Amount} value
|
||||||
* @param {SighashType} type
|
* @param {SighashType} type
|
||||||
|
* @param {Boolean} [includeFloData=true] - Should floData be included in the signature Hash
|
||||||
* @returns {Buffer}
|
* @returns {Buffer}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
signatureHashV1(index, prev, value, type) {
|
signatureHashV1(index, prev, value, type, includeFloData = true) {
|
||||||
const input = this.inputs[index];
|
const input = this.inputs[index];
|
||||||
let prevouts = consensus.ZERO_HASH;
|
let prevouts = consensus.ZERO_HASH;
|
||||||
let sequences = consensus.ZERO_HASH;
|
let sequences = consensus.ZERO_HASH;
|
||||||
@ -741,13 +734,10 @@ class TX {
|
|||||||
bw.writeU32(this.locktime);
|
bw.writeU32(this.locktime);
|
||||||
|
|
||||||
// Add the FloData to the transaction
|
// Add the FloData to the transaction
|
||||||
if (this.version >= 2 && !fOmitTxComment) {
|
if (this.version >= 2 && includeFloData) {
|
||||||
bw.writeVarBytes(Buffer.from(this.strFloData));
|
bw.writeVarBytes(Buffer.from(this.strFloData));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the OMIT_TX_COMMENT flag if included
|
|
||||||
type &= ~hashType.OMIT_TX_COMMENT;
|
|
||||||
|
|
||||||
bw.writeU32(type);
|
bw.writeU32(type);
|
||||||
|
|
||||||
return hash256.digest(bw.render());
|
return hash256.digest(bw.render());
|
||||||
@ -770,15 +760,12 @@ class TX {
|
|||||||
|
|
||||||
let type = sig[sig.length - 1];
|
let type = sig[sig.length - 1];
|
||||||
let signature = sig.slice(0, -1);
|
let signature = sig.slice(0, -1);
|
||||||
let hash = this.signatureHash(index, prev, value, type, version);
|
let hash = this.signatureHash(index, prev, value, type, version, true);
|
||||||
|
|
||||||
if (secp256k1.verifyDER(hash, signature, key)){
|
if (secp256k1.verifyDER(hash, signature, key)){
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
type ^= hashType.OMIT_TX_COMMENT;
|
hash = this.signatureHash(index, prev, value, type, version, false);
|
||||||
|
|
||||||
hash = this.signatureHash(index, prev, value, type, version);
|
|
||||||
|
|
||||||
return secp256k1.verifyDER(hash, signature, key);
|
return secp256k1.verifyDER(hash, signature, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -803,7 +790,7 @@ class TX {
|
|||||||
if (version == null)
|
if (version == null)
|
||||||
version = 0;
|
version = 0;
|
||||||
|
|
||||||
const hash = this.signatureHash(index, prev, value, type, version);
|
const hash = this.signatureHash(index, prev, value, type, version, true);
|
||||||
const sig = secp256k1.signDER(hash, key);
|
const sig = secp256k1.signDER(hash, key);
|
||||||
const bw = bio.write(sig.length + 1);
|
const bw = bio.write(sig.length + 1);
|
||||||
|
|
||||||
|
|||||||
@ -1135,19 +1135,17 @@ class Script {
|
|||||||
let hash;
|
let hash;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
hash = tx.signatureHash(index, subscript, value, type, version);
|
hash = tx.signatureHash(index, subscript, value, type, version, true);
|
||||||
res = checksig(hash, sig, key);
|
res = checksig(hash, sig, key);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Having issues with signatures? Log this error then!
|
// Having issues with signatures? Log this error then!
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!res){
|
if (!res){
|
||||||
type ^= Script.hashType.OMIT_TX_COMMENT;
|
|
||||||
try {
|
try {
|
||||||
hash = tx.signatureHash(index, subscript, value, type, version);
|
hash = tx.signatureHash(index, subscript, value, type, version, false);
|
||||||
res = checksig(hash, sig, key);
|
res = checksig(hash, sig, key);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Having issues with signatures? Log this error then!
|
|
||||||
throw new ScriptError('CHECKSIGVERIFY_ERROR', e)
|
throw new ScriptError('CHECKSIGVERIFY_ERROR', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -68,7 +68,7 @@ const errs = {
|
|||||||
WALLET_ALREADY_UNLOCKED: -17
|
WALLET_ALREADY_UNLOCKED: -17
|
||||||
};
|
};
|
||||||
|
|
||||||
const MAGIC_STRING = 'Bitcoin Signed Message:\n';
|
const MAGIC_STRING = 'Florincoin Signed Message:\n';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wallet RPC
|
* Wallet RPC
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user