mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
move opcodes to bitcoin.py
This commit is contained in:
parent
c03c17f1c7
commit
e7f38467d7
5 changed files with 183 additions and 188 deletions
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
from typing import List, Tuple, TYPE_CHECKING, Optional, Union
|
from typing import List, Tuple, TYPE_CHECKING, Optional, Union
|
||||||
|
from enum import IntEnum
|
||||||
|
|
||||||
from .util import bfh, bh2u, BitcoinException, assert_bytes, to_bytes, inv_dict
|
from .util import bfh, bh2u, BitcoinException, assert_bytes, to_bytes, inv_dict
|
||||||
from . import version
|
from . import version
|
||||||
|
@ -49,6 +50,147 @@ TYPE_PUBKEY = 1
|
||||||
TYPE_SCRIPT = 2
|
TYPE_SCRIPT = 2
|
||||||
|
|
||||||
|
|
||||||
|
class opcodes(IntEnum):
|
||||||
|
# push value
|
||||||
|
OP_0 = 0x00
|
||||||
|
OP_FALSE = OP_0
|
||||||
|
OP_PUSHDATA1 = 0x4c
|
||||||
|
OP_PUSHDATA2 = 0x4d
|
||||||
|
OP_PUSHDATA4 = 0x4e
|
||||||
|
OP_1NEGATE = 0x4f
|
||||||
|
OP_RESERVED = 0x50
|
||||||
|
OP_1 = 0x51
|
||||||
|
OP_TRUE = OP_1
|
||||||
|
OP_2 = 0x52
|
||||||
|
OP_3 = 0x53
|
||||||
|
OP_4 = 0x54
|
||||||
|
OP_5 = 0x55
|
||||||
|
OP_6 = 0x56
|
||||||
|
OP_7 = 0x57
|
||||||
|
OP_8 = 0x58
|
||||||
|
OP_9 = 0x59
|
||||||
|
OP_10 = 0x5a
|
||||||
|
OP_11 = 0x5b
|
||||||
|
OP_12 = 0x5c
|
||||||
|
OP_13 = 0x5d
|
||||||
|
OP_14 = 0x5e
|
||||||
|
OP_15 = 0x5f
|
||||||
|
OP_16 = 0x60
|
||||||
|
|
||||||
|
# control
|
||||||
|
OP_NOP = 0x61
|
||||||
|
OP_VER = 0x62
|
||||||
|
OP_IF = 0x63
|
||||||
|
OP_NOTIF = 0x64
|
||||||
|
OP_VERIF = 0x65
|
||||||
|
OP_VERNOTIF = 0x66
|
||||||
|
OP_ELSE = 0x67
|
||||||
|
OP_ENDIF = 0x68
|
||||||
|
OP_VERIFY = 0x69
|
||||||
|
OP_RETURN = 0x6a
|
||||||
|
|
||||||
|
# stack ops
|
||||||
|
OP_TOALTSTACK = 0x6b
|
||||||
|
OP_FROMALTSTACK = 0x6c
|
||||||
|
OP_2DROP = 0x6d
|
||||||
|
OP_2DUP = 0x6e
|
||||||
|
OP_3DUP = 0x6f
|
||||||
|
OP_2OVER = 0x70
|
||||||
|
OP_2ROT = 0x71
|
||||||
|
OP_2SWAP = 0x72
|
||||||
|
OP_IFDUP = 0x73
|
||||||
|
OP_DEPTH = 0x74
|
||||||
|
OP_DROP = 0x75
|
||||||
|
OP_DUP = 0x76
|
||||||
|
OP_NIP = 0x77
|
||||||
|
OP_OVER = 0x78
|
||||||
|
OP_PICK = 0x79
|
||||||
|
OP_ROLL = 0x7a
|
||||||
|
OP_ROT = 0x7b
|
||||||
|
OP_SWAP = 0x7c
|
||||||
|
OP_TUCK = 0x7d
|
||||||
|
|
||||||
|
# splice ops
|
||||||
|
OP_CAT = 0x7e
|
||||||
|
OP_SUBSTR = 0x7f
|
||||||
|
OP_LEFT = 0x80
|
||||||
|
OP_RIGHT = 0x81
|
||||||
|
OP_SIZE = 0x82
|
||||||
|
|
||||||
|
# bit logic
|
||||||
|
OP_INVERT = 0x83
|
||||||
|
OP_AND = 0x84
|
||||||
|
OP_OR = 0x85
|
||||||
|
OP_XOR = 0x86
|
||||||
|
OP_EQUAL = 0x87
|
||||||
|
OP_EQUALVERIFY = 0x88
|
||||||
|
OP_RESERVED1 = 0x89
|
||||||
|
OP_RESERVED2 = 0x8a
|
||||||
|
|
||||||
|
# numeric
|
||||||
|
OP_1ADD = 0x8b
|
||||||
|
OP_1SUB = 0x8c
|
||||||
|
OP_2MUL = 0x8d
|
||||||
|
OP_2DIV = 0x8e
|
||||||
|
OP_NEGATE = 0x8f
|
||||||
|
OP_ABS = 0x90
|
||||||
|
OP_NOT = 0x91
|
||||||
|
OP_0NOTEQUAL = 0x92
|
||||||
|
|
||||||
|
OP_ADD = 0x93
|
||||||
|
OP_SUB = 0x94
|
||||||
|
OP_MUL = 0x95
|
||||||
|
OP_DIV = 0x96
|
||||||
|
OP_MOD = 0x97
|
||||||
|
OP_LSHIFT = 0x98
|
||||||
|
OP_RSHIFT = 0x99
|
||||||
|
|
||||||
|
OP_BOOLAND = 0x9a
|
||||||
|
OP_BOOLOR = 0x9b
|
||||||
|
OP_NUMEQUAL = 0x9c
|
||||||
|
OP_NUMEQUALVERIFY = 0x9d
|
||||||
|
OP_NUMNOTEQUAL = 0x9e
|
||||||
|
OP_LESSTHAN = 0x9f
|
||||||
|
OP_GREATERTHAN = 0xa0
|
||||||
|
OP_LESSTHANOREQUAL = 0xa1
|
||||||
|
OP_GREATERTHANOREQUAL = 0xa2
|
||||||
|
OP_MIN = 0xa3
|
||||||
|
OP_MAX = 0xa4
|
||||||
|
|
||||||
|
OP_WITHIN = 0xa5
|
||||||
|
|
||||||
|
# crypto
|
||||||
|
OP_RIPEMD160 = 0xa6
|
||||||
|
OP_SHA1 = 0xa7
|
||||||
|
OP_SHA256 = 0xa8
|
||||||
|
OP_HASH160 = 0xa9
|
||||||
|
OP_HASH256 = 0xaa
|
||||||
|
OP_CODESEPARATOR = 0xab
|
||||||
|
OP_CHECKSIG = 0xac
|
||||||
|
OP_CHECKSIGVERIFY = 0xad
|
||||||
|
OP_CHECKMULTISIG = 0xae
|
||||||
|
OP_CHECKMULTISIGVERIFY = 0xaf
|
||||||
|
|
||||||
|
# expansion
|
||||||
|
OP_NOP1 = 0xb0
|
||||||
|
OP_CHECKLOCKTIMEVERIFY = 0xb1
|
||||||
|
OP_NOP2 = OP_CHECKLOCKTIMEVERIFY
|
||||||
|
OP_CHECKSEQUENCEVERIFY = 0xb2
|
||||||
|
OP_NOP3 = OP_CHECKSEQUENCEVERIFY
|
||||||
|
OP_NOP4 = 0xb3
|
||||||
|
OP_NOP5 = 0xb4
|
||||||
|
OP_NOP6 = 0xb5
|
||||||
|
OP_NOP7 = 0xb6
|
||||||
|
OP_NOP8 = 0xb7
|
||||||
|
OP_NOP9 = 0xb8
|
||||||
|
OP_NOP10 = 0xb9
|
||||||
|
|
||||||
|
OP_INVALIDOPCODE = 0xff
|
||||||
|
|
||||||
|
def hex(self) -> str:
|
||||||
|
return bytes([self]).hex()
|
||||||
|
|
||||||
|
|
||||||
def rev_hex(s: str) -> str:
|
def rev_hex(s: str) -> str:
|
||||||
return bh2u(bfh(s)[::-1])
|
return bh2u(bfh(s)[::-1])
|
||||||
|
|
||||||
|
@ -112,15 +254,15 @@ def witness_push(item: str) -> str:
|
||||||
return var_int(len(item) // 2) + item
|
return var_int(len(item) // 2) + item
|
||||||
|
|
||||||
|
|
||||||
def op_push(i: int) -> str:
|
def _op_push(i: int) -> str:
|
||||||
if i<0x4c: # OP_PUSHDATA1
|
if i < opcodes.OP_PUSHDATA1:
|
||||||
return int_to_hex(i)
|
return int_to_hex(i)
|
||||||
elif i<=0xff:
|
elif i <= 0xff:
|
||||||
return '4c' + int_to_hex(i)
|
return opcodes.OP_PUSHDATA1.hex() + int_to_hex(i, 1)
|
||||||
elif i<=0xffff:
|
elif i <= 0xffff:
|
||||||
return '4d' + int_to_hex(i,2)
|
return opcodes.OP_PUSHDATA2.hex() + int_to_hex(i, 2)
|
||||||
else:
|
else:
|
||||||
return '4e' + int_to_hex(i,4)
|
return opcodes.OP_PUSHDATA4.hex() + int_to_hex(i, 4)
|
||||||
|
|
||||||
|
|
||||||
def push_script(data: str) -> str:
|
def push_script(data: str) -> str:
|
||||||
|
@ -131,19 +273,17 @@ def push_script(data: str) -> str:
|
||||||
ported from https://github.com/btcsuite/btcd/blob/fdc2bc867bda6b351191b5872d2da8270df00d13/txscript/scriptbuilder.go#L128
|
ported from https://github.com/btcsuite/btcd/blob/fdc2bc867bda6b351191b5872d2da8270df00d13/txscript/scriptbuilder.go#L128
|
||||||
"""
|
"""
|
||||||
data = bfh(data)
|
data = bfh(data)
|
||||||
from .transaction import opcodes
|
|
||||||
|
|
||||||
data_len = len(data)
|
data_len = len(data)
|
||||||
|
|
||||||
# "small integer" opcodes
|
# "small integer" opcodes
|
||||||
if data_len == 0 or data_len == 1 and data[0] == 0:
|
if data_len == 0 or data_len == 1 and data[0] == 0:
|
||||||
return bh2u(bytes([opcodes.OP_0]))
|
return opcodes.OP_0.hex()
|
||||||
elif data_len == 1 and data[0] <= 16:
|
elif data_len == 1 and data[0] <= 16:
|
||||||
return bh2u(bytes([opcodes.OP_1 - 1 + data[0]]))
|
return bh2u(bytes([opcodes.OP_1 - 1 + data[0]]))
|
||||||
elif data_len == 1 and data[0] == 0x81:
|
elif data_len == 1 and data[0] == 0x81:
|
||||||
return bh2u(bytes([opcodes.OP_1NEGATE]))
|
return opcodes.OP_1NEGATE.hex()
|
||||||
|
|
||||||
return op_push(data_len) + bh2u(data)
|
return _op_push(data_len) + bh2u(data)
|
||||||
|
|
||||||
|
|
||||||
def add_number_to_script(i: int) -> bytes:
|
def add_number_to_script(i: int) -> bytes:
|
||||||
|
@ -305,19 +445,18 @@ def address_to_script(addr: str, *, net=None) -> str:
|
||||||
if witprog is not None:
|
if witprog is not None:
|
||||||
if not (0 <= witver <= 16):
|
if not (0 <= witver <= 16):
|
||||||
raise BitcoinException(f'impossible witness version: {witver}')
|
raise BitcoinException(f'impossible witness version: {witver}')
|
||||||
OP_n = witver + 0x50 if witver > 0 else 0
|
script = bh2u(add_number_to_script(witver))
|
||||||
script = bh2u(bytes([OP_n]))
|
|
||||||
script += push_script(bh2u(bytes(witprog)))
|
script += push_script(bh2u(bytes(witprog)))
|
||||||
return script
|
return script
|
||||||
addrtype, hash_160_ = b58_address_to_hash160(addr)
|
addrtype, hash_160_ = b58_address_to_hash160(addr)
|
||||||
if addrtype == net.ADDRTYPE_P2PKH:
|
if addrtype == net.ADDRTYPE_P2PKH:
|
||||||
script = '76a9' # op_dup, op_hash_160
|
script = bytes([opcodes.OP_DUP, opcodes.OP_HASH160]).hex()
|
||||||
script += push_script(bh2u(hash_160_))
|
script += push_script(bh2u(hash_160_))
|
||||||
script += '88ac' # op_equalverify, op_checksig
|
script += bytes([opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG]).hex()
|
||||||
elif addrtype == net.ADDRTYPE_P2SH:
|
elif addrtype == net.ADDRTYPE_P2SH:
|
||||||
script = 'a9' # op_hash_160
|
script = opcodes.OP_HASH160.hex()
|
||||||
script += push_script(bh2u(hash_160_))
|
script += push_script(bh2u(hash_160_))
|
||||||
script += '87' # op_equal
|
script += opcodes.OP_EQUAL.hex()
|
||||||
else:
|
else:
|
||||||
raise BitcoinException(f'unknown address type: {addrtype}')
|
raise BitcoinException(f'unknown address type: {addrtype}')
|
||||||
return script
|
return script
|
||||||
|
@ -331,9 +470,7 @@ def script_to_scripthash(script: str) -> str:
|
||||||
return bh2u(bytes(reversed(h)))
|
return bh2u(bytes(reversed(h)))
|
||||||
|
|
||||||
def public_key_to_p2pk_script(pubkey: str) -> str:
|
def public_key_to_p2pk_script(pubkey: str) -> str:
|
||||||
script = push_script(pubkey)
|
return push_script(pubkey) + opcodes.OP_CHECKSIG.hex()
|
||||||
script += 'ac' # op_checksig
|
|
||||||
return script
|
|
||||||
|
|
||||||
__b58chars = b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
__b58chars = b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||||
assert len(__b58chars) == 58
|
assert len(__b58chars) == 58
|
||||||
|
|
|
@ -30,7 +30,8 @@ from PyQt5.QtGui import QFontMetrics
|
||||||
|
|
||||||
from electrum import bitcoin
|
from electrum import bitcoin
|
||||||
from electrum.util import bfh, PrintError
|
from electrum.util import bfh, PrintError
|
||||||
from electrum.transaction import TxOutput
|
from electrum.transaction import TxOutput, push_script
|
||||||
|
from electrum.bitcoin import opcodes
|
||||||
|
|
||||||
from .qrtextedit import ScanQRTextEdit
|
from .qrtextedit import ScanQRTextEdit
|
||||||
from .completion_text_edit import CompletionTextEdit
|
from .completion_text_edit import CompletionTextEdit
|
||||||
|
@ -91,7 +92,6 @@ class PayToEdit(CompletionTextEdit, ScanQRTextEdit, PrintError):
|
||||||
return bitcoin.TYPE_SCRIPT, script
|
return bitcoin.TYPE_SCRIPT, script
|
||||||
|
|
||||||
def parse_script(self, x):
|
def parse_script(self, x):
|
||||||
from electrum.transaction import opcodes, push_script
|
|
||||||
script = ''
|
script = ''
|
||||||
for word in x.split():
|
for word in x.split():
|
||||||
if word[0:3] == 'OP_':
|
if word[0:3] == 'OP_':
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
|
|
||||||
from electrum.plugin import BasePlugin, hook
|
from electrum.plugin import BasePlugin, hook
|
||||||
from electrum.i18n import _
|
from electrum.i18n import _
|
||||||
from electrum.bitcoin import is_address, TYPE_SCRIPT
|
from electrum.bitcoin import is_address, TYPE_SCRIPT, opcodes
|
||||||
from electrum.util import bfh, versiontuple, UserFacingException
|
from electrum.util import bfh, versiontuple, UserFacingException
|
||||||
from electrum.transaction import opcodes, TxOutput, Transaction
|
from electrum.transaction import TxOutput, Transaction
|
||||||
|
|
||||||
|
|
||||||
class HW_PluginBase(BasePlugin):
|
class HW_PluginBase(BasePlugin):
|
||||||
|
|
|
@ -3,18 +3,18 @@ import sys
|
||||||
|
|
||||||
from electrum.bitcoin import (public_key_to_p2pkh, address_from_private_key,
|
from electrum.bitcoin import (public_key_to_p2pkh, address_from_private_key,
|
||||||
is_address, is_private_key, is_new_seed, is_old_seed,
|
is_address, is_private_key, is_new_seed, is_old_seed,
|
||||||
var_int, op_push, address_to_script,
|
var_int, _op_push, address_to_script,
|
||||||
deserialize_privkey, serialize_privkey, is_segwit_address,
|
deserialize_privkey, serialize_privkey, is_segwit_address,
|
||||||
is_b58_address, address_to_scripthash, is_minikey,
|
is_b58_address, address_to_scripthash, is_minikey,
|
||||||
is_compressed_privkey, seed_type, EncodeBase58Check,
|
is_compressed_privkey, seed_type, EncodeBase58Check,
|
||||||
script_num_to_hex, push_script, add_number_to_script, int_to_hex)
|
script_num_to_hex, push_script, add_number_to_script, int_to_hex,
|
||||||
|
opcodes)
|
||||||
from electrum.bip32 import (bip32_root, bip32_public_derivation, bip32_private_derivation,
|
from electrum.bip32 import (bip32_root, bip32_public_derivation, bip32_private_derivation,
|
||||||
xpub_from_xprv, xpub_type, is_xprv, is_bip32_derivation,
|
xpub_from_xprv, xpub_type, is_xprv, is_bip32_derivation,
|
||||||
is_xpub, convert_bip32_path_to_list_of_uint32)
|
is_xpub, convert_bip32_path_to_list_of_uint32)
|
||||||
from electrum.crypto import sha256d, SUPPORTED_PW_HASH_VERSIONS
|
from electrum.crypto import sha256d, SUPPORTED_PW_HASH_VERSIONS
|
||||||
from electrum import ecc, crypto, constants
|
from electrum import ecc, crypto, constants
|
||||||
from electrum.ecc import number_to_string, string_to_number
|
from electrum.ecc import number_to_string, string_to_number
|
||||||
from electrum.transaction import opcodes
|
|
||||||
from electrum.util import bfh, bh2u, InvalidPassword
|
from electrum.util import bfh, bh2u, InvalidPassword
|
||||||
from electrum.storage import WalletStorage
|
from electrum.storage import WalletStorage
|
||||||
from electrum.keystore import xtype_from_derivation
|
from electrum.keystore import xtype_from_derivation
|
||||||
|
@ -291,18 +291,18 @@ class Test_bitcoin(SequentialTestCase):
|
||||||
self.assertEqual(var_int(0x0123456789abcdef), "ffefcdab8967452301")
|
self.assertEqual(var_int(0x0123456789abcdef), "ffefcdab8967452301")
|
||||||
|
|
||||||
def test_op_push(self):
|
def test_op_push(self):
|
||||||
self.assertEqual(op_push(0x00), '00')
|
self.assertEqual(_op_push(0x00), '00')
|
||||||
self.assertEqual(op_push(0x12), '12')
|
self.assertEqual(_op_push(0x12), '12')
|
||||||
self.assertEqual(op_push(0x4b), '4b')
|
self.assertEqual(_op_push(0x4b), '4b')
|
||||||
self.assertEqual(op_push(0x4c), '4c4c')
|
self.assertEqual(_op_push(0x4c), '4c4c')
|
||||||
self.assertEqual(op_push(0xfe), '4cfe')
|
self.assertEqual(_op_push(0xfe), '4cfe')
|
||||||
self.assertEqual(op_push(0xff), '4cff')
|
self.assertEqual(_op_push(0xff), '4cff')
|
||||||
self.assertEqual(op_push(0x100), '4d0001')
|
self.assertEqual(_op_push(0x100), '4d0001')
|
||||||
self.assertEqual(op_push(0x1234), '4d3412')
|
self.assertEqual(_op_push(0x1234), '4d3412')
|
||||||
self.assertEqual(op_push(0xfffe), '4dfeff')
|
self.assertEqual(_op_push(0xfffe), '4dfeff')
|
||||||
self.assertEqual(op_push(0xffff), '4dffff')
|
self.assertEqual(_op_push(0xffff), '4dffff')
|
||||||
self.assertEqual(op_push(0x10000), '4e00000100')
|
self.assertEqual(_op_push(0x10000), '4e00000100')
|
||||||
self.assertEqual(op_push(0x12345678), '4e78563412')
|
self.assertEqual(_op_push(0x12345678), '4e78563412')
|
||||||
|
|
||||||
def test_script_num_to_hex(self):
|
def test_script_num_to_hex(self):
|
||||||
# test vectors from https://github.com/btcsuite/btcd/blob/fdc2bc867bda6b351191b5872d2da8270df00d13/txscript/scriptnum.go#L77
|
# test vectors from https://github.com/btcsuite/btcd/blob/fdc2bc867bda6b351191b5872d2da8270df00d13/txscript/scriptnum.go#L77
|
||||||
|
|
|
@ -32,14 +32,14 @@ import traceback
|
||||||
import sys
|
import sys
|
||||||
from typing import (Sequence, Union, NamedTuple, Tuple, Optional, Iterable,
|
from typing import (Sequence, Union, NamedTuple, Tuple, Optional, Iterable,
|
||||||
Callable, List, Dict)
|
Callable, List, Dict)
|
||||||
from enum import IntEnum
|
|
||||||
|
|
||||||
from . import ecc, bitcoin, constants, segwit_addr
|
from . import ecc, bitcoin, constants, segwit_addr
|
||||||
from .util import print_error, profiler, to_bytes, bh2u, bfh
|
from .util import print_error, profiler, to_bytes, bh2u, bfh
|
||||||
from .bitcoin import (TYPE_ADDRESS, TYPE_PUBKEY, TYPE_SCRIPT, hash_160,
|
from .bitcoin import (TYPE_ADDRESS, TYPE_PUBKEY, TYPE_SCRIPT, hash_160,
|
||||||
hash160_to_p2sh, hash160_to_p2pkh, hash_to_segwit_addr,
|
hash160_to_p2sh, hash160_to_p2pkh, hash_to_segwit_addr,
|
||||||
hash_encode, var_int, TOTAL_COIN_SUPPLY_LIMIT_IN_BTC, COIN,
|
hash_encode, var_int, TOTAL_COIN_SUPPLY_LIMIT_IN_BTC, COIN,
|
||||||
push_script, int_to_hex, push_script, b58_address_to_hash160)
|
push_script, int_to_hex, push_script, b58_address_to_hash160,
|
||||||
|
opcodes, add_number_to_script)
|
||||||
from .crypto import sha256d
|
from .crypto import sha256d
|
||||||
from .keystore import xpubkey_to_address, xpubkey_to_pubkey
|
from .keystore import xpubkey_to_address, xpubkey_to_pubkey
|
||||||
|
|
||||||
|
@ -191,148 +191,6 @@ class BCDataStream(object):
|
||||||
self.write(s)
|
self.write(s)
|
||||||
|
|
||||||
|
|
||||||
class opcodes(IntEnum):
|
|
||||||
# push value
|
|
||||||
OP_0 = 0x00
|
|
||||||
OP_FALSE = OP_0
|
|
||||||
OP_PUSHDATA1 = 0x4c
|
|
||||||
OP_PUSHDATA2 = 0x4d
|
|
||||||
OP_PUSHDATA4 = 0x4e
|
|
||||||
OP_1NEGATE = 0x4f
|
|
||||||
OP_RESERVED = 0x50
|
|
||||||
OP_1 = 0x51
|
|
||||||
OP_TRUE = OP_1
|
|
||||||
OP_2 = 0x52
|
|
||||||
OP_3 = 0x53
|
|
||||||
OP_4 = 0x54
|
|
||||||
OP_5 = 0x55
|
|
||||||
OP_6 = 0x56
|
|
||||||
OP_7 = 0x57
|
|
||||||
OP_8 = 0x58
|
|
||||||
OP_9 = 0x59
|
|
||||||
OP_10 = 0x5a
|
|
||||||
OP_11 = 0x5b
|
|
||||||
OP_12 = 0x5c
|
|
||||||
OP_13 = 0x5d
|
|
||||||
OP_14 = 0x5e
|
|
||||||
OP_15 = 0x5f
|
|
||||||
OP_16 = 0x60
|
|
||||||
|
|
||||||
# control
|
|
||||||
OP_NOP = 0x61
|
|
||||||
OP_VER = 0x62
|
|
||||||
OP_IF = 0x63
|
|
||||||
OP_NOTIF = 0x64
|
|
||||||
OP_VERIF = 0x65
|
|
||||||
OP_VERNOTIF = 0x66
|
|
||||||
OP_ELSE = 0x67
|
|
||||||
OP_ENDIF = 0x68
|
|
||||||
OP_VERIFY = 0x69
|
|
||||||
OP_RETURN = 0x6a
|
|
||||||
|
|
||||||
# stack ops
|
|
||||||
OP_TOALTSTACK = 0x6b
|
|
||||||
OP_FROMALTSTACK = 0x6c
|
|
||||||
OP_2DROP = 0x6d
|
|
||||||
OP_2DUP = 0x6e
|
|
||||||
OP_3DUP = 0x6f
|
|
||||||
OP_2OVER = 0x70
|
|
||||||
OP_2ROT = 0x71
|
|
||||||
OP_2SWAP = 0x72
|
|
||||||
OP_IFDUP = 0x73
|
|
||||||
OP_DEPTH = 0x74
|
|
||||||
OP_DROP = 0x75
|
|
||||||
OP_DUP = 0x76
|
|
||||||
OP_NIP = 0x77
|
|
||||||
OP_OVER = 0x78
|
|
||||||
OP_PICK = 0x79
|
|
||||||
OP_ROLL = 0x7a
|
|
||||||
OP_ROT = 0x7b
|
|
||||||
OP_SWAP = 0x7c
|
|
||||||
OP_TUCK = 0x7d
|
|
||||||
|
|
||||||
# splice ops
|
|
||||||
OP_CAT = 0x7e
|
|
||||||
OP_SUBSTR = 0x7f
|
|
||||||
OP_LEFT = 0x80
|
|
||||||
OP_RIGHT = 0x81
|
|
||||||
OP_SIZE = 0x82
|
|
||||||
|
|
||||||
# bit logic
|
|
||||||
OP_INVERT = 0x83
|
|
||||||
OP_AND = 0x84
|
|
||||||
OP_OR = 0x85
|
|
||||||
OP_XOR = 0x86
|
|
||||||
OP_EQUAL = 0x87
|
|
||||||
OP_EQUALVERIFY = 0x88
|
|
||||||
OP_RESERVED1 = 0x89
|
|
||||||
OP_RESERVED2 = 0x8a
|
|
||||||
|
|
||||||
# numeric
|
|
||||||
OP_1ADD = 0x8b
|
|
||||||
OP_1SUB = 0x8c
|
|
||||||
OP_2MUL = 0x8d
|
|
||||||
OP_2DIV = 0x8e
|
|
||||||
OP_NEGATE = 0x8f
|
|
||||||
OP_ABS = 0x90
|
|
||||||
OP_NOT = 0x91
|
|
||||||
OP_0NOTEQUAL = 0x92
|
|
||||||
|
|
||||||
OP_ADD = 0x93
|
|
||||||
OP_SUB = 0x94
|
|
||||||
OP_MUL = 0x95
|
|
||||||
OP_DIV = 0x96
|
|
||||||
OP_MOD = 0x97
|
|
||||||
OP_LSHIFT = 0x98
|
|
||||||
OP_RSHIFT = 0x99
|
|
||||||
|
|
||||||
OP_BOOLAND = 0x9a
|
|
||||||
OP_BOOLOR = 0x9b
|
|
||||||
OP_NUMEQUAL = 0x9c
|
|
||||||
OP_NUMEQUALVERIFY = 0x9d
|
|
||||||
OP_NUMNOTEQUAL = 0x9e
|
|
||||||
OP_LESSTHAN = 0x9f
|
|
||||||
OP_GREATERTHAN = 0xa0
|
|
||||||
OP_LESSTHANOREQUAL = 0xa1
|
|
||||||
OP_GREATERTHANOREQUAL = 0xa2
|
|
||||||
OP_MIN = 0xa3
|
|
||||||
OP_MAX = 0xa4
|
|
||||||
|
|
||||||
OP_WITHIN = 0xa5
|
|
||||||
|
|
||||||
# crypto
|
|
||||||
OP_RIPEMD160 = 0xa6
|
|
||||||
OP_SHA1 = 0xa7
|
|
||||||
OP_SHA256 = 0xa8
|
|
||||||
OP_HASH160 = 0xa9
|
|
||||||
OP_HASH256 = 0xaa
|
|
||||||
OP_CODESEPARATOR = 0xab
|
|
||||||
OP_CHECKSIG = 0xac
|
|
||||||
OP_CHECKSIGVERIFY = 0xad
|
|
||||||
OP_CHECKMULTISIG = 0xae
|
|
||||||
OP_CHECKMULTISIGVERIFY = 0xaf
|
|
||||||
|
|
||||||
# expansion
|
|
||||||
OP_NOP1 = 0xb0
|
|
||||||
OP_CHECKLOCKTIMEVERIFY = 0xb1
|
|
||||||
OP_NOP2 = OP_CHECKLOCKTIMEVERIFY
|
|
||||||
OP_CHECKSEQUENCEVERIFY = 0xb2
|
|
||||||
OP_NOP3 = OP_CHECKSEQUENCEVERIFY
|
|
||||||
OP_NOP4 = 0xb3
|
|
||||||
OP_NOP5 = 0xb4
|
|
||||||
OP_NOP6 = 0xb5
|
|
||||||
OP_NOP7 = 0xb6
|
|
||||||
OP_NOP8 = 0xb7
|
|
||||||
OP_NOP9 = 0xb8
|
|
||||||
OP_NOP10 = 0xb9
|
|
||||||
|
|
||||||
OP_INVALIDOPCODE = 0xff
|
|
||||||
|
|
||||||
def hex(self) -> str:
|
|
||||||
return bytes([self]).hex()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def script_GetOp(_bytes : bytes):
|
def script_GetOp(_bytes : bytes):
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(_bytes):
|
while i < len(_bytes):
|
||||||
|
@ -714,10 +572,10 @@ def deserialize(raw: str, force_full_parse=False) -> dict:
|
||||||
def multisig_script(public_keys: Sequence[str], m: int) -> str:
|
def multisig_script(public_keys: Sequence[str], m: int) -> str:
|
||||||
n = len(public_keys)
|
n = len(public_keys)
|
||||||
assert 1 <= m <= n <= 15, f'm {m}, n {n}'
|
assert 1 <= m <= n <= 15, f'm {m}, n {n}'
|
||||||
op_m = bh2u(bytes([opcodes.OP_1 - 1 + m]))
|
op_m = bh2u(add_number_to_script(m))
|
||||||
op_n = bh2u(bytes([opcodes.OP_1 - 1 + n]))
|
op_n = bh2u(add_number_to_script(n))
|
||||||
keylist = [push_script(k) for k in public_keys]
|
keylist = [push_script(k) for k in public_keys]
|
||||||
return op_m + ''.join(keylist) + op_n + 'ae'
|
return op_m + ''.join(keylist) + op_n + opcodes.OP_CHECKMULTISIG.hex()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1024,7 +882,7 @@ class Transaction:
|
||||||
scriptSig = bitcoin.p2wsh_nested_script(witness_script)
|
scriptSig = bitcoin.p2wsh_nested_script(witness_script)
|
||||||
return push_script(scriptSig)
|
return push_script(scriptSig)
|
||||||
elif _type == 'address':
|
elif _type == 'address':
|
||||||
return 'ff00' + push_script(pubkeys[0]) # fd extended pubkey
|
return bytes([opcodes.OP_INVALIDOPCODE, opcodes.OP_0]).hex() + push_script(pubkeys[0])
|
||||||
elif _type == 'unknown':
|
elif _type == 'unknown':
|
||||||
return txin['scriptSig']
|
return txin['scriptSig']
|
||||||
return script
|
return script
|
||||||
|
|
Loading…
Add table
Reference in a new issue