如何在 Python 中使用 OP_RETURN 編寫事務?
目前正試圖弄清楚如何使用 Python 來構造一個帶有 OP_RETURN 的事務。我試圖自己編碼消息,但沒有運氣。我在網際網路上找到了一個函式 OPReturn(),但是當我嘗試使用它時,我得到了錯誤(來自 Blockchain.info 廣播 API):
Exception: None Standard Script Output OP_RETURN 594f4c4f53574147
程式碼:
# coding: utf-8 from bitcoin import * import binascii from test import * priv = sha256('brain wallet') pub = privtopub(priv) addr = pubtoaddr(pub) inputs = unspent(addr) message = "YOLOSWAG" FullLen = format(len(message)+2,'x').rjust(2,'0') MessageLen = format(len(message),'x').rjust(2,'0') ID = binascii.hexlify(str(message)) snd = "6a"+MessageLen+ID outputs = [{'value': 50000, 'address': addr}, {'value': 0, 'script': snd}] fee = 10000 tx = mksend(inputs, outputs, addr, fee) dt = deserialize(tx) ins = dt['ins'] #print addr #print ins for ind, elm in enumerate(ins): print elm tx = sign(tx, ind, priv) #print tx print(pushtx(tx))
我已經分叉了pybitcointools 庫以返回格式正確的
OP_RETURN
十六進製字元串,或將其OP_RETURN
插入原始十六進制事務中。我的叉子可以在這裡找到。程式碼如下:
from bitcoin.pyspecials import safe_hexlify, from_string_to_bytes, from_int_to_byte, from_string_to_bytes def mk_opreturn(msg, rawtx=None, json=0): def op_push(data): import struct if len(data) < 0x4c: return from_int_to_byte(len(data)) + from_string_to_bytes(data) elif len(data) < 0xff: return from_int_to_byte(76) + struct.pack('<B', len(data)) + from_string_to_bytes(data) elif len(data) < 0xffff: return from_int_to_byte(77) + struct.pack('<H', len(data)) + from_string_to_bytes(data) elif len(data) < 0xffffffff: return from_int_to_byte(78) + struct.pack('<I', len(data)) + from_string_to_bytes(data) else: raise Exception("Input data error. Rawtx must be hex chars" \ + "0xffffffff > len(data) > 0") orhex = safe_hexlify(b'\x6a' + op_push(msg)) orjson = {'script' : orhex, 'value' : 0} if rawtx is not None: try: txo = deserialize(rawtx) if not 'outs' in txo.keys(): raise Exception("OP_Return cannot be the sole output!") txo['outs'].append(orjson) newrawtx = serialize(txo) return newrawtx except: raise Exception("Raw Tx Error!") return orhex if not json else orjson
請注意,我的 fork 中的模組名稱已更改為
btc
(frombitcoin
)。要執行它,您將使用
os.chdir("c:/python/pybitcointools")
(或它已下載到的任何目錄。然後from bitcoin import *
。現在,讓我們使用msg = 'The enemy of my enemy is my friend'
andrawtx = "01000000016e3cd2b24fcf49259db29888ec5fe6521070041cb8c7bb2017537046f9e00f2b0000000000ffffffff0168d61100000000001976a91469bbbb16301e40b9fb67130e1aa53a2281d60af088ac00000000"
。
mk_opreturn(msg, rawtx)
返回:01000000016e3cd2b24fcf49259db29888ec5fe6521070041cb8c7bb2017537046f9e00f2b0000000000ffffffff0268d61100000000001976a91469bbbb16301e40b9fb67130e1aa53a2281d60af088ac0000000000000000246a2254686520656e656d79206f66206d7920656e656d79206973206d7920667269656e6400000000
這是
OP_RETURN
正確插入的原始 Tx。執行不帶rawtx
參數的函式並返回字元串6a2254686520656e656d79206f66206d7920656e656d79206973206d7920667269656e64
該腳本只是(可以這麼說)獲取原始交易並拼接一個十六進制數字,該數字表示額外的 Tx 輸出。所以它正在尋找ffffffff(序列)並附加
6a
hex encoding of your msg
(最多 20 個字節)消息需要轉換為十六進制(程式碼就是這樣做的)。
該程式碼對我來說很好,雖然我還沒有嘗試廣播。根據您引用的錯誤
我收到錯誤(來自 Blockchain.info 廣播 API):異常:無標準腳本輸出 OP_RETURN 594f4c4f53574147
我不得不說 BCI 正在
MessageLen
對程式碼的一部分做出反應。( ) 和 1 字節的 msg 長度之間應該有一個OP_PUSHDATA1
( ) 。0x4c``OP_RETURN``0x6a``0x08
嘗試:
6a4c08594f4c4f53574147
或者,嘗試另一個服務來推送原始 Tx,例如:
- <https://insight.bitpay.com/tx/send>
- <https://brainwallet.github.io/#tx>