def test_verify_scenario_2():
    context = scryptlib.utils.create_dummy_input_context()
    context.utxo.script_pubkey = escrow.locking_script
    context.utxo.value = input_sats

    change_out = TxOutput(int(input_sats - fee),
                          P2PKH_Address(pkh_A, Bitcoin).to_script())
    context.tx.outputs.append(change_out)

    sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID)
    sighash = context.tx.signature_hash(0, input_sats, escrow.locking_script,
                                        sighash_flag)

    sig_A = key_priv_A.sign(sighash, hasher=None)
    sig_A = sig_A + pack_byte(sighash_flag)

    sig_E = key_priv_E.sign(sighash, hasher=None)
    sig_E = sig_E + pack_byte(sighash_flag)

    preimage = scryptlib.utils.get_preimage_from_input_context(
        context, sighash_flag)

    verify_result = escrow.unlock(SigHashPreimage(preimage), PubKey(key_pub_A),
                                  Sig(sig_A), PubKey(key_pub_E), Sig(sig_E),
                                  Bytes(secret0)).verify(context)
    assert verify_result == True

    # Wrong secret
    with pytest.raises(bitcoinx.VerifyFailed):
        verify_result = escrow.unlock(SigHashPreimage(preimage),
                                      PubKey(key_pub_A), Sig(sig_A),
                                      PubKey(key_pub_E), Sig(sig_E),
                                      Bytes(secret1)).verify(context)
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_from_WIF_bad_suffix_byte(self, value):
     payload = pack_byte(Bitcoin.WIF_byte) + global_privkey.to_bytes() + pack_byte(value)
     WIF = base58_encode_check(payload)
     if value == 0x01:
         PrivateKey.from_WIF(WIF)
     else:
         with pytest.raises(ValueError):
             PrivateKey.from_WIF(WIF)
Ejemplo n.º 4
0
 def test_from_template(self, threshold, count):
     good_output = P2MultiSig_Output(MS_PUBKEYS[:count], threshold)
     public_keys = [public_key.to_bytes() for public_key in MS_PUBKEYS[:count]]
     output = P2MultiSig_Output.from_template(pack_byte(threshold), *public_keys,
                                              pack_byte(count))
     assert list(output.public_keys) == MS_PUBKEYS[:count]
     assert output.threshold == threshold
     assert output == good_output
Ejemplo n.º 5
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.º 6
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.º 7
0
 def test_from_template_bad(self):
     public_keys = [
         PrivateKey.from_random().public_key.to_bytes() for n in range(2)
     ]
     with pytest.raises(ValueError):
         script = P2MultiSig_Output.from_template(pack_byte(1),
                                                  *public_keys,
                                                  pack_byte(1))
     with pytest.raises(ValueError):
         script = P2MultiSig_Output.from_template(pack_byte(1),
                                                  *public_keys,
                                                  pack_byte(3))
Ejemplo n.º 8
0
def get_push_item(item_bytes):
    '''
    Returns script bytes to push item on the stack. ALL data is length prefixed.
    '''
    dlen = len(item_bytes)
    if dlen < Ops.OP_PUSHDATA1:
        return pack_byte(dlen) + item_bytes
    elif dlen <= 0xff:
        return pack_byte(Ops.OP_PUSHDATA1) + pack_byte(dlen) + item_bytes
    elif dlen <= 0xffff:
        return pack_byte(Ops.OP_PUSHDATA2) + pack_le_uint16(dlen) + item_bytes
    return pack_byte(Ops.OP_PUSHDATA4) + pack_le_uint32(dlen) + item_bytes
Ejemplo n.º 9
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.º 10
0
def get_push_int(value):
    '''Returns script bytes to push a numerical value to the stack.  Stack values are stored as
    signed-magnitude little-endian numbers.
    '''
    if value == 0:
        return b'\x01\x00'
    item = int_to_le_bytes(abs(value))
    if item[-1] & 0x80:
        item += pack_byte(0x80 if value < 0 else 0x00)
    elif value < 0:
        item = item[:-1] + pack_byte(item[-1] | 0x80)

    return get_push_item(item)
