Author

Topic: Технические подробности майнинга Bitcoin. (Read 251 times)

legendary
Activity: 2317
Merit: 2318
В чём может быть проблема?
В том, что вы не проверили транзакцию coinbase на корректность, декодировав её, например, при помощи decoderawtransaction.

У вас в этой транзакции два выхода. Вы указали длину scriptPubKey 44 - для первого выхода и 4С - для второго, хотя реальная длина scriptPubKey в байтах в два раза меньше.
newbie
Activity: 14
Merit: 1
На "regtest" при попытке отправить блок на подтверждение(submitblock). Я полуаю ошибку. В чём может быть проблема?

Code:
head_block: 02000000f8024dbfc207544804e79609b318eded16dc496a3d8ac37541b2f710b4baca5a9752c595ea7f7ab91cf0717a328c7e50eef049a04bf16d8bbcdeeff042080f27e33b2c65ffff7f203028d939
txs: 0300
coinbase: 020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff3103cc00002773bdc148321e51289c1b3fed2d2d23338fb2e4a97aef9ff315bd2c9a30a4cabe2008dac529fbe05707d71c04ffffffff0240f83195000000004400209ac557ece1b52289a27efd1a63a7b2d77640bcfd7be25d9e45f97ab9331bf02800000000000000004c6a24aa21a9ed574959f5964b70e0bf54900f35d100b8755042d2c1da8e94bf755aa3411adce90120000000000000000000000000000000000000000000000000000000000000000000000000
tx0: 02000000000101b4a280789a22484e02f5b2d3f624e16bb60b9d05da9337bc678f6420cf540ba30000000000fdffffff02e0ce3e0d00000000225120e96eaa7a3def447531eb28b58ff0974974656d599566abb165160a4a0a5d673d80a3af1c01000000225120db9d070fd847cc0c0068f4c7f562874ab442ce105d8eef80fc4df1d6696f92b601400dcd13a372361fb006fadf9abefd9cf016dfe8d32838e986a1c0e34850f191d256cf06a0799a3978b9c7e3e2578dbc5453505137554fd7d8a692a13d3b39957bcb000000
tx1: 020000000001016f1b375ca92ed3d179aa6e210c4a474ee611a9b8a37804114a2e8c90dface1b50000000000fdffffff0260409f0600000000225120ce6e4ceb8f6d5a6b100ae9830c0cb87b6e7e0655940589be6a857a7ff5ee552600324f23010000002251207717106b74ff2b332e0f48d04e8342a7b8c4b7184f554cf9f6cad8bed1a600ed014024877d751eca430065e38b3015ed7c7ce60a837197e92a92d506a3f06d8f1f5937084b19f3166b16e4196aa123c655b9b9ac4ac6788a613c8cbde7cafc6604cfcb000000
{'result': None, 'error': {'code': -22, 'message': 'Block does not start with a coinbase'}, 'id': None}
legendary
Activity: 2317
Merit: 2318
Как создавать "coinbase tx"? Можно ли построить её через createrawtransaction или её можно создать только в коде?
createrawtransaction - только для обычных транзакций, транзакцию coinbase так сделать не получится.

Тогда я не полностью понимаю как устроенно построение данной транзакции.
Тут на примере показана структура транзакции coinbase:
Code:
01000000 .............................. Version

01 .................................... Number of inputs
| 00000000000000000000000000000000
| 00000000000000000000000000000000 ...  Previous outpoint TXID
| ffffffff ............................ Previous outpoint index
|
| 29 .................................. Bytes in coinbase
| |
| | 03 ................................ Bytes in height
| | | 4e0105 .......................... Height: 328014
| |
| | 062f503253482f0472d35454085fffed
| | f2400000f90f54696d65202620486561
| | 6c74682021 ........................ Arbitrary data
| 00000000 ............................ Sequence

01 .................................... Output count
| 2c37449500000000 .................... Satoshis (25.04275756 BTC)
| 1976a914a09be8040cbf399926aeb1f4
| 70c37d1341f3b46588ac ................ P2PKH script
| 00000000 ............................ Locktime

Но есть нюанс. SegWit, внедрённый в августе 2017, кое-что добавляет к примеру выше, а именно ещё один выход, в котором хранится witness_commitment и txinwitness, содержащий witness reserved value (на текущий момент это всегда 32 нулевых байта).
newbie
Activity: 14
Merit: 1
Как создавать "coinbase tx"? Можно ли построить её через createrawtransaction или её можно создать только в коде? Тогда я не полностью понимаю как устроенно построение данной транзакции.

На примере транзакции из реального блока, приведу то что я понимаю в ней. То что помечено вопросами или не обозначено, я не понимаю.

Code:
{
    "result": {
        "in_active_chain": true,
        "txid": "26110d654a1e52dd6fb6aa141e9ed37b83367daf3cfd35059188285bf5a4ca23",
        "hash": "fe239009e8a7c65da8ff48be0a50a3bd1cb19016e29d16453a94a89570b50ce9",
        "version": 2,
        "size": 214,
        "vsize": 187,
        "weight": 748,
        "locktime": 0,
        "vin": [
            {
                "coinbase": "03ed630c04a95e29652f466f756e6472792055534120506f6f6c202364726f70676f6c642f1a0727769676000000000000",
                "txinwitness": [
                    "0000000000000000000000000000000000000000000000000000000000000000"
                ],
                "sequence": 4294967295
            }
        ],
        "vout": [
            {
                "value": 6.36546374,
                "n": 0,
                "scriptPubKey": {
                    "asm": "0 35f6de260c9f3bdee47524c473a6016c0c055cb9",
                    "desc": "addr(bc1qxhmdufsvnuaaaer4ynz88fspdsxq2h9e9cetdj)#ry8yggxl",
                    "hex": "001435f6de260c9f3bdee47524c473a6016c0c055cb9",
                    "address": "bc1qxhmdufsvnuaaaer4ynz88fspdsxq2h9e9cetdj",
                    "type": "witness_v0_keyhash"
                }
            },
            {
                "value": 0.0,
                "n": 1,
                "scriptPubKey": {
                    "asm": "OP_RETURN aa21a9ed95c53abf59b8c6df571b1ca9ff8ad0e6f77a82b2b59c229463cda7a0281a4caf",
                    "desc": "raw(6a24aa21a9ed95c53abf59b8c6df571b1ca9ff8ad0e6f77a82b2b59c229463cda7a0281a4caf)#thl9sjed",
                    "hex": "6a24aa21a9ed95c53abf59b8c6df571b1ca9ff8ad0e6f77a82b2b59c229463cda7a0281a4caf",
                    "type": "nulldata"
                }
            }
        ],
        "hex": "020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff3103ed630c04a95e29652f466f756e6472792055534120506f6f6c202364726f70676f6c642f1a0727769676000000000000ffffffff0246edf0250000000016001435f6de260c9f3bdee47524c473a6016c0c055cb90000000000000000266a24aa21a9ed95c53abf59b8c6df571b1ca9ff8ad0e6f77a82b2b59c229463cda7a0281a4caf0120000000000000000000000000000000000000000000000000000000000000000000000000",
        "blockhash": "00000000000000000002faa1874cb499bcc39f45689a36387c4fbe9f3e5a28e4",
        "confirmations": 1,
        "time": 1697210044,
        "blocktime": 1697210044
    },
    "error": null,
    "id": null

Code:
# nVersion: 02000000
#   marker: 00
#     flag: 01
#     txIns:
#        #    countIns: 01
#        #          in: 0000000000000000000000000000000000000000000000000000000000000000
         #    sequence: ffffffff
         #              31 - ?????????????
         # heigt_block: 03ed630c
         #              04 - ?????????????
         #        time: a95e2965
         #     message: 2f466f756e6472792055534120506f6f6c202364726f70676f6c642f1a0727769676000000000000 - extranonce?
#                           : ffffffff
#                           : 02
#                           : 46edf025
#                           : 0000000016
#   (hex_address vout n - 0): 001435f6de260c9f3bdee47524c473a6016c0c055cb9
#                           : 000000000000000026
# default_witness_commitment: 6a24aa21a9ed95c53abf59b8c6df571b1ca9ff8ad0e6f77a82b2b59c229463cda7a0281a4caf  - ???????
#                   whitness: 01200000000000000000000000000000000000000000000000000000000000000000
#                  nLockTime: 00000000
newbie
Activity: 14
Merit: 1
Я так же делал двойной хеш, а так же пробовал получить корень хешированием TXID
merkleroot вычисляется из txid. В качестве алгоритма хеширования используется двойной SHA256.
Пример вычисления корня дерева Меркла на Питоне.

Большое спасибо за пример! Очень легко запутаться в этих обратных байтах и двойном хешировании.

Вот полностью рабочий код для MainNet:

Code:
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
from hashlib import sha256

import json
import requests

DEFAULT_RPC_REGTEST_PORT = "18443"
DEFAULT_RPC_TEST_PORT = "18332"
DEFAULT_RPC_MAIN_PORT = "8332"

rpcAddress = "127.0.0.1"
rpcPort = DEFAULT_RPC_MAIN_PORT
rpcUser = "rpcuser"
rpcPassword = "rpcpassword"
rpcUrl = "http://" + rpcAddress + ":" + rpcPort

headers = {'content-type': 'application/json'}


# Double HASH SHA256
def double_sha256(data): return sha256(sha256(data).digest()).digest()


# Reverse
def r(data): return data[::-1]


def request_rpc(method, params):
    payload = json.dumps(
        {
            "method": method,
            "params": params
        }
    )
    return requests.request("POST", rpcUrl, data=payload, headers=headers,
                            auth=(rpcUser, rpcPassword))


if __name__ == "__main__":
    res = request_rpc(method="getblock", params=["00000000000000000000bd684e36789d16da2cf5b08b47deb72d1448a73eae5c"])
    tx = res.json()["result"]["tx"]

    hashes = [bytes.fromhex(x) for x in tx]
    while len(hashes) > 1:
        if len(hashes) % 2 == 1:
            hashes.append(hashes[-1])
        parent_level = []
        for i in range(0, len(hashes), 2):
            x = r(double_sha256(r(hashes[i]) + r(hashes[i + 1])))
            parent_level.append(x)
        hashes = parent_level
    merkleroot = hashes[0].hex()
    print(merkleroot)
legendary
Activity: 2464
Merit: 4415
🔐BitcoinMessage.Tools🔑
Я так же делал двойной хеш, а так же пробовал получить корень хешированием TXID, но это так же не помогло мне получить нужный результат.
ID транзакций хранятся в little-endian формате, а вот хэшируются в big-endian. После хэширование нужно опять переводить в little-endian и это может запутать неподготовленного. Зачем нужна такая запутанность никто не знает, но так исторически сложилось. В поисковиках и всяких блок эксплорерах поиск обычно производится уже в "перевернутом" формате.

Здесь можно почитать подробнее: https://learnmeabitcoin.com/technical/txid
legendary
Activity: 2317
Merit: 2318
Я так же делал двойной хеш, а так же пробовал получить корень хешированием TXID
merkleroot вычисляется из txid. В качестве алгоритма хеширования используется двойной SHA256.
Пример вычисления корня дерева Меркла на Питоне.
newbie
Activity: 14
Merit: 1
Не могли вы мне подсказать что именно не так я делаю с получением корня Меркла? Вот мой код на Python, но я не получаю тот результат который должен быть.

Target: "merkleroot": "19f3769778eb2019476630aafb376634cdf3f114e617a7e0a300e822265022bc"

Code:
from hashlib import sha256
import requests, json

DEFAULT_RPC_REGTEST_PORT = "18443"
DEFAULT_RPC_TEST_PORT = "18332"
DEFAULT_RPC_MAIN_PORT = "8332"

rpcAddress = "127.0.0.1"  # localhost
rpcPort = DEFAULT_RPC_MAIN_PORT
rpcUser = "rpcuser"
rpcPassword = "rpcpassword"
rpcUrl = "http://" + rpcAddress + ":" + rpcPort
headers = {'content-type': 'application/json'}

def double_sha256(data):
    return bytes.fromhex(sha256(bytes.fromhex(sha256(bytes.fromhex(data)).hexdigest())).hexdigest())

def request_rpc(method, params):
    payload = json.dumps(
        {
            "jsonrpc": "2.0",
            "id": "1",
            "method": method,
            "params": params
        }
    )
    return requests.request("POST", rpcUrl, data=payload, headers=headers,
                                auth=(rpcUser, rpcPassword))


if __name__ == "__main__":
    res = request_rpc(method="getblock", params=["00000000000000000000bd684e36789d16da2cf5b08b47deb72d1448a73eae5c"])
    tx = res.json()["result"]["tx"]
    print(tx)

    hashes = []
    for i in range(len(tx)):
        res = request_rpc(method="getrawtransaction",
                          params=[tx[i], 1, '00000000000000000000bd684e36789d16da2cf5b08b47deb72d1448a73eae5c'])
        hashes.append(res.json()["result"]["hash"])
    print(len(hashes))
    # print(hashes)

    hashes = [bytes.fromhex(x) for x in hashes]
    while len(hashes) > 1:
        if len(hashes) % 2 == 1:
            hashes.append(hashes[-1])
        parent_level = []
        for x in range(0, len(hashes), 2):
            hash = sha256(hashes[x] + hashes[x + 1]).digest()
            parent_level.append(hash)
        hashes = parent_level

    print(hashes[0].hex())

Я так же делал двойной хеш, а так же пробовал получить корень хешированием TXID, но это так же не помогло мне получить нужный результат.
newbie
Activity: 14
Merit: 1
В английской ветке мне помогли с этим подробно. Вот полный пример https://bitcointalksearch.org/topic/m.62976595
Поздравляю, что в английской ветке вы получили готовое решение для своей задачи. В русскоязычной ветке же предлагают только хардкор, дают ссылки и надеятся, что спрашивающий немного пошевелит мозгами и сам придет к ответу. Мне кажется, что если разбираться самому, то похожие задачи и вообще связанная с ней тематика будут даваться гораздо легче и не придется при каждой непонятке создавать отдельную тему и ждать пока кто-то погуглит за вас и выложит все на блюдечке.

Биткоин это очень сложно для меня, но интересно. Я пытаюсь вникать, но техническая документация очень поверхностная, я не могу её понять сразу. Поверте я гуглил и очень долго искал нужную мне информацию и читал бипы которые мне скидывали по ссылкам, ещё до того как я зарегистрировался на этом форуме. Примеров в сети не так уж и много, множество примеров сильно устаревших, я бы возможно потратил несколько недель прежде чем пришёл бы к желаемому результату в своей программе. Я не собираюсь создавать на каждый свой вопрос отдельную ветку темы, все проблеммы возникающие у меня, я буду задавать здесь и в английской ветке. По итогу я думаю смогу изложить всё здесь и выложить исходный код "минимайнера" для прямого соло майнинга с ноды биткоина. Да это бесполезно, но в учебных целях думаю что разбор майнера очень даже подходит, что бы понять часть того как устроена сеть биткоина.
legendary
Activity: 2464
Merit: 4415
🔐BitcoinMessage.Tools🔑
В английской ветке мне помогли с этим подробно. Вот полный пример https://bitcointalksearch.org/topic/m.62976595
Поздравляю, что в английской ветке вы получили готовое решение для своей задачи. В русскоязычной ветке же предлагают только хардкор, дают ссылки и надеятся, что спрашивающий немного пошевелит мозгами и сам придет к ответу. Мне кажется, что если разбираться самому, то похожие задачи и вообще связанная с ней тематика будут даваться гораздо легче и не придется при каждой непонятке создавать отдельную тему и ждать пока кто-то погуглит за вас и выложит все на блюдечке.
newbie
Activity: 14
Merit: 1
В английской ветке мне помогли с этим подробно. Вот полный пример https://bitcointalksearch.org/topic/m.62976595
legendary
Activity: 2464
Merit: 4415
🔐BitcoinMessage.Tools🔑
У меня в закладках была эта статья https://medium.com/coinmonks/creating-and-signing-a-segwit-transaction-from-scratch-ec98577b526a Там в целом объясняется довольно подробно какие поля куда добавлять и что нужно хэшировать для получения TxID.

Также формат для сериализации SegWit транзакций можно найти в комментариях к коду: https://github.com/bitcoin/bitcoin/blob/v25.1rc1/src/primitives/transaction.h#L200
legendary
Activity: 2317
Merit: 2318
Но я не могу найти информацию и примеры как получить TXID транзакции.
Здесь были?
newbie
Activity: 14
Merit: 1
Всем привет. Я пытаюсь разобратся в работе Bitcoin. Немного получается но часть этого мне не даётся. Множество информации в сети либо устарело либо не даёт мне полного понимания. Прошу помощи у знающих и понимающих Bitcoin кодеров.

Я могу получить HASH транзакции делая двойное хеширование HEX-данных(raw transaction). Но я не могу найти информацию и примеры как получить TXID транзакции.

Для примера:

Code:
{
    "result": {
        "in_active_chain": true,
        "txid": "f0acda99bd6f1042f98e042853e99dc0febb55325dda6ce8c4df7fe307816631",
        "hash": "eb55e1c0fc83dda66b9d69701ee6f79a49b5af73952600766d6d3af83fb9046e",
        "version": 1,
        "size": 262,
        "vsize": 235,
        "weight": 940,
        "locktime": 3758567493,
        "vin": [
            {
                "coinbase": "03e7610c0446f724652f4d41524120506f6f6c2ffabe6d6d621175c7c1371ebd43cefcefc3ab0453b7f952101cb5575976420d0104e9f0dd01000000000000006ffead5c76d2571ade6aa17dc7be6bde12b33031f30094000000ffffffff",
                "txinwitness": [
                    "0000000000000000000000000000000000000000000000000000000000000000"
                ],
                "sequence": 4294967295
            }
        ],
        "vout": [
            {
                "value": 6.3601069,
                "n": 0,
                "scriptPubKey": {
                    "asm": "OP_DUP OP_HASH160 2fc701e2049ee4957b07134b6c1d771dd5a96b21 OP_EQUALVERIFY OP_CHECKSIG",
                    "desc": "addr(15MdAHnkxt9TMC2Rj595hsg8Hnv693pPBB)#j6z3mx70",
                    "hex": "76a9142fc701e2049ee4957b07134b6c1d771dd5a96b2188ac",
                    "address": "15MdAHnkxt9TMC2Rj595hsg8Hnv693pPBB",
                    "type": "pubkeyhash"
                }
            },
            {
                "value": 0.0,
                "n": 1,
                "scriptPubKey": {
                    "asm": "OP_RETURN aa21a9edaf182da3eb02887057bacf92ae319a024020f02c8d50537fe33f45f1c922e08d",
                    "desc": "raw(6a24aa21a9edaf182da3eb02887057bacf92ae319a024020f02c8d50537fe33f45f1c922e08d)#rst44kmt",
                    "hex": "6a24aa21a9edaf182da3eb02887057bacf92ae319a024020f02c8d50537fe33f45f1c922e08d",
                    "type": "nulldata"
                }
            }
        ],
        "hex": "010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff5e03e7610c0446f724652f4d41524120506f6f6c2ffabe6d6d621175c7c1371ebd43cefcefc3ab0453b7f952101cb5575976420d0104e9f0dd01000000000000006ffead5c76d2571ade6aa17dc7be6bde12b33031f30094000000ffffffffffffffff02c2c0e825000000001976a9142fc701e2049ee4957b07134b6c1d771dd5a96b2188ac0000000000000000266a24aa21a9edaf182da3eb02887057bacf92ae319a024020f02c8d50537fe33f45f1c922e08d01200000000000000000000000000000000000000000000000000000000000000000453007e0",
        "blockhash": "00000000000000000000bd684e36789d16da2cf5b08b47deb72d1448a73eae5c",
        "confirmations": 77,
        "time": 1696921412,
        "blocktime": 1696921412
    },
    "error": null,
    "id": "1"
}

Какие данные из этого блока мне нужно хешировать что бы получить TXID?
Jump to: