commit 2efad717d8af578af321681275009d0bce5865ba
parent 508d8a798f7bf7605d3b220386e042e62882614d
Author: ThomasV <thomasv@gitorious>
Date: Fri, 27 Jun 2014 17:08:20 +0200
support for OP_RETURN
Diffstat:
4 files changed, 28 insertions(+), 20 deletions(-)
diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
@@ -987,7 +987,12 @@ class ElectrumWindow(QMainWindow):
return
for addr, x in outputs:
- if addr is None or not bitcoin.is_address(addr):
+ if addr is None:
+ QMessageBox.warning(self, _('Error'), _('Bitcoin Address is None'), _('OK'))
+ return
+ if addr.startswith('OP_RETURN:'):
+ continue
+ if not bitcoin.is_address(addr):
QMessageBox.warning(self, _('Error'), _('Invalid Bitcoin Address'), _('OK'))
return
if x is None:
diff --git a/gui/qt/paytoedit.py b/gui/qt/paytoedit.py
@@ -69,9 +69,14 @@ class PayToEdit(QRTextEdit):
self.setStyleSheet("QWidget { background-color:#ffcccc;}")
def parse_address_and_amount(self, line):
- x, y = line.split(',')
- address = self.parse_address(x)
- amount = self.parse_amount(y)
+ m = re.match('^OP_RETURN\s+"(.+)"$', line.strip())
+ if m:
+ address = 'OP_RETURN:' + m.group(1)
+ amount = 0
+ else:
+ x, y = line.split(',')
+ address = self.parse_address(x)
+ amount = self.parse_amount(y)
return address, amount
@@ -121,7 +126,7 @@ class PayToEdit(QRTextEdit):
self.outputs = outputs
self.payto_address = None
- if total:
+ if outputs:
self.amount_edit.setAmount(total)
else:
self.amount_edit.setText("")
@@ -202,11 +207,7 @@ class PayToEdit(QRTextEdit):
e.ignore()
return
- isShortcut = (e.modifiers() and Qt.ControlModifier) and e.key() == Qt.Key_E
-
- if not self.c or not isShortcut:
- QTextEdit.keyPressEvent(self, e)
-
+ QTextEdit.keyPressEvent(self, e)
ctrlOrShift = e.modifiers() and (Qt.ControlModifier or Qt.ShiftModifier)
if self.c is None or (ctrlOrShift and e.text().isEmpty()):
@@ -216,7 +217,7 @@ class PayToEdit(QRTextEdit):
hasModifier = (e.modifiers() != Qt.NoModifier) and not ctrlOrShift;
completionPrefix = self.textUnderCursor()
- if not isShortcut and (hasModifier or e.text().isEmpty() or completionPrefix.length() < 1 or eow.contains(e.text().right(1)) ):
+ if hasModifier or e.text().isEmpty() or completionPrefix.length() < 1 or eow.contains(e.text().right(1)):
self.c.popup().hide()
return
@@ -228,4 +229,3 @@ class PayToEdit(QRTextEdit):
cr.setWidth(self.c.popup().sizeHintForColumn(0) + self.c.popup().verticalScrollBar().sizeHint().width())
self.c.complete(cr)
-
diff --git a/lib/transaction.py b/lib/transaction.py
@@ -428,9 +428,10 @@ def get_address_from_output_script(bytes):
+push_script = lambda x: op_push(len(x)/2) + x
class Transaction:
-
+
def __init__(self, raw):
self.raw = raw
self.deserialize()
@@ -505,16 +506,17 @@ class Transaction:
@classmethod
def pay_script(self, addr):
+ if addr.startswith('OP_RETURN:'):
+ h = addr[10:].encode('hex')
+ return '6a' + push_script(h)
addrtype, hash_160 = bc_address_to_hash_160(addr)
if addrtype == 0:
script = '76a9' # op_dup, op_hash_160
- script += '14' # push 0x14 bytes
- script += hash_160.encode('hex')
+ script += push_script(hash_160.encode('hex'))
script += '88ac' # op_equalverify, op_checksig
elif addrtype == 5:
script = 'a9' # op_hash_160
- script += '14' # push 0x14 bytes
- script += hash_160.encode('hex')
+ script += push_script(hash_160.encode('hex'))
script += '87' # op_equal
else:
raise
@@ -524,7 +526,6 @@ class Transaction:
@classmethod
def serialize( klass, inputs, outputs, for_sig = None ):
- push_script = lambda x: op_push(len(x)/2) + x
s = int_to_hex(1,4) # version
s += var_int( len(inputs) ) # number of inputs
for i in range(len(inputs)):
diff --git a/lib/wallet.py b/lib/wallet.py
@@ -350,7 +350,7 @@ class Abstract_Wallet:
raise Exception("Address not found", address)
def getpubkeys(self, addr):
- assert is_valid(addr) and self.is_mine(addr)
+ assert is_address(addr) and self.is_mine(addr)
account, sequence = self.get_address_index(addr)
a = self.accounts[account]
return a.get_pubkeys( sequence )
@@ -779,7 +779,9 @@ class Abstract_Wallet:
def make_unsigned_transaction(self, outputs, fee=None, change_addr=None, domain=None, coins=None ):
for address, x in outputs:
- assert is_valid(address), "Address " + address + " is invalid!"
+ if address.startswith('OP_RETURN:'):
+ continue
+ assert is_address(address), "Address " + address + " is invalid!"
amount = sum( map(lambda x:x[1], outputs) )
inputs, total, fee = self.choose_tx_inputs( amount, fee, len(outputs), domain, coins )
if not inputs: