0
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@127.0.0.1:8332"%("__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.append(merklehashes[-1])
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']) + \
b'NONC'
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)
print(res)
def main():
test1()
main()
Can you show the hex block you're trying to submit? – Pieter Wuille – 2019-06-29T18:35:55.713
well the whole block has a length of over 3,000,000. Here is – baku – 2019-06-29T18:54:16.800
blkdata = blkheader + varintEncode(len(txnlist)) + coinbasetxn – baku – 2019-06-29T18:54:23.370
000000200000000000000000000c78d907f94b413a2f591d69aa62d7ae10d56c673ba9923f3d87e2f8112640480837210c5ef53fb5eef2dda0a0312f76c40e208eb5aceb85b1175d1723792c4e4f4e4386020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff040387e508bf824a0000000017a914a36e55683d4cc8a5466f6d2cf48b8eef1f23e6c18700000000 – baku – 2019-06-29T18:54:33.030
I uploaded the plain text of the full block to this link https://www.pastefs.com/pid/137105
– baku – 2019-06-29T19:13:30.553