Example #1
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}")
    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)
Example #3
0
 def set_data_part(self, state):
     if isinstance(state, bytes):
         self._manual_data_part = Script(state)
     elif isinstance(state, str):
         self._manual_data_part = Script(bytes.fromhex(state))
     elif isinstance(state, dict):
         self._manual_data_part = Script(serializer.serialize_state(state))
     else:
         raise NotImplementedError('Invalid object type for contract data part "{}".'.format(state.__class__))
Example #4
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)
Example #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)
Example #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)
Example #7
0
 def read(cls, read):
     prev_hash = read(32)
     prev_idx = read_le_uint32(read)
     script_sig = Script(read_varbytes(read))
     sequence = read_le_uint32(read)
     kwargs = {'x_pubkeys': [], 'address': None, 'threshold': 0, 'signatures': []}
     if prev_hash != bytes(32):
         _parse_script_sig(script_sig.to_bytes(), kwargs)
     result = cls(prev_hash, prev_idx, script_sig, sequence, value=0, **kwargs)
     if not result.is_complete():
         result.value = read_le_int64(read)
     return result
Example #8
0
 def _get_address_from_script_hex(self, script_hex):
     # NOTE: In theory we could verify the bytes and extract the variable P2PKH hash.
     script_bytes = bytes.fromhex(script_hex)
     script_asm = Script(script_bytes).to_asm()
     tokens = script_asm.split(" ")
     assert len(tokens) == 5
     assert tokens[0] == "OP_DUP"
     assert tokens[1] == "OP_HASH160"
     assert tokens[3] == "OP_EQUALVERIFY"
     assert tokens[4] == "OP_CHECKSIG"
     pkh_hex = tokens[2]
     return address.Address.from_P2PKH_hash(bytes.fromhex(pkh_hex))
Example #9
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
Example #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)
Example #11
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)
def test_verify_withdraw():
    withdraw_sats = 2000000
    fee = 3000
    input_sats = 10000000
    output_sats = input_sats - withdraw_sats - fee
    mature_time = 1627122529

    faucet.set_data_part(scryptlib.utils.get_push_int(mature_time))

    context = scryptlib.utils.create_dummy_input_context()
    context.utxo.script_pubkey = faucet.locking_script
    context.utxo.value = input_sats

    new_locking_script = faucet.code_part << Script(
        scryptlib.utils.get_push_int(mature_time + 300))
    tx_out_0 = TxOutput(value=output_sats, script_pubkey=new_locking_script)
    context.tx.outputs.append(tx_out_0)

    tx_out_1 = TxOutput(value=withdraw_sats,
                        script_pubkey=P2PKH_Address(pkh, Bitcoin).to_script())
    context.tx.outputs.append(tx_out_1)

    context.tx.inputs[0].sequence = 0xfffffffe
    context.tx.locktime = mature_time + 300

    preimage = scryptlib.utils.get_preimage_from_input_context(context)

    verify_result = faucet.withdraw(SigHashPreimage(preimage),
                                    Ripemd160(pkh)).verify(context)
    assert verify_result == True

    # Wrong mature time
    context.tx.outputs = []

    new_locking_script = faucet.code_part << Script(
        scryptlib.utils.get_push_int(mature_time + 299))
    tx_out_0 = TxOutput(value=output_sats, script_pubkey=new_locking_script)
    context.tx.outputs.append(tx_out_0)

    tx_out_1 = TxOutput(value=withdraw_sats,
                        script_pubkey=P2PKH_Address(pkh, Bitcoin).to_script())
    context.tx.outputs.append(tx_out_1)

    context.tx.locktime = mature_time + 299

    preimage = scryptlib.utils.get_preimage_from_input_context(context)

    with pytest.raises(bitcoinx.VerifyFailed):
        faucet.withdraw(SigHashPreimage(preimage),
                        Ripemd160(pkh)).verify(context)
