Esempio n. 1
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)
Esempio n. 2
0
 def estimated_size(self):
     '''Return an estimated of serialized input size in bytes.'''
     saved_script_sig = self.script_sig
     x_pubkeys = [x_pubkey.to_public_key() for x_pubkey in self.x_pubkeys]
     signatures = [dummy_signature] * self.threshold
     self.script_sig = self._realize_script_sig(x_pubkeys, signatures)
     size = len(TxInput.to_bytes(self))  # base class implementation
     self.script_sig = saved_script_sig
     return size
Esempio n. 3
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 create_input_context(utxo_satoshis, utxo_locking_script, new_out):
    tx_version = 2
    tx_locktime = 0x00000000

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

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

    input_idx = 0
    return TxInputContext(curr_tx, input_idx, utxo, is_utxo_after_genesis=True)
Esempio n. 5
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)
Esempio n. 6
0
def initialize_counter(counter_obj, counter_initial_val, funding_txid, funding_out_idx, \
        unlock_key_priv, miner_fee, contract_out_sats, change_addr):
    counter_obj.set_data_part(
        scryptlib.utils.get_push_int(counter_initial_val))

    # Funding TX
    funding_tx_hash = hex_str_to_hash(funding_txid)
    unlock_key_pub = unlock_key_priv.public_key

    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 = int(r['vout'][funding_out_idx]['value'] * 10**8)
    n_sequence = 0xffffffff
    tx_input = TxInput(funding_tx_hash, funding_out_idx, None, n_sequence)

    # Output with counter script code
    contract_out = TxOutput(contract_out_sats, counter_obj.locking_script)

    # Change output
    tx_output_script = P2PKH_Address.from_string(change_addr,
                                                 Bitcoin).to_script()
    change_out = TxOutput(unlocked_satoshis - miner_fee - contract_out_sats,
                          tx_output_script)

    tx = Tx(2, [tx_input], [contract_out, change_out], 0x00000000)

    # Create signature for input
    sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID)
    sighash = tx.signature_hash(0, unlocked_satoshis, funding_locking_script,
                                sighash_flag)
    sig = unlock_key_priv.sign(sighash, hasher=None)
    sig = sig + pack_byte(sighash_flag)

    # Set script for input
    unlock_script = Script() << sig << unlock_key_pub.to_bytes()
    tx.inputs[0].script_sig = unlock_script

    broadcast_tx(tx)
Esempio n. 7
0
 def size(self) -> int:
     return len(TxInput.to_bytes(self))
Esempio n. 8
0
def random_input():
    sequence = SEQUENCE_FINAL if random_bool() else randrange(0, SEQUENCE_FINAL)
    return TxInput(urandom(32), randrange(0, 4), random_script(), sequence)
Esempio n. 9
0
P2PKH = scryptlib.contract.build_contract_class(desc)
p2pkh_obj = P2PKH(Ripemd160(addr_dest))

prev_tx_hash = hex_str_to_hash(prev_txid)
prev_out_idx = 0

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'])
unlocked_satoshis = int(r['vout'][prev_out_idx]['value'] * 10**8)
out_satoshis = unlocked_satoshis - miner_fee
n_sequence = 0xffffffff

tx_input = TxInput(prev_tx_hash, prev_out_idx, None, n_sequence)
tx_output = TxOutput(out_satoshis, p2pkh_obj.locking_script)

tx = Tx(2, [tx_input], [tx_output], 0x00000000)

sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID)
sighash = tx.signature_hash(0, unlocked_satoshis, prev_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[0].script_sig = unlock_script

######## Broadcast transaction ########
import json