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]
  Print  
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
 #1

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.

Code:
'''
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

1HZBd22eQLgbwxjwbCtSjhoPFWxQg8rBd9
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.
1670544404
Hero Member
*
Offline Offline

Posts: 1670544404

View Profile Personal Message (Offline)

Ignore
1670544404
Reply with quote  #2

1670544404
Report to moderator
harding
Jr. Member
*
Offline Offline

Activity: 50
Merit: 46


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

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.
Pages: [1]
  Print  
 
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!