opcodeCheckLockTimeVerify compares the top item on the data stack to the LockTime field of the transaction containing the script signature validating if the transaction outputs are spendable yet. If flag ScriptVerifyCheckLockTimeVerify is not set, the code continues as if OP_NOP2 were executed.
(op *opcode, data []byte, vm *Engine)
| 1049 | // ScriptVerifyCheckLockTimeVerify is not set, the code continues as if OP_NOP2 |
| 1050 | // were executed. |
| 1051 | func opcodeCheckLockTimeVerify(op *opcode, data []byte, vm *Engine) error { |
| 1052 | // If the ScriptVerifyCheckLockTimeVerify script flag is not set, treat |
| 1053 | // opcode as OP_NOP2 instead. |
| 1054 | if !vm.hasFlag(ScriptVerifyCheckLockTimeVerify) { |
| 1055 | if vm.hasFlag(ScriptDiscourageUpgradableNops) { |
| 1056 | return scriptError(ErrDiscourageUpgradableNOPs, |
| 1057 | "OP_NOP2 reserved for soft-fork upgrades") |
| 1058 | } |
| 1059 | return nil |
| 1060 | } |
| 1061 | |
| 1062 | // The current transaction locktime is a uint32 resulting in a maximum |
| 1063 | // locktime of 2^32-1 (the year 2106). However, scriptNums are signed |
| 1064 | // and therefore a standard 4-byte scriptNum would only support up to a |
| 1065 | // maximum of 2^31-1 (the year 2038). Thus, a 5-byte scriptNum is used |
| 1066 | // here since it will support up to 2^39-1 which allows dates beyond the |
| 1067 | // current locktime limit. |
| 1068 | // |
| 1069 | // PeekByteArray is used here instead of PeekInt because we do not want |
| 1070 | // to be limited to a 4-byte integer for reasons specified above. |
| 1071 | so, err := vm.dstack.PeekByteArray(0) |
| 1072 | if err != nil { |
| 1073 | return err |
| 1074 | } |
| 1075 | lockTime, err := MakeScriptNum(so, vm.dstack.verifyMinimalData, 5) |
| 1076 | if err != nil { |
| 1077 | return err |
| 1078 | } |
| 1079 | |
| 1080 | // In the rare event that the argument needs to be < 0 due to some |
| 1081 | // arithmetic being done first, you can always use |
| 1082 | // 0 OP_MAX OP_CHECKLOCKTIMEVERIFY. |
| 1083 | if lockTime < 0 { |
| 1084 | str := fmt.Sprintf("negative lock time: %d", lockTime) |
| 1085 | return scriptError(ErrNegativeLockTime, str) |
| 1086 | } |
| 1087 | |
| 1088 | // The lock time field of a transaction is either a block height at |
| 1089 | // which the transaction is finalized or a timestamp depending on if the |
| 1090 | // value is before the txscript.LockTimeThreshold. When it is under the |
| 1091 | // threshold it is a block height. |
| 1092 | err = verifyLockTime(int64(vm.tx.LockTime), LockTimeThreshold, |
| 1093 | int64(lockTime)) |
| 1094 | if err != nil { |
| 1095 | return err |
| 1096 | } |
| 1097 | |
| 1098 | // The lock time feature can also be disabled, thereby bypassing |
| 1099 | // OP_CHECKLOCKTIMEVERIFY, if every transaction input has been finalized by |
| 1100 | // setting its sequence to the maximum value (wire.MaxTxInSequenceNum). This |
| 1101 | // condition would result in the transaction being allowed into the blockchain |
| 1102 | // making the opcode ineffective. |
| 1103 | // |
| 1104 | // This condition is prevented by enforcing that the input being used by |
| 1105 | // the opcode is unlocked (its sequence number is less than the max |
| 1106 | // value). This is sufficient to prove correctness without having to |
| 1107 | // check every input. |
| 1108 | // |
nothing calls this directly
no test coverage detected
searching dependent graphs…