Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
[RPC] Add utility getsignaturehash #11653
Conversation
fanquake
added
the
RPC/REST/ZMQ
label
Nov 10, 2017
| + if (!request.params[5].isNull()) { | ||
| + RPCTypeCheckArgument(request.params[5], UniValue::VSTR); | ||
| + static std::map<std::string, int> mapSigHashValues = { | ||
| + { std::string("ALL"), int(SIGHASH_ALL) }, |
laanwj
Nov 10, 2017
Owner
This table is duplicated with signrawtransaction, which makes it harder to change later. Please factor it out.
|
Just refactored. |
| + self.setup_clean_chain = True | ||
| + | ||
| + def run_test(self): | ||
| + assert_equal("64e049981a10cf597406a175d7443c8499d308168915377637e3f706ce186137", self.nodes[0].getsignaturehash( |
promag
reviewed
Nov 10, 2017
Some comments.
Missing tests for all sighashtype values and missing test for sigversion = WITNESS_V0?
| + "\nCreate the hash to sign for the given input\n" | ||
| + | ||
| + "\nArguments:\n" | ||
| + "1. \"tx\" (string, required) The transaction hex string\n" |
| + UniValue::VSTR, // amount | ||
| + UniValue::VSTR, // sigVersion | ||
| + UniValue::VNUM // inputIndex | ||
| + }, |
| + false); | ||
| + | ||
| + CMutableTransaction mtx; | ||
| + if (!DecodeHexTx(mtx, request.params[0].get_str(), true)) |
| @@ -131,6 +131,25 @@ uint256 ParseHashV(const UniValue& v, std::string strName) | ||
| result.SetHex(strHex); | ||
| return result; | ||
| } | ||
| + | ||
| +int ParseSigHash(std::string strHashType) |
| +int ParseSigHash(std::string strHashType) | ||
| +{ | ||
| + int nHashType = 0; | ||
| + static std::map<std::string, int> mapSigHashValues = { |
| + { std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY) }, | ||
| + }; | ||
| + if (mapSigHashValues.count(strHashType)) | ||
| + nHashType = mapSigHashValues[strHashType]; |
| + if (mapSigHashValues.count(strHashType)) | ||
| + nHashType = mapSigHashValues[strHashType]; | ||
| + else | ||
| + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param"); |
| +from test_framework.test_framework import BitcoinTestFramework | ||
| +from test_framework.util import * | ||
| + | ||
| + |
| + # optional | ||
| + assert_equal("64e049981a10cf597406a175d7443c8499d308168915377637e3f706ce186137", self.nodes[0].getsignaturehash( | ||
| + # tx | ||
| + "010000000243ec7a579f5561a42a7e9637ad4156672735a658be2752181801f723ba3316d200000000844730440220449a203d0062ea01022f565c94c4b62bf2cc9a05de20519bc18cded9e99aa5f702201a2b8361e2af179eb93e697d9fedd0bf1e036f0a5be39af4b1f791df803bdb6501210363e38e2e0e55cdebfb7e27d0cb53ded150c320564a4614c18738feb124c8efd21976a9141a5fdcb6201f7e4fd160f9dca81075bd8537526088acffffffff43ec7a579f5561a42a7e9637ad4156672735a658be2752181801f723ba3316d20100000085483045022100ff6e7edffa5e0758244af6af77edd14f1d80226d66f81ed58dba2def34778236022057d95177497758e467c194f0d897f175645d30e7ac2f9490247e13227ac4d2fc01210363e38e2e0e55cdebfb7e27d0cb53ded150c320564a4614c18738feb124c8efd21976a9141a5fdcb6201f7e4fd160f9dca81075bd8537526088acffffffff0100752b7d000000001976a9141a5fdcb6201f7e4fd160f9dca81075bd8537526088ac00000000", |
promag
Nov 10, 2017
Contributor
Declare tx only once, and at the same time these 2 asserts will be more readable.
| + 0 | ||
| + )) | ||
| + | ||
| + |
| + | ||
| + "\nArguments:\n" | ||
| + "1. \"tx\" (string, required) The transaction hex string\n" | ||
| + "2. \"scriptcode\" (string, required) The scriptCode to sign\n" |
NicolasDorier
Nov 11, 2017
•
Member
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.
| + std::vector<unsigned char> scriptCodeData(ParseHexV(request.params[1], "scriptCode")); | ||
| + CScript scriptCode(scriptCodeData.begin(), scriptCodeData.end()); | ||
| + | ||
| + auto amount = AmountFromValue(request.params[2].get_str()); |
|
(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. |
|
I addressed the nits, I keep this open while working on an alternative |
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Nov 11, 2017
|
Alternative |
NicolasDorier commentedNov 10, 2017
•
Edited 1 time
-
NicolasDorier
Nov 10, 2017
Add an utility to get the signature hash in a generic way.
signrawtransactioncan't create a signature for an arbitrary scriptCode, as it is usingProduceSignatureinternally. This make it impossible to create complex scripts without a library.