Ejemplo n.º 11
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.º 12
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)
    def test_issue(priv_key,
                   receiver,
                   new_issuer=issuer,
                   next_tok_id=curr_token_id + 1,
                   issued_tok_id=curr_token_id):
        context = scryptlib.utils.create_dummy_input_context()
        context.utxo.script_pubkey = token.locking_script
        context.utxo.value = input_sats

        new_data_part = b'\x23' + scryptlib.utils.get_push_int(next_tok_id)[1:] + \
                        new_issuer.to_bytes() + action_issue
        new_locking_script = Script(token.code_part.to_bytes() + new_data_part)
        tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script)
        context.tx.outputs.append(tx_out)

        new_data_part = b'\x23' + scryptlib.utils.get_push_int(issued_tok_id)[1:] + \
                        receiver.to_bytes() + action_transfer
        new_locking_script = Script(token.code_part.to_bytes() + new_data_part)
        tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script)
        context.tx.outputs.append(tx_out)

        sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID)
        sighash = context.tx.signature_hash(0, input_sats,
                                            token.locking_script, sighash_flag)
        sig = priv_key.sign(sighash, hasher=None)
        sig = sig + pack_byte(sighash_flag)

        preimage = scryptlib.utils.get_preimage_from_input_context(
            context, sighash_flag)

        return token.issue(Sig(sig), PubKey(receiver), out_sats, out_sats,
                           SigHashPreimage(preimage)).verify(context)
Ejemplo n.º 14
0
 def test_der_signature(self):
     s = Signature(MISSING_SIG_BYTES)
     with pytest.raises(InvalidSignatureError):
         s.der_signature
     der_sig = serialization_testcases[0][0]
     s = Signature(der_sig + pack_byte(0x41))
     assert s.der_signature == der_sig
Ejemplo n.º 15
0
    def test_finish(key_priv, pkh_B, action_A, action_B, total_sats,
                    input_sats, out_sats, change_sats):
        rps.set_data_part(player_A_data + pkh_B +
                          scryptlib.utils.get_push_int(action_B)[1:])

        context = scryptlib.utils.create_dummy_input_context()
        context.utxo.script_pubkey = rps.locking_script
        context.utxo.value = total_sats

        change_out = TxOutput(change_sats,
                              P2PKH_Address(pkh_A, Bitcoin).to_script())
        context.tx.outputs.append(change_out)

        if out_sats > 0:
            pay_out = TxOutput(out_sats,
                               P2PKH_Address(pkh_B, Bitcoin).to_script())
            context.tx.outputs.append(pay_out)

        preimage = scryptlib.utils.get_preimage_from_input_context(
            context, sighash_flag)

        input_idx = 0
        utxo_satoshis = context.utxo.value
        sighash = context.tx.signature_hash(input_idx, utxo_satoshis,
                                            rps.locking_script, sighash_flag)
        sig = key_priv.sign(sighash, hasher=None)
        sig = sig + pack_byte(sighash_flag)

        return rps.finish(SigHashPreimage(preimage), action_A, Sig(sig),
                          PubKey(key_pub_A), change_sats).verify(context)
def test_verify_wrong_key():
    MultiSig = scryptlib.contract.build_contract_class(desc)
    multisig = MultiSig([Ripemd160(pkh_0), Ripemd160(pkh_1), Ripemd160(pkh_2)])

    context = scryptlib.utils.create_dummy_input_context()
    sighash = context.tx.signature_hash(input_idx, context.utxo.value,
                                        multisig.locking_script, sighash_flag)

    sig_0 = key_priv_0.sign(sighash, hasher=None) + pack_byte(sighash_flag)
    sig_1 = key_priv_1.sign(sighash, hasher=None) + pack_byte(sighash_flag)
    sig_2 = key_priv_1.sign(sighash, hasher=None) + pack_byte(sighash_flag)

    with pytest.raises(bitcoinx.NullFailError):
        verify_result = multisig.unlock(
            [PubKey(key_pub_0),
             PubKey(key_pub_2),
             PubKey(key_pub_2)],
            [Sig(sig_0), Sig(sig_1), Sig(sig_2)]).verify(context)
Ejemplo n.º 17
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}")
Ejemplo n.º 18
0
def test_verify_p2pkh_correct():
    context = scryptlib.utils.create_dummy_input_context()
    sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID)
    sighash = context.tx.signature_hash(0, context.utxo.value,
                                        asm.locking_script, sighash_flag)
    sig = key_priv.sign(sighash, hasher=None)
    sig = sig + pack_byte(sighash_flag)
    verify_result = asm.p2pkh(Sig(sig), PubKey(key_pub)).verify(context)
    assert verify_result == True
