def t(n: int, op: CScriptOp) -> None: actual_op = CScriptOp.encode_op_n(n) self.assertEqual(actual_op, op) self.assertTrue(isinstance(actual_op, CScriptOp)) actual_int = op.decode_op_n() self.assertEqual(actual_int, n) self.assertTrue(isinstance(actual_int, int))
def test_tokenize_roundtrip(self): def T(serialized_script, expected_tokens, test_roundtrip=True): serialized_script = x(serialized_script) script_obj = CScript(serialized_script) actual_tokens = list(script_obj) self.assertEqual(actual_tokens, expected_tokens) if test_roundtrip: recreated_script = CScript(actual_tokens) self.assertEqual(recreated_script, serialized_script) T('', []) # standard pushdata T('00', [OP_0]) T('0100', [b'\x00']) T('4b' + 'ff'*0x4b, [b'\xff'*0x4b]) # non-optimal pushdata T('4c00', [b''], False) T('4c04deadbeef', [x('deadbeef')], False) T('4d0000', [b''], False) T('4d0400deadbeef', [x('deadbeef')], False) T('4e00000000', [b''], False) T('4e04000000deadbeef', [x('deadbeef')], False) # numbers T('00', [0x0]) T('4f', [OP_1NEGATE]) T('51', [0x1]) T('52', [0x2]) T('53', [0x3]) T('54', [0x4]) T('55', [0x5]) T('56', [0x6]) T('57', [0x7]) T('58', [0x8]) T('59', [0x9]) T('5a', [0xa]) T('5b', [0xb]) T('5c', [0xc]) T('5d', [0xd]) T('5e', [0xe]) T('5f', [0xf]) # some opcodes T('9b', [OP_BOOLOR]) T('9a9b', [OP_BOOLAND, OP_BOOLOR]) T('ff', [OP_INVALIDOPCODE]) T('fafbfcfd', [CScriptOp(0xfa), CScriptOp(0xfb), CScriptOp(0xfc), CScriptOp(0xfd)]) # all three types T('512103e2a0e6a91fa985ce4dda7f048fca5ec8264292aed9290594321aa53d37fdea32410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc345552ae', [1, x('03e2a0e6a91fa985ce4dda7f048fca5ec8264292aed9290594321aa53d37fdea32'), x('0478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455'), 2, OP_CHECKMULTISIG])
def generate_multisig_redeem_list(pubkeys, m): ''' creates m of n multisig redeem script, encoded as a list pubkeys is a list of pubkeys m is the number of signatures required to redeem ''' op_m = CScriptOp.encode_op_n(m) op_n = CScriptOp.encode_op_n(len(pubkeys)) redeem_list = pubkeys redeem_list.insert(0, op_m) redeem_list.append(op_n) redeem_list.append(OP_CHECKMULTISIG) return redeem_list
def test_encode_decode_op_n(self): def t(n, op): actual = CScriptOp.encode_op_n(n) self.assertEqual(actual, op) self.assertTrue(isinstance(actual, CScriptOp)) actual = op.decode_op_n() self.assertEqual(actual, n) self.assertTrue(isinstance(actual, int)) t(0, OP_0) t(1, OP_1) t(2, OP_2) t(3, OP_3) t(4, OP_4) t(5, OP_5) t(6, OP_6) t(7, OP_7) t(8, OP_8) t(9, OP_9) t(9, OP_9) t(10, OP_10) t(11, OP_11) t(12, OP_12) t(13, OP_13) t(14, OP_14) t(15, OP_15) t(16, OP_16) with self.assertRaises(ValueError): OP_CHECKSIG.decode_op_n() with self.assertRaises(ValueError): CScriptOp(1).decode_op_n()
def t(n, op): actual = CScriptOp.encode_op_n(n) self.assertEqual(actual, op) self.assertTrue(isinstance(actual, CScriptOp)) actual = op.decode_op_n() self.assertEqual(actual, n) self.assertTrue(isinstance(actual, int))
class AsimovOpCode: """new opcode added in asimov""" OP_DATA_21 = CScriptOp(21) OP_TEMPLATE = CScriptOp(192) OP_CREATE = CScriptOp(193) OP_CALL = CScriptOp(194) OP_SPEND = CScriptOp(195) OP_IFLAG_EQUAL = CScriptOp(196) OP_IFLAG_EQUALVERIFY = CScriptOp(197) OP_VOTE = CScriptOp(198)
def test_is_singleton(self): self.assertTrue(OP_0 is CScriptOp(0x00)) self.assertTrue(OP_1 is CScriptOp(0x51)) self.assertTrue(OP_16 is CScriptOp(0x60)) self.assertTrue(OP_CHECKSIG is CScriptOp(0xac)) for i in range(0x0, 0x100): self.assertTrue(CScriptOp(i) is CScriptOp(i))
def T(data, expected): data = x(data) expected = x(expected) serialized_data = CScriptOp.encode_op_pushdata(data) self.assertEqual(serialized_data, expected)
def T(data_hex: str, expected_hex: str) -> None: data = x(data_hex) expected = x(expected_hex) serialized_data = CScriptOp.encode_op_pushdata(data) self.assertEqual(serialized_data, expected)
from bitcointx.core.key import CKey, CKeyBase from bitcointx.core.script import ( ScriptCoinClassDispatcher, ScriptCoinClass, CScript, CScriptOp, SIGVERSION_BASE, SIGVERSION_WITNESS_V0, CScriptInvalidError, RawBitcoinSignatureHash, OP_RETURN, SIGHASH_NONE, SIGHASH_SINGLE, SIGHASH_ANYONECANPAY, SIGHASH_Type, SIGVERSION_Type) from bitcointx.core.serialize import BytesSerializer import elementstx.core # We do not register these extra opcodes in script.OPCODE_NAMES # and script.OPCODE_BY_NAME. If we do so, we will pollute these # bitcoin-specific tables with Elements opcodes. Proper way would be # to have CBitcoinScriptOp and CElementsScriptOp, but # this is too heavy for this small issue. These opcodes are useable as-is, # the only proble is that they will be shown as UNKNOWN for repr(script). OP_DETERMINISTICRANDOM = CScriptOp(0xc1) OP_CHECKSIGFROMSTACK = CScriptOp(0xc1) OP_CHECKSIGFROMSTACKVERIFY = CScriptOp(0xc2) class ScriptElementsClassDispatcher(ScriptCoinClassDispatcher): ... class ScriptElementsClass(ScriptCoinClass, metaclass=ScriptElementsClassDispatcher): ... def RawElementsSignatureHash( script: CScript,