move opcodes to bitcoin.py
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
|
||||
import hashlib
|
||||
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 . import version
|
||||
@@ -49,6 +50,147 @@ TYPE_PUBKEY = 1
|
||||
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:
|
||||
return bh2u(bfh(s)[::-1])
|
||||
|
||||
@@ -112,15 +254,15 @@ def witness_push(item: str) -> str:
|
||||
return var_int(len(item) // 2) + item
|
||||
|
||||
|
||||
def op_push(i: int) -> str:
|
||||
if i<0x4c: # OP_PUSHDATA1
|
||||
def _op_push(i: int) -> str:
|
||||
if i < opcodes.OP_PUSHDATA1:
|
||||
return int_to_hex(i)
|
||||
elif i<=0xff:
|
||||
return '4c' + int_to_hex(i)
|
||||
elif i<=0xffff:
|
||||
return '4d' + int_to_hex(i,2)
|
||||
elif i <= 0xff:
|
||||
return opcodes.OP_PUSHDATA1.hex() + int_to_hex(i, 1)
|
||||
elif i <= 0xffff:
|
||||
return opcodes.OP_PUSHDATA2.hex() + int_to_hex(i, 2)
|
||||
else:
|
||||
return '4e' + int_to_hex(i,4)
|
||||
return opcodes.OP_PUSHDATA4.hex() + int_to_hex(i, 4)
|
||||
|
||||
|
||||
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
|
||||
"""
|
||||
data = bfh(data)
|
||||
from .transaction import opcodes
|
||||
|
||||
data_len = len(data)
|
||||
|
||||
# "small integer" opcodes
|
||||
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:
|
||||
return bh2u(bytes([opcodes.OP_1 - 1 + data[0]]))
|
||||
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:
|
||||
@@ -305,19 +445,18 @@ def address_to_script(addr: str, *, net=None) -> str:
|
||||
if witprog is not None:
|
||||
if not (0 <= witver <= 16):
|
||||
raise BitcoinException(f'impossible witness version: {witver}')
|
||||
OP_n = witver + 0x50 if witver > 0 else 0
|
||||
script = bh2u(bytes([OP_n]))
|
||||
script = bh2u(add_number_to_script(witver))
|
||||
script += push_script(bh2u(bytes(witprog)))
|
||||
return script
|
||||
addrtype, hash_160_ = b58_address_to_hash160(addr)
|
||||
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 += '88ac' # op_equalverify, op_checksig
|
||||
script += bytes([opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG]).hex()
|
||||
elif addrtype == net.ADDRTYPE_P2SH:
|
||||
script = 'a9' # op_hash_160
|
||||
script = opcodes.OP_HASH160.hex()
|
||||
script += push_script(bh2u(hash_160_))
|
||||
script += '87' # op_equal
|
||||
script += opcodes.OP_EQUAL.hex()
|
||||
else:
|
||||
raise BitcoinException(f'unknown address type: {addrtype}')
|
||||
return script
|
||||
@@ -331,9 +470,7 @@ def script_to_scripthash(script: str) -> str:
|
||||
return bh2u(bytes(reversed(h)))
|
||||
|
||||
def public_key_to_p2pk_script(pubkey: str) -> str:
|
||||
script = push_script(pubkey)
|
||||
script += 'ac' # op_checksig
|
||||
return script
|
||||
return push_script(pubkey) + opcodes.OP_CHECKSIG.hex()
|
||||
|
||||
__b58chars = b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
||||
assert len(__b58chars) == 58
|
||||
|
||||
Reference in New Issue
Block a user