-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Transaction: get normalized hash / id #355
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/transaction.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: please adhere to project style by adding whitespace after the if keyword, and always use strict equality where possible.
if (hashScript !== null && inIndex >= 0) {
txTmp.ins[inIndex].script = hashScript
}|
Everything looks great after you fix the above comments :). The only remaining question is, what problems does this solve? return this.hashForSignature(-1, null, Transaction.SIGHASH_ALL)It returns a hash which accounts for all inputs disregarding their script signatures. I feel like there is a hidden gotcha in what might allow unknowing users to use this without knowing its consequence... however, granted, they might use the standard Id/Hash also... @gmaxwell makes a succinct case-in point why this could be a bad idea. The Bitcoin core team eventually voted against merging it, but it should be noted large companies like Coinbase mentioned that they did use a normalized hash internally. bitcoinj have no such thing. The Bitcore team merged it. @ryanxcharles, thoughts on whether you felt normalized hash has had a positive net gain for Bitcore? (or even https://github.com/ryanxcharles/fullnode) |
|
Also pinging @jprichardson, @locksley, @weilu |
|
@mhanne I'm almost tempted to not add the methods, but allow for the parameter support of: return this.hashForSignature(-1, null, Transaction.SIGHASH_ALL)Which you have only just added, that way the implications are obvious, but the potential for mistakes by users who don't know what the implications are, is hopefully less. |
5257d56 to
3e4ae73
Compare
|
Alright, I fixed the issues you mentioned, thanks for pointing it out :) I think there is a valid use for an identifier of a specific set of changes to the current state of the blockchain. If you look at it like that, it's not supposed to be the same hash for different stages of ANYONECANPAY, nor should it care about how a transaction is signed (ie. who signed it):
The "sighash with all inputs zeroed out" kind of suggests itself, though I agree that "normalized hash/id" probably isn't the best name. Maybe "empty sighash" or "null sighash" or something like that? "normalized sighash"? That would make it clearer and hint at what it actually is. Unless I'm mistaken, @gmaxwell is only arguing why it wouldn't be a workable solution to exclusively use the normalized hash for tracking, not how it could hurt to have it additionally. It's not meant to replace the regular tx hash, nor is it a simple drop-in replacement to magically fix all code that is vulnerable to malleability. It's also not required to deal with it, but it can be handy. I don't see how it not being applicable to every situation would be a reason not to use it when it is. |
|
To clarify, the specific usecases I'm thinking of are:
Is there anything fundamentally wrong with that? I'm not actually using bitcoinjs to send/receive transactions, so to me the first point is more theoretical, but I'm working on something involving case two right now. Personally, I'd be fine with calling hashForSignature() directly, but having a shortcut/label for it would be nice. |
|
ACK on all changes, good to merge. Just a matter of whether I agree with the fundamentals now :). Still thinking it over and waiting for others feedback if possible. Thanks @mhanne |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly think this function can be achieved much cleaner without using and modifying hashForSignature:
function getNormalizedHash = function(tx) {
var txTmp = tx.clone()
txTmp.ins.forEach(function(txIn) {
txIn.script = Script.EMPTY
})
var hashTypeBuffer = new Buffer(4)
hashTypeBuffer.writeInt32LE(Transaction.SIGHASH_ALL, 0)
return crypto.hash256(Buffer.concat([txTmp.toBuffer(), hashTypeBuffer]))
}@dcousens put up a very nice summary of the whole debate. IMHO, aligning bitcoinjs' features with bitcoin core as much as possible provides consistency and least surprise for devs. I'm not comfortable merging a feature explicitly rejected by the core team after much debate, especially when this feature is very easy to implement when one indeed needs it for their own purposes.
|
@weilu said it best:
👍 |
|
Alright then, thanks for taking the time to consider it. |
Function to get the normalized tx hash / id.
This is
neededconvenient to deal with transaction malleability and is useful to keep track of partially signed multisig transactions where the regular hash changes after each signature is added.