-
Notifications
You must be signed in to change notification settings - Fork 35.5k
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
[RPC] Add utility getsignaturehash #11653
Conversation
src/rpc/misc.cpp
Outdated
if (!request.params[5].isNull()) { | ||
RPCTypeCheckArgument(request.params[5], UniValue::VSTR); | ||
static std::map<std::string, int> mapSigHashValues = { | ||
{ std::string("ALL"), int(SIGHASH_ALL) }, |
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.
This table is duplicated with signrawtransaction, which makes it harder to change later. Please factor it out.
8875b95
to
3f98c3c
Compare
Just refactored. |
test/functional/getsignaturehash.py
Outdated
self.setup_clean_chain = True | ||
|
||
def run_test(self): | ||
assert_equal("64e049981a10cf597406a175d7443c8499d308168915377637e3f706ce186137", self.nodes[0].getsignaturehash( |
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.
No trailing white space, please.
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.
Some comments.
Missing tests for all sighashtype
values and missing test for sigversion = WITNESS_V0
?
src/rpc/server.cpp
Outdated
@@ -131,6 +131,25 @@ uint256 ParseHashV(const UniValue& v, std::string strName) | |||
result.SetHex(strHex); | |||
return result; | |||
} | |||
|
|||
int ParseSigHash(std::string strHashType) |
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.
const std::string& hash_type
src/rpc/server.cpp
Outdated
{ std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY) }, | ||
}; | ||
if (mapSigHashValues.count(strHashType)) | ||
nHashType = mapSigHashValues[strHashType]; |
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.
Avoid 2nd lookup by using map::find
.
src/rpc/server.cpp
Outdated
if (mapSigHashValues.count(strHashType)) | ||
nHashType = mapSigHashValues[strHashType]; | ||
else | ||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param"); |
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.
For getsignaturehash
the parameter name is sighashtype
.
test/functional/getsignaturehash.py
Outdated
from test_framework.test_framework import BitcoinTestFramework | ||
from test_framework.util import * | ||
|
||
|
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, remove 2nd empty line.
test/functional/getsignaturehash.py
Outdated
# optional | ||
assert_equal("64e049981a10cf597406a175d7443c8499d308168915377637e3f706ce186137", self.nodes[0].getsignaturehash( | ||
# tx | ||
"010000000243ec7a579f5561a42a7e9637ad4156672735a658be2752181801f723ba3316d200000000844730440220449a203d0062ea01022f565c94c4b62bf2cc9a05de20519bc18cded9e99aa5f702201a2b8361e2af179eb93e697d9fedd0bf1e036f0a5be39af4b1f791df803bdb6501210363e38e2e0e55cdebfb7e27d0cb53ded150c320564a4614c18738feb124c8efd21976a9141a5fdcb6201f7e4fd160f9dca81075bd8537526088acffffffff43ec7a579f5561a42a7e9637ad4156672735a658be2752181801f723ba3316d20100000085483045022100ff6e7edffa5e0758244af6af77edd14f1d80226d66f81ed58dba2def34778236022057d95177497758e467c194f0d897f175645d30e7ac2f9490247e13227ac4d2fc01210363e38e2e0e55cdebfb7e27d0cb53ded150c320564a4614c18738feb124c8efd21976a9141a5fdcb6201f7e4fd160f9dca81075bd8537526088acffffffff0100752b7d000000001976a9141a5fdcb6201f7e4fd160f9dca81075bd8537526088ac00000000", |
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.
Declare tx
only once, and at the same time these 2 asserts will be more readable.
test/functional/getsignaturehash.py
Outdated
0 | ||
)) | ||
|
||
|
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.
Remove 2nd empty line.
src/rpc/server.cpp
Outdated
int ParseSigHash(std::string strHashType) | ||
{ | ||
int nHashType = 0; | ||
static std::map<std::string, int> mapSigHashValues = { |
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.
Should ANYONECANPAY|SINGLE
be possible?
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.
why not?
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.
Currently it's not.
src/rpc/misc.cpp
Outdated
UniValue::VSTR, // amount | ||
UniValue::VSTR, // sigVersion | ||
UniValue::VNUM // inputIndex | ||
}, |
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.
Wrong indentation?
src/rpc/misc.cpp
Outdated
false); | ||
|
||
CMutableTransaction mtx; | ||
if (!DecodeHexTx(mtx, request.params[0].get_str(), true)) |
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, there are a couple of {}
missing, as per developer notes.
src/rpc/misc.cpp
Outdated
"\nCreate the hash to sign for the given input\n" | ||
|
||
"\nArguments:\n" | ||
"1. \"tx\" (string, required) The transaction hex string\n" |
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.
Please align the descriptions.
src/rpc/misc.cpp
Outdated
std::vector<unsigned char> scriptCodeData(ParseHexV(request.params[1], "scriptCode")); | ||
CScript scriptCode(scriptCodeData.begin(), scriptCodeData.end()); | ||
|
||
auto amount = AmountFromValue(request.params[2].get_str()); |
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.
New RPCs should use satoshis, especially for low-level stuff.
src/rpc/misc.cpp
Outdated
|
||
"\nArguments:\n" | ||
"1. \"tx\" (string, required) The transaction hex string\n" | ||
"2. \"scriptcode\" (string, required) The scriptCode to sign\n" |
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.
This doesn't explain what it is.
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.
the scriptCode is difficult to explain, it depends on OP_CODESEPARATOR
and whether you are using Segwit/P2SH/Segwit-P2SH/Normal script. It will never fit in one line.
(Light concept NACK because utilities should be in libraries, not RPC.) |
@luke-jr I understand that but there is no harm in having these utilities:
That said, most |
@luke-jr When you start doing services which span multiple blockchain (cross chain swap), then library can't possibly know how to sign each and every of them. While if each expose |
@NicolasDorier I don't see how that is related. You need some code specific for each chain anyway, no? |
@sipa, not really. By using using |
@NicolasDorier I don't understand, you can't just paste signature hashes into any other RPC, so it can't be a 'missing piece'. You still need to know what the chain's signatures look like (ECDSA, sighash flags, scripting system, ...) to use that information for anything. I expect that if not already, between any two interesting chains those things will differ significantly. A more useful thing would be an RPC which you give an unsigned transaction, a key and/or an output being spent, possibly a scriptCode, and a sighash flag, and it gives you a piece of scriptSig/witness containing a valid signature for it. You'd still be responsible for combining it with other script elements. Even that isn't a missing piece IMHO, but it wouldn't need intricate knowledge of the digital signature system in your application. |
@sipa there is indeed the creation of script that the library need. But the scripts are most likely similar accross all chains. |
3f98c3c
to
b899e24
Compare
b899e24
to
0a688c4
Compare
I addressed the nits, I keep this open while working on an alternative |
Github-Pull: bitcoin#11653 Rebased-From: 0a688c4
Alternative |
supersede by #11666 |
Add an utility to get the signature hash in a generic way.
signrawtransaction
can't create a signature for an arbitrary scriptCode, as it is usingProduceSignature
internally. This make it impossible to create complex scripts without a library.