def fund(self, ): outputs = [(TYPE_ADDRESS, self.contract.address, 1000)] try: tx = self.wallet.mktx(outputs, self.password, self.config, domain=self.fund_domain, change_addr=self.fund_change_address) except NotEnoughFunds: return self.show_critical( _("Not enough balance to fund smart contract.")) except Exception as e: return self.show_critical(repr(e)) for i, out in enumerate(tx.outputs()): if out[1] == self.contract.address: self.fund_txout_e.setText(str(i)) self.fund_value_e.setText(str(out[2])) break else: raise RuntimeError("Created tx is incorrect!") self.fund_txid_e.setText(tx.txid()) self.fund_txid_e.setCursorPosition(0) show_transaction(tx, self.main_window, "Make splittable coin (master:%s)" % (self.entropy_address.to_ui_string()), prompt_if_unsaved=True) self.changed_coin()
def end(self): inputs = self.manager.txin # Mark style fee estimation outputs = [ (TYPE_ADDRESS, self.manager.contract.addresses[self.manager.mode], self.manager.value) ] tx = Transaction.from_io(inputs, outputs, locktime=0) tx.version = 2 fee = len(tx.serialize(True)) // 2 if fee > self.manager.value: self.show_error("Not enough funds to make the transaction!") return outputs = [ (TYPE_ADDRESS, self.manager.contract.addresses[self.manager.mode], self.manager.value - fee) ] tx = Transaction.from_io(inputs, outputs, locktime=0) tx.version = 2 if not self.wallet.is_watching_only(): self.manager.signtx(tx) self.manager.completetx(tx) show_transaction(tx, self.main_window, "End Last Will contract", prompt_if_unsaved=True) self.plugin.switch_to(Manage, self.wallet_name, None, None)
def on_receive(self, keyhash, message): self.print_error("signal arrived for", keyhash) for key, _hash, window in self.keys: if _hash == keyhash: break else: self.print_error("keyhash not found") return wallet = window.wallet if wallet.has_password(): password = window.password_dialog('An encrypted transaction was retrieved from cosigning pool.\nPlease enter your password to decrypt it.') if not password: return else: password = None if not window.question(_("An encrypted transaction was retrieved from cosigning pool.\nDo you want to open it now?")): return xprv = wallet.keystore.get_master_private_key(password) if not xprv: return try: k = bitcoin.deserialize_xprv(xprv)[-1].encode('hex') EC = bitcoin.EC_KEY(k.decode('hex')) message = EC.decrypt_message(message) except Exception as e: traceback.print_exc(file=sys.stdout) window.show_message(str(e)) return self.listener.clear(keyhash) tx = transaction.Transaction(message) show_transaction(tx, window, prompt_if_unsaved=True)
def do_fund(self, preview=False): outputs = self.make_outputs() if outputs == []: return if not outputs: self.show_error("Minimum value too low to sweep with bitcoin.com") return tab = self.tab() tab.get_password() password = tab.password try: tx = self.wallet.mktx(outputs, password, tab.main_window.config) except NotEnoughFunds: return self.show_critical(_("Not enough balance to fund biletoj.")) except Exception as e: return self.show_critical(repr(e)) #self.main_window.show_message("Click \'broadcast\' to fund biletoj.") if preview: show_transaction(tx, self.main_window, "Fund biletoj", prompt_if_unsaved=False) else: try: self.main_window.network.broadcast_transaction2(tx) self.main_window.show_message("Done.") except Exception: self.main_window.show_message( "Error. Transaction failed to broadcast.")
def create_last_will(self, ): outputs = [(TYPE_SCRIPT, ScriptOutput(make_opreturn(self.contract.address.to_ui_string().encode('utf8'))),0), (TYPE_ADDRESS, self.refresh_address, self.value+190), (TYPE_ADDRESS, self.cold_address, 546), (TYPE_ADDRESS, self.inheritor_address, 546)] try: tx = self.wallet.mktx(outputs, self.password, self.config, domain=self.fund_domain, change_addr=self.fund_change_address) id = tx.txid() except NotEnoughFunds: return self.show_critical(_("Not enough balance to fund smart contract.")) except Exception as e: return self.show_critical(repr(e)) # preparing transaction, contract can't give a change self.main_window.network.broadcast_transaction2(tx) self.create_button.setText("Creating Last Will...") self.create_button.setDisabled(True) coin = self.wait_for_coin(id,10) self.wallet.add_input_info(coin) inputs = [coin] outputs = [(TYPE_ADDRESS, self.contract.address, self.value)] tx = Transaction.from_io(inputs, outputs, locktime=0) tx.version=2 show_transaction(tx, self.main_window, "Make Last Will contract", prompt_if_unsaved=True) if self.notification.do_anything() : outputs = self.notification.notification_outputs(self.contract.address) tx = self.wallet.mktx(outputs, self.password, self.config, domain=self.fund_domain, change_addr=self.fund_change_address) show_transaction(tx, self.main_window, "Notification service payment", prompt_if_unsaved=True) self.plugin.switch_to(Intro, self.wallet_name, None, None)
def end(self): inputs = [self.manager.txin] outputs = [(TYPE_ADDRESS, self.manager.contract.addresses[self.manager.mode], self.manager.value - self.fee)] tx = Transaction.from_io(inputs, outputs, locktime=0) tx.version=2 if not self.wallet.is_watching_only(): self.manager.signtx(tx) self.manager.completetx(tx) show_transaction(tx, self.main_window, "End Last Will contract", prompt_if_unsaved=True) self.plugin.switch_to(Intro, self.wallet_name, None, None)
def create_last_will(self, ): yorn = self.main_window.question( _("Do you wish to create the Last Will Contract?")) if not yorn: return data1 = self.contract.address.to_ui_string() + ' ' + str( self.contract.version) data2 = str(self.contract.i_time) + ' ' + str(self.contract.rl_time) op_return = joinbytes([ OpCodes.OP_RETURN, 4, b'>sh\x00', len(data1), data1.encode('utf8'), len(data2), data2.encode('utf8') ]) assert len(data1) < 76 and len(data2) < 76 print(op_return) outputs = [(TYPE_SCRIPT, ScriptOutput(op_return), 0), (TYPE_ADDRESS, self.refresh_address, 546), (TYPE_ADDRESS, self.cold_address, 546), (TYPE_ADDRESS, self.inheritor_address, 546), (TYPE_ADDRESS, self.contract.address, self.value)] try: tx = self.wallet.mktx(outputs, self.password, self.config, domain=self.fund_domain, change_addr=self.fund_change_address) id = tx.txid() except NotEnoughFunds: return self.show_critical( _("Not enough balance to fund smart contract.")) except Exception as e: return self.show_critical(repr(e)) tx.version = 2 try: self.main_window.network.broadcast_transaction2(tx) except: pass self.create_button.setText("Creating Last Will...") self.create_button.setDisabled(True) if self.notification.do_anything(): outputs = self.notification.notification_outputs( self.contract.address) tx = self.wallet.mktx(outputs, self.password, self.config, domain=self.fund_domain, change_addr=self.fund_change_address) show_transaction(tx, self.main_window, "Notification service payment", prompt_if_unsaved=True) self.plugin.switch_to(Intro, self.wallet_name, None, None)
def on_load(self): tx = None try: text = text_dialog(self.top_level_window(), _('Input raw transaction'), _("Transaction:"), _("Load transaction")) if not text: return tx = self.main_window.tx_from_text(text) except SerializationError as e: self.show_critical( _("Electron Cash was unable to deserialize the transaction:") + "\n" + str(e)) if tx: tx.raw = tx.serialize() inputs = tx.inputs() metadata = inputs[0]['scriptSig'].split('1234567890') sig = metadata[1] xpub = metadata[0][-66:] addr1 = Address.from_pubkey(str(xpub)) other_party_role = self.manager.contract.addresses.index(addr1) for inp in tx.inputs(): for i, j in self.manager.txin[0].items(): inp[i] = j inp['pubkeys'] = inp[ 'x_pubkeys'] # problems with signing without it inp['sequence'] = 0 inp['signatures'] = [None] tx.raw = tx.serialize() self.manager.signtx(tx) #self.wallet.sign_transaction(tx, self.password) for inp in tx.inputs(): print(inp['signatures']) inp['x_pubkeys'].append(xpub) inp['signatures'].append(sig) if self.manager.mode > other_party_role: # sender key can be on any place but receiver has to be on the first and arbiter has to be on the second. # see sender_v3.spedn inp['x_pubkeys'][0], inp['x_pubkeys'][1] = inp[ 'x_pubkeys'][1], inp['x_pubkeys'][0] inp['signatures'][0], inp['signatures'][1] = inp[ 'signatures'][1], inp['signatures'][0] inp['num_sig'] = 2 tx.raw = tx.serialize() complete = self.manager.complete_method("end") complete(tx) print("Script Public Key: ", self.manager.script_pub_key) show_transaction(tx, self.main_window, "End Sender Contract", prompt_if_unsaved=True)
def spend(self, mode): prevout_hash = self.fund_txid_e.text() prevout_n = int(self.fund_txout_e.text()) value = int(self.fund_value_e.text()) locktime = 0 estimate_fee = lambda x: (1 * x) out_addr = Address.from_string(self.redeem_address_e.text()) # generate the special spend inp = self.contract.makeinput(prevout_hash, prevout_n, value, mode) inputs = [inp] invalue = value # add on other spends if self.option1_rb.isChecked(): domain = [] elif self.option2_rb.isChecked(): domain = [self.fund_change_address] elif self.option3_rb.isChecked(): domain = None else: raise RuntimeError other_coins = self.wallet.get_utxos(domain, exclude_frozen=True, mature=True, confirmed_only=False) for coin in other_coins: self.wallet.add_input_info(coin) inputs.append(coin) invalue += coin['value'] outputs = [(TYPE_ADDRESS, out_addr, 0)] tx1 = Transaction.from_io(inputs, outputs, locktime) txsize = len(tx1.serialize(True)) // 2 fee = estimate_fee(txsize) outputs = [(TYPE_ADDRESS, out_addr, invalue - fee)] tx = Transaction.from_io(inputs, outputs, locktime) self.contract.signtx(tx) self.wallet.sign_transaction(tx, self.password) self.contract.completetx(tx) if mode == 'refund': desc = "Spend splittable coin (replayable on any chain)" elif mode == 'redeem': desc = "Spend splittable coin (CDS chain only!)" show_transaction(tx, self.main_window, desc, prompt_if_unsaved=True)
def on_receive(self, keyhash, message): self.print_error("signal arrived for", keyhash) for key, _hash, window in self.keys: if _hash == keyhash: break else: self.print_error("keyhash not found") return wallet = window.wallet if isinstance(wallet.keystore, keystore.Hardware_KeyStore): window.show_warning( _('An encrypted transaction was retrieved from cosigning pool.' ) + '\n' + _('However, hardware wallets do not support message decryption, ' 'which makes them not compatible with the current design of cosigner pool.' )) return if wallet.has_password(): password = window.password_dialog( _('An encrypted transaction was retrieved from cosigning pool.' ) + '\n' + _('Please enter your password to decrypt it.')) if not password: return else: password = None if not window.question( _("An encrypted transaction was retrieved from cosigning pool." ) + '\n' + _("Do you want to open it now?")): return xprv = wallet.keystore.get_master_private_key(password) if not xprv: return try: k = bh2u(bitcoin.deserialize_xprv(xprv)[-1]) EC = bitcoin.EC_KEY(bfh(k)) message = bh2u(EC.decrypt_message(message)) except Exception as e: traceback.print_exc(file=sys.stdout) window.show_message(str(e)) return self.listener.clear(keyhash) tx = transaction.Transaction(message) show_transaction(tx, window, prompt_if_unsaved=True)
def do_sweep(self, selected): if not selected: return if isinstance(selected[0].data(2, Qt.UserRole), str): privkeys = [s.data(2, Qt.UserRole) for s in selected] elif isinstance(selected[0].data(2, Qt.UserRole), list): privkeys = selected[0].data(2, Qt.UserRole) else: privkeys = [] tab = self.tab() target = tab.wallet.get_unused_address() label = selected[0].data(0, Qt.UserRole) try: tx = sweep(privkeys, self.main_window.network, self.main_window.config, target) except ValueError: self.show_error("No confirmed coins found!") else: show_transaction(tx, self.main_window, "Sweep " + label)
def refresh(self): if self.manager.mode!=0: print("This wallet can't refresh a contract!") return print("Notification Service: ") print(self.notification.do_anything()) if self.notification.do_anything() : outputs = self.notification.notification_outputs(self.manager.contract.address) tx = self.wallet.mktx(outputs, self.password, self.config, None, None) show_transaction(tx, self.main_window, "Notification service payment", prompt_if_unsaved=True) inputs = [self.manager.txin] outputs = [(TYPE_ADDRESS, self.manager.contract.address, self.manager.value-self.fee)] tx = Transaction.from_io(inputs, outputs, locktime=0) tx.version = 2 self.manager.signtx(tx) self.wallet.sign_transaction(tx, self.password) self.manager.completetx_ref(tx) show_transaction(tx, self.main_window, "Refresh Last Will contract", prompt_if_unsaved=True) self.plugin.switch_to(Intro, self.wallet_name,None,None)
def refresh(self): if self.manager.mode != 0: print("This wallet can't refresh a contract!") return contract, utxo_index, m = self.contract_tree.get_selected_id() if utxo_index >= 0: self.manager.choice(contract, utxo_index, m) yorn = self.main_window.question( _("Do you wish to refresh the selected entry?")) if yorn: tx = self.ref_tx(contract, utxo_index, m) if tx: # self.main_window.network.broadcast_transaction2(tx) show_transaction(tx, self.main_window, "Refresh entry", prompt_if_unsaved=True) return else: return else: yorn = self.main_window.question( _("Do you wish to refresh the selected contract?")) if yorn: for i in range(len(contract[UTXO])): self.manager.choice(contract, i, m) tx = self.ref_tx(contract, i, m) if tx: # self.main_window.network.broadcast_transaction2(tx) show_transaction(tx, self.main_window, "Refresh entry", prompt_if_unsaved=True) print("Notification Service: ") print(self.notification.do_anything()) if self.notification.do_anything(): outputs = self.notification.notification_outputs( self.manager.contract.address) tx = self.wallet.mktx(outputs, self.password, self.config, None, None) show_transaction(tx, self.main_window, "Notification service payment", prompt_if_unsaved=True) #show_transaction(tx, self.main_window, "Refresh Last Will contract", prompt_if_unsaved=True) self.plugin.switch_to(Manage, self.wallet_name, None, None)
def on_receive(self, window, keyhash, message): self.print_error("signal arrived for", keyhash, "@", window.diagnostic_name()) state = getattr(window, 'cosigner_pool_state', None) if not state: self.print_error("Error: state object not found") return keys = state.keys for key, _hash in keys: if _hash == keyhash: break else: self.print_error("keyhash not found") return wallet = window.wallet if isinstance(wallet.keystore, keystore.Hardware_KeyStore): window.show_warning( _('An encrypted transaction was retrieved from cosigning pool.' ) + '\n' + _('However, hardware wallets do not support message decryption, ' 'which makes them not compatible with the current design of cosigner pool.' )) return password = None if wallet.has_password(): password = window.password_dialog( _('An encrypted transaction was retrieved from cosigning pool.' ) + '\n' + _('Please enter your password to decrypt it.')) if not password: return else: details = (_( "If you choose 'Yes', it will be decrypted and a transaction window will be shown, giving you the opportunity to sign the transaction." ) + "\n\n" + _( "If you choose 'No', you will be asked again later (the next time this wallet window is opened)." )) ret = window.msg_box( icon=QMessageBox.Question, parent=None, title=_("Cosigner Pool"), buttons=QMessageBox.Yes | QMessageBox.No, text= _("An encrypted transaction was retrieved from cosigning pool." ) + '\n' + _("Do you want to open it now?"), detail_text=details) if ret != QMessageBox.Yes: return err, badpass = "******", False try: xprv = wallet.keystore.get_master_private_key(password) except InvalidPassword as e: err, badpass = str(e), True xprv = None if not xprv: window.show_error(err) if badpass: self.on_receive(window, keyhash, message) # try again return try: k = bh2u(bitcoin.deserialize_xprv(xprv)[-1]) EC = bitcoin.EC_KEY(bfh(k)) message = bh2u(EC.decrypt_message(message)) except Exception as e: traceback.print_exc(file=sys.stdout) window.show_error(repr(e)) return state.listener.clear(keyhash) tx = transaction.Transaction(message) show_transaction(tx, window, prompt_if_unsaved=True)