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)
def test_verify_with_change():
    deposit_sats = 100000
    input_sats = 100000
    output_sats = deposit_sats + input_sats
    change_sats = 547

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

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

    tx_out_0 = TxOutput(value=output_sats, script_pubkey=faucet.locking_script)
    context.tx.outputs.append(tx_out_0)

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

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

    verify_result = faucet.deposit(SigHashPreimage(preimage), deposit_sats,
                                   Ripemd160(pkh), change_sats).verify(context)
    assert verify_result == True

    with pytest.raises(bitcoinx.VerifyFailed):
        faucet.deposit(SigHashPreimage(preimage), deposit_sats, Ripemd160(pkh),
                       change_sats + 1).verify(context)
    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)
Exemple #4
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_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)
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)
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
Exemple #8
0
    def serialize(self, jsontx):
        """Create a transaction from json inputs.
        Inputs must have a redeemPubkey.
        Outputs must be a list of {'address':address, 'value':satoshi_amount}.
        """
        keypairs = {}
        inputs = jsontx.get('inputs')
        outputs = jsontx.get('outputs')
        locktime = jsontx.get('locktime', 0)
        for txin in inputs:
            if txin.get('output'):
                prevout_hash, prevout_n = txin['output'].split(':')
                txin['prevout_n'] = int(prevout_n)
                txin['prevout_hash'] = prevout_hash
            sec = txin.get('privkey')
            if sec:
                privkey = PrivateKey.from_text(sec)
                txin_type, privkey, compressed = ('p2pkh', privkey.to_bytes(),
                                                  privkey.is_compressed())
                pubkey = privkey.public_key.to_hex()
                keypairs[pubkey] = privkey, compressed
                txin['type'] = txin_type
                txin['x_pubkeys'] = [pubkey]
                txin['signatures'] = [None]
                txin['num_sig'] = 1

        outputs = [
            TxOutput(output['value'],
                     Address.from_string(output['address']).to_script())
            for output in outputs
        ]
        tx = Transaction.from_io(inputs, outputs, locktime=locktime)
        tx.sign(keypairs)
        return tx.as_dict()
Exemple #9
0
    def test_tx_unsigned(self):
        tx = Transaction.from_hex(unsigned_blob)
        assert tx.version == 1
        assert len(tx.inputs) == 1
        txin = tx.inputs[0]
        assert txin.prev_hash.hex(
        ) == '49f35e43fefd22d8bb9e4b3ff294c6286154c25712baf6ab77b646e5074d6aed'
        assert txin.prev_idx == 1
        assert txin.script_sig.to_hex(
        ) == '01ff4c53ff0488b21e0000000000000000004f130d773e678a58366711837ec2e33ea601858262f8eaef246a7ebd19909c9a03c3b30e38ca7d797fee1223df1c9827b2a9f3379768f520910260220e0560014600002300'
        assert txin.sequence == 4294967294
        assert txin.value == 20112600
        assert txin.signatures == [NO_SIGNATURE]
        assert txin.x_pubkeys == [
            XPublicKey(
                'ff0488b21e0000000000000000004f130d773e678a58366711837ec2e33ea601858262f8eaef246a7ebd19909c9a03c3b30e38ca7d797fee1223df1c9827b2a9f3379768f520910260220e0560014600002300'
            )
        ]
        assert txin.address == address_from_string(
            '13Vp8Y3hD5Cb6sERfpxePz5vGJizXbWciN')
        assert txin.threshold == 1
        assert tx.outputs == [
            TxOutput(
                20112408,
                address_from_string(
                    '1MYXdf4moacvaEKZ57ozerpJ3t9xSeN6LK').to_script())
        ]
        assert tx.locktime == 507231

        assert tx.as_dict() == {'hex': unsigned_blob, 'complete': False}
Exemple #10
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(),
        }
Exemple #11
0
    def _mktx(self,
              outputs,
              fee=None,
              change_addr=None,
              domain=None,
              nocheck=False,
              unsigned=False,
              password=None,
              locktime=None):
        self.nocheck = nocheck
        change_addr = None if change_addr is None else Address.from_string(
            change_addr)
        domain = None if domain is None else [
            Address.from_string(x) for x in domain
        ]
        final_outputs = []
        for address, amount in outputs:
            address = Address.from_string(address)
            amount = satoshis(amount)
            final_outputs.append(TxOutput(amount, address.to_script()))

        coins = self.wallet.get_spendable_coins(domain, self.config)
        tx = self.wallet.make_unsigned_transaction(coins, final_outputs,
                                                   self.config, fee,
                                                   change_addr)
        if locktime is not None:
            tx.locktime = locktime
        if not unsigned:
            self.wallet.sign_transaction(tx, password)
        return tx
