add proto.common module
This commit is contained in:
parent
7558c539a1
commit
362d8cfeed
9 changed files with 69 additions and 53 deletions
|
|
@ -20,7 +20,7 @@
|
|||
addrgen.py: Address and view key generation classes for the MMGen suite
|
||||
"""
|
||||
|
||||
from .proto.btc import hash160,_b58chk_encode
|
||||
from .proto.common import hash160,b58chk_encode
|
||||
from .addr import CoinAddr,MMGenAddrType,MoneroViewKey,ZcashViewKey
|
||||
|
||||
# decorator for to_addr() and to_viewkey()
|
||||
|
|
@ -118,14 +118,14 @@ class addr_generator:
|
|||
|
||||
@check_data
|
||||
def to_addr(self,data):
|
||||
ret = _b58chk_encode(
|
||||
ret = b58chk_encode(
|
||||
self.proto.addr_fmt_to_ver_bytes('zcash_z')
|
||||
+ data.pubkey )
|
||||
return CoinAddr( self.proto, ret )
|
||||
|
||||
@check_data
|
||||
def to_viewkey(self,data):
|
||||
ret = _b58chk_encode(
|
||||
ret = b58chk_encode(
|
||||
self.proto.addr_fmt_to_ver_bytes('viewkey')
|
||||
+ data.viewkey_bytes )
|
||||
return ZcashViewKey( self.proto, ret )
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ class AddrList(MMGenObject): # Address info for a single seed ID
|
|||
return out
|
||||
|
||||
def gen_wallet_passwd(self,privbytes):
|
||||
from .proto.btc import hash256
|
||||
from .proto.common import hash256
|
||||
return WalletPassword( hash256(privbytes)[:16].hex() )
|
||||
|
||||
def check_format(self,addr):
|
||||
|
|
|
|||
|
|
@ -556,10 +556,10 @@ class CoinInfo(object):
|
|||
return '1'
|
||||
|
||||
def phash2addr(ver_num,pk_hash):
|
||||
from .proto.btc import _b58chk_encode
|
||||
from .proto.common import b58chk_encode
|
||||
bl = ver_num.bit_length()
|
||||
ver_bytes = int.to_bytes(ver_num,bl//8 + bool(bl%8),'big')
|
||||
return _b58chk_encode(ver_bytes + pk_hash)
|
||||
return b58chk_encode(ver_bytes + pk_hash)
|
||||
|
||||
low = phash2addr(ver_num,b'\x00'*20)
|
||||
high = phash2addr(ver_num,b'\xff'*20)
|
||||
|
|
|
|||
|
|
@ -12,38 +12,8 @@
|
|||
Bitcoin protocol
|
||||
"""
|
||||
|
||||
from ..protocol import CoinProtocol,parsed_wif,parsed_addr,_finfo,_b58a,_nw
|
||||
import hashlib
|
||||
|
||||
def hash160(in_bytes): # OP_HASH160
|
||||
return hashlib.new('ripemd160',hashlib.sha256(in_bytes).digest()).digest()
|
||||
|
||||
def hash256(in_bytes): # OP_HASH256
|
||||
return hashlib.sha256(hashlib.sha256(in_bytes).digest()).digest()
|
||||
|
||||
# From en.bitcoin.it:
|
||||
# The Base58 encoding used is home made, and has some differences.
|
||||
# Especially, leading zeroes are kept as single zeroes when conversion happens.
|
||||
# Test: 5JbQQTs3cnoYN9vDYaGY6nhQ1DggVsY4FJNBUfEfpSQqrEp3srk
|
||||
# The 'zero address':
|
||||
# 1111111111111111111114oLvT2 (pubkeyhash = '\0'*20)
|
||||
|
||||
def _b58chk_encode(in_bytes):
|
||||
lzeroes = len(in_bytes) - len(in_bytes.lstrip(b'\x00'))
|
||||
def do_enc(n):
|
||||
while n:
|
||||
yield _b58a[n % 58]
|
||||
n //= 58
|
||||
return ('1' * lzeroes) + ''.join(do_enc(int.from_bytes(in_bytes+hash256(in_bytes)[:4],'big')))[::-1]
|
||||
|
||||
def _b58chk_decode(s):
|
||||
lzeroes = len(s) - len(s.lstrip('1'))
|
||||
res = sum(_b58a.index(ch) * 58**n for n,ch in enumerate(s[::-1]))
|
||||
bl = res.bit_length()
|
||||
out = b'\x00' * lzeroes + res.to_bytes(bl//8 + bool(bl%8),'big')
|
||||
if out[-4:] != hash256(out[:-4])[:4]:
|
||||
raise ValueError('_b58chk_decode(): incorrect checksum')
|
||||
return out[:-4]
|
||||
from ..protocol import CoinProtocol,parsed_wif,parsed_addr,_finfo,_nw
|
||||
from .common import *
|
||||
|
||||
class mainnet(CoinProtocol.Secp256k1): # chainparams.cpp
|
||||
"""
|
||||
|
|
@ -83,13 +53,13 @@ class mainnet(CoinProtocol.Secp256k1): # chainparams.cpp
|
|||
def bytes2wif(self,privbytes,pubkey_type,compressed): # input is preprocessed hex
|
||||
assert len(privbytes) == self.privkey_len, f'{len(privbytes)} bytes: incorrect private key length!'
|
||||
assert pubkey_type in self.wif_ver_num, f'{pubkey_type!r}: invalid pubkey_type'
|
||||
return _b58chk_encode(
|
||||
return b58chk_encode(
|
||||
bytes.fromhex(self.wif_ver_num[pubkey_type])
|
||||
+ privbytes
|
||||
+ (b'',b'\x01')[bool(compressed)])
|
||||
|
||||
def parse_wif(self,wif):
|
||||
key = _b58chk_decode(wif)
|
||||
key = b58chk_decode(wif)
|
||||
|
||||
for k,v in self.wif_ver_num.items():
|
||||
v = bytes.fromhex(v)
|
||||
|
|
@ -126,11 +96,11 @@ class mainnet(CoinProtocol.Secp256k1): # chainparams.cpp
|
|||
|
||||
return parsed_addr( bytes(ret[1]), 'bech32' ) if ret[1] else False
|
||||
|
||||
return self.parse_addr_bytes(_b58chk_decode(addr))
|
||||
return self.parse_addr_bytes(b58chk_decode(addr))
|
||||
|
||||
def pubhash2addr(self,pubkey_hash,p2sh):
|
||||
assert len(pubkey_hash) == 20, f'{len(pubkey_hash)}: invalid length for pubkey hash'
|
||||
return _b58chk_encode(
|
||||
return b58chk_encode(
|
||||
self.addr_fmt_to_ver_bytes(('p2pkh','p2sh')[p2sh],return_hex=False) + pubkey_hash
|
||||
)
|
||||
|
||||
|
|
|
|||
47
mmgen/proto/common.py
Executable file
47
mmgen/proto/common.py
Executable file
|
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
|
||||
# Copyright (C)2013-2022 The MMGen Project <mmgen@tuta.io>
|
||||
# Licensed under the GNU General Public License, Version 3:
|
||||
# https://www.gnu.org/licenses
|
||||
# Public project repositories:
|
||||
# https://github.com/mmgen/mmgen
|
||||
# https://gitlab.com/mmgen/mmgen
|
||||
|
||||
"""
|
||||
Functions and constants used by multiple protocols
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
|
||||
b58a = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
|
||||
def hash160(in_bytes): # OP_HASH160
|
||||
return hashlib.new('ripemd160',hashlib.sha256(in_bytes).digest()).digest()
|
||||
|
||||
def hash256(in_bytes): # OP_HASH256
|
||||
return hashlib.sha256(hashlib.sha256(in_bytes).digest()).digest()
|
||||
|
||||
# From en.bitcoin.it:
|
||||
# The Base58 encoding used is home made, and has some differences.
|
||||
# Especially, leading zeroes are kept as single zeroes when conversion happens.
|
||||
# Test: 5JbQQTs3cnoYN9vDYaGY6nhQ1DggVsY4FJNBUfEfpSQqrEp3srk
|
||||
# The 'zero address':
|
||||
# 1111111111111111111114oLvT2 (pubkeyhash = '\0'*20)
|
||||
|
||||
def b58chk_encode(in_bytes):
|
||||
lzeroes = len(in_bytes) - len(in_bytes.lstrip(b'\x00'))
|
||||
def do_enc(n):
|
||||
while n:
|
||||
yield b58a[n % 58]
|
||||
n //= 58
|
||||
return ('1' * lzeroes) + ''.join(do_enc(int.from_bytes(in_bytes+hash256(in_bytes)[:4],'big')))[::-1]
|
||||
|
||||
def b58chk_decode(s):
|
||||
lzeroes = len(s) - len(s.lstrip('1'))
|
||||
res = sum(b58a.index(ch) * 58**n for n,ch in enumerate(s[::-1]))
|
||||
bl = res.bit_length()
|
||||
out = b'\x00' * lzeroes + res.to_bytes(bl//8 + bool(bl%8),'big')
|
||||
if out[-4:] != hash256(out[:-4])[:4]:
|
||||
raise ValueError('b58chk_decode(): incorrect checksum')
|
||||
return out[:-4]
|
||||
|
|
@ -31,8 +31,6 @@ parsed_addr = namedtuple('parsed_addr',['bytes','fmt'])
|
|||
_finfo = namedtuple('fork_info',['height','hash','name','replayable'])
|
||||
_nw = namedtuple('coin_networks',['mainnet','testnet','regtest'])
|
||||
|
||||
_b58a='123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' # shared by Bitcoin and Monero
|
||||
|
||||
class CoinProtocol(MMGenObject):
|
||||
|
||||
proto_info = namedtuple('proto_info',['name','trust_level']) # trust levels: see altcoin.py
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ class tool_cmd(tool_cmd_base):
|
|||
if self.mmtype.name == 'segwit':
|
||||
return self.proto.pubkey2segwitaddr( pubkey )
|
||||
else:
|
||||
from ..proto.btc import hash160
|
||||
from ..proto.common import hash160
|
||||
return self.pubhash2addr( hash160(pubkey).hex() )
|
||||
|
||||
def pubhex2redeem_script(self,pubkeyhex:'sstr'): # new
|
||||
|
|
@ -146,7 +146,7 @@ class tool_cmd(tool_cmd_base):
|
|||
assert self.mmtype.name == 'segwit', 'This command is meaningful only for --type=segwit'
|
||||
assert redeem_scripthex[:4] == '0014', f'{redeem_scripthex!r}: invalid redeem script'
|
||||
assert len(redeem_scripthex) == 44, f'{len(redeem_scripthex)//2} bytes: invalid redeem script length'
|
||||
from ..proto.btc import hash160
|
||||
from ..proto.common import hash160
|
||||
return self.pubhash2addr( hash160(bytes.fromhex(redeem_scripthex)).hex() )
|
||||
|
||||
def pubhash2addr(self,pubhashhex:'sstr'):
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class tool_cmd(tool_cmd_base):
|
|||
|
||||
def hash160(self,hexstr:'sstr'):
|
||||
"compute ripemd160(sha256(data)) (convert hex pubkey to hex addr)"
|
||||
from ..proto.btc import hash160
|
||||
from ..proto.common import hash160
|
||||
return hash160( bytes.fromhex(hexstr) ).hex()
|
||||
|
||||
def hash256(self,string_or_bytes:str,file_input=False,hex_input=False): # TODO: handle stdin
|
||||
|
|
@ -143,13 +143,13 @@ class tool_cmd(tool_cmd_base):
|
|||
|
||||
def hextob58chk(self,hexstr:'sstr'):
|
||||
"convert a hexadecimal number to base58-check encoding"
|
||||
from ..proto.btc import _b58chk_encode
|
||||
return _b58chk_encode( bytes.fromhex(hexstr) )
|
||||
from ..proto.common import b58chk_encode
|
||||
return b58chk_encode( bytes.fromhex(hexstr) )
|
||||
|
||||
def b58chktohex(self,b58chk_num:'sstr'):
|
||||
"convert a base58-check encoded number to hexadecimal"
|
||||
from ..proto.btc import _b58chk_decode
|
||||
return _b58chk_decode(b58chk_num).hex()
|
||||
from ..proto.common import b58chk_decode
|
||||
return b58chk_decode(b58chk_num).hex()
|
||||
|
||||
def hextob32(self,hexstr:'sstr',pad=0):
|
||||
"convert a hexadecimal number to MMGen's flavor of base 32"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ from .common import *
|
|||
from .objmethods import Hilite,InitErrors
|
||||
from .obj import CoinTxID
|
||||
from .seed import SeedID
|
||||
from .protocol import init_proto,_b58a
|
||||
from .protocol import init_proto
|
||||
from .proto.common import b58a
|
||||
from .addr import CoinAddr,AddrIdx
|
||||
from .addrlist import KeyAddrList,AddrIdxList
|
||||
from .rpc import MoneroRPCClientRaw,MoneroWalletRPCClient,json_encoder
|
||||
|
|
@ -36,7 +37,7 @@ xmrwallet_uarg_info = (
|
|||
lambda e,hp: {
|
||||
'daemon': e('HOST:PORT', hp),
|
||||
'tx_relay_daemon': e('HOST:PORT[:PROXY_HOST:PROXY_PORT]', rf'({hp})(?::({hp}))?'),
|
||||
'transfer_spec': e('SOURCE_WALLET_NUM:ACCOUNT:ADDRESS,AMOUNT', rf'(\d+):(\d+):([{_b58a}]+),([0-9.]+)'),
|
||||
'transfer_spec': e('SOURCE_WALLET_NUM:ACCOUNT:ADDRESS,AMOUNT', rf'(\d+):(\d+):([{b58a}]+),([0-9.]+)'),
|
||||
'sweep_spec': e('SOURCE_WALLET_NUM:ACCOUNT[,DEST_WALLET_NUM]', r'(\d+):(\d+)(?:,(\d+))?'),
|
||||
})(
|
||||
namedtuple('uarg_info_entry',['annot','pat']),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue