I'm trying to create a little mining-script that connects over rpc to bitcoin core. I have problems following the documentation and all attempts to create a valid block (with dummy-nonce for testing) and submit it over "submitblock" are raising this error:

bitcoinrpc.authproxy.JSONRPCException: -22: Block decode failed

I tried to follow this source, but it seemed outdated: https://en.bitcoin.it/wiki/Getblocktemplate

For bip34-implementation I tried to follow this to create a correct coinbasetransaction: https://learnmeabitcoin.com/glossary/coinbase-transaction

Most likely my function bip34 is creating a wrong coinbasetxn I would assume. My second guess would be, that the decoding of the block before submitting it causes the error. I'm getting out of ideas, so any help is appreciated. Here's my humble hack:

from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
import hashlib
import binascii
import struct

def dblsha(data):
    return hashlib.sha256(hashlib.sha256(data).digest()).digest()

def varintEncode(n):
    if n < 0xfd:
        return struct.pack('<B', n)
    return b'\xfd' + struct.pack('<H', n)

def bip34(coinbasetxn, height):
    txn_bytes = binascii.a2b_hex(coinbasetxn)
    # https://learnmeabitcoin.com/glossary/coinbase-transaction
    height_to_bytes = height.to_bytes(3, byteorder='big')[::-1]
    length = 3
    length_to_bytes = length.to_bytes(1, byteorder='big')
    res = length_to_bytes + height_to_bytes
    #seems that createrawtransaction() allways creates a scriptsig of length == 1 byte, so change it to 4 bytes
    txn_bytes = txn_bytes[:46] + (4).to_bytes(1, byteorder='big') + res + txn_bytes[48:]
    return txn_bytes

def test1():
    rpc_connection = AuthServiceProxy(
            "http://%s:%s@"%("__cookie__", "rpc_password"), timeout=10020)
    block_template =rpc_connection.getblocktemplate({"rules": ["segwit"],"capabilities": ["coinbase/append"]})
    #change value from sat to btc
    coinbase_val = block_template["coinbasevalue"]/100000000
    coinbasetxn = rpc_connection.createrawtransaction(
        [{"txid":"0000000000000000000000000000000000000000000000000000000000000000","vout":0}], {"3GbAEvhB6XUYG79SfCamYPVzhJpchzq3ZY":coinbase_val})
    height = block_template["height"]
    coinbasetxn = bip34(coinbasetxn, height)
    txnlist = [coinbasetxn] + [binascii.a2b_hex(a['data']) for a in block_template['transactions']]
    merklehashes = [dblsha(t) for t in txnlist]
    while len(merklehashes) > 1:
        if len(merklehashes) % 2:
        merklehashes = [dblsha(merklehashes[i] + merklehashes[i + 1]) for i in range(0, len(merklehashes), 2)]
    merkleroot = merklehashes[0]
    blkheader = struct.pack('<I', block_template['version']) + \
                binascii.a2b_hex(block_template['previousblockhash']) + \
                merkleroot + \
                struct.pack('<I', block_template['curtime']) + \
                binascii.a2b_hex(block_template['bits']) + \
    blkdata = blkheader + varintEncode(len(txnlist)) + coinbasetxn
    for txn in txnlist[1:]:
            blkdata += txn
    blkdata = binascii.hexlify(blkdata)
    blkdata = blkdata.decode("ascii")
    res = rpc_connection.submitblock(blkdata)

def main():

  • Can you show the hex block you're trying to submit? – Pieter Wuille Jun 29 '19 at 18:35
  • well the whole block has a length of over 3,000,000. Here is – baku Jun 29 '19 at 18:54
  • blkdata = blkheader + varintEncode(len(txnlist)) + coinbasetxn – baku Jun 29 '19 at 18:54
  • 000000200000000000000000000c78d907f94b413a2f591d69aa62d7ae10d56c673ba9923f3d87e2f8112640480837210c5ef53fb5eef2dda0a0312f76c40e208eb5aceb85b1175d1723792c4e4f4e4386020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff040387e508bf824a0000000017a914a36e55683d4cc8a5466f6d2cf48b8eef1f23e6c18700000000 – baku Jun 29 '19 at 18:54
  • I uploaded the plain text of the full block to this link pastefs.com/pid/137105 – baku Jun 29 '19 at 19:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.