Exemple #12
0
 def _parse_tx_output(self, line):
     x, y = line.split(',')
     script = self._parse_output(x)
     if not isinstance(script, Script):  # An Address object
         script = script.to_script()
     amount = self._parse_amount(y)
     return TxOutput(amount, script)
def test_verify_wrong_out_amount():
    pkh_0_out_wrong = TxOutput(in_sats - miner_fee + 123,
                               P2PKH_Address(pkh_0, Bitcoin).to_script())
    context = create_input_context(in_sats, acs.locking_script,
                                   pkh_0_out_wrong)
    preimage = scryptlib.utils.get_preimage_from_input_context(
        context, sighash_flag)
    verify_result = acs.unlock(SigHashPreimage(preimage)).verify(context)
    assert verify_result == False
Exemple #14
0
    def _ask_send_split_transaction(self):
        window = self.window()
        wallet = self.get_wallet()

        unused_address = wallet.get_unused_address()
        outputs = [TxOutput(all, unused_address.to_script())]
        coins = wallet.get_utxos(None,
                                 exclude_frozen=True,
                                 mature=True,
                                 confirmed_only=False)
        # Verify that our dust receiving address is in the available UTXOs, if it isn't, the
        # process has failed in some unexpected way.
        for coin in coins:
            if coin['address'] == self.receiving_address:
                break
        else:
            window.show_error(
                _("Error accessing dust coins for correct splitting."))
            self._cleanup_tx_final()
            return
        tx = wallet.make_unsigned_transaction(coins, outputs, window.config)

        amount = tx.output_value()
        fee = tx.get_fee()

        msg = [
            _("Amount to be sent") + ": " +
            window.format_amount_and_units(amount),
            _("Mining fee") + ": " + window.format_amount_and_units(fee),
        ]

        if wallet.has_password():
            msg.append("")
            msg.append(_("Enter your password to proceed"))
            password = window.password_dialog('\n'.join(msg))
        else:
            msg.append(_('Proceed?'))
            password = None
            if not window.question('\n'.join(msg)):
                self._cleanup_tx_final()
                return

        def sign_done(success):
            if success:
                if not tx.is_complete():
                    dialog = self.window().show_transaction(tx)
                    dialog.exec()
                else:
                    extra_text = _("Your split coins")
                    window.broadcast_transaction(
                        wallet,
                        tx,
                        f"{TX_DESC_PREFIX}: {extra_text}",
                        success_text=_("Your coins have now been split."))
            self._cleanup_tx_final()

        window.sign_tx_with_password(tx, sign_done, password)
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)
Exemple #16
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)
def get_context(hashed_map):
    new_ls = state_map.get_state_script({'_mpData': Bytes(hashed_map.hex)})

    context = scryptlib.create_dummy_input_context()
    context.utxo.script_pubkey = state_map.locking_script

    tx_out = TxOutput(value=0, script_pubkey=new_ls)
    context.tx.outputs.append(tx_out)

    return context
Exemple #18
0
    def get_outputs(self, is_max):
        if self.payto_address:
            if is_max:
                amount = all
            else:
                amount = self.amount_edit.get_amount()

            addr = self.payto_address
            self.outputs = [TxOutput(amount, addr.to_script())]

        return self.outputs[:]
def test_verify_wrong_addr():
    key_priv = PrivateKey.from_arbitrary_bytes(b'123test')
    key_pub = key_priv.public_key
    pkh = key_pub.hash160()
    pkh_0_out_wrong = TxOutput(in_sats - miner_fee,
                               P2PKH_Address(pkh, Bitcoin).to_script())
    context = create_input_context(in_sats, acs.locking_script,
                                   pkh_0_out_wrong)
    preimage = scryptlib.utils.get_preimage_from_input_context(
        context, sighash_flag)
    verify_result = acs.unlock(SigHashPreimage(preimage)).verify(context)
    assert verify_result == False
