Ejemplo n.º 1
0
 def _realize_script_sig(self, x_pubkeys, signatures):
     type_ = self.type()
     if type_ == 'p2pk':
         return Script(push_item(signatures[0]))
     if type_ == 'p2pkh':
         return Script(push_item(signatures[0]) + push_item(x_pubkeys[0].to_bytes()))
     if type_ == 'p2sh':
         parts = [pack_byte(Ops.OP_0)]
         parts.extend(push_item(signature) for signature in signatures)
         nested_script = multisig_script(x_pubkeys, self.threshold)
         parts.append(push_item(nested_script))
         return Script(b''.join(parts))
     return self.script_sig
Ejemplo n.º 2
0
def create_script_sig(script_type: ScriptType, threshold: int,
                      x_pubkeys: List[XPublicKey],
                      signatures: List[bytes]) -> Script:
    if script_type == ScriptType.P2PK:
        return Script(push_item(signatures[0]))
    elif script_type == ScriptType.P2PKH:
        return Script(
            push_item(signatures[0]) + push_item(x_pubkeys[0].to_bytes()))
    elif script_type == ScriptType.MULTISIG_P2SH:
        parts = [pack_byte(Ops.OP_0)]
        parts.extend(push_item(signature) for signature in signatures)
        nested_script = multisig_script(x_pubkeys, threshold)
        parts.append(push_item(nested_script))
        return Script(b''.join(parts))
    elif script_type == ScriptType.MULTISIG_BARE:
        parts = [pack_byte(Ops.OP_0)]
        parts.extend(push_item(signature) for signature in signatures)
        return Script(b''.join(parts))
    elif script_type == ScriptType.MULTISIG_ACCUMULATOR:
        parts = []
        for i, signature in enumerate(signatures):
            if signature == NO_SIGNATURE:
                parts.append([pack_byte(Ops.OP_FALSE)])
            else:
                parts.append([
                    push_item(signature),
                    push_item(x_pubkeys[i].to_bytes()),
                    pack_byte(Ops.OP_TRUE),
                ])
        parts.reverse()
        return Script(b''.join([value for l in parts for value in l]))
    raise ValueError(f"unable to realize script {script_type}")
Ejemplo n.º 3
0
    def test_P2PK(self):
        script_hex = '210363f75554e05e05a04551e59d78d78965ec6789f42199f7cbaa9fa4bd2df0a4b4ac'
        s = Script.from_hex(script_hex)
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, P2PK_Output)
        assert (sc.public_key.to_hex() ==
                '0363f75554e05e05a04551e59d78d78965ec6789f42199f7cbaa9fa4bd2df0a4b4')

        suffix = push_item(b'foo') + push_item(b'bar') + pack_byte(OP_2DROP)
        s2 = Script.from_hex(script_hex + suffix.hex())
        sc2 = classify_output_script(s2, Bitcoin)
        assert sc2.public_key == sc.public_key
        assert s2 != s
        assert isinstance(sc2, P2PK_Output)
Ejemplo n.º 4
0
 def test_to_script_bytes(self):
     pubkey_hex = '0363f75554e05e05a04551e59d78d78965ec6789f42199f7cbaa9fa4bd2df0a4b4'
     pubkey = PublicKey.from_hex(pubkey_hex)
     output = P2PK_Output(pubkey, Bitcoin)
     raw = output.to_script_bytes()
     assert isinstance(raw, bytes)
     assert raw == push_item(bytes.fromhex(pubkey_hex)) + pack_byte(OP_CHECKSIG)
Ejemplo n.º 5
0
 def to_script_bytes(self):
     parts = [
         pack_byte(Ops.OP_0),
         pack_byte(Ops.OP_TOALTSTACK),
     ]
     for public_key in self.public_keys:
         parts.extend([
             pack_byte(Ops.OP_IF),
             pack_byte(Ops.OP_DUP),
             pack_byte(Ops.OP_HASH160),
             push_item(public_key.hash160()),
             pack_byte(Ops.OP_EQUALVERIFY),
             pack_byte(Ops.OP_CHECKSIGVERIFY),
             pack_byte(Ops.OP_FROMALTSTACK),
             pack_byte(Ops.OP_1ADD),
             pack_byte(Ops.OP_TOALTSTACK),
             pack_byte(Ops.OP_ENDIF),
         ])
     parts.extend([
         # Is this the right order?
         pack_byte(Ops.OP_FROMALTSTACK),
         push_int(self.threshold),
         pack_byte(Ops.OP_GREATERTHANOREQUAL),
     ])
     return b''.join(parts)
