Require atomic swap contracts to specify the secret size.

This allows redeeming parties to audit the secret size and ensure it
will be usable once revealed.
This commit is contained in:
Josh Rickmar 2018-02-16 16:18:43 -05:00
parent 9866016012
commit 1cd648d784

View file

@ -629,6 +629,7 @@ type AtomicSwapDataPushes struct {
RecipientHash160 [20]byte RecipientHash160 [20]byte
RefundHash160 [20]byte RefundHash160 [20]byte
SecretHash [32]byte SecretHash [32]byte
SecretSize int64
LockTime int64 LockTime int64
} }
@ -643,47 +644,61 @@ type AtomicSwapDataPushes struct {
// //
// This function is only defined in the txscript package due to API limitations // This function is only defined in the txscript package due to API limitations
// which prevent callers using txscript to parse nonstandard scripts. // which prevent callers using txscript to parse nonstandard scripts.
func ExtractAtomicSwapDataPushes(pkScript []byte) (*AtomicSwapDataPushes, error) { func ExtractAtomicSwapDataPushes(version uint16, pkScript []byte) (*AtomicSwapDataPushes, error) {
pops, err := parseScript(pkScript) pops, err := parseScript(pkScript)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(pops) != 17 { if len(pops) != 20 {
return nil, nil return nil, nil
} }
isAtomicSwap := pops[0].opcode.value == OP_IF && isAtomicSwap := pops[0].opcode.value == OP_IF &&
pops[1].opcode.value == OP_SHA256 && pops[1].opcode.value == OP_SIZE &&
pops[2].opcode.value == OP_DATA_32 && canonicalPush(pops[2]) &&
pops[3].opcode.value == OP_EQUALVERIFY && pops[3].opcode.value == OP_EQUALVERIFY &&
pops[4].opcode.value == OP_DUP && pops[4].opcode.value == OP_SHA256 &&
pops[5].opcode.value == OP_HASH160 && pops[5].opcode.value == OP_DATA_32 &&
pops[6].opcode.value == OP_DATA_20 && pops[6].opcode.value == OP_EQUALVERIFY &&
pops[7].opcode.value == OP_ELSE && pops[7].opcode.value == OP_DUP &&
canonicalPush(pops[8]) && pops[8].opcode.value == OP_HASH160 &&
pops[9].opcode.value == OP_CHECKLOCKTIMEVERIFY && pops[9].opcode.value == OP_DATA_20 &&
pops[10].opcode.value == OP_DROP && pops[10].opcode.value == OP_ELSE &&
pops[11].opcode.value == OP_DUP && canonicalPush(pops[11]) &&
pops[12].opcode.value == OP_HASH160 && pops[12].opcode.value == OP_CHECKLOCKTIMEVERIFY &&
pops[13].opcode.value == OP_DATA_20 && pops[13].opcode.value == OP_DROP &&
pops[14].opcode.value == OP_ENDIF && pops[14].opcode.value == OP_DUP &&
pops[15].opcode.value == OP_EQUALVERIFY && pops[15].opcode.value == OP_HASH160 &&
pops[16].opcode.value == OP_CHECKSIG pops[16].opcode.value == OP_DATA_20 &&
pops[17].opcode.value == OP_ENDIF &&
pops[18].opcode.value == OP_EQUALVERIFY &&
pops[19].opcode.value == OP_CHECKSIG
if !isAtomicSwap { if !isAtomicSwap {
return nil, nil return nil, nil
} }
pushes := new(AtomicSwapDataPushes) pushes := new(AtomicSwapDataPushes)
copy(pushes.SecretHash[:], pops[2].data) copy(pushes.SecretHash[:], pops[5].data)
copy(pushes.RecipientHash160[:], pops[6].data) copy(pushes.RecipientHash160[:], pops[9].data)
copy(pushes.RefundHash160[:], pops[13].data) copy(pushes.RefundHash160[:], pops[16].data)
if pops[8].data != nil { if pops[2].data != nil {
locktime, err := makeScriptNum(pops[8].data, true, 5) locktime, err := makeScriptNum(pops[2].data, true, 5)
if err != nil {
return nil, nil
}
pushes.SecretSize = int64(locktime)
} else if op := pops[2].opcode; isSmallInt(op) {
pushes.SecretSize = int64(asSmallInt(op))
} else {
return nil, nil
}
if pops[11].data != nil {
locktime, err := makeScriptNum(pops[11].data, true, 5)
if err != nil { if err != nil {
return nil, nil return nil, nil
} }
pushes.LockTime = int64(locktime) pushes.LockTime = int64(locktime)
} else if op := pops[8].opcode; isSmallInt(op) { } else if op := pops[11].opcode; isSmallInt(op) {
pushes.LockTime = int64(asSmallInt(op)) pushes.LockTime = int64(asSmallInt(op))
} else { } else {
return nil, nil return nil, nil