Exemple #20
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)
Exemple #21
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)
Exemple #22
0
    def test_tx_unsigned(self):
        outputs = [
            TxOutput(
                20112408,
                Address.from_string(
                    '1MYXdf4moacvaEKZ57ozerpJ3t9xSeN6LK').to_script())
        ]
        expected = {
            'inputs': [{
                'address':
                Address.from_string('13Vp8Y3hD5Cb6sERfpxePz5vGJizXbWciN'),
                'num_sig':
                1,
                'prevout_hash':
                'ed6a4d07e546b677abf6ba1257c2546128c694f23f4b9ebbd822fdfe435ef349',
                'prevout_n':
                1,
                'pubkeys': [
                    '03b5bbebceeb33c1b61f649596b9c3611c6b2853a1f6b48bce05dd54f667fa2166'
                ],
                'scriptSig':
                '01ff4c53ff0488b21e0000000000000000004f130d773e678a58366711837ec2e33ea601858262f8eaef246a7ebd19909c9a03c3b30e38ca7d797fee1223df1c9827b2a9f3379768f520910260220e0560014600002300',
                'sequence':
                4294967294,
                'signatures': [None],
                'type':
                'p2pkh',
                'value':
                20112600,
                'x_pubkeys': [
                    'ff0488b21e0000000000000000004f130d773e678a58366711837ec2e33ea601858262f8eaef246a7ebd19909c9a03c3b30e38ca7d797fee1223df1c9827b2a9f3379768f520910260220e0560014600002300'
                ]
            }],
            'lockTime':
            507231,
            'outputs':
            outputs,
            'version':
            1
        }
        tx = transaction.Transaction(unsigned_blob)
        calc = tx.deserialize()
        self.assertEqual(calc, expected)
        self.assertEqual(tx.deserialize(), None)

        self.assertEqual(tx.as_dict(), {
            'hex': unsigned_blob,
            'complete': False,
            'final': True
        })
        self.assertEqual(tx.outputs(), outputs)
        self.assertEqual(tx.serialize(), unsigned_blob)
Exemple #23
0
    def test_tx_signed(self):
        expected = {
            'inputs': [{
                'address':
                Address.from_string('13Vp8Y3hD5Cb6sERfpxePz5vGJizXbWciN'),
                'num_sig':
                1,
                'prevout_hash':
                'ed6a4d07e546b677abf6ba1257c2546128c694f23f4b9ebbd822fdfe435ef349',
                'prevout_n':
                1,
                'pubkeys': [
                    '03b5bbebceeb33c1b61f649596b9c3611c6b2853a1f6b48bce05dd54f667fa2166'
                ],
                'scriptSig':
                '473044022025bdc804c6fe30966f6822dc25086bc6bb0366016e68e880cf6efd2468921f3202200e665db0404f6d6d9f86f73838306ac55bb0d0f6040ac6047d4e820f24f46885412103b5bbebceeb33c1b61f649596b9c3611c6b2853a1f6b48bce05dd54f667fa2166',
                'sequence':
                4294967294,
                'signatures': [
                    '3044022025bdc804c6fe30966f6822dc25086bc6bb0366016e68e880cf6efd2468921f3202200e665db0404f6d6d9f86f73838306ac55bb0d0f6040ac6047d4e820f24f4688541'
                ],
                'type':
                'p2pkh',
                'x_pubkeys': [
                    '03b5bbebceeb33c1b61f649596b9c3611c6b2853a1f6b48bce05dd54f667fa2166'
                ]
            }],
            'lockTime':
            507231,
            'outputs': [
                TxOutput(
                    20112408,
                    Address.from_string(
                        '1MYXdf4moacvaEKZ57ozerpJ3t9xSeN6LK').to_script())
            ],
            'version':
            1
        }
        tx = transaction.Transaction(signed_blob)
        self.assertEqual(tx.deserialize(), expected)
        self.assertEqual(tx.deserialize(), None)
        self.assertEqual(tx.as_dict(), {
            'hex': signed_blob,
            'complete': True,
            'final': True
        })

        self.assertEqual(tx.serialize(), signed_blob)

        tx.update_signatures(signed_blob)

        self.assertEqual(tx.estimated_size(), 191)
Exemple #24
0
def test_verify_wrong_output():
    context = scryptlib.utils.create_dummy_input_context()
    context.utxo.script_pubkey = gol.locking_script

    new_locking_script = Script(gol.code_part.to_bytes() + wb1)
    tx_out = TxOutput(value=out_amount, 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)

    verify_result = gol.play(out_amount, SigHashPreimage(preimage)).verify(context)
    assert verify_result == False