def test_verify_correct():
    MultiSig = scryptlib.contract.build_contract_class(desc)
    multisig = MultiSig([Ripemd160(pkh_0), Ripemd160(pkh_1), Ripemd160(pkh_2)])

    context = scryptlib.utils.create_dummy_input_context()
    sighash = context.tx.signature_hash(input_idx, context.utxo.value,
                                        multisig.locking_script, sighash_flag)

    sig_0 = key_priv_0.sign(sighash, hasher=None) + pack_byte(sighash_flag)
    sig_1 = key_priv_1.sign(sighash, hasher=None) + pack_byte(sighash_flag)
    sig_2 = key_priv_2.sign(sighash, hasher=None) + pack_byte(sighash_flag)

    verify_result = multisig.unlock(
        [PubKey(key_pub_0),
         PubKey(key_pub_1),
         PubKey(key_pub_2)],
        [Sig(sig_0), Sig(sig_1), Sig(sig_2)]).verify(context)
    assert verify_result == True
Ejemplo n.º 20
0
def increment_counter(counter_obj, prev_txid, prev_out_idx, funding_txid,
                      funding_out_idx, unlock_key_priv, miner_fee):
    # Get data from previous counter tx
    r = requests.get('https://api.whatsonchain.com/v1/bsv/main/tx/{}'.format(
        prev_txid)).json()
    prev_locking_script = Script.from_hex(
        r['vout'][prev_out_idx]['scriptPubKey']['hex'])
    prev_counter_bytes = list(prev_locking_script.ops())[-1]
    prev_counter_val = int.from_bytes(prev_counter_bytes, 'little')
    unlocked_satoshis_counter = int(r['vout'][prev_out_idx]['value'] * 10**8)

    # Get data from funding tx
    r = requests.get('https://api.whatsonchain.com/v1/bsv/main/tx/{}'.format(
        funding_txid)).json()
    funding_locking_script = Script.from_hex(
        r['vout'][funding_out_idx]['scriptPubKey']['hex'])
    unlocked_satoshis_funding = int(r['vout'][funding_out_idx]['value'] *
                                    10**8)

    # Set data for next iteration
    counter_obj.set_data_part(
        scryptlib.utils.get_push_int(prev_counter_val + 1))

    ## Construct tx
    n_sequence = 0xffffffff

    # Counter input and output
    prev_tx_hash = hex_str_to_hash(prev_txid)
    counter_in = TxInput(prev_tx_hash, prev_out_idx, None, n_sequence)
    out_satoshis = unlocked_satoshis_counter + unlocked_satoshis_funding - miner_fee
    contract_out = TxOutput(out_satoshis, counter_obj.locking_script)

    # Funding input
    funding_tx_hash = hex_str_to_hash(funding_txid)
    funding_in = TxInput(funding_tx_hash, funding_out_idx, None, n_sequence)

    tx = Tx(2, [counter_in, funding_in], [contract_out], 0x00000000)

    # Set input script to unlock previous counter
    sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID)
    preimage = scryptlib.utils.get_preimage(tx, 0, unlocked_satoshis_counter,
                                            prev_locking_script, sighash_flag)
    increment_func_call = counter_obj.increment(SigHashPreimage(preimage),
                                                Int(out_satoshis))
    tx.inputs[0].script_sig = increment_func_call.script

    # Set input script to unlock funding output
    unlock_key_pub = unlock_key_priv.public_key
    sighash = tx.signature_hash(1, unlocked_satoshis_funding,
                                funding_locking_script, sighash_flag)
    sig = unlock_key_priv.sign(sighash, hasher=None)
    sig = sig + pack_byte(sighash_flag)
    unlock_script = Script() << sig << unlock_key_pub.to_bytes()
    tx.inputs[1].script_sig = unlock_script

    broadcast_tx(tx)
Ejemplo n.º 21
0
def encode_state_len(len_int, size_bytes):
    len_bytes = pack_byte(len_int)
    size_diff = size_bytes - len(len_bytes)

    if size_diff < 0:
        raise Exception(
            'Size of encoding too small for passed state length. Needs at least {} additional bytes.'
            .fromat(size_diff * -1))

    return len_bytes[::-1] + b'\x00' * size_diff
