Wie erstelle ich eine Transaktion mit OP_RETURN in Python?

Ich versuche derzeit herauszufinden, wie Python verwendet wird, um eine Transaktion mit OP_RETURN zu erstellen. Ich habe versucht, die Nachricht selbst zu verschlüsseln, und hatte kein Glück. Ich habe eine Funktion, OPReturn(), im Internet gefunden, aber wenn ich versuche, sie zu verwenden, erhalte ich den Fehler (von der Broadcast-API von Blockchain.info):Exception: None Standard Script Output OP_RETURN 594f4c4f53574147

Code:

# 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))
Beachten Sie, dass dieser Code nur für Nachrichten von 75 Byte oder weniger funktioniert.
@NickODell sind es nicht 40 Bytes? (EDIT: Du meinst insgesamt 75 Bytes, die ich gerade erkannt habe?)
Welche Python-Version? Ich bin mir ziemlich sicher, dass Sie versuchen, dies unter Python 3.x zu tun, wo das Struct -Feld "q/Q" nicht mehr verfügbar ist. Pybitcointools benötigen Python 2.7 (tatsächlich ist praktisch alles Bitcoin-Python-Zeug Version 2.x aufgrund der Art und Weise, wie es Strings als Bytes ohne Binascii und dergleichen behandelt.

Antworten (3)

Ich habe die pybitcointools-Bibliothek gegabelt , um eine richtig formatierte OP_RETURNHex-Zeichenfolge zurückzugeben oder sie OP_RETURNin eine rohe Hex-Transaktion einzufügen.

Meine Gabel findet ihr hier . Der Code lautet wie folgt:

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

Beachten Sie, dass der Modulname in meinem Fork in btc(von ) geändert wurde.bitcoin

Um dies auszuführen, verwenden Sie os.chdir("c:/python/pybitcointools")(oder das Verzeichnis, in das es heruntergeladen wurde. Dann from bitcoin import *. Lassen Sie uns jetzt msg = 'The enemy of my enemy is my friend'und verwenden rawtx = "01000000016e3cd2b24fcf49259db29888ec5fe6521070041cb8c7bb2017537046f9e00f2b0000000000ffffffff0168d61100000000001976a91469bbbb16301e40b9fb67130e1aa53a2281d60af088ac00000000".

mk_opreturn(msg, rawtx)kehrt zurück:

01000000016e3cd2b24fcf49259db29888ec5fe6521070041cb8c7bb2017537046f9e00f2b0000000000ffffffff0268d61100000000001976a91469bbbb16301e40b9fb67130e1aa53a2281d60af088ac0000000000000000246a2254686520656e656d79206f66206d7920656e656d79206973206d7920667269656e6400000000

Dies ist der Roh-Tx mit dem OP_RETURNrichtig eingefügten. Führen Sie die Funktion ohne den rawtxParameter aus und sie gibt die Zeichenfolge zurück6a2254686520656e656d79206f66206d7920656e656d79206973206d7920667269656e64

Wolltest du das zweimal beantworten? PS. Ich habe dir eine PR auf github geschickt. :)
Ja und nein :). Ich hatte das Gefühl, dass eine separate Antwort erforderlich war, da ich versuche, die Frage „wie man OP_RETURN mit Python mithilfe von Code einfach verwendet“ zu beantworten. Diese Antwort ist meiner Meinung nach eigenständiger. Guter Fang auf der PR BTW

Das Skript nimmt (sozusagen) einfach eine Rohtransaktion und fügt eine Hexadezimalzahl ein, die eine zusätzliche Tx-Ausgabe darstellt. Es wird also nach ffffffff ( Sequenz ) gesucht und angehängt 6a hex encoding of your msg(bis zu 20 Bytes)

Die Nachricht muss in Hex konvertiert werden (was der Code tut).

Der Code funktioniert gut für mich, obwohl ich das Senden noch nicht versucht habe. Basierend auf Ihrem zitierten Fehler