def test_verify_correct():
    context = scryptlib.utils.create_dummy_input_context()
    context.utxo.script_pubkey = p2sh.locking_script
    context.utxo.value = input_sats

    tx_out = TxOutput(value=input_sats, script_pubkey=demo_contract.code_part)
    context.tx.outputs.append(tx_out)

    preimage = scryptlib.utils.get_preimage_from_input_context(context)

    verify_result = p2sh.redeem(Bytes(demo_contract.code_part.to_bytes()),
                                SigHashPreimage(preimage)).verify(context)
    assert verify_result == True
Exemple #26
0
def test_verify_wrong_nextval():
    subsequent_counter_val_bytes = scryptlib.utils.get_push_int(
        COUNTER_INITIAL_VAL + 2)
    new_locking_script = counter.code_part << Script(
        subsequent_counter_val_bytes)
    tx_out = TxOutput(value=out_sats, script_pubkey=new_locking_script)
    context.tx.outputs[0] = tx_out
    preimage = scryptlib.utils.get_preimage_from_input_context(
        context, sighash_flag)

    verify_result = counter.increment(SigHashPreimage(preimage), out_sats,
                                      Ripemd160(pkh_0),
                                      change_sats - 1).verify(context)
    assert verify_result == False
Exemple #27
0
def test_verify_incorrect_sat_amount():
    context = scryptlib.utils.create_dummy_input_context()
    context.utxo.script_pubkey = counter_obj.locking_script

    subsequent_counter_val_bytes = scryptlib.utils.get_push_int(COUNTER_INITIAL_VAL + 1)
    new_locking_script = counter_obj.code_part << Script(subsequent_counter_val_bytes)
    tx_out = TxOutput(value=0, 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)
    new_output_satoshis = 100
    verify_result = counter_obj.increment(SigHashPreimage(preimage), Int(new_output_satoshis)).verify(context)
    assert verify_result == False
Exemple #28
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 _ask_send_split_transaction(self) -> None:
        coins = self._account.get_utxos(exclude_frozen=True, mature=True)
        # Verify that our dust receiving address is in the available UTXOs, if it isn't, the
        # process has failed in some unexpected way.
        for coin in coins:
            if coin['address'] == self.receiving_script_template:
                break
        else:
            self._main_window.show_error(
                _("Error accessing dust coins for correct splitting."))
            self._cleanup_tx_final()
            return

        unused_key = self._account.get_fresh_keys(RECEIVING_SUBPATH, 1)[0]
        script = self._account.get_script_for_id(unused_key.keyinstance_id)
        outputs = [TxOutput(all, script)]
        tx = self._account.make_unsigned_transaction(coins, outputs,
                                                     self._main_window.config)

        amount = tx.output_value()
        fee = tx.get_fee()

        msg = [
            _("Amount to be sent") + ": " +
            self._main_window.format_amount_and_units(amount),
            _("Mining fee") + ": " +
            self._main_window.format_amount_and_units(fee),
        ]

        msg.append("")
        msg.append(_("Enter your password to proceed"))
        password = self._main_window.password_dialog('\n'.join(msg))

        def sign_done(success):
            if success:
                if not tx.is_complete():
                    dialog = self._main_window.show_transaction(
                        self._account, tx)
                    dialog.exec()
                else:
                    extra_text = _("Your split coins")
                    self._main_window.broadcast_transaction(
                        self._account,
                        tx,
                        f"{TX_DESC_PREFIX}: {extra_text}",
                        success_text=_("Your coins have now been split."))
            self._cleanup_tx_final()

        self._main_window.sign_tx_with_password(tx, sign_done, password)
Exemple #30
0
 def change_outputs(self, tx, change_addrs, fee_estimator, dust_threshold):
     amounts = self.change_amounts(tx, len(change_addrs), fee_estimator,
                                   dust_threshold)
     assert min(amounts) >= 0
     assert len(change_addrs) >= len(amounts)
     # If change is above dust threshold after accounting for the
     # size of the change output, add it to the transaction.
     dust = sum(amount for amount in amounts if amount < dust_threshold)
     amounts = [amount for amount in amounts if amount >= dust_threshold]
     change = [TxOutput(amount, addr.to_script())
               for addr, amount in zip(change_addrs, amounts)]
     logger.debug('change %s', change)
     if dust:
         logger.debug('not keeping dust %s', dust)
     return change, dust