Ejemplo n.º 6
0
def multisig_script(x_pubkeys: List[XPublicKey], threshold: int) -> bytes:
    '''Returns bytes.

    x_pubkeys is an array of XPulicKey objects or an array of PublicKey objects.
    '''
    assert 1 <= threshold <= len(x_pubkeys)
    parts = [push_int(threshold)]
    parts.extend(push_item(x_pubkey.to_bytes()) for x_pubkey in x_pubkeys)
    parts.append(push_int(len(x_pubkeys)))
    parts.append(pack_byte(Ops.OP_CHECKMULTISIG))
    return b''.join(parts)
Ejemplo n.º 7
0
    def test_P2SH(self):
        script_hex = 'a9143e4501f9f212cb6813b3815edbc7013d6a3f0f1087'
        s = Script.from_hex(script_hex)
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, P2SH_Address)

        suffix = push_item(b'foobar') + pack_byte(OP_DROP) + pack_byte(OP_NOP)
        s2 = Script.from_hex(script_hex + suffix.hex())
        sc2 = classify_output_script(s2, Bitcoin)
        assert s2 != s
        assert isinstance(sc2, P2SH_Address)
Ejemplo n.º 8
0
    def test_P2PKH(self):
        script_hex = '76a914a6dbba870185ab6689f386a40522ae6cb5c7b61a88ac'
        s = Script.from_hex(script_hex)
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, P2PKH_Address)

        prefix = push_item(b'foobar') + pack_byte(OP_DROP) + pack_byte(OP_NOP)
        s2 = Script.from_hex(prefix.hex() + script_hex)
        sc2 = classify_output_script(s2, Bitcoin)
        assert s2 != s
        assert isinstance(sc2, P2PKH_Address)
Ejemplo n.º 9
0
def multisig_script(public_keys, threshold):
    '''public_keys should be sorted hex strings.  P2MultiSig_Ouput is not used as they may be
    derivation rules and not valid public keys.
    '''
    if sorted(public_keys) != public_keys:
        logger.warning('public keys are not sorted')
    assert 1 <= threshold <= len(public_keys)
    parts = [push_int(threshold)]
    parts.extend(
        push_item(bytes.fromhex(public_key)) for public_key in public_keys)
    parts.append(push_int(len(public_keys)))
    parts.append(pack_byte(Ops.OP_CHECKMULTISIG))
    return b''.join(parts).hex()
Ejemplo n.º 10
0
    def test_OP_RETURN(self):
        s = Script(pack_byte(OP_RETURN))
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, OP_RETURN_Output)

        s = Script(pack_byte(OP_RETURN) + push_item(b'BitcoinSV'))
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, OP_RETURN_Output)

        # Truncated OP_RETURN script
        s = Script(pack_byte(OP_RETURN) + pack_byte(1))
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, OP_RETURN_Output)
Ejemplo n.º 11
0
 def test_to_script_bytes(self, threshold, count):
     output = P2MultiSig_Output(MS_PUBKEYS[:count], threshold)
     assert output.public_key_count() == count
     raw = output.to_script_bytes()
     assert isinstance(raw, bytes)
     assert raw == b''.join((
         push_int(threshold),
         b''.join(push_item(public_key.to_bytes()) for public_key in MS_PUBKEYS[:count]),
         push_int(count),
         pack_byte(OP_CHECKMULTISIG),
     ))
     S = output.to_script()
     assert isinstance(S, Script)
     assert S == raw
Ejemplo n.º 12
0
    def _test_op_return(self, old=False):
        prefix = b'' if old else pack_byte(OP_0)

        s = Script(prefix + pack_byte(OP_RETURN))
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, OP_RETURN_Output)

        s = Script(prefix + pack_byte(OP_RETURN) + push_item(b'BitcoinSV'))
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, OP_RETURN_Output)

        # Truncated OP_RETURN script
        s = Script(prefix + pack_byte(OP_RETURN) + pack_byte(1))
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, OP_RETURN_Output)
Ejemplo n.º 13
0
 def _realize_script_sig(self, x_pubkeys: List[XPublicKey],
                         signatures: List[bytes]) -> Script:
     if self.script_type == ScriptType.P2PK:
         return Script(push_item(signatures[0]))
     elif self.script_type == ScriptType.P2PKH:
         return Script(
             push_item(signatures[0]) + push_item(x_pubkeys[0].to_bytes()))
     elif self.script_type == ScriptType.MULTISIG_P2SH:
         parts = [pack_byte(Ops.OP_0)]
         parts.extend(push_item(signature) for signature in signatures)
         nested_script = multisig_script(x_pubkeys, self.threshold)
         parts.append(push_item(nested_script))
         return Script(b''.join(parts))
     elif self.script_type == ScriptType.MULTISIG_BARE:
         parts = [pack_byte(Ops.OP_0)]
         parts.extend(push_item(signature) for signature in signatures)
         return Script(b''.join(parts))
     raise ValueError(f"unable to realize script {self.script_type}")