aboutsummaryrefslogtreecommitdiff
path: root/qa/rpc-tests/test_framework/script.py
diff options
context:
space:
mode:
Diffstat (limited to 'qa/rpc-tests/test_framework/script.py')
-rw-r--r--qa/rpc-tests/test_framework/script.py91
1 files changed, 71 insertions, 20 deletions
diff --git a/qa/rpc-tests/test_framework/script.py b/qa/rpc-tests/test_framework/script.py
index e37ab5d45..83bbf2047 100644
--- a/qa/rpc-tests/test_framework/script.py
+++ b/qa/rpc-tests/test_framework/script.py
@@ -1,20 +1,23 @@
+#!/usr/bin/env python3
+# Copyright (c) 2015-2016 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
#
# script.py
#
# This file is modified from python-bitcoinlib.
#
-# Distributed under the MIT/X11 software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#
"""Scripts
Functionality to build scripts, as well as SignatureHash().
"""
-from __future__ import absolute_import, division, print_function, unicode_literals
-from test_framework.mininode import CTransaction, CTxOut, hash256
+from .mininode import CTransaction, CTxOut, sha256, hash256, uint256_from_str, ser_uint256, ser_string
+from binascii import hexlify
+import hashlib
import sys
bchr = chr
@@ -24,10 +27,9 @@ if sys.version > '3':
bchr = lambda x: bytes([x])
bord = lambda x: x
-import copy
import struct
-import test_framework.bignum
+from .bignum import bn2vch
MAX_SCRIPT_SIZE = 10000
MAX_SCRIPT_ELEMENT_SIZE = 520
@@ -35,6 +37,10 @@ MAX_SCRIPT_OPCODES = 201
OPCODE_NAMES = {}
+def hash160(s):
+ return hashlib.new('ripemd160', sha256(s)).digest()
+
+
_opcode_instances = []
class CScriptOp(int):
"""A single script opcode"""
@@ -226,8 +232,8 @@ OP_CHECKMULTISIGVERIFY = CScriptOp(0xaf)
# expansion
OP_NOP1 = CScriptOp(0xb0)
-OP_NOP2 = CScriptOp(0xb1)
-OP_NOP3 = CScriptOp(0xb2)
+OP_CHECKLOCKTIMEVERIFY = CScriptOp(0xb1)
+OP_CHECKSEQUENCEVERIFY = CScriptOp(0xb2)
OP_NOP4 = CScriptOp(0xb3)
OP_NOP5 = CScriptOp(0xb4)
OP_NOP6 = CScriptOp(0xb5)
@@ -353,8 +359,8 @@ VALID_OPCODES = {
OP_CHECKMULTISIGVERIFY,
OP_NOP1,
- OP_NOP2,
- OP_NOP3,
+ OP_CHECKLOCKTIMEVERIFY,
+ OP_CHECKSEQUENCEVERIFY,
OP_NOP4,
OP_NOP5,
OP_NOP6,
@@ -472,8 +478,8 @@ OPCODE_NAMES.update({
OP_CHECKMULTISIG : 'OP_CHECKMULTISIG',
OP_CHECKMULTISIGVERIFY : 'OP_CHECKMULTISIGVERIFY',
OP_NOP1 : 'OP_NOP1',
- OP_NOP2 : 'OP_NOP2',
- OP_NOP3 : 'OP_NOP3',
+ OP_CHECKLOCKTIMEVERIFY : 'OP_CHECKLOCKTIMEVERIFY',
+ OP_CHECKSEQUENCEVERIFY : 'OP_CHECKSEQUENCEVERIFY',
OP_NOP4 : 'OP_NOP4',
OP_NOP5 : 'OP_NOP5',
OP_NOP6 : 'OP_NOP6',
@@ -591,8 +597,8 @@ OPCODES_BY_NAME = {
'OP_CHECKMULTISIG' : OP_CHECKMULTISIG,
'OP_CHECKMULTISIGVERIFY' : OP_CHECKMULTISIGVERIFY,
'OP_NOP1' : OP_NOP1,
- 'OP_NOP2' : OP_NOP2,
- 'OP_NOP3' : OP_NOP3,
+ 'OP_CHECKLOCKTIMEVERIFY' : OP_CHECKLOCKTIMEVERIFY,
+ 'OP_CHECKSEQUENCEVERIFY' : OP_CHECKSEQUENCEVERIFY,
'OP_NOP4' : OP_NOP4,
'OP_NOP5' : OP_NOP5,
'OP_NOP6' : OP_NOP6,
@@ -629,7 +635,7 @@ class CScriptNum(object):
neg = obj.value < 0
absvalue = -obj.value if neg else obj.value
while (absvalue):
- r.append(chr(absvalue & 0xff))
+ r.append(absvalue & 0xff)
absvalue >>= 8
if r[-1] & 0x80:
r.append(0x80 if neg else 0)
@@ -658,13 +664,13 @@ class CScript(bytes):
other = bchr(CScriptOp(OP_0))
else:
other = CScriptNum.encode(other)
- elif isinstance(other, (int, long)):
+ elif isinstance(other, int):
if 0 <= other <= 16:
other = bytes(bchr(CScriptOp.encode_op_n(other)))
elif other == -1:
other = bytes(bchr(OP_1NEGATE))
else:
- other = CScriptOp.encode_op_pushdata(bignum.bn2vch(other))
+ other = CScriptOp.encode_op_pushdata(bn2vch(other))
elif isinstance(other, (bytes, bytearray)):
other = CScriptOp.encode_op_pushdata(other)
return other
@@ -777,7 +783,7 @@ class CScript(bytes):
# need to change
def _repr(o):
if isinstance(o, bytes):
- return "x('%s')" % binascii.hexlify(o).decode('utf8')
+ return b"x('%s')" % hexlify(o).decode('ascii')
else:
return repr(o)
@@ -876,7 +882,7 @@ def SignatureHash(script, txTo, inIdx, hashtype):
tmp = txtmp.vout[outIdx]
txtmp.vout = []
for i in range(outIdx):
- txtmp.vout.append(CTxOut())
+ txtmp.vout.append(CTxOut(-1))
txtmp.vout.append(tmp)
for i in range(len(txtmp.vin)):
@@ -894,3 +900,48 @@ def SignatureHash(script, txTo, inIdx, hashtype):
hash = hash256(s)
return (hash, None)
+
+# TODO: Allow cached hashPrevouts/hashSequence/hashOutputs to be provided.
+# Performance optimization probably not necessary for python tests, however.
+# Note that this corresponds to sigversion == 1 in EvalScript, which is used
+# for version 0 witnesses.
+def SegwitVersion1SignatureHash(script, txTo, inIdx, hashtype, amount):
+
+ hashPrevouts = 0
+ hashSequence = 0
+ hashOutputs = 0
+
+ if not (hashtype & SIGHASH_ANYONECANPAY):
+ serialize_prevouts = bytes()
+ for i in txTo.vin:
+ serialize_prevouts += i.prevout.serialize()
+ hashPrevouts = uint256_from_str(hash256(serialize_prevouts))
+
+ if (not (hashtype & SIGHASH_ANYONECANPAY) and (hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE):
+ serialize_sequence = bytes()
+ for i in txTo.vin:
+ serialize_sequence += struct.pack("<I", i.nSequence)
+ hashSequence = uint256_from_str(hash256(serialize_sequence))
+
+ if ((hashtype & 0x1f) != SIGHASH_SINGLE and (hashtype & 0x1f) != SIGHASH_NONE):
+ serialize_outputs = bytes()
+ for o in txTo.vout:
+ serialize_outputs += o.serialize()
+ hashOutputs = uint256_from_str(hash256(serialize_outputs))
+ elif ((hashtype & 0x1f) == SIGHASH_SINGLE and inIdx < len(txTo.vout)):
+ serialize_outputs = txTo.vout[inIdx].serialize()
+ hashOutputs = uint256_from_str(hash256(serialize_outputs))
+
+ ss = bytes()
+ ss += struct.pack("<i", txTo.nVersion)
+ ss += ser_uint256(hashPrevouts)
+ ss += ser_uint256(hashSequence)
+ ss += txTo.vin[inIdx].prevout.serialize()
+ ss += ser_string(script)
+ ss += struct.pack("<q", amount)
+ ss += struct.pack("<I", txTo.vin[inIdx].nSequence)
+ ss += ser_uint256(hashOutputs)
+ ss += struct.pack("<i", txTo.nLockTime)
+ ss += struct.pack("<I", hashtype)
+
+ return hash256(ss)