Ordinal Swap
Ordinal swap settlement and cancel flow.
txt
Contract OrdinalSwap:
Struct Script:
SuffixData: string
PartialHash: string
Size: number
Struct Output:
Value: number
LockingScript: Script
Struct CurrentTX:
Outputs: Output[3]
def swap(aliceSig: hex, ctx: CurrentTX, prevouts: hex, path: number):
if path == 1:
Delete(aliceSig)
# The supplied prevouts bytes must hash to the transaction input digest.
prevouts_for_hash = prevouts.Clone()
EqualVerify(Sha256(prevouts_for_hash), BVM.inputsHash)
# Input 0 is reserved for the outpoint being unlocked now.
prevouts_for_first = prevouts.Clone()
first_outpoint = prevouts_for_first.Slice(0, 36)
current_outpoint = BVM.unlockingInput.Slice(0, 36)
EqualVerify(first_outpoint, current_outpoint)
# Input 1 must match Bob's pre-agreed outpoint and amount.
second_outpoint = prevouts.Slice(40, 36)
EqualVerify(second_outpoint, self.prevoutBob)
# Output 0 sends the one-satoshi item to Bob's P2PKH address.
out0_suffix = ctx.Outputs[0].LockingScript.SuffixData.Clone()
{ out0_prefix, out0_suffix } = Split(out0_suffix, 3)
EqualVerify(out0_prefix, 0x76a914)
{ out0_pkh, out0_tail } = Split(out0_suffix, 20)
EqualVerify(out0_tail, 0x88ac)
EqualVerify(out0_pkh, Hash160(self.bob))
out0_value_num = BinToNum(ctx.Outputs[0].Value.Clone())
NumEqualVerify(out0_value_num, 1)
# Output 1 pays Alice the agreed value from Bob's side of the swap.
out1_suffix = ctx.Outputs[1].LockingScript.SuffixData.Clone()
{ out1_prefix, out1_suffix } = Split(out1_suffix, 3)
EqualVerify(out1_prefix, 0x76a914)
{ out1_pkh, out1_tail } = Split(out1_suffix, 20)
EqualVerify(out1_tail, 0x88ac)
EqualVerify(out1_pkh, Hash160(self.alice))
out1_value_num = BinToNum(ctx.Outputs[1].Value.Clone())
NumEqualVerify(out1_value_num, self.prevoutBobAmount)
# Hash the three expected outputs and bind them to the current transaction.
outputs_data = Push(0)
SetAlt(outputs_data)
for i in Range(2, -1, -1):
size = ctx.Outputs[i].LockingScript.Size.Clone()
if size != 0:
outputs_data_temp = PartialHash(ctx.Outputs[i].LockingScript.SuffixData, ctx.Outputs[i].LockingScript.PartialHash, ctx.Outputs[i].LockingScript.Size)
outputs_data_temp = Cat(ctx.Outputs[i].Value, outputs_data_temp)
SetMain(outputs_data)
outputs_data = Cat(outputs_data_temp, outputs_data)
SetAlt(outputs_data)
Keep(outputs_data)
else:
Delete(ctx.Outputs[i].LockingScript.Size)
Delete(ctx.Outputs[i].LockingScript.PartialHash)
Delete(ctx.Outputs[i].LockingScript.SuffixData)
Delete(ctx.Outputs[i].Value)
SetMain(outputs_data)
outputs_data = Sha256(outputs_data)
EqualVerify(outputs_data, BVM.outputsHash)
else:
# Cancel is a simple Alice-signed branch; transaction-shape data is discarded.
Delete(prevouts)
Delete(ctx)
CheckSigVerify(self.alice, aliceSig)