Transactions

如何在 Python 中使用 OP_RETURN 編寫事務?

  • June 22, 2017

目前正試圖弄清楚如何使用 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(from bitcoin)。

要執行它,您將使用os.chdir("c:/python/pybitcointools")(或它已下載到的任何目錄。然後from bitcoin import *。現在,讓我們使用msg = 'The enemy of my enemy is my friend'and rawtx = "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>

引用自:https://bitcoin.stackexchange.com/questions/35958