Title: Get block header electrum plugin
Post by: belcher on July 05, 2015, 11:16:38 PM
I couldn't find a way to query what the electrum server thinks about the blockchain through the GUI. During the chain fork after bip66, this information was important. I was able to hack up this plugin. ''' GET BLOCK HEADER
An electrum plugin for querying the electrum server about it's block headers
HOW TO 1. place plugin in electrum/plugins 2. start electrum on the command line 3. in the gui go Tools -> Plugins 4. enable the GetServerBlockHeaderData and press button 5. input a block height and watch the shell terminal (not electrum's console tab) for the result
example output [{u'nonce': 697162691, u'prev_block_hash': u'00000000000000000e20bcf213a0bbd6be88d5fede6b060c737f7f8b7f1df504', u'timestamp': 1436136522, u'merkle_root': u'0fa543c7aa9f2b3b6d9755024e586c443cc1cf1cb513f9177ada9c718a1be3e6', u'block_height': 364001, u'version': 3, u'bits': 404111758}]
'''
from PyQt4 import QtCore from PyQt4.QtGui import *
from electrum.plugins import BasePlugin, hook from electrum.i18n import _ from electrum.wallet import Abstract_Wallet
from electrum_gui.qt.util import EnterButton
import time, traceback, threading, socket, json
class Plugin(BasePlugin):
gui = None daemon_comm = None
def fullname(self): return 'GetServerBlockHeaderData'
def description(self): return _("Get block header data from the server, useful for obtaining data when the chain forks")
def requires_settings(self): return True
def settings_widget(self, window): return EnterButton(_('GetBlockHeader'), self.settings_dialog)
def settings_dialog(self): print 'pressed settings' #self.daemon_comm.send_json({'command': 'echo', 'stuff': 'here'}) d = QDialog() d.setWindowTitle("Settings")
blockheight = QInputDialog.getText(None, 'Block Height', 'Input block height you wish to get the header of') if not blockheight[1]: return blockheight = int(blockheight[0]) raw = self.gui.network.synchronous_get([ ('blockchain.block.get_header', [blockheight]) ]) print raw #blockhash = 10 #raw = self.gui.network.synchronous_get([ ('blockchain.block.get_chunk', [blockhash]) ]) #jsonraw = str(json.loads(raw)) #print jsonraw.keys()
#if d.exec_(): # return True #else: # return False
@hook def set_enabled(self, enabled): BasePlugin.set_enabled(self, enabled) print 'set enabled = ' + str(enabled) ''' if enabled: self.start_daemon_connection() else: self.stop_daemon_connection() if not enabled and isinstance(self.gui.main_window.wallet, JoinMarketWallet): print 'returning wallet to normal' self.gui.main_window.wallet = self.gui.main_window.wallet.underlying_wallet '''
@hook def load_wallet(self, wallet): print 'load wallet' #if self.gui and self.gui.main_window.wallet and not isinstance(self.gui.main_window.wallet, JoinMarketWallet): # print 'creating JM wallet' # self.gui.main_window.wallet = JoinMarketWallet(self.gui.main_window.wallet, self.gui.main_window.wallet)
#in ./gui/qt/main_window.py there is broadcast_transaction()
@hook def init_qt(self, gui): print 'init gui' self.gui = gui #if self.gui.main_window.wallet and not isinstance(self.gui.main_window.wallet, JoinMarketWallet): # print 'creating JM wallet' # self.gui.main_window.wallet = JoinMarketWallet(self.gui.main_window.wallet, self.gui.main_window.wallet)
@hook def make_unsigned_transaction(self, tx): '''called when the user presses send or edits the send dialog''' print 'make unsigned tx' #print str(tx)
#see https://electrum.orain.org/wiki/Stratum_protocol_specification
''' #get the address and value like this tx_hash = '6719c7e225972bb2f935d0f923748a69868fab094fc302bbd64b7d10d89a16b0' print 'getting txhash = ' + tx_hash raw = self.gui.network.synchronous_get([ ('blockchain.transaction.get',[tx_hash]) ]) print str(raw)
#check its unspent and confirmed #addr = '1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu' addr = '1EtnpHTBthhXbjLn2TRfJMXu982fjPKcwM' print 'getting addr listunspent = ' + addr data = self.gui.network.synchronous_get([ ('blockchain.address.listunspent', [addr]) ]) print str(data) #taker needs the following information # info on tx being spent, unconfirmed or genuinly just in the utxo set # the value and scriptpubkey (/ address) of such a utxo # pushtx, should be easy ''' if len(tx.outputs) > 2: self.print_error('cant make coinjoins with more than one output address yet') return
cj_addr = None change_addr = None cj_amount = 0 for otype, addr, value in tx.outputs: if otype != 'address': self.print_error('whoops, cant send to places other than addresses') return if self.wallet.is_change(addr): change_addr = addr else: cj_addr = addr cj_amount = value print 'cj=' + cj_addr + ' change=' + change_addr
@hook def sign_transaction(self, tx, password): '''called when the user types in password after send is clicked''' print 'sign tx ' + str(type(tx)) print str(tx) #tx is of instance Transaction # need to somehow find out which is the change address address = '' if len(address) > 0: priv = self.wallet.get_private_key(address, password) print 'priv = ' + str(priv) #the tx needs enough inputs to pay the coinjoin fee, check it has enough # if not, repeat the process in make_unsigned_transaction() to get more # trustedcoin.py adds a fee to a tx, look how they do it # they override Wallet class and override get_tx_fee() # for us it might be worth overriding the function pointer #if/when the user clicks boardcast, then send it to electrum or somehow halt the broadcast # and send it to a maker # need to add a hook to electrum that has the ability to halt a broadcast # ThomasV says he would accept such a hook # probably best is that it is able to raise an exception
@hook def transaction_dialog(self, d): '''called when the transaction is displayed to the user right before broadcast''' print 'transaction dialog ' + str(type(d))
@hook def create_send_tab(self, grid): print 'create send tab, put coinjoin fee amount here that updates as the user types in amounts' #self.start_daemon_connection() #maybe get access to the address/amount field, to be able to tell between output and change #better way would be to hook mktx() so you can see outputs
Luckily this page helped https://electrum.orain.org/wiki/Stratum_protocol_specification blockchain.block.get_chunk looked like a useful method too but I couldn't figure it out straight away
Title: Re: Get block header electrum plugin
Post by: harding on July 06, 2015, 01:52:11 AM
I added information about finding a safe server with Electrum here: https://en.bitcoin.it/wiki/July_2015_Forks
If you find any more servers whose banner lists a safe version, please add it to that list.
|