separate signtxwithkey and signtxwithwallet, and simplify sign_transaction
This commit is contained in:
parent
c1226b0f6e
commit
581ed1ed26
3
electrum
3
electrum
|
@ -375,9 +375,6 @@ if __name__ == '__main__':
|
||||||
if len(args) == 1:
|
if len(args) == 1:
|
||||||
args.append(prompt_password('Enter PrivateKey (will not echo):', False))
|
args.append(prompt_password('Enter PrivateKey (will not echo):', False))
|
||||||
|
|
||||||
elif cmd.name == 'signrawtransaction':
|
|
||||||
args = [cmd, args[1], json.loads(args[2]) if len(args) > 2 else [] ]
|
|
||||||
|
|
||||||
elif cmd.name == 'createmultisig':
|
elif cmd.name == 'createmultisig':
|
||||||
args = [cmd, int(args[1]), json.loads(args[2])]
|
args = [cmd, int(args[1]), json.loads(args[2])]
|
||||||
|
|
||||||
|
|
|
@ -1113,9 +1113,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
def sign_thread():
|
def sign_thread():
|
||||||
if self.wallet.is_watching_only():
|
if self.wallet.is_watching_only():
|
||||||
return tx
|
return tx
|
||||||
keypairs = {}
|
self.wallet.sign_transaction(tx, password)
|
||||||
self.wallet.add_keypairs(tx, keypairs, password)
|
|
||||||
self.wallet.sign_transaction(tx, keypairs, password)
|
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
def sign_done(tx):
|
def sign_done(tx):
|
||||||
|
@ -2179,7 +2177,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
@protected
|
@protected
|
||||||
def sign_raw_transaction(self, tx, password):
|
def sign_raw_transaction(self, tx, password):
|
||||||
try:
|
try:
|
||||||
self.wallet.signrawtransaction(tx, [], password)
|
self.wallet.sign_transaction(tx, password)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
traceback.print_exc(file=sys.stdout)
|
traceback.print_exc(file=sys.stdout)
|
||||||
QMessageBox.warning(self, _("Error"), str(e))
|
QMessageBox.warning(self, _("Error"), str(e))
|
||||||
|
|
|
@ -97,7 +97,8 @@ register_command('restore', 0, 0, True, True, False, 'Restore a w
|
||||||
register_command('setconfig', 2, 2, False, False, False, 'Set a configuration variable', 'setconfig <name> <value>')
|
register_command('setconfig', 2, 2, False, False, False, 'Set a configuration variable', 'setconfig <name> <value>')
|
||||||
register_command('setlabel', 2,-1, False, True, False, 'Assign a label to an item', 'setlabel <tx_hash> <label>')
|
register_command('setlabel', 2,-1, False, True, False, 'Assign a label to an item', 'setlabel <tx_hash> <label>')
|
||||||
register_command('sendrawtransaction', 1, 1, True, False, False, 'Broadcasts a transaction to the network.', 'sendrawtransaction <tx in hexadecimal>')
|
register_command('sendrawtransaction', 1, 1, True, False, False, 'Broadcasts a transaction to the network.', 'sendrawtransaction <tx in hexadecimal>')
|
||||||
register_command('signrawtransaction', 1, 3, False, True, True, 'Sign a serailized transaction','signrawtransaction <tx in hexadecimal>')
|
register_command('signtxwithkey', 1, 3, False, False, False, 'Sign a serialized transaction with a key','signtxwithkey <tx> <key>')
|
||||||
|
register_command('signtxwithwallet', 1, 3, False, True, True, 'Sign a serialized transaction with a wallet','signtxwithwallet <tx>')
|
||||||
register_command('signmessage', 2,-1, False, True, True, 'Sign a message with a key', signmessage_syntax)
|
register_command('signmessage', 2,-1, False, True, True, 'Sign a message with a key', signmessage_syntax)
|
||||||
register_command('unfreeze', 1, 1, False, True, False, 'Unfreeze the funds at one of your wallet\'s address', 'unfreeze <address>')
|
register_command('unfreeze', 1, 1, False, True, False, 'Unfreeze the funds at one of your wallet\'s address', 'unfreeze <address>')
|
||||||
register_command('validateaddress', 1, 1, False, False, False, 'Check that the address is valid', 'validateaddress <address>')
|
register_command('validateaddress', 1, 1, False, False, False, 'Check that the address is valid', 'validateaddress <address>')
|
||||||
|
@ -164,9 +165,15 @@ class Commands:
|
||||||
tx = Transaction(inputs, outputs)
|
tx = Transaction(inputs, outputs)
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
def signrawtransaction(self, raw_tx, private_keys):
|
def signtxwithkey(self, raw_tx, sec):
|
||||||
tx = Transaction.deserialize(raw_tx)
|
tx = Transaction.deserialize(raw_tx)
|
||||||
self.wallet.signrawtransaction(tx, private_keys, self.password)
|
pubkey = bitcoin.public_key_from_private_key(sec)
|
||||||
|
tx.sign({ pubkey:sec })
|
||||||
|
return tx
|
||||||
|
|
||||||
|
def signtxwithwallet(self, raw_tx):
|
||||||
|
tx = Transaction.deserialize(raw_tx)
|
||||||
|
self.wallet.sign_transaction(tx, self.password)
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
def decoderawtransaction(self, raw):
|
def decoderawtransaction(self, raw):
|
||||||
|
|
|
@ -322,7 +322,9 @@ def x_to_xpub(x_pubkey):
|
||||||
|
|
||||||
|
|
||||||
def parse_xpub(x_pubkey):
|
def parse_xpub(x_pubkey):
|
||||||
if x_pubkey[0:2] == 'ff':
|
if x_pubkey[0:2] in ['02','03','04']:
|
||||||
|
pubkey = x_pubkey
|
||||||
|
elif x_pubkey[0:2] == 'ff':
|
||||||
from account import BIP32_Account
|
from account import BIP32_Account
|
||||||
xpub, s = BIP32_Account.parse_xpubkey(x_pubkey)
|
xpub, s = BIP32_Account.parse_xpubkey(x_pubkey)
|
||||||
pubkey = BIP32_Account.derive_pubkey_from_xpub(xpub, s[0], s[1])
|
pubkey = BIP32_Account.derive_pubkey_from_xpub(xpub, s[0], s[1])
|
||||||
|
@ -331,7 +333,7 @@ def parse_xpub(x_pubkey):
|
||||||
mpk, s = OldAccount.parse_xpubkey(x_pubkey)
|
mpk, s = OldAccount.parse_xpubkey(x_pubkey)
|
||||||
pubkey = OldAccount.get_pubkey_from_mpk(mpk.decode('hex'), s[0], s[1])
|
pubkey = OldAccount.get_pubkey_from_mpk(mpk.decode('hex'), s[0], s[1])
|
||||||
else:
|
else:
|
||||||
pubkey = x_pubkey
|
raise BaseException("Cannnot parse pubkey")
|
||||||
return pubkey
|
return pubkey
|
||||||
|
|
||||||
|
|
||||||
|
@ -595,8 +597,8 @@ class Transaction:
|
||||||
def serialize(self, for_sig=None):
|
def serialize(self, for_sig=None):
|
||||||
# for_sig:
|
# for_sig:
|
||||||
# -1 : do not sign, estimate length
|
# -1 : do not sign, estimate length
|
||||||
# i>=0 : sign input i
|
# i>=0 : serialized tx for signing input i
|
||||||
# None : add all signatures
|
# None : add all known signatures
|
||||||
|
|
||||||
inputs = self.inputs
|
inputs = self.inputs
|
||||||
outputs = self.outputs
|
outputs = self.outputs
|
||||||
|
|
|
@ -362,45 +362,6 @@ class Abstract_Wallet(object):
|
||||||
account_id, sequence = self.get_address_index(address)
|
account_id, sequence = self.get_address_index(address)
|
||||||
return self.accounts[account_id].get_pubkeys(*sequence)
|
return self.accounts[account_id].get_pubkeys(*sequence)
|
||||||
|
|
||||||
def add_keypairs(self, tx, keypairs, password):
|
|
||||||
|
|
||||||
if self.is_watching_only():
|
|
||||||
return
|
|
||||||
self.check_password(password)
|
|
||||||
|
|
||||||
addr_list, xpub_list = tx.inputs_to_sign()
|
|
||||||
for addr in addr_list:
|
|
||||||
if self.is_mine(addr):
|
|
||||||
private_keys = self.get_private_key(addr, password)
|
|
||||||
for sec in private_keys:
|
|
||||||
pubkey = public_key_from_private_key(sec)
|
|
||||||
keypairs[ pubkey ] = sec
|
|
||||||
|
|
||||||
for xpub, sequence in xpub_list:
|
|
||||||
# look for account that can sign
|
|
||||||
for k, account in self.accounts.items():
|
|
||||||
if xpub in account.get_master_pubkeys():
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
pk = account.get_private_key(sequence, self, password)
|
|
||||||
for sec in pk:
|
|
||||||
pubkey = public_key_from_private_key(sec)
|
|
||||||
keypairs[pubkey] = sec
|
|
||||||
|
|
||||||
def signrawtransaction(self, tx, private_keys, password):
|
|
||||||
# check that the password is correct. This will raise if it's not.
|
|
||||||
self.check_password(password)
|
|
||||||
# build a list of public/private keys
|
|
||||||
keypairs = {}
|
|
||||||
# add private keys from parameter
|
|
||||||
for sec in private_keys:
|
|
||||||
pubkey = public_key_from_private_key(sec)
|
|
||||||
keypairs[ pubkey ] = sec
|
|
||||||
# add private_keys
|
|
||||||
self.add_keypairs(tx, keypairs, password)
|
|
||||||
# sign the transaction
|
|
||||||
self.sign_transaction(tx, keypairs, password)
|
|
||||||
|
|
||||||
def sign_message(self, address, message, password):
|
def sign_message(self, address, message, password):
|
||||||
keys = self.get_private_key(address, password)
|
keys = self.get_private_key(address, password)
|
||||||
|
@ -777,10 +738,7 @@ class Abstract_Wallet(object):
|
||||||
|
|
||||||
def mktx(self, outputs, password, fee=None, change_addr=None, domain= None, coins = None ):
|
def mktx(self, outputs, password, fee=None, change_addr=None, domain= None, coins = None ):
|
||||||
tx = self.make_unsigned_transaction(outputs, fee, change_addr, domain, coins)
|
tx = self.make_unsigned_transaction(outputs, fee, change_addr, domain, coins)
|
||||||
keypairs = {}
|
self.sign_transaction(tx, password)
|
||||||
self.add_keypairs(tx, keypairs, password)
|
|
||||||
if keypairs:
|
|
||||||
self.sign_transaction(tx, keypairs, password)
|
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
def add_input_info(self, txin):
|
def add_input_info(self, txin):
|
||||||
|
@ -803,8 +761,40 @@ class Abstract_Wallet(object):
|
||||||
txin['redeemPubkey'] = account.get_pubkey(*sequence)
|
txin['redeemPubkey'] = account.get_pubkey(*sequence)
|
||||||
txin['num_sig'] = 1
|
txin['num_sig'] = 1
|
||||||
|
|
||||||
def sign_transaction(self, tx, keypairs, password):
|
def sign_transaction(self, tx, password):
|
||||||
|
if self.is_watching_only():
|
||||||
|
return
|
||||||
|
# check that the password is correct. This will raise if it's not.
|
||||||
|
self.check_password(password)
|
||||||
|
|
||||||
|
|
||||||
|
keypairs = {}
|
||||||
|
|
||||||
|
# tx.inputs_to_sign() : return list of addresses or derivations
|
||||||
|
# this list should be enriched by add_keypairs
|
||||||
|
addr_list, xpub_list = tx.inputs_to_sign()
|
||||||
|
for addr in addr_list:
|
||||||
|
if self.is_mine(addr):
|
||||||
|
private_keys = self.get_private_key(addr, password)
|
||||||
|
for sec in private_keys:
|
||||||
|
pubkey = public_key_from_private_key(sec)
|
||||||
|
keypairs[ pubkey ] = sec
|
||||||
|
|
||||||
|
for xpub, sequence in xpub_list:
|
||||||
|
# look for account that can sign
|
||||||
|
for k, account in self.accounts.items():
|
||||||
|
if xpub in account.get_master_pubkeys():
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
pk = account.get_private_key(sequence, self, password)
|
||||||
|
for sec in pk:
|
||||||
|
pubkey = public_key_from_private_key(sec)
|
||||||
|
keypairs[pubkey] = sec
|
||||||
|
|
||||||
|
if keypairs:
|
||||||
tx.sign(keypairs)
|
tx.sign(keypairs)
|
||||||
|
|
||||||
run_hook('sign_transaction', tx, password)
|
run_hook('sign_transaction', tx, password)
|
||||||
|
|
||||||
def sendtx(self, tx):
|
def sendtx(self, tx):
|
||||||
|
|
Loading…
Reference in New Issue