Example #13
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)
Example #14
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)
Example #15
0
    def test_P2MultiSig(self):
        script_hex = ('5221022812701688bc76ef3610b46c8e97f4b385241d5ed6eab6269b8af5f9bfd5a89c210'
                      '3fa0879c543ac97f34daffdaeed808f3500811aa5070e4a1f7e2daed3dd22ef2052ae')
        s = Script.from_hex(script_hex)
        sc = classify_output_script(s, Bitcoin)
        assert isinstance(sc, P2MultiSig_Output)
        assert len(sc.public_keys) == 2
        assert sc.threshold == 2

        # Confirm suffix fails to match
        s = Script.from_hex(script_hex + 'a0')
        assert isinstance(classify_output_script(s, Bitcoin), Unknown_Output)
        # Confirm prefix fails to match
        s = Script.from_hex('a0' + script_hex)
        assert isinstance(classify_output_script(s, Bitcoin), Unknown_Output)
Example #16
0
 def test_eq(self):
     assert Signature(MISSING_SIG_BYTES) == MISSING_SIG_BYTES
     assert Signature(MISSING_SIG_BYTES) == Script(MISSING_SIG_BYTES)
     assert Signature(MISSING_SIG_BYTES) == Signature(MISSING_SIG_BYTES)
     assert Signature(MISSING_SIG_BYTES) == bytearray(MISSING_SIG_BYTES)
     assert Signature(MISSING_SIG_BYTES) == memoryview(MISSING_SIG_BYTES)
     assert Signature(MISSING_SIG_BYTES) != 2.5
Example #17
0
def string_to_bip276_script(text: str) -> Script:
    if text.startswith(PREFIX_BIP276_SCRIPT):
        prefix, version, network, data = bip276_decode(text,
                                                       Net.BIP276_VERSION)
        assert network == Net.BIP276_VERSION, "incompatible network"
        return Script(data)
    raise ValueError("string is not bip276")
Example #18
0
def sale(n_bought, pkh, pub_key):
    context = scryptlib.utils.create_dummy_input_context()
    context.utxo.script_pubkey = ats.locking_script
    context.utxo.value = input_sats

    new_data_part = ats.data_part << pub_key.to_bytes(
    ) + scryptlib.utils.get_push_int(n_bought)[1:]
    new_locking_script = Script(ats.code_part.to_bytes() +
                                new_data_part.to_bytes())

    change_sats = input_sats - n_bought * SATS_PER_TOKEN
    out_sats = input_sats + n_bought * SATS_PER_TOKEN

    # Counter output
    tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script)
    context.tx.outputs.append(tx_out)

    # Change output
    change_out = TxOutput(
        change_sats,
        P2PKH_Address(pub_key.hash160(), Bitcoin).to_script())
    context.tx.outputs.append(change_out)

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

    verify_result = ats.buy(SigHashPreimage(preimage), Ripemd160(pkh),
                            change_sats, Bytes(pub_key.to_bytes()),
                            n_bought).verify(context)
    assert verify_result == True

    return new_data_part
def test_verify_correct():

    # Intial state
    state = {'counter': 11, 'buf': b'\x12\x34', 'flag': True}

    counter.set_data_part(state)

    # Alter state
    state['counter'] += 1
    state['buf'] += b'\xff\xff'
    state['flag'] = False

    serialized_state = scryptlib.serializer.serialize_state(state)
    new_locking_script = Script(counter.code_part.to_bytes() +
                                serialized_state)

    # Deserialize state from new locking script
    new_state = scryptlib.serializer.deserialize_state(new_locking_script,
                                                       state)
    assert new_state['counter'] == 12
    assert new_state['buf'] == b'\x12\x34\xff\xff'
    assert new_state['flag'] == False

    context = scryptlib.utils.create_dummy_input_context()
    context.utxo.script_pubkey = counter.locking_script

    tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script)
    context.tx.outputs.append(tx_out)

    preimage = scryptlib.utils.get_preimage_from_input_context(context)

    verfiy_result = counter.mutate(SigHashPreimage(preimage),
                                   out_sats).verify(context)
    assert verfiy_result == True
