mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-22 23:04:09 +02:00
Merge #19239: tests: move generate_wif_key to wallet_util.py
3a83a01694160f2e722e1bc90a328bd569b8e109 [tests] move generate_wif_key to wallet_util.py (John Newbery) b216b0b71f7853d747af8b712fc250c699f3c320 [tests] sort imports in rpc_createmultisig.py (John Newbery) e38081846d889fcbbbc6ca4a4d3bca26807fde2f Revert "[TESTS] Move base58 to own module to break circular dependency" (John Newbery) Pull request description: generate_wif_key is a wallet utility function. Move it from the EC key module to the wallet util module. This fixes the circular dependency issue in #17977 ACKs for top commit: MarcoFalke: ACK 3a83a01694160f2e722e1bc90a328bd569b8e109 🍪 Tree-SHA512: 24985dffb75202721ccc0c6c5b52f1fa5d1ce7963bccde24389feb913cab4dad0c265274ca67892c46c8b64e6a065a0f23263a89be4fb9134dfefbdbe5c7238a
This commit is contained in:
commit
85f7db2284
@ -3,22 +3,22 @@
|
|||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test multisig RPCs"""
|
"""Test multisig RPCs"""
|
||||||
|
|
||||||
from test_framework.authproxy import JSONRPCException
|
|
||||||
from test_framework.descriptors import descsum_create, drop_origins
|
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
|
||||||
from test_framework.util import (
|
|
||||||
assert_raises_rpc_error,
|
|
||||||
assert_equal,
|
|
||||||
)
|
|
||||||
from test_framework.key import ECPubKey, ECKey, bytes_to_wif
|
|
||||||
|
|
||||||
import binascii
|
import binascii
|
||||||
import decimal
|
import decimal
|
||||||
import itertools
|
import itertools
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from test_framework.authproxy import JSONRPCException
|
||||||
|
from test_framework.descriptors import descsum_create, drop_origins
|
||||||
|
from test_framework.key import ECPubKey, ECKey
|
||||||
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
|
from test_framework.util import (
|
||||||
|
assert_raises_rpc_error,
|
||||||
|
assert_equal,
|
||||||
|
)
|
||||||
|
from test_framework.wallet_util import bytes_to_wif
|
||||||
|
|
||||||
class RpcCreateMultiSigTest(BitcoinTestFramework):
|
class RpcCreateMultiSigTest(BitcoinTestFramework):
|
||||||
def set_test_params(self):
|
def set_test_params(self):
|
||||||
self.setup_clean_chain = True
|
self.setup_clean_chain = True
|
||||||
|
@ -5,13 +5,15 @@
|
|||||||
"""Encode and decode BASE58, P2PKH and P2SH addresses."""
|
"""Encode and decode BASE58, P2PKH and P2SH addresses."""
|
||||||
|
|
||||||
import enum
|
import enum
|
||||||
|
import unittest
|
||||||
|
|
||||||
from .base58 import byte_to_base58
|
from .script import hash256, hash160, sha256, CScript, OP_0
|
||||||
from .script import hash160, sha256, CScript, OP_0
|
|
||||||
from .util import hex_str_to_bytes
|
from .util import hex_str_to_bytes
|
||||||
|
|
||||||
from . import segwit_addr
|
from . import segwit_addr
|
||||||
|
|
||||||
|
from test_framework.util import assert_equal
|
||||||
|
|
||||||
ADDRESS_BCRT1_UNSPENDABLE = 'bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj'
|
ADDRESS_BCRT1_UNSPENDABLE = 'bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj'
|
||||||
ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR = 'addr(bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj)#juyq9d97'
|
ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR = 'addr(bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj)#juyq9d97'
|
||||||
# Coins sent to this address can be spent with a witness stack of just OP_TRUE
|
# Coins sent to this address can be spent with a witness stack of just OP_TRUE
|
||||||
@ -23,6 +25,52 @@ class AddressType(enum.Enum):
|
|||||||
p2sh_segwit = 'p2sh-segwit'
|
p2sh_segwit = 'p2sh-segwit'
|
||||||
legacy = 'legacy' # P2PKH
|
legacy = 'legacy' # P2PKH
|
||||||
|
|
||||||
|
|
||||||
|
chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||||
|
|
||||||
|
|
||||||
|
def byte_to_base58(b, version):
|
||||||
|
result = ''
|
||||||
|
str = b.hex()
|
||||||
|
str = chr(version).encode('latin-1').hex() + str
|
||||||
|
checksum = hash256(hex_str_to_bytes(str)).hex()
|
||||||
|
str += checksum[:8]
|
||||||
|
value = int('0x'+str,0)
|
||||||
|
while value > 0:
|
||||||
|
result = chars[value % 58] + result
|
||||||
|
value //= 58
|
||||||
|
while (str[:2] == '00'):
|
||||||
|
result = chars[0] + result
|
||||||
|
str = str[2:]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def base58_to_byte(s, verify_checksum=True):
|
||||||
|
if not s:
|
||||||
|
return b''
|
||||||
|
n = 0
|
||||||
|
for c in s:
|
||||||
|
n *= 58
|
||||||
|
assert c in chars
|
||||||
|
digit = chars.index(c)
|
||||||
|
n += digit
|
||||||
|
h = '%x' % n
|
||||||
|
if len(h) % 2:
|
||||||
|
h = '0' + h
|
||||||
|
res = n.to_bytes((n.bit_length() + 7) // 8, 'big')
|
||||||
|
pad = 0
|
||||||
|
for c in s:
|
||||||
|
if c == chars[0]:
|
||||||
|
pad += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
res = b'\x00' * pad + res
|
||||||
|
if verify_checksum:
|
||||||
|
assert_equal(hash256(res[:-4])[:4], res[-4:])
|
||||||
|
|
||||||
|
return res[1:-4], int(res[0])
|
||||||
|
|
||||||
|
|
||||||
def keyhash_to_p2pkh(hash, main = False):
|
def keyhash_to_p2pkh(hash, main = False):
|
||||||
assert len(hash) == 20
|
assert len(hash) == 20
|
||||||
version = 0 if main else 111
|
version = 0 if main else 111
|
||||||
@ -80,3 +128,22 @@ def check_script(script):
|
|||||||
if (type(script) is bytes or type(script) is CScript):
|
if (type(script) is bytes or type(script) is CScript):
|
||||||
return script
|
return script
|
||||||
assert False
|
assert False
|
||||||
|
|
||||||
|
|
||||||
|
class TestFrameworkScript(unittest.TestCase):
|
||||||
|
def test_base58encodedecode(self):
|
||||||
|
def check_base58(data, version):
|
||||||
|
self.assertEqual(base58_to_byte(byte_to_base58(data, version)), (data, version))
|
||||||
|
|
||||||
|
check_base58(b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 111)
|
||||||
|
check_base58(b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 111)
|
||||||
|
check_base58(b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
|
||||||
|
check_base58(b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
|
||||||
|
check_base58(b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
|
||||||
|
check_base58(b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
|
||||||
|
check_base58(b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 0)
|
||||||
|
check_base58(b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 0)
|
||||||
|
check_base58(b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
|
||||||
|
check_base58(b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
|
||||||
|
check_base58(b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
|
||||||
|
check_base58(b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# Copyright (c) 2016-2020 The Bitcoin Core developers
|
|
||||||
# Distributed under the MIT software license, see the accompanying
|
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
||||||
"""Encode BASE58."""
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from .messages import hash256
|
|
||||||
from .util import hex_str_to_bytes, assert_equal
|
|
||||||
|
|
||||||
chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
|
||||||
|
|
||||||
def byte_to_base58(b, version):
|
|
||||||
result = ''
|
|
||||||
str = b.hex()
|
|
||||||
str = chr(version).encode('latin-1').hex() + str
|
|
||||||
checksum = hash256(hex_str_to_bytes(str)).hex()
|
|
||||||
str += checksum[:8]
|
|
||||||
value = int('0x'+str,0)
|
|
||||||
while value > 0:
|
|
||||||
result = chars[value % 58] + result
|
|
||||||
value //= 58
|
|
||||||
while (str[:2] == '00'):
|
|
||||||
result = chars[0] + result
|
|
||||||
str = str[2:]
|
|
||||||
return result
|
|
||||||
|
|
||||||
def base58_to_byte(s, verify_checksum=True):
|
|
||||||
if not s:
|
|
||||||
return b''
|
|
||||||
n = 0
|
|
||||||
for c in s:
|
|
||||||
n *= 58
|
|
||||||
assert c in chars
|
|
||||||
digit = chars.index(c)
|
|
||||||
n += digit
|
|
||||||
h = '%x' % n
|
|
||||||
if len(h) % 2:
|
|
||||||
h = '0' + h
|
|
||||||
res = n.to_bytes((n.bit_length() + 7) // 8, 'big')
|
|
||||||
pad = 0
|
|
||||||
for c in s:
|
|
||||||
if c == chars[0]:
|
|
||||||
pad += 1
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
res = b'\x00' * pad + res
|
|
||||||
if verify_checksum:
|
|
||||||
assert_equal(hash256(res[:-4])[:4], res[-4:])
|
|
||||||
|
|
||||||
return res[1:-4], int(res[0])
|
|
||||||
|
|
||||||
class TestFrameworkScript(unittest.TestCase):
|
|
||||||
def test_base58encodedecode(self):
|
|
||||||
def check_base58(data, version):
|
|
||||||
self.assertEqual(base58_to_byte(byte_to_base58(data, version)), (data, version))
|
|
||||||
|
|
||||||
check_base58(b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 111)
|
|
||||||
check_base58(b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 111)
|
|
||||||
check_base58(b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
|
|
||||||
check_base58(b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
|
|
||||||
check_base58(b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
|
|
||||||
check_base58(b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
|
|
||||||
check_base58(b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 0)
|
|
||||||
check_base58(b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 0)
|
|
||||||
check_base58(b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
|
|
||||||
check_base58(b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
|
|
||||||
check_base58(b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
|
|
||||||
check_base58(b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
|
|
@ -8,8 +8,6 @@ keys, and is trivially vulnerable to side channel attacks. Do not use for
|
|||||||
anything but tests."""
|
anything but tests."""
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from .base58 import byte_to_base58
|
|
||||||
|
|
||||||
def modinv(a, n):
|
def modinv(a, n):
|
||||||
"""Compute the modular inverse of a modulo n
|
"""Compute the modular inverse of a modulo n
|
||||||
|
|
||||||
@ -386,14 +384,3 @@ class ECKey():
|
|||||||
rb = r.to_bytes((r.bit_length() + 8) // 8, 'big')
|
rb = r.to_bytes((r.bit_length() + 8) // 8, 'big')
|
||||||
sb = s.to_bytes((s.bit_length() + 8) // 8, 'big')
|
sb = s.to_bytes((s.bit_length() + 8) // 8, 'big')
|
||||||
return b'\x30' + bytes([4 + len(rb) + len(sb), 2, len(rb)]) + rb + bytes([2, len(sb)]) + sb
|
return b'\x30' + bytes([4 + len(rb) + len(sb), 2, len(rb)]) + rb + bytes([2, len(sb)]) + sb
|
||||||
|
|
||||||
def bytes_to_wif(b, compressed=True):
|
|
||||||
if compressed:
|
|
||||||
b += b'\x01'
|
|
||||||
return byte_to_base58(b, 239)
|
|
||||||
|
|
||||||
def generate_wif_key():
|
|
||||||
# Makes a WIF privkey for imports
|
|
||||||
k = ECKey()
|
|
||||||
k.generate()
|
|
||||||
return bytes_to_wif(k.get_bytes(), k.is_compressed)
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from test_framework.address import (
|
from test_framework.address import (
|
||||||
|
byte_to_base58,
|
||||||
key_to_p2pkh,
|
key_to_p2pkh,
|
||||||
key_to_p2sh_p2wpkh,
|
key_to_p2sh_p2wpkh,
|
||||||
key_to_p2wpkh,
|
key_to_p2wpkh,
|
||||||
@ -13,10 +14,7 @@ from test_framework.address import (
|
|||||||
script_to_p2sh_p2wsh,
|
script_to_p2sh_p2wsh,
|
||||||
script_to_p2wsh,
|
script_to_p2wsh,
|
||||||
)
|
)
|
||||||
from test_framework.key import (
|
from test_framework.key import ECKey
|
||||||
bytes_to_wif,
|
|
||||||
ECKey,
|
|
||||||
)
|
|
||||||
from test_framework.script import (
|
from test_framework.script import (
|
||||||
CScript,
|
CScript,
|
||||||
OP_0,
|
OP_0,
|
||||||
@ -120,3 +118,14 @@ def test_address(node, address, **kwargs):
|
|||||||
raise AssertionError("key {} unexpectedly returned in getaddressinfo.".format(key))
|
raise AssertionError("key {} unexpectedly returned in getaddressinfo.".format(key))
|
||||||
elif addr_info[key] != value:
|
elif addr_info[key] != value:
|
||||||
raise AssertionError("key {} value {} did not match expected value {}".format(key, addr_info[key], value))
|
raise AssertionError("key {} value {} did not match expected value {}".format(key, addr_info[key], value))
|
||||||
|
|
||||||
|
def bytes_to_wif(b, compressed=True):
|
||||||
|
if compressed:
|
||||||
|
b += b'\x01'
|
||||||
|
return byte_to_base58(b, 239)
|
||||||
|
|
||||||
|
def generate_wif_key():
|
||||||
|
# Makes a WIF privkey for imports
|
||||||
|
k = ECKey()
|
||||||
|
k.generate()
|
||||||
|
return bytes_to_wif(k.get_bytes(), k.is_compressed)
|
||||||
|
@ -67,7 +67,7 @@ TEST_EXIT_PASSED = 0
|
|||||||
TEST_EXIT_SKIPPED = 77
|
TEST_EXIT_SKIPPED = 77
|
||||||
|
|
||||||
TEST_FRAMEWORK_MODULES = [
|
TEST_FRAMEWORK_MODULES = [
|
||||||
"base58",
|
"address",
|
||||||
"blocktools",
|
"blocktools",
|
||||||
"script",
|
"script",
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user