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?
|
|
|
|
|
|
|
|
|
Be very wary of relying on JavaScript for security on crypto sites. The site can change the JavaScript at any time unless you take unusual precautions, and browsers are not generally known for their airtight security.
|
|
|
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
|
|
A-Bolt
Legendary
Offline
Activity: 2311
Merit: 2297
|
|
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: 2310
Merit: 4313
🔐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: 2311
Merit: 2297
|
|
October 13, 2023, 01:32:18 PM Merited by Symmetrick (2) |
|
Я так же делал двойной хеш, а так же пробовал получить корень хешированием TXID
merkleroot вычисляется из txid. В качестве алгоритма хеширования используется двойной SHA256. Пример вычисления корня дерева Меркла на Питоне.
|
|
|
|
witcher_sense
Legendary
Offline
Activity: 2310
Merit: 4313
🔐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: 2311
Merit: 2297
|
Как создавать "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: 2311
Merit: 2297
|
|
October 16, 2023, 10:12:37 PM |
|
В чём может быть проблема?
В том, что вы не проверили транзакцию coinbase на корректность, декодировав её, например, при помощи decoderawtransaction. У вас в этой транзакции два выхода. Вы указали длину scriptPubKey 44 - для первого выхода и 4С - для второго, хотя реальная длина scriptPubKey в байтах в два раза меньше.
|
|
|
|
|