Changeset View
Changeset View
Standalone View
Standalone View
test/functional/test_framework/script.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2015-2019 The Bitcoin Core developers | # Copyright (c) 2015-2019 The Bitcoin Core developers | ||||
# Distributed under the MIT software license, see the accompanying | # Distributed under the MIT software license, see the accompanying | ||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
"""Functionality to build scripts, as well as SignatureHash(). | """Functionality to build scripts, as well as SignatureHash(). | ||||
This file is modified from python-bitcoinlib. | This file is modified from python-bitcoinlib. | ||||
""" | """ | ||||
from .bignum import bn2vch | |||||
import hashlib | import hashlib | ||||
import struct | import struct | ||||
from .messages import ( | from .messages import ( | ||||
CTransaction, | CTransaction, | ||||
CTxOut, | CTxOut, | ||||
hash256, | hash256, | ||||
ser_string, | ser_string, | ||||
ser_uint256, | ser_uint256, | ||||
sha256, | sha256, | ||||
uint256_from_str, | uint256_from_str, | ||||
) | ) | ||||
MAX_SCRIPT_ELEMENT_SIZE = 520 | MAX_SCRIPT_ELEMENT_SIZE = 520 | ||||
OPCODE_NAMES = {} | OPCODE_NAMES = {} | ||||
def hash160(s): | def hash160(s): | ||||
return hashlib.new('ripemd160', sha256(s)).digest() | return hashlib.new('ripemd160', sha256(s)).digest() | ||||
def bn2vch(v): | |||||
"""Convert number to bitcoin-specific little endian format.""" | |||||
# We need v.bit_length() bits, plus a sign bit for every nonzero number. | |||||
n_bits = v.bit_length() + (v != 0) | |||||
# The number of bytes for that is: | |||||
n_bytes = (n_bits + 7) // 8 | |||||
# Convert number to absolute value + sign in top bit. | |||||
encoded_v = 0 if v == 0 else abs(v) | ((v < 0) << (n_bytes * 8 - 1)) | |||||
# Serialize to bytes | |||||
return encoded_v.to_bytes(n_bytes, 'little') | |||||
_opcode_instances = [] | _opcode_instances = [] | ||||
class CScriptOp(int): | class CScriptOp(int): | ||||
"""A single script opcode""" | """A single script opcode""" | ||||
__slots__ = () | __slots__ = () | ||||
@staticmethod | @staticmethod | ||||
def encode_op_pushdata(d): | def encode_op_pushdata(d): | ||||
"""Encode a PUSHDATA op, returning bytes""" | """Encode a PUSHDATA op, returning bytes""" | ||||
if len(d) < 0x4c: | if len(d) < 0x4c: | ||||
# OP_PUSHDATA | # OP_PUSHDATA | ||||
return b'' + bytes([len(d)]) + d | return b'' + bytes([len(d)]) + d | ||||
elif len(d) <= 0xff: | elif len(d) <= 0xff: | ||||
# OP_PUSHDATA1 | # OP_PUSHDATA1 | ||||
return b'\x4c' + bytes([len(d)]) + d | return b'\x4c' + bytes([len(d)]) + d | ||||
elif len(d) <= 0xffff: | elif len(d) <= 0xffff: | ||||
return b'\x4d' + struct.pack(b'<H', len(d)) + d # OP_PUSHDATA2 | # OP_PUSHDATA2 | ||||
return b'\x4d' + struct.pack(b'<H', len(d)) + d | |||||
elif len(d) <= 0xffffffff: | elif len(d) <= 0xffffffff: | ||||
return b'\x4e' + struct.pack(b'<I', len(d)) + d # OP_PUSHDATA4 | # OP_PUSHDATA4 | ||||
return b'\x4e' + struct.pack(b'<I', len(d)) + d | |||||
else: | else: | ||||
raise ValueError("Data too long to encode in a PUSHDATA op") | raise ValueError("Data too long to encode in a PUSHDATA op") | ||||
@staticmethod | @staticmethod | ||||
def encode_op_n(n): | def encode_op_n(n): | ||||
"""Encode a small integer op, returning an opcode""" | """Encode a small integer op, returning an opcode""" | ||||
if not (0 <= n <= 16): | if not (0 <= n <= 16): | ||||
raise ValueError( | raise ValueError( | ||||
▲ Show 20 Lines • Show All 687 Lines • Show Last 20 Lines |