Example #20
0
 def _parse_output(self, x):
     try:
         address = self._parse_address(x)
         self._show_cashaddr_warning(x)
         return address
     except:
         return Script.from_asm(x)
Example #21
0
    def make_signed_opreturn_transaction(
            self,
            wallet_name: Optional[str] = None,
            password: Optional[str] = None,
            pushdatas_b64: Optional[List[str]] = None) -> dict:
        wallet = self._get_wallet(wallet_name)

        pushdatas = []
        for pushdata_b64 in pushdatas_b64:
            pushdata_bytes = base64.b64decode(pushdata_b64)
            pushdatas.append(pushdata_bytes)

        domain = None
        confirmed_coins = wallet.get_spendable_coins(None,
                                                     {'confirmed_only': True})
        script = (Script() << OP_RETURN).push_many(pushdatas)
        outputs = [TxOutput(0, script)]
        tx = wallet.make_unsigned_transaction(confirmed_coins, outputs,
                                              app_state.config)
        wallet.sign_transaction(tx, password)
        return {
            "tx_id": tx.txid(),
            "tx_hex": str(tx),
            "fee": tx.get_fee(),
        }
Example #22
0
def string_to_script_template(text: str) -> ScriptTemplate:
    # raises bip276.ChecksumMismatchError
    if text.startswith(PREFIX_SCRIPT):
        prefix, version, network, data = bip276_decode(text, Net.BIP276_VERSION)
        assert network == Net.BIP276_VERSION, "incompatible network"
        return classify_output_script(Script(data), Net.COIN)
    return Address.from_string(text, Net.COIN)
Example #23
0
def script_to_display_text(script: Script, kind: ScriptTemplate) -> str:
    if isinstance(kind, Address):
        text = kind.to_string()
    elif isinstance(kind, P2PK_Output):
        text = kind.public_key.to_hex()
    else:
        text = script.to_asm()
    return text
Example #24
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)
Example #25
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}")
def get_preimage_after_purchase(key_pub):
    new_locking_script = Script(token_sale.locking_script.to_bytes() +
                                key_pub.to_bytes() +
                                scryptlib.utils.get_push_int(n_tokens)[1:])
    tx_out = TxOutput(value=in_sats + n_tokens * token_price_sats,
                      script_pubkey=new_locking_script)
    context.tx.outputs.append(tx_out)

    return scryptlib.utils.get_preimage_from_input_context(context)
Example #27
0
    def hex(self):
        self.bind()

        res_buff = []
        flat_struct = utils.flatten_struct(self, '')
        for elem in flat_struct:
            res_buff.append(elem['value'].hex)

        return Script.from_hex(''.join(res_buff)).to_hex()
Example #28
0
def script_bytes_to_asm(script: Script) -> str:
    # Adapted version of `script.to_asm` which just shows "[error]" in event of truncation.
    # Ideally we need an updated version in bitcoinx that identifies the truncation point.
    op_to_asm_word = script.op_to_asm_word
    parts = []
    try:
        for op in script.ops():
            parts.append(op_to_asm_word(op))
    except TruncatedScriptError:
        parts.insert(0, "[decoding error]")
        parts.append("[script truncated]")
    return ' '.join(parts)
Example #29
0
def create_dummy_input_context():
    '''
    Creates dummy instance of bitoinx.TxInputContext with empty locking and unlocking scripts.
    '''
    tx_version = 2
    tx_locktime = 0x00000000

    utxo_satoshis = 0
    script_pubkey = Script()
    utxo = TxOutput(utxo_satoshis, script_pubkey)
    prev_tx = Tx(tx_version, [], [utxo], tx_locktime)
    prev_txid = prev_tx.hash()

    utxo_idx = 0
    script_sig = Script()
    n_sequence = 0xffffffff
    curr_in = TxInput(prev_txid, utxo_idx, script_sig, n_sequence)
    curr_tx = Tx(tx_version, [curr_in], [], tx_locktime)

    input_idx = 0
    return TxInputContext(curr_tx, input_idx, utxo, is_utxo_after_genesis=True)
Example #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)