# Verifying change

With bitpost, you can create child transactions of PSTs previously relayed to us. To do this, you will probably want to query what change is available from ongoing requests with the /utxos endpoint. Unless showunknownchange is set to true, the provided utxos will just contain the change utxos (guessed from the fee being discounted in them or specified by the user), which the user can verify as being spendable by him. If showrawtx is set to true, the user can perform two additional verifications: verify that the all the provided change belongs to mutually exclusive pre-signed transactions (PSTs), so that a double spend is impossible; and to verify that the provided PSTs are valid.

Although we think that the last two types of verification are mostly unecessary and don't justify the extra bandwith, we encourage the philisophy of "don't trust, verify".

# Verifying spendability

The answer to /utxos will provide the scriptPubKey of every change (often the same). You can then query your wallet if this scriptPuKey/address belongs to it. With a bitcoin core wallet you can check spendability with:

bitcoin-cli getaddressinfo $(bitcoin-cli decodescript 'YOUR_SCRIPT' | jq .addresses[0] | tr -d '"') | jq .solvable

In the case of bit, the library we have used to provide code examples, it doesn't support BIP 32 wallets, so we just have to check if its address is equal to the private key's P2PKH or P2SH(PWPKH) address.

from binascii import unhexlify
import bit
from bitcoin.core.script import CScript # python-bitcoinlib: https://pypi.org/project/python-bitcoinlib
from bitcoin.wallet import CBitcoinAddress

CHANGE_SCRIPT = 'a914406fea471691f061ac2a7ee1065e157a0acaeed787' # replace with yours

scriptPubKey = CScript(unhexlify(CHANGE_SCRIPT))
addr = CBitcoinAddress.from_scriptPubKey(scriptPubKey)

key = bit.Key.from_bytes(b'REPLACE_WITH_YOUR_PRIVATE_KEY')
print('matches segwit address={}, matches legacy address={}'.format(str(addr) == key.segwit_address, str(addr) == key.address))

# Verifying mutual exclusivity

This type of verification tells you whether the change UTXOs provided by Bitpost are mutually exclusive or not. By construction, it should be impossible for them not to be, as this is checked every time new PSTs are relayed. If you wish to do this verification, the showrawtx=true option should be passed when calling the /utxos endpoint. The code below how you can perform this verification - it uses our pyhton interface and bit.

# class under https://github.com/bitpostAPI/examples
from bit_integration.bitpos_interface_for_bit import BipostInterfaceForBit

bitpostInterface = BipostInterfaceForBit('YOUR_WALLETTOKEN')
result, message = bitpostInterface.verify_change()

if result:
    print("Successfully verified that change utxos are mutually exclusive. Child transaction are double-spend safe!")
else:
    # This should NEVER happen. If it ever does during the beta, please get in touch immediately
    print("Verification failed! Change utxos are not multiple exclusive. Error message=" + message)

# Verifying validity

This form of verification is the hardest to implement and may be labor-intensive in the general case. However, this task is often simplified because the relayed PSTs are signed by only one party or belong to a small set of common transaction types. Right now, we don't provide any code examples for this. If you want to do this type of verification and are struggling, even with the tips below, get in touch.

Verifying that scriptSig and witness fields can unlock the scriptPubKey can usually be done, without broadcasting, via the testmempoolaccept RPC command of bitcoin core. However, this command will reply "false, missing inputs" if a pre-signed transaction spends from another, which is not yet in the mempool or mined. A pull request has been made to account for this case, but it hasn't been merged or bundled in a release at the time of writing.

Many bitcoin libraries like bitcoinJ and python-bitcoinlib offer a script interpreter that can validate a particular scriptPubKey against a scriptSig/witness. Still, they require some "verification flags" as additional input. So if you want to be able to check every type of transaction, you might need to build your own "verification flag factory".

WARNING

In many bitcoin libraries, the method transaction.verify(), one exception being 1200wd's bitcoinlib, only does some very basic sanity checks on the transaction.

When the transactions relayed to Bitpost are signed by a single party (excluding e.g. multisig), there is a hacky way of verifying the validity of the PSTs: clear the signatures (scriptSig and witness fields) and sign the transactions again. If the new PSTs are equal to the old PSTs, then the PSTs provided by us are had valid signatures.