fixes for signrawtransaction
This commit is contained in:
parent
6bb8af5822
commit
81b84fd5ef
3
electrum
3
electrum
|
@ -429,7 +429,8 @@ if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
result = func(*args[1:])
|
result = func(*args[1:])
|
||||||
except BaseException, e:
|
except BaseException, e:
|
||||||
print_msg("Error: " + str(e))
|
import traceback
|
||||||
|
traceback.print_exc(file=sys.stdout)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if type(result) == str:
|
if type(result) == str:
|
||||||
|
|
|
@ -604,6 +604,9 @@ class Transaction:
|
||||||
redeem_script = txin.get('redeemScript')
|
redeem_script = txin.get('redeemScript')
|
||||||
num, redeem_pubkeys = deserialize.parse_redeemScript(redeem_script) if redeem_script else (1, [txin.get('redeemPubkey')])
|
num, redeem_pubkeys = deserialize.parse_redeemScript(redeem_script) if redeem_script else (1, [txin.get('redeemPubkey')])
|
||||||
|
|
||||||
|
# add pubkeys
|
||||||
|
txin["pubkeys"] = redeem_pubkeys
|
||||||
|
|
||||||
# get list of already existing signatures
|
# get list of already existing signatures
|
||||||
signatures = txin.get("signatures",[])
|
signatures = txin.get("signatures",[])
|
||||||
# continue if this txin is complete
|
# continue if this txin is complete
|
||||||
|
@ -624,9 +627,8 @@ class Transaction:
|
||||||
sig = private_key.sign_digest( Hash( tx_for_sig.decode('hex') ), sigencode = ecdsa.util.sigencode_der )
|
sig = private_key.sign_digest( Hash( tx_for_sig.decode('hex') ), sigencode = ecdsa.util.sigencode_der )
|
||||||
assert public_key.verify_digest( sig, Hash( tx_for_sig.decode('hex') ), sigdecode = ecdsa.util.sigdecode_der)
|
assert public_key.verify_digest( sig, Hash( tx_for_sig.decode('hex') ), sigdecode = ecdsa.util.sigdecode_der)
|
||||||
signatures.append( sig.encode('hex') )
|
signatures.append( sig.encode('hex') )
|
||||||
|
|
||||||
txin["signatures"] = signatures
|
txin["signatures"] = signatures
|
||||||
txin["pubkeys"] = redeem_pubkeys
|
|
||||||
print_error("signatures", signatures)
|
print_error("signatures", signatures)
|
||||||
is_complete = is_complete and len(signatures) == num
|
is_complete = is_complete and len(signatures) == num
|
||||||
|
|
||||||
|
|
|
@ -356,6 +356,16 @@ class Wallet:
|
||||||
return dd
|
return dd
|
||||||
|
|
||||||
|
|
||||||
|
def get_keyID(self, account, sequence):
|
||||||
|
rs = self.rebase_sequence(account, sequence)
|
||||||
|
dd = []
|
||||||
|
for root, public_sequence in rs:
|
||||||
|
c, K, _ = self.master_public_keys[root]
|
||||||
|
s = '/' + '/'.join( map(lambda x:str(x), public_sequence) )
|
||||||
|
dd.append( 'bip32(%s,%s,%s)'%(c,K, s) )
|
||||||
|
return '&'.join(dd)
|
||||||
|
|
||||||
|
|
||||||
def get_public_key(self, address):
|
def get_public_key(self, address):
|
||||||
account, sequence = self.get_address_index(address)
|
account, sequence = self.get_address_index(address)
|
||||||
return self.accounts[account].get_pubkey( *sequence )
|
return self.accounts[account].get_pubkey( *sequence )
|
||||||
|
@ -414,27 +424,27 @@ class Wallet:
|
||||||
else:
|
else:
|
||||||
for item in unspent_coins:
|
for item in unspent_coins:
|
||||||
if txin['tx_hash'] == item['tx_hash'] and txin['index'] == item['index']:
|
if txin['tx_hash'] == item['tx_hash'] and txin['index'] == item['index']:
|
||||||
|
print_error( "tx input is in unspent coins" )
|
||||||
txin['raw_output_script'] = item['raw_output_script']
|
txin['raw_output_script'] = item['raw_output_script']
|
||||||
|
account, sequence = self.get_address_index(item['address'])
|
||||||
|
if account != -1:
|
||||||
|
txin['redeemScript'] = self.accounts[account].redeem_script(sequence)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# if neither, we might want to get it from the server..
|
raise BaseException("Unknown transaction input. Please provide the 'input_info' parameter, or synchronize this wallet")
|
||||||
raise
|
|
||||||
|
|
||||||
# find the address and fill private_keys
|
# if available, derive private_keys from KeyID
|
||||||
keyid = txin.get('KeyID')
|
keyid = txin.get('KeyID')
|
||||||
if keyid:
|
if keyid:
|
||||||
|
|
||||||
roots = []
|
roots = []
|
||||||
for s in keyid.split('&'):
|
for s in keyid.split('&'):
|
||||||
m = re.match("bip32\(([0-9a-f]+),([0-9a-f]+),(/\d+/\d+/\d+)", s)
|
m = re.match("bip32\(([0-9a-f]+),([0-9a-f]+),(/\d+/\d+/\d+)", s)
|
||||||
if not m: continue
|
if not m: continue
|
||||||
|
|
||||||
c = m.group(1)
|
c = m.group(1)
|
||||||
K = m.group(2)
|
K = m.group(2)
|
||||||
sequence = m.group(3)
|
sequence = m.group(3)
|
||||||
root = self.find_root_by_master_key(c,K)
|
root = self.find_root_by_master_key(c,K)
|
||||||
if not root: continue
|
if not root: continue
|
||||||
|
|
||||||
sequence = map(lambda x:int(x), sequence.strip('/').split('/'))
|
sequence = map(lambda x:int(x), sequence.strip('/').split('/'))
|
||||||
root = root + '%d'%sequence[0]
|
root = root + '%d'%sequence[0]
|
||||||
sequence = sequence[1:]
|
sequence = sequence[1:]
|
||||||
|
@ -451,18 +461,22 @@ class Wallet:
|
||||||
keypairs[pubkey] = sec
|
keypairs[pubkey] = sec
|
||||||
|
|
||||||
redeem_script = txin.get("redeemScript")
|
redeem_script = txin.get("redeemScript")
|
||||||
|
print_error( "p2sh:", "yes" if redeem_script else "no")
|
||||||
if redeem_script:
|
if redeem_script:
|
||||||
num, redeem_pubkeys = deserialize.parse_redeemScript(redeem_script)
|
|
||||||
addr = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), 5)
|
addr = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), 5)
|
||||||
txin['address'] = addr
|
else:
|
||||||
|
addr = deserialize.get_address_from_output_script(txin["raw_output_script"].decode('hex'))
|
||||||
|
txin['address'] = addr
|
||||||
|
|
||||||
elif txin.get("raw_output_script"):
|
# add private keys that are in the wallet
|
||||||
addr = deserialize.get_address_from_output_script(txin.get("raw_output_script").decode('hex'))
|
pk = self.get_private_key(addr, password)
|
||||||
sec = self.get_private_key(addr, password)
|
for sec in pk:
|
||||||
pubkey = public_key_from_private_key(sec)
|
pubkey = public_key_from_private_key(sec)
|
||||||
if sec:
|
keypairs[pubkey] = sec
|
||||||
keypairs[pubkey] = sec
|
if not redeem_script:
|
||||||
txin['address'] = addr
|
txin['redeemPubkey'] = pubkey
|
||||||
|
|
||||||
|
print txin
|
||||||
|
|
||||||
tx.sign( keypairs )
|
tx.sign( keypairs )
|
||||||
|
|
||||||
|
@ -948,13 +962,6 @@ class Wallet:
|
||||||
|
|
||||||
|
|
||||||
def mktx(self, outputs, password, fee=None, change_addr=None, account=None ):
|
def mktx(self, outputs, password, fee=None, change_addr=None, account=None ):
|
||||||
"""
|
|
||||||
create a transaction
|
|
||||||
account parameter:
|
|
||||||
None means use all accounts
|
|
||||||
-1 means imported keys
|
|
||||||
0, 1, etc are seed accounts
|
|
||||||
"""
|
|
||||||
|
|
||||||
for address, x in outputs:
|
for address, x in outputs:
|
||||||
assert is_valid(address)
|
assert is_valid(address)
|
||||||
|
@ -973,15 +980,7 @@ class Wallet:
|
||||||
address = txin['address']
|
address = txin['address']
|
||||||
|
|
||||||
account, sequence = self.get_address_index(address)
|
account, sequence = self.get_address_index(address)
|
||||||
|
txin['KeyID'] = self.get_keyID(account, sequence)
|
||||||
rs = self.rebase_sequence(account, sequence)
|
|
||||||
dd = []
|
|
||||||
for root, public_sequence in rs:
|
|
||||||
c, K, _ = self.master_public_keys[root]
|
|
||||||
s = '/' + '/'.join( map(lambda x:str(x), public_sequence) )
|
|
||||||
dd.append( 'bip32(%s,%s,%s)'%(c,K, s) )
|
|
||||||
|
|
||||||
txin['KeyID'] = '&'.join(dd)
|
|
||||||
|
|
||||||
redeemScript = self.accounts[account].redeem_script(sequence)
|
redeemScript = self.accounts[account].redeem_script(sequence)
|
||||||
if redeemScript:
|
if redeemScript:
|
||||||
|
@ -992,7 +991,6 @@ class Wallet:
|
||||||
|
|
||||||
private_keys = self.get_private_key(address, password)
|
private_keys = self.get_private_key(address, password)
|
||||||
|
|
||||||
print "pk", address, private_keys
|
|
||||||
for sec in private_keys:
|
for sec in private_keys:
|
||||||
pubkey = public_key_from_private_key(sec)
|
pubkey = public_key_from_private_key(sec)
|
||||||
keypairs[ pubkey ] = sec
|
keypairs[ pubkey ] = sec
|
||||||
|
|
Loading…
Reference in New Issue