Bitcoin Forum
December 09, 2022, 12:06:44 AM *
News: Reminder: do not keep your money in online accounts
   Home   Help Search Login Register More  
Pages: [1]
Author Topic: Get block header electrum plugin  (Read 1083 times)
belcher (OP)
Sr. Member
Offline Offline

Activity: 261
Merit: 427

View Profile
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.


An electrum plugin for querying the electrum server about it's block headers

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()

        blockheight = QInputDialog.getText(None, 'Block Height', 'Input block height you wish to get the header of')
        if not blockheight[1]:
        blockheight = int(blockheight[0])
        raw =[ ('blockchain.block.get_header', [blockheight]) ])
        print raw
        #blockhash = 10
        #raw =[ ('blockchain.block.get_chunk', [blockhash]) ])
        #jsonraw = str(json.loads(raw))
        #print jsonraw.keys()

        #if d.exec_():
        #    return True
        #    return False

    def set_enabled(self, enabled):
        BasePlugin.set_enabled(self, enabled)
        print 'set enabled = ' + str(enabled)
        if enabled:
        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

    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/ there is broadcast_transaction()

    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)

    def make_unsigned_transaction(self, tx):
        '''called when the user presses send or edits the send dialog'''
        print 'make unsigned tx'
        #print str(tx)


        #get the address and value like this
        tx_hash = '6719c7e225972bb2f935d0f923748a69868fab094fc302bbd64b7d10d89a16b0'
        print 'getting txhash = ' + tx_hash
        raw =[ ('blockchain.transaction.get',[tx_hash]) ])
        print str(raw)

        #check its unspent and confirmed
        #addr = '1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu'
        addr = '1EtnpHTBthhXbjLn2TRfJMXu982fjPKcwM'
        print 'getting addr listunspent = ' + addr
        data =[ ('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')

        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')
            if self.wallet.is_change(addr):
                change_addr = addr
                cj_addr = addr
                cj_amount = value
        print 'cj=' + cj_addr + ' change=' + change_addr

    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
        # 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

    def transaction_dialog(self, d):
        '''called when the transaction is displayed to the user right before broadcast'''
        print 'transaction dialog ' + str(type(d))

    def create_send_tab(self, grid):
        print 'create send tab, put coinjoin fee amount here that updates as the user types in amounts'
        #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

blockchain.block.get_chunk looked like a useful method too but I couldn't figure it out straight away

JoinMarket - CoinJoin that people will actually use.
PGP fingerprint: 0A8B 038F 5E10 CC27 89BF CFFF EF73 4EA6 77F3 1129
If you want to be a moderator, report many posts with accuracy. You will be noticed.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
Hero Member
Offline Offline

Posts: 1670544404

View Profile Personal Message (Offline)

Reply with quote  #2

Report to moderator
Jr. Member
Offline Offline

Activity: 50
Merit: 46

View Profile WWW
July 06, 2015, 01:52:11 AM

I added information about finding a safe server with Electrum here:

If you find any more servers whose banner lists a safe version, please add it to that list.
Pages: [1]
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!