1
1
#!/usr/bin/env python
3
3
# Electrum - lightweight Bitcoin client
4
# Copyright (C) 2011 thomasv@gitorious
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with this program. If not, see <http://www.gnu.org/licenses/>.
4
# Copyright (C) 2011 Thomas Voegtlin
6
# Permission is hereby granted, free of charge, to any person
7
# obtaining a copy of this software and associated documentation files
8
# (the "Software"), to deal in the Software without restriction,
9
# including without limitation the rights to use, copy, modify, merge,
10
# publish, distribute, sublicense, and/or sell copies of the Software,
11
# and to permit persons to whom the Software is furnished to do so,
12
# subject to the following conditions:
14
# The above copyright notice and this permission notice shall be
15
# included in all copies or substantial portions of the Software.
17
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
28
# Note: The deserialization code originally comes from ABE.
393
402
# 65 BYTES:... CHECKSIG
394
403
match = [ opcodes.OP_PUSHDATA4, opcodes.OP_CHECKSIG ]
395
404
if match_decoded(decoded, match):
396
return 'pubkey', decoded[0][1].encode('hex')
405
return TYPE_PUBKEY, decoded[0][1].encode('hex')
398
407
# Pay-by-Bitcoin-address TxOuts look like:
399
408
# DUP HASH160 20 BYTES:... EQUALVERIFY CHECKSIG
400
409
match = [ opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG ]
401
410
if match_decoded(decoded, match):
402
return 'address', hash_160_to_bc_address(decoded[2][1])
411
return TYPE_ADDRESS, hash_160_to_bc_address(decoded[2][1])
405
414
match = [ opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL ]
406
415
if match_decoded(decoded, match):
407
return 'address', hash_160_to_bc_address(decoded[1][1],5)
416
return TYPE_ADDRESS, hash_160_to_bc_address(decoded[1][1],5)
409
return 'script', bytes
418
return TYPE_SCRIPT, bytes
478
487
self.raw = raw['hex']
480
489
raise BaseException("cannot initialize transaction", raw)
483
493
def update(self, raw):
486
496
self.deserialize()
499
if self._inputs is None:
504
if self._outputs is None:
488
508
def update_signatures(self, raw):
489
509
"""Add new signatures to a transaction"""
490
510
d = deserialize(raw)
491
for i, txin in enumerate(self.inputs):
511
for i, txin in enumerate(self.inputs()):
492
512
sigs1 = txin.get('signatures')
493
513
sigs2 = d['inputs'][i].get('signatures')
494
514
for sig in sigs2:
508
528
public_key.verify_digest(sig_string, for_sig, sigdecode = ecdsa.util.sigdecode_string)
509
529
j = pubkeys.index(pubkey)
510
530
print_error("adding sig", i, j, pubkey, sig)
511
self.inputs[i]['signatures'][j] = sig
512
self.inputs[i]['x_pubkeys'][j] = pubkey
531
self._inputs[i]['signatures'][j] = sig
532
self._inputs[i]['x_pubkeys'][j] = pubkey
515
535
self.raw = self.serialize()
518
538
def deserialize(self):
519
539
if self.raw is None:
520
540
self.raw = self.serialize()
521
if self.inputs is not None:
541
if self._inputs is not None:
523
543
d = deserialize(self.raw)
524
self.inputs = d['inputs']
525
self.outputs = [(x['type'], x['address'], x['value']) for x in d['outputs']]
544
self._inputs = d['inputs']
545
self._outputs = [(x['type'], x['address'], x['value']) for x in d['outputs']]
526
546
self.locktime = d['lockTime']
530
550
def from_io(klass, inputs, outputs, locktime=0):
531
551
self = klass(None)
533
self.outputs = outputs
552
self._inputs = inputs
553
self._outputs = outputs
534
554
self.locktime = locktime
542
562
pubkey = public_key_from_private_key(privkey)
543
563
address = address_from_private_key(privkey)
544
564
u = network.synchronous_get(('blockchain.address.listunspent',[address]))
545
pay_script = klass.pay_script('address', address)
565
pay_script = klass.pay_script(TYPE_ADDRESS, address)
547
567
item['scriptPubKey'] = pay_script
548
568
item['redeemPubkey'] = pubkey
562
582
total = sum(i.get('value') for i in inputs) - fee
563
outputs = [('address', to_address, total)]
583
outputs = [(TYPE_ADDRESS, to_address, total)]
564
584
self = klass.from_io(inputs, outputs)
565
585
self.sign(keypairs)
579
599
def pay_script(self, output_type, addr):
580
if output_type == 'script':
600
if output_type == TYPE_SCRIPT:
581
601
return addr.encode('hex')
582
elif output_type == 'address':
602
elif output_type == TYPE_ADDRESS:
583
603
addrtype, hash_160 = bc_address_to_hash_160(addr)
584
604
if addrtype == 0:
585
605
script = '76a9' # op_dup, op_hash_160
635
656
script += push_script(redeem_script)
638
script = txin['redeemScript'] if p2sh else self.pay_script('address', address)
659
script = txin['redeemScript'] if p2sh else self.pay_script(TYPE_ADDRESS, address)
666
def serialize_input(self, txin, i, for_sig):
667
# Prev hash and index
668
s = txin['prevout_hash'].decode('hex')[::-1].encode('hex')
669
s += int_to_hex(txin['prevout_n'], 4)
670
# Script length, script, sequence
671
script = self.input_script(txin, i, for_sig)
672
s += var_int(len(script) / 2)
644
677
def BIP_LI01_sort(self):
645
678
# See https://github.com/kristovatlas/rfc/blob/master/bips/bip-li01.mediawiki
646
self.inputs.sort(key = lambda i: (i['prevout_hash'], i['prevout_n']))
647
self.outputs.sort(key = lambda o: (o[2], self.pay_script(o[0], o[1])))
679
self._inputs.sort(key = lambda i: (i['prevout_hash'], i['prevout_n']))
680
self._outputs.sort(key = lambda o: (o[2], self.pay_script(o[0], o[1])))
649
682
def serialize(self, for_sig=None):
651
outputs = self.outputs
683
inputs = self.inputs()
684
outputs = self.outputs()
652
685
s = int_to_hex(1,4) # version
653
686
s += var_int( len(inputs) ) # number of inputs
654
687
for i, txin in enumerate(inputs):
655
s += txin['prevout_hash'].decode('hex')[::-1].encode('hex') # prev hash
656
s += int_to_hex(txin['prevout_n'], 4) # prev index
657
script = self.input_script(txin, i, for_sig)
658
s += var_int( len(script)/2 ) # script length
660
s += "ffffffff" # sequence
688
s += self.serialize_input(txin, i, for_sig)
661
689
s += var_int( len(outputs) ) # number of outputs
662
690
for output in outputs:
663
691
output_type, addr, amount = output
677
705
return Hash(self.raw.decode('hex') )[::-1].encode('hex')
679
def add_input(self, input):
680
self.inputs.append(input)
707
def add_inputs(self, inputs):
708
self._inputs.extend(inputs)
711
def add_outputs(self, outputs):
712
self._outputs.extend(outputs)
683
715
def input_value(self):
684
return sum(x['value'] for x in self.inputs)
716
return sum(x['value'] for x in self.inputs())
686
718
def output_value(self):
687
return sum( val for tp,addr,val in self.outputs)
719
return sum( val for tp,addr,val in self.outputs())
689
721
def get_fee(self):
690
722
return self.input_value() - self.output_value()
725
return not any([x.get('sequence') < 0xffffffff - 1 for x in self.inputs()])
728
def estimated_size(self):
729
'''Return an estimated tx size in bytes.'''
730
return len(self.serialize(-1)) / 2 # ASCII hex string
733
def estimated_input_size(self, txin):
734
'''Return an estimated of serialized input size in bytes.'''
735
return len(self.serialize_input(txin, -1, -1)) / 2
692
737
def signature_count(self):
695
for txin in self.inputs:
740
for txin in self.inputs():
696
741
if txin.get('is_coinbase'):
698
743
signatures = filter(None, txin.get('signatures',[]))
707
752
def inputs_without_script(self):
709
for i, txin in enumerate(self.inputs):
754
for i, txin in enumerate(self.inputs()):
710
755
if txin.get('scriptSig') == '':
714
759
def inputs_to_sign(self):
716
for txin in self.inputs:
761
for txin in self.inputs():
717
762
num_sig = txin.get('num_sig')
718
763
if num_sig is None:
732
777
def sign(self, keypairs):
733
for i, txin in enumerate(self.inputs):
778
for i, txin in enumerate(self.inputs()):
734
779
num = txin['num_sig']
735
780
for x_pubkey in txin['x_pubkeys']:
736
781
signatures = filter(None, txin['signatures'])
740
785
if x_pubkey in keypairs.keys():
741
786
print_error("adding signature for", x_pubkey)
742
787
# add pubkey to txin
743
txin = self.inputs[i]
788
txin = self._inputs[i]
744
789
x_pubkeys = txin['x_pubkeys']
745
790
ii = x_pubkeys.index(x_pubkey)
746
791
sec = keypairs[x_pubkey]
747
792
pubkey = public_key_from_private_key(sec)
748
793
txin['x_pubkeys'][ii] = pubkey
749
794
txin['pubkeys'][ii] = pubkey
750
self.inputs[i] = txin
795
self._inputs[i] = txin
752
797
for_sig = Hash(self.tx_for_sig(i).decode('hex'))
753
798
pkey = regenerate_key(sec)
757
802
sig = private_key.sign_digest_deterministic( for_sig, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der )
758
803
assert public_key.verify_digest( sig, for_sig, sigdecode = ecdsa.util.sigdecode_der)
759
804
txin['signatures'][ii] = sig.encode('hex')
760
self.inputs[i] = txin
805
self._inputs[i] = txin
761
806
print_error("is_complete", self.is_complete())
762
807
self.raw = self.serialize()
765
810
def get_outputs(self):
766
811
"""convert pubkeys to addresses"""
768
for type, x, v in self.outputs:
769
if type == 'address':
813
for type, x, v in self.outputs():
814
if type == TYPE_ADDRESS:
771
elif type == 'pubkey':
816
elif type == TYPE_PUBKEY:
772
817
addr = public_key_to_bc_address(x.decode('hex'))
774
819
addr = 'SCRIPT ' + x.encode('hex')
807
852
# priority must be large enough for free tx
808
853
threshold = 57600000
810
for txin in self.inputs:
855
for txin in self.inputs():
811
856
age = wallet.get_confirmations(txin["prevout_hash"])[0]
812
857
weight += txin["value"] * age
813
858
priority = weight / size
814
859
print_error(priority, threshold)
816
861
return priority < threshold
865
def tx_from_str(txt):
866
"json or raw hexadecimal"
875
return Transaction(txt)
876
tx_dict = json.loads(str(txt))
877
assert "hex" in tx_dict.keys()
878
tx = Transaction(tx_dict["hex"])