mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 12:32:48 +01:00
p2wpkh, p2wsh and p2sh-nested scripts in decodescript
plus tests
This commit is contained in:
parent
d09968f4d0
commit
4f933b3d23
@ -563,6 +563,38 @@ UniValue decodescript(const JSONRPCRequest& request)
|
||||
// P2SH cannot be wrapped in a P2SH. If this script is already a P2SH,
|
||||
// don't return the address for a P2SH of the P2SH.
|
||||
r.pushKV("p2sh", EncodeDestination(CScriptID(script)));
|
||||
// P2SH and witness programs cannot be wrapped in P2WSH, if this script
|
||||
// is a witness program, don't return addresses for a segwit programs.
|
||||
if (type.get_str().find("witness") == std::string::npos) {
|
||||
txnouttype which_type;
|
||||
std::vector<std::vector<unsigned char>> solutions_data;
|
||||
Solver(script, which_type, solutions_data);
|
||||
// Uncompressed pubkeys cannot be used with segwit checksigs.
|
||||
// If the script contains an uncompressed pubkey, skip encoding of a segwit program.
|
||||
if ((which_type == TX_PUBKEY) || (which_type == TX_MULTISIG)) {
|
||||
for (const auto& solution : solutions_data) {
|
||||
if ((solution.size() != 1) && !CPubKey(solution).IsCompressed()) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
UniValue sr(UniValue::VOBJ);
|
||||
CScript segwitScr;
|
||||
if (which_type == TX_PUBKEY) {
|
||||
segwitScr = GetScriptForDestination(WitnessV0KeyHash(Hash160(solutions_data[0].begin(), solutions_data[0].end())));
|
||||
} else if (which_type == TX_PUBKEYHASH) {
|
||||
segwitScr = GetScriptForDestination(WitnessV0KeyHash(solutions_data[0]));
|
||||
} else {
|
||||
// Scripts that are not fit for P2WPKH are encoded as P2WSH.
|
||||
// Newer segwit program versions should be considered when then become available.
|
||||
uint256 scriptHash;
|
||||
CSHA256().Write(script.data(), script.size()).Finalize(scriptHash.begin());
|
||||
segwitScr = GetScriptForDestination(WitnessV0ScriptHash(scriptHash));
|
||||
}
|
||||
ScriptPubKeyToUniv(segwitScr, sr, true);
|
||||
sr.pushKV("p2sh-segwit", EncodeDestination(CScriptID(segwitScr)));
|
||||
r.pushKV("segwit", sr);
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -50,8 +50,11 @@ class DecodeScriptTest(BitcoinTestFramework):
|
||||
def decodescript_script_pub_key(self):
|
||||
public_key = '03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2'
|
||||
push_public_key = '21' + public_key
|
||||
public_key_hash = '11695b6cd891484c2d49ec5aa738ec2b2f897777'
|
||||
public_key_hash = '5dd1d3a048119c27b28293056724d9522f26d945'
|
||||
push_public_key_hash = '14' + public_key_hash
|
||||
uncompressed_public_key = '04b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb25e01fc8fde47c96c98a4f3a8123e33a38a50cf9025cc8c4494a518f991792bb7'
|
||||
push_uncompressed_public_key = '41' + uncompressed_public_key
|
||||
p2wsh_p2pk_script_hash = 'd8590cf8ea0674cf3d49fd7ca249b85ef7485dea62c138468bddeb20cd6519f7'
|
||||
|
||||
# below are test cases for all of the standard transaction types
|
||||
|
||||
@ -59,18 +62,26 @@ class DecodeScriptTest(BitcoinTestFramework):
|
||||
# <pubkey> OP_CHECKSIG
|
||||
rpc_result = self.nodes[0].decodescript(push_public_key + 'ac')
|
||||
assert_equal(public_key + ' OP_CHECKSIG', rpc_result['asm'])
|
||||
# P2PK is translated to P2WPKH
|
||||
assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm'])
|
||||
|
||||
# 2) P2PKH scriptPubKey
|
||||
# OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
||||
rpc_result = self.nodes[0].decodescript('76a9' + push_public_key_hash + '88ac')
|
||||
assert_equal('OP_DUP OP_HASH160 ' + public_key_hash + ' OP_EQUALVERIFY OP_CHECKSIG', rpc_result['asm'])
|
||||
# P2PKH is translated to P2WPKH
|
||||
assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm'])
|
||||
|
||||
# 3) multisig scriptPubKey
|
||||
# <m> <A pubkey> <B pubkey> <C pubkey> <n> OP_CHECKMULTISIG
|
||||
# just imagine that the pub keys used below are different.
|
||||
# for our purposes here it does not matter that they are the same even though it is unrealistic.
|
||||
rpc_result = self.nodes[0].decodescript('52' + push_public_key + push_public_key + push_public_key + '53ae')
|
||||
multisig_script = '52' + push_public_key + push_public_key + push_public_key + '53ae'
|
||||
rpc_result = self.nodes[0].decodescript(multisig_script)
|
||||
assert_equal('2 ' + public_key + ' ' + public_key + ' ' + public_key + ' 3 OP_CHECKMULTISIG', rpc_result['asm'])
|
||||
# multisig in P2WSH
|
||||
multisig_script_hash = bytes_to_hex_str(sha256(hex_str_to_bytes(multisig_script)))
|
||||
assert_equal('0 ' + multisig_script_hash, rpc_result['segwit']['asm'])
|
||||
|
||||
# 4) P2SH scriptPubKey
|
||||
# OP_HASH160 <Hash160(redeemScript)> OP_EQUAL.
|
||||
@ -78,6 +89,8 @@ class DecodeScriptTest(BitcoinTestFramework):
|
||||
# but this works the same for purposes of this test.
|
||||
rpc_result = self.nodes[0].decodescript('a9' + push_public_key_hash + '87')
|
||||
assert_equal('OP_HASH160 ' + public_key_hash + ' OP_EQUAL', rpc_result['asm'])
|
||||
# P2SH does not work in segwit secripts. decodescript should not return a result for it.
|
||||
assert 'segwit' not in rpc_result
|
||||
|
||||
# 5) null data scriptPubKey
|
||||
# use a signature look-alike here to make sure that we do not decode random data as a signature.
|
||||
@ -101,8 +114,49 @@ class DecodeScriptTest(BitcoinTestFramework):
|
||||
# <sender-pubkey> OP_CHECKSIG
|
||||
#
|
||||
# lock until block 500,000
|
||||
rpc_result = self.nodes[0].decodescript('63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac')
|
||||
cltv_script = '63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac'
|
||||
rpc_result = self.nodes[0].decodescript(cltv_script)
|
||||
assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm'])
|
||||
# CLTV script in P2WSH
|
||||
cltv_script_hash = bytes_to_hex_str(sha256(hex_str_to_bytes(cltv_script)))
|
||||
assert_equal('0 ' + cltv_script_hash, rpc_result['segwit']['asm'])
|
||||
|
||||
# 7) P2PK scriptPubKey
|
||||
# <pubkey> OP_CHECKSIG
|
||||
rpc_result = self.nodes[0].decodescript(push_uncompressed_public_key + 'ac')
|
||||
assert_equal(uncompressed_public_key + ' OP_CHECKSIG', rpc_result['asm'])
|
||||
# uncompressed pubkeys are invalid for checksigs in segwit scripts.
|
||||
# decodescript should not return a P2WPKH equivalent.
|
||||
assert 'segwit' not in rpc_result
|
||||
|
||||
# 8) multisig scriptPubKey with an uncompressed pubkey
|
||||
# <m> <A pubkey> <B pubkey> <n> OP_CHECKMULTISIG
|
||||
# just imagine that the pub keys used below are different.
|
||||
# the purpose of this test is to check that a segwit script is not returned for bare multisig scripts
|
||||
# with an uncompressed pubkey in them.
|
||||
rpc_result = self.nodes[0].decodescript('52' + push_public_key + push_uncompressed_public_key +'52ae')
|
||||
assert_equal('2 ' + public_key + ' ' + uncompressed_public_key + ' 2 OP_CHECKMULTISIG', rpc_result['asm'])
|
||||
# uncompressed pubkeys are invalid for checksigs in segwit scripts.
|
||||
# decodescript should not return a P2WPKH equivalent.
|
||||
assert 'segwit' not in rpc_result
|
||||
|
||||
# 9) P2WPKH scriptpubkey
|
||||
# 0 <PubKeyHash>
|
||||
rpc_result = self.nodes[0].decodescript('00' + push_public_key_hash)
|
||||
assert_equal('0 ' + public_key_hash, rpc_result['asm'])
|
||||
# segwit scripts do not work nested into each other.
|
||||
# a nested segwit script should not be returned in the results.
|
||||
assert 'segwit' not in rpc_result
|
||||
|
||||
# 10) P2WSH scriptpubkey
|
||||
# 0 <ScriptHash>
|
||||
# even though this hash is of a P2PK script which is better used as bare P2WPKH, it should not matter
|
||||
# for the purpose of this test.
|
||||
rpc_result = self.nodes[0].decodescript('0020' + p2wsh_p2pk_script_hash)
|
||||
assert_equal('0 ' + p2wsh_p2pk_script_hash, rpc_result['asm'])
|
||||
# segwit scripts do not work nested into each other.
|
||||
# a nested segwit script should not be returned in the results.
|
||||
assert 'segwit' not in rpc_result
|
||||
|
||||
def decoderawtransaction_asm_sighashtype(self):
|
||||
"""Test decoding scripts via RPC command "decoderawtransaction".
|
||||
|
Loading…
Reference in New Issue
Block a user