diff --git a/jmbitcoin/jmbitcoin/secp256k1_transaction.py b/jmbitcoin/jmbitcoin/secp256k1_transaction.py index 395e5e6..605a6c3 100644 --- a/jmbitcoin/jmbitcoin/secp256k1_transaction.py +++ b/jmbitcoin/jmbitcoin/secp256k1_transaction.py @@ -311,6 +311,16 @@ def script_to_address(script, vbyte=0): if vbyte == 0: raise Exception("Invalid version byte for P2SH") return bin_to_b58check(script[2:-1], vbyte) +def pubkey_to_p2sh_p2wpkh_script(pub): + if re.match('^[0-9a-fA-F]*$', pub): + pub = binascii.unhexlify(pub) + return "0014" + hash160(pub) + +def pubkey_to_p2sh_p2wpkh_address(pub, magicbyte=5): + if re.match('^[0-9a-fA-F]*$', pub): + pub = binascii.unhexlify(pub) + script = pubkey_to_p2sh_p2wpkh_script(pub) + return p2sh_scriptaddr(script, magicbyte=magicbyte) def p2sh_scriptaddr(script, magicbyte=5): if re.match('^[0-9a-fA-F]*$', script): diff --git a/jmclient/jmclient/__init__.py b/jmclient/jmclient/__init__.py index d9569f2..a296c0d 100644 --- a/jmclient/jmclient/__init__.py +++ b/jmclient/jmclient/__init__.py @@ -18,7 +18,7 @@ from .slowaes import decryptData, encryptData from .taker import Taker from .wallet import (AbstractWallet, BitcoinCoreInterface, Wallet, BitcoinCoreWallet, estimate_tx_fee, WalletError, - create_wallet_file) + create_wallet_file, SegwitWallet) from .configure import (load_program_config, jm_single, get_p2pk_vbyte, get_network, jm_single, get_network, validate_address, get_irc_mchannels, check_utxo_blacklist, get_blockchain_interface_instance, get_p2sh_vbyte, diff --git a/jmclient/jmclient/taker_utils.py b/jmclient/jmclient/taker_utils.py index b1eaac4..450aab4 100644 --- a/jmclient/jmclient/taker_utils.py +++ b/jmclient/jmclient/taker_utils.py @@ -6,7 +6,7 @@ import os import time from .configure import get_log, jm_single, validate_address from .schedule import human_readable_schedule_entry, tweak_tumble_schedule -from .wallet import Wallet, estimate_tx_fee +from .wallet import Wallet, SegwitWallet, estimate_tx_fee from jmclient import mktx, deserialize, sign, txhash log = get_log() @@ -41,9 +41,10 @@ def direct_send(wallet, amount, mixdepth, destaddr, answeryes=False, assert mixdepth >= 0 assert isinstance(amount, int) assert amount >=0 - assert isinstance(wallet, Wallet) + assert isinstance(wallet, Wallet) or isinstance(wallet, SegwitWallet) from pprint import pformat + txtype = 'p2sh-p2wpkh' if isinstance(wallet, SegwitWallet) else 'p2pkh' if amount == 0: utxos = wallet.get_utxos_by_mixdepth()[mixdepth] if utxos == {}: @@ -51,10 +52,11 @@ def direct_send(wallet, amount, mixdepth, destaddr, answeryes=False, "There are no utxos in mixdepth: " + str(mixdepth) + ", quitting.") return total_inputs_val = sum([va['value'] for u, va in utxos.iteritems()]) - fee_est = estimate_tx_fee(len(utxos), 1) + fee_est = estimate_tx_fee(len(utxos), 1, txtype=txtype) outs = [{"address": destaddr, "value": total_inputs_val - fee_est}] else: - initial_fee_est = estimate_tx_fee(8,2) #8 inputs to be conservative + #8 inputs to be conservative + initial_fee_est = estimate_tx_fee(8,2, txtype=txtype) utxos = wallet.select_utxos(mixdepth, amount + initial_fee_est) if len(utxos) < 8: fee_est = estimate_tx_fee(len(utxos), 2) @@ -76,7 +78,8 @@ def direct_send(wallet, amount, mixdepth, destaddr, answeryes=False, utxo = ins['outpoint']['hash'] + ':' + str( ins['outpoint']['index']) addr = utxos[utxo]['address'] - tx = sign(tx, index, wallet.get_key_from_addr(addr)) + signing_amount = utxos[utxo]['value'] + tx = sign(tx, index, wallet.get_key_from_addr(addr), amount=signing_amount) txsigned = deserialize(tx) log.info("Got signed transaction:\n") log.info(tx + "\n") diff --git a/jmclient/jmclient/wallet.py b/jmclient/jmclient/wallet.py index 43c45a0..21fc6c0 100644 --- a/jmclient/jmclient/wallet.py +++ b/jmclient/jmclient/wallet.py @@ -12,7 +12,7 @@ from getpass import getpass import btc from jmclient.slowaes import encryptData, decryptData from jmclient.blockchaininterface import BitcoinCoreInterface, RegtestBitcoinCoreInterface -from jmclient.configure import jm_single, get_network, get_p2pk_vbyte +from jmclient.configure import jm_single, get_network, get_p2pk_vbyte, get_p2sh_vbyte from jmbase.support import get_log from jmclient.support import select_gradual, select_greedy,select_greediest, select @@ -364,10 +364,11 @@ class Wallet(AbstractWallet): class SegwitWallet(Wallet): - def __init__(self, seedarg, max_mix_depth=2, gaplimit=6, - extend_mixdepth=False, storepassword=False): - super(SegwitWallet, self).__init__(seedarg, max_mix_depth, gaplimit, - extend_mixdepth, storepassword) + def __init__(self, seedarg, pwd, max_mix_depth=2, gaplimit=6, + extend_mixdepth=False, storepassword=False, wallet_dir=None): + super(SegwitWallet, self).__init__(seedarg, pwd, max_mix_depth, gaplimit, + extend_mixdepth, storepassword, + wallet_dir=wallet_dir) self.vflag = JM_WALLET_SW_P2SH_P2WPKH def get_vbyte(self): diff --git a/scripts/sendpayment.py b/scripts/sendpayment.py index ee71ab5..6a216e4 100644 --- a/scripts/sendpayment.py +++ b/scripts/sendpayment.py @@ -24,7 +24,7 @@ from jmclient import (Taker, load_program_config, get_schedule, cheapest_order_choose, weighted_order_choose, Wallet, BitcoinCoreWallet, sync_wallet, RegtestBitcoinCoreInterface, estimate_tx_fee, - direct_send) + direct_send, SegwitWallet) from jmbase.support import get_log, debug_dump_object, get_password from cli_options import get_sendpayment_parser @@ -124,12 +124,12 @@ def main(): if not options.userpcwallet: max_mix_depth = max([mixdepth, options.amtmixdepths]) if not os.path.exists(os.path.join('wallets', wallet_name)): - wallet = Wallet(wallet_name, None, max_mix_depth, options.gaplimit) + wallet = SegwitWallet(wallet_name, None, max_mix_depth, options.gaplimit) else: while True: try: pwd = get_password("Enter wallet decryption passphrase: ") - wallet = Wallet(wallet_name, pwd, max_mix_depth, options.gaplimit) + wallet = SegwitWallet(wallet_name, pwd, max_mix_depth, options.gaplimit) except WalletError: print("Wrong password, try again.") continue diff --git a/scripts/wallet-tool.py b/scripts/wallet-tool.py index 2e50513..957ce4c 100644 --- a/scripts/wallet-tool.py +++ b/scripts/wallet-tool.py @@ -1,6 +1,7 @@ from __future__ import absolute_import, print_function from jmclient import load_program_config, wallet_tool_main + SegwitWallet, get_p2sh_vbyte) if __name__ == "__main__": load_program_config()