Ejemplo n.º 22
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.º 23
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.º 24
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.º 25
0
    def test_merge(input_idx, balance0, balance1):
        context = scryptlib.utils.create_dummy_input_context()
        context.utxo.value = in_sats
        context.input_index = input_idx

        tx_in = TxInput(context.tx.inputs[0].prev_hash, 1, Script(), 0xffffffff)
        context.tx.inputs.append(tx_in)

        prev_txid = context.tx.inputs[0].prev_hash
        prevouts = prev_txid + b'\x00\x00\x00\x00' + prev_txid + b'\x01\x00\x00\x00'

        new_locking_script = Script(token.code_part.to_bytes() + b'\x23' +
                key_pub_2.to_bytes() + scryptlib.utils.get_push_int(balance0)[1:] + scryptlib.utils.get_push_int(balance1)[1:])
        tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script)
        context.tx.outputs.append(tx_out)

        if input_idx == 0:
            balance = balance1
            context.utxo.script_pubkey = locking_script_0
            key_to_sign = key_priv_0
            token.set_data_part(b'\x23' + data_part_0)
        else:
            balance = balance0
            context.utxo.script_pubkey = locking_script_1
            key_to_sign = key_priv_1
            token.set_data_part(b'\x23' + data_part_1)

        sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID)
        #preimage = scryptlib.utils.get_preimage_from_input_context(context, sighash_flag)
        if input_idx == 0:
            preimage = scryptlib.utils.get_preimage(context.tx, input_idx, in_sats, locking_script_0, sighash_flag=sighash_flag)
        else:
            preimage = scryptlib.utils.get_preimage(context.tx, input_idx, in_sats, locking_script_1, sighash_flag=sighash_flag)

        if input_idx == 0:
            sighash = context.tx.signature_hash(input_idx, in_sats, locking_script_0, sighash_flag)
        else:
            sighash = context.tx.signature_hash(input_idx, in_sats, locking_script_1, sighash_flag)
        sig = key_to_sign.sign(sighash, hasher=None)
        sig = sig + pack_byte(sighash_flag)


        return token.merge(
                    Sig(sig),
                    PubKey(key_pub_2),
                    Bytes(prevouts),
                    balance,
                    out_sats,
                    SigHashPreimage(preimage)
                ).verify(context)
Ejemplo n.º 26
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.º 27
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.º 28
0
    def test_unknown(self):
        # Modified final pubkey byte; not a curve point
        script_hex = '210363f75554e05e05a04551e59d78d78965ec6789f42199f7cbaa9fa4bd2df0a4b3ac'
        s = Script.from_hex(script_hex)
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, Unknown_Output)

        # Truncated script
        script_hex = '210363f7'
        s = Script.from_hex(script_hex)
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, Unknown_Output)

        # Unknown script
        script_hex = pack_byte(OP_1).hex()
        s = Script.from_hex(script_hex)
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, Unknown_Output)
Ejemplo n.º 29
0
 def to_public_key(self) -> Union[BIP32PublicKey, PublicKey]:
     '''Returns a PublicKey instance or an Address instance.'''
     kind = self.kind()
     if self._pubkey_bytes is not None:
         return PublicKey.from_bytes(self._pubkey_bytes)
     elif self._bip32_xpub is not None:
         assert self._derivation_path is not None
         result = bip32_key_from_string(self._bip32_xpub)
         for n in self._derivation_path:
             result = result.child(n)
         return result
     elif self._old_mpk is not None:
         assert self._derivation_path is not None
         path = self._derivation_path
         pubkey = PublicKey.from_bytes(pack_byte(4) + self._old_mpk)
         # pylint: disable=unsubscriptable-object
         delta = double_sha256(f'{path[1]}:{path[0]}:'.encode() + self._old_mpk)
         return pubkey.add(delta)
     raise ValueError("invalid key data")
Ejemplo n.º 30
0
    def test_split(key_priv, balance0, balance1, balance_input0=None, balance_input1=None):
        if not balance_input0:
            balance_input0 = balance0
        if not balance_input1:
            balance_input1 = balance1

        context = scryptlib.utils.create_dummy_input_context()
        context.utxo.script_pubkey = token.locking_script
        context.utxo.value = in_sats
            
        new_locking_script = Script(token.code_part.to_bytes() + b'\x23' +
                key_pub_1.to_bytes() + b'\x00' + scryptlib.utils.get_push_int(balance0)[1:])
        tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script)
        context.tx.outputs.append(tx_out)

        if balance1 > 0:
            new_locking_script = Script(token.code_part.to_bytes() + b'\x23' + 
                    key_pub_2.to_bytes() + b'\x00' + scryptlib.utils.get_push_int(balance1)[1:])
            tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script)
            context.tx.outputs.append(tx_out)

        sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID)
        preimage = scryptlib.utils.get_preimage_from_input_context(context, sighash_flag)

        input_idx = 0
        utxo_satoshis = context.utxo.value
        sighash = context.tx.signature_hash(input_idx, utxo_satoshis, token.locking_script, sighash_flag)
        sig = key_priv.sign(sighash, hasher=None)
        sig = sig + pack_byte(sighash_flag)

        return token.split(
                    Sig(sig),
                    PubKey(key_pub_1),
                    balance_input0,
                    out_sats,
                    PubKey(key_pub_2),
                    balance_input1,
                    out_sats,
                    SigHashPreimage(preimage)
                ).verify(context)