Ich erhalte den Fehler (von der Blockchain.info Broadcast API): Exception: None Standard Script Output OP_RETURN 594f4c4f53574147

Ich muss sagen, BCI reagiert auf den MessageLenTeil des Codes. Zwischen ( ) und der Nachrichtenlänge von 1 Byte sollte ein OP_PUSHDATA1( ) stehen .0x4cOP_RETURN0x6a0x08

Versuchen:6a4c08594f4c4f53574147

Versuchen Sie alternativ einen anderen Dienst, um den Roh-Tx zu pushen, z.

Kümmert sich meine Linie nicht ID = binascii.hexlify(str(message))schon darum?
@rsmoz lass mich für dich nachsehen. Können Sie die URL für das Skript und die Python-Version bestätigen, auf der Sie sich befinden?
2.7. Ich bin dabei, den Code mit einigen Änderungen zu aktualisieren, die ich vorgenommen habe.
Ich habe den Push-Code hinzugefügt, hat nicht funktioniert. Versuchte Bitpays tx send, sagte mir, meine Transaktion sei Staub, was, wie ich mich erinnerte, bedeutete, dass die Transaktion zu klein war. Habe es größer gemacht, dann den Bitpay-Versand verwendet und es hat funktioniert! blockchain.info/tx/…
@rsmoz gute Sachen! Mich würde interessieren, ob es das 550-Satoshi-Staublimit oder der Push-Op-Code war, der es bewirkt hat. Ich werde meine Antwort bearbeiten, um die nicht hilfreichen Binascii-Kommentare zu entfernen, die ich gemacht habe
Hm, habe immer noch Probleme. Jetzt, wo ich viele Eingaben zu verarbeiten habe, wird die Transaktion nicht richtig zusammengestellt.
Ich wollte eine Klarstellung hinzufügen: Beim Zusammenbau eines 40-Byte -OP_RETURN -Txn lautet der Code: 2a6a28 40 byte data, wo 2asagt, push next 42 bytes, 6aist OP_RETURN und 28sagt, push the 40 bytes. Dies ist das erforderliche Format für Bitcoincore.

Möglicherweise finden Sie unsere python-OP_RETURN-Bibliothek hilfreich, entweder um sie sofort zu verwenden oder um zu sehen, wie wir OP_RETURN-Transaktionen erstellen.

https://github.com/coinspark/python-OP_RETURN

Es hat auch eine nette Funktion, um Daten beliebiger Größe in der Blockchain mithilfe mehrerer verketteter Transaktionen mit OP_RETURNs zu speichern und diese Daten mithilfe einer einzigen 12-stelligen Referenznummer abzurufen.

Was entspricht der Referenznummer?
Es hat folgendes Format: [geschätzte Höhe]-[Teil-TXID] [geschätzte Höhe] ist der Block, in dem die erste Transaktion erscheinen kann. Beim Speichern setzen wir [geschätzte Höhe] auf 1+(aktuelle Höhe). Beim Abrufen versuchen wir diesen Block dann einige später und einige von vorher im Falle von Reorgs. [partial txid] enthält 2 benachbarte Bytes aus der txid: position=2*([partial txid] div 65536) ([partial txid] mod 256) ist das Byte an Position ([partial txid] mod 65536) div 256) ist das byte at (position+1) Sie können keine txid für die Referenz verwenden, da die meisten Knoten nicht nach txid indizieren.
@Gideon Greenspan - Ich habe versucht, Ihren Code zu verwenden, habe aber diesen Fehler erhalten:'OP_RETURN.py", line 456, in OP_RETURN_bitcoin_cmd if not len(port): TypeError: object of type 'int' has no len()'
Legen Sie OP_RETURN_BITCOIN_PORTmithilfe einer ganzen Zahl in einer Zeichenfolge statt einer ganzen Zahl fest.