Non-Custodial Agent Bitcoin Transfer

Curtis Ellis
Tokenized Blog
Published in
2 min readAug 9, 2021

When a Tokenized “Atomic” swap of tokens for bitcoin is done the bitcoin must currently be sent to the Smart Contract Agent (SCA) address and the SCA then disburses the bitcoin to the recipient when it approves the transfer, or refunds to the original address if the transfer is rejected.

We don’t ever want the Tokenized Smart Contract Agent to need to hold bitcoin, at least no more than basic tx fees to function. sCrypt provides us a good option to fix this via their higher level language, IDE, and sample code.

So this contract can be unlocked in three ways:

  1. The SCA signs (P2PKH) and includes the output that hashes to the specified “approve” output hash.
  2. The SCA signs (P2PKH) and includes the output that hashes to the specified “refund” output hash.
  3. The sender signs (P2PKH) and the transaction specifies a lock time at or after the expiration specified.

This only allows the SCA to send the bitcoin to one of two addresses and if the SCA doesn’t respond before the expiration the sender can reclaim their bitcoin.

How it works

Thanks to the breakthrough of OP_PUSH_TX we can create locking scripts that can only be spent by spending them into a transaction the meets the requirements specified in the locking script. These rules are all applied by checking the signature hash preimage, meaning the data that is signed when a transaction is signed and that signature is verified by the OP_CHECKSIG op code. There is a cost as bitcoin script doesn’t directly allow accessing that data. So to check the data the preimage must be included in the unlocking script as well as any data that might need to be examined within a hashed set of data. Then the locking script can verify the preimage in the unlocking script is correct for the current transaction and analyze that data to verify it meets the requirements.

One piece of data included in the preimage is a double SHA256 hash of the outputs of the transaction. So by using a SIGHASH_SINGLE, that only signs one output, the outputs hash in the preimage is the hash of a single output. In the script above the locking script includes the hashes of two outputs. The locking script then allows spending by providing the SCA key (specified in the locking script) signature as well as the hash of the output of the current transaction to match one of the specified output hashes.

Other pieces of data in the preimage are the lock time (time before which a tx is not valid to the network), and hash of the sequences of the inputs (only when SIGHASH_ALL). When the sequence of one of the inputs is not the MAX value and lock time is not zero, then the transaction is not valid until the lock time is reached. The locking script then allows spending by providing the sender key (specified in the locking script) signature as wells as specifying a non-MAX sequence and a lock time after the expiration time specified in the locking script.

--

--