diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index 3ba07b69..aea27e3d 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -545,6 +545,14 @@ TX.prototype.signatureHashV0 = function signatureHashV0(index, prev, type) { bw.writeU32(this.locktime); + var fOmitTxComment = !!(type & hashType.OMIT_TX_COMMENT); + + if (this.version >= 2 && !fOmitTxComment) { + bw.writeVarBytes(Buffer.from(this.strFloData)); + } + + type &= ~hashType.OMIT_TX_COMMENT; + // Append the hash type. bw.writeU32(type); @@ -594,6 +602,19 @@ TX.prototype.hashSize = function hashSize(index, prev, type) { break; } + var fOmitTxComment = !!(type & hashType.OMIT_TX_COMMENT); + + if (!fOmitTxComment){ + let bufferLength = Buffer.from(this.strFloData).length; + + if (this.strFloData.length > 0){ + size += encoding.sizeVarint(bufferLength); + size += bufferLength + } else { + size += encoding.sizeVarint(0); + } + } + size += 8; return size; @@ -709,10 +730,19 @@ TX.prototype.checksig = function checksig(index, prev, value, sig, key, version) if (sig.length === 0) return false; - const type = sig[sig.length - 1]; - const hash = this.signatureHash(index, prev, value, type, version); + let type = sig[sig.length - 1]; + let signature = sig.slice(0, -1); + let hash = this.signatureHash(index, prev, value, type, version); - return secp256k1.verify(hash, sig.slice(0, -1), key); + if (secp256k1.verify(hash, signature, key)){ + return true; + } else { + type ^= hashType.OMIT_TX_COMMENT; + + hash = this.signatureHash(index, prev, value, type, version); + + return secp256k1.verify(hash, signature, key); + } }; /** @@ -2194,7 +2224,8 @@ TX.prototype.getJSON = function getJSON(network, view, entry, index) { return output.getJSON(network); }), locktime: this.locktime, - hex: this.toRaw().toString('hex') + hex: this.toRaw().toString('hex'), + floData: this.strFloData }; }; @@ -2296,7 +2327,7 @@ TX.prototype.fromReader = function fromReader(br) { if (this.version >= 2){ var floDataBuffer = br.readVarBytes(); - this.floDataStr = Buffer.from(floDataBuffer).toString(); + this.strFloData = Buffer.from(floDataBuffer).toString(); } if (!this.mutable) { @@ -2369,7 +2400,7 @@ TX.prototype.fromWitnessReader = function fromWitnessReader(br) { if (this.version >= 2){ var floDataLength = br.readVarint(); var floDataBuffer = br.readBytes(floDataLength); - this.floDataStr = Buffer.from(floDataBuffer).toString(); + this.strFloData = Buffer.from(floDataBuffer).toString(); } if (!this.mutable && hasWitness) { @@ -2438,7 +2469,6 @@ TX.prototype.writeNormal = function writeNormal(bw) { bw.writeU32(this.locktime); if (this.version >= 2){ - bw.writeVarint(this.strFloData); bw.writeVarBytes(Buffer.from(this.strFloData)); } @@ -2507,6 +2537,17 @@ TX.prototype.getNormalSizes = function getNormalSizes() { for (const output of this.outputs) base += output.getSize(); + if (this.version >= 2){ + let bufferLength = Buffer.from(this.strFloData).length; + + if (this.strFloData.length > 0){ + base += encoding.sizeVarint(bufferLength); + base += bufferLength + } else { + base += encoding.sizeVarint(0); + } + } + base += 4; return new RawTX(base, 0); diff --git a/lib/script/common.js b/lib/script/common.js index 4313a329..02c0d8e0 100644 --- a/lib/script/common.js +++ b/lib/script/common.js @@ -286,7 +286,13 @@ exports.hashType = { * Sign only the current input (mask). */ - ANYONECANPAY: 0x80 + ANYONECANPAY: 0x80, + + /* + * Omit the Flo TX Comment from the signature + */ + + OMIT_TX_COMMENT: (1 << 6) }; /** diff --git a/lib/script/script.js b/lib/script/script.js index 751ea81e..2f71e3f0 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -1169,9 +1169,21 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers let res = false; if (sig.length > 0) { - const type = sig[sig.length - 1]; - const hash = tx.signatureHash(index, subscript, value, type, version); - res = checksig(hash, sig, key); + let type = sig[sig.length - 1]; + let hash; + + try { + hash = tx.signatureHash(index, subscript, value, type, version); + res = checksig(hash, sig, key); + } catch (e) {} + + if (!res){ + type ^= Script.hashType.OMIT_TX_COMMENT; + try { + hash = tx.signatureHash(index, subscript, value, type, version); + res = checksig(hash, sig, key); + } catch (e) {} + } } if (!res && (flags & Script.flags.VERIFY_NULLFAIL)) { diff --git a/package.json b/package.json index ade89446..5bc8a964 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fcoin", - "version": "1.0.0-beta.16", + "version": "1.0.0-beta.17", "description": "Flo bike-shed", "license": "MIT", "repository": "git://github.com/oipwg/fcoin.git",