xDilettante (OP)
Newbie
Offline
Activity: 14
Merit: 1
|
|
October 10, 2023, 08:03:20 PM |
|
Всем привет. Я пытаюсь разобратся в работе Bitcoin. Немного получается но часть этого мне не даётся. Множество информации в сети либо устарело либо не даёт мне полного понимания. Прошу помощи у знающих и понимающих Bitcoin кодеров. Я могу получить HASH транзакции делая двойное хеширование HEX-данных(raw transaction). Но я не могу найти информацию и примеры как получить TXID транзакции. Для примера: { "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?
|
|
|
|
A-Bolt
Legendary
Offline
Activity: 2324
Merit: 2353
|
|
October 10, 2023, 08:43:24 PM |
|
Но я не могу найти информацию и примеры как получить TXID транзакции.
Здесь были?
|
|
|
|
|
xDilettante (OP)
Newbie
Offline
Activity: 14
Merit: 1
|
|
October 12, 2023, 07:15:04 PM |
|
|
|
|
|
witcher_sense
Legendary
Offline
Activity: 2422
Merit: 4393
🔐BitcoinMessage.Tools🔑
|
|
October 13, 2023, 05:55:52 AM |
|
Поздравляю, что в английской ветке вы получили готовое решение для своей задачи. В русскоязычной ветке же предлагают только хардкор, дают ссылки и надеятся, что спрашивающий немного пошевелит мозгами и сам придет к ответу. Мне кажется, что если разбираться самому, то похожие задачи и вообще связанная с ней тематика будут даваться гораздо легче и не придется при каждой непонятке создавать отдельную тему и ждать пока кто-то погуглит за вас и выложит все на блюдечке.
|
|
|
|
xDilettante (OP)
Newbie
Offline
Activity: 14
Merit: 1
|
|
October 13, 2023, 12:43:42 PM Last edit: October 13, 2023, 01:31:57 PM by xDilettante |
|
Поздравляю, что в английской ветке вы получили готовое решение для своей задачи. В русскоязычной ветке же предлагают только хардкор, дают ссылки и надеятся, что спрашивающий немного пошевелит мозгами и сам придет к ответу. Мне кажется, что если разбираться самому, то похожие задачи и вообще связанная с ней тематика будут даваться гораздо легче и не придется при каждой непонятке создавать отдельную тему и ждать пока кто-то погуглит за вас и выложит все на блюдечке. Биткоин это очень сложно для меня, но интересно. Я пытаюсь вникать, но техническая документация очень поверхностная, я не могу её понять сразу. Поверте я гуглил и очень долго искал нужную мне информацию и читал бипы которые мне скидывали по ссылкам, ещё до того как я зарегистрировался на этом форуме. Примеров в сети не так уж и много, множество примеров сильно устаревших, я бы возможно потратил несколько недель прежде чем пришёл бы к желаемому результату в своей программе. Я не собираюсь создавать на каждый свой вопрос отдельную ветку темы, все проблеммы возникающие у меня, я буду задавать здесь и в английской ветке. По итогу я думаю смогу изложить всё здесь и выложить исходный код "минимайнера" для прямого соло майнинга с ноды биткоина. Да это бесполезно, но в учебных целях думаю что разбор майнера очень даже подходит, что бы понять часть того как устроена сеть биткоина.
|
|
|
|
xDilettante (OP)
Newbie
Offline
Activity: 14
Merit: 1
|
|
October 13, 2023, 12:50:18 PM Last edit: October 13, 2023, 01:44:25 PM by xDilettante |
|
Не могли вы мне подсказать что именно не так я делаю с получением корня Меркла? Вот мой код на Python, но я не получаю тот результат который должен быть. Target: "merkleroot": "19f3769778eb2019476630aafb376634cdf3f114e617a7e0a300e822265022bc" 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, но это так же не помогло мне получить нужный результат.
|
|
|
|
A-Bolt
Legendary
Offline
Activity: 2324
Merit: 2353
|
|
October 13, 2023, 01:32:18 PM Merited by Symmetrick (2) |
|
Я так же делал двойной хеш, а так же пробовал получить корень хешированием TXID
merkleroot вычисляется из txid. В качестве алгоритма хеширования используется двойной SHA256. Пример вычисления корня дерева Меркла на Питоне.
|
|
|
|
witcher_sense
Legendary
Offline
Activity: 2422
Merit: 4393
🔐BitcoinMessage.Tools🔑
|
|
October 13, 2023, 02:47:50 PM |
|
Я так же делал двойной хеш, а так же пробовал получить корень хешированием TXID, но это так же не помогло мне получить нужный результат.
ID транзакций хранятся в little-endian формате, а вот хэшируются в big-endian. После хэширование нужно опять переводить в little-endian и это может запутать неподготовленного. Зачем нужна такая запутанность никто не знает, но так исторически сложилось. В поисковиках и всяких блок эксплорерах поиск обычно производится уже в "перевернутом" формате. Здесь можно почитать подробнее: https://learnmeabitcoin.com/technical/txid
|
|
|
|
xDilettante (OP)
Newbie
Offline
Activity: 14
Merit: 1
|
|
October 13, 2023, 02:53:05 PM |
|
Большое спасибо за пример! Очень легко запутаться в этих обратных байтах и двойном хешировании. Вот полностью рабочий код для MainNet: #! /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)
|
|
|
|
xDilettante (OP)
Newbie
Offline
Activity: 14
Merit: 1
|
|
October 13, 2023, 08:13:21 PM |
|
Как создавать "coinbase tx"? Можно ли построить её через createrawtransaction или её можно создать только в коде? Тогда я не полностью понимаю как устроенно построение данной транзакции. На примере транзакции из реального блока, приведу то что я понимаю в ней. То что помечено вопросами или не обозначено, я не понимаю. { "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
# 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
|
|
|
|
A-Bolt
Legendary
Offline
Activity: 2324
Merit: 2353
|
Как создавать "coinbase tx"? Можно ли построить её через createrawtransaction или её можно создать только в коде?
createrawtransaction - только для обычных транзакций, транзакцию coinbase так сделать не получится. Тогда я не полностью понимаю как устроенно построение данной транзакции.
Тут на примере показана структура транзакции coinbase: 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 нулевых байта).
|
|
|
|
xDilettante (OP)
Newbie
Offline
Activity: 14
Merit: 1
|
|
October 15, 2023, 07:48:06 PM |
|
На "regtest" при попытке отправить блок на подтверждение(submitblock). Я полуаю ошибку. В чём может быть проблема? 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}
|
|
|
|
A-Bolt
Legendary
Offline
Activity: 2324
Merit: 2353
|
|
October 16, 2023, 10:12:37 PM |
|
В чём может быть проблема?
В том, что вы не проверили транзакцию coinbase на корректность, декодировав её, например, при помощи decoderawtransaction. У вас в этой транзакции два выхода. Вы указали длину scriptPubKey 44 - для первого выхода и 4С - для второго, хотя реальная длина scriptPubKey в байтах в два раза меньше.
|
|
|
|
|