{"type":"rich","version":"1.0","author_name":"npub1m230cem2yh3mtdzkg32qhj73uytgkyg5ylxsu083n3tpjnajxx4qqa2np2","author_url":"https://nostr.ae/npub1m230cem2yh3mtdzkg32qhj73uytgkyg5ylxsu083n3tpjnajxx4qqa2np2","provider_name":"njump","provider_url":"https://nostr.ae","html":"📅 Original date posted:2014-10-01\n📝 Original message:I've written a reference implementation and BIP draft for a new opcode,\nCHECKLOCKTIMEVERIFY. The BIP, reproduced below, can be found at:\n\n    https://github.com/petertodd/bips/blob/checklocktimeverify/bip-checklocktimeverify.mediawiki\n\nThe reference implementation, including a full-set of unittests for the\nopcode semantics can be found at:\n\n    https://github.com/petertodd/bitcoin/compare/checklocktimeverify\n\n\u003cpre\u003e\n  BIP:\n  Title: OP_CHECKLOCKTIMEVERIFY\n  Author: Peter Todd \u003cpete at petertodd.org\u003e\n  Status: Draft\n  Type: Standards Track\n  Created: 2014-10-01\n\u003c/pre\u003e\n\n==Abstract==\n\nThis BIP describes a new opcode (OP_CHECKLOCKTIMEVERIFY) for the Bitcoin\nscripting system that allows a transaction output to be made unspendable until\nsome point in the future.\n\n\n==Summary==\n\nCHECKLOCKTIMEVERIFY re-defines the existing NOP2 opcode. When executed it\ncompares the top item on the stack to the nLockTime field of the transaction\ncontaining the scriptSig. If that top stack item is greater than the transation\nnLockTime the script fails immediately, otherwise script evaluation continues\nas though a NOP was executed.\n\nThe nLockTime field in a transaction prevents the transaction from being mined\nuntil either a certain block height, or block time, has been reached. By\ncomparing the argument to CHECKLOCKTIMEVERIFY against the nLockTime field, we\nindirectly verify that the desired block height or block time has been reached;\nuntil that block height or block time has been reached the transaction output\nremains unspendable.\n\n\n==Motivation==\n\nThe nLockTime field in transactions makes it possible to prove that a\ntransaction output can be spent in the future: a valid signature for a\ntransaction with the desired nLockTime can be constructed, proving that it is\npossible to spend the output with that signature when the nLockTime is reached.\nAn example where this technique is used is in micro-payment channels, where the\nnLockTime field proves that should the receiver vanish the sender is guaranteed\nto get all their escrowed funds back when the nLockTime is reached.\n\nHowever the nLockTime field is insufficient if you wish to prove that\ntransaction output ''can-not'' be spent until some time in the future, as there\nis no way to prove that the secret keys corresponding to the pubkeys controling\nthe funds have not been used to create a valid signature.\n\n\n===Escrow===\n\nIf Alice and Bob jointly operate a business they may want to\nensure that all funds are kept in 2-of-2 multisig transaction outputs that\nrequire the co-operation of both parties to spend. However, they recognise that\nin exceptional circumstances such as either party getting \"hit by a bus\" they\nneed a backup plan to retrieve the funds. So they appoint their lawyer, Lenny,\nto act as a third-party.\n\nWith a standard 2-of-3 CHECKMULTISIG at any time Lenny could conspire with\neither Alice or Bob to steal the funds illegitimately. Equally Lenny may prefer\nnot to have immediate access to the funds to discourage bad actors from\nattempting to get the secret keys from him by force.\n\nHowever with CHECKLOCKTIMEVERIFY the funds can be stored in scriptPubKeys of\nthe form:\n\n    IF\n        \u003cnow + 3 months\u003e CHECKLOCKTIMEVERIFY DROP\n        \u003cLenny's pubkey\u003e CHECKSIGVERIFY\n        1\n    ELSE\n        2\n    ENDIF\n    \u003cAlice's pubkey\u003e \u003cBob's pubkey\u003e 2 CHECKMULTISIG\n\nAt any time the funds can be spent with the following scriptSig:\n\n    \u003cAlice's signature\u003e \u003cBob's signature\u003e 0\n\nAfter 3 months have passed Lenny and one of either Alice or Bob can spend the\nfunds with the following scriptSig:\n\n    \u003cAlice/Bob's signature\u003e \u003cLenny's signature\u003e 1\n\n\n===Non-interactive time-locked refunds===\n\nThere exist a number of protocols where a transaction output is created that\nthe co-operation of both parties to spend the output. To ensure the failure of\none party does not result in the funds becoming lost refund transactions are\nsetup in advance using nLockTime. These refund transactions need to be created\ninteractively, and additionaly, are currently vulnerable to transaction\nmutability. CHECKLOCKTIMEVERIFY can be used in these protocols, replacing the\ninteractive setup with a non-interactive setup, and additionally, making\ntransaction mutability a non-issue.\n\n\n====Two-factor wallets====\n\nServices like GreenAddress store Bitcoins with 2-of-2 multisig scriptPubKey's\nsuch that one keypair is controlled by the user, and the other keypair is\ncontrolled by the service. To spend funds the user uses locally installed\nwallet software that generates one of the required signatures, and then uses a\n2nd-factor authentication method to authorize the service to create the second\nSIGHASH_NONE signature that is locked until some time in the future and sends\nthe user that signature for storage. If the user needs to spend their funds and\nthe service is not available, they wait until the nLockTime expires.\n\nThe problem is there exist numerous occasions the user will not have a valid\nsignature for some or all of their transaction outputs. With\nCHECKLOCKTIMEVERIFY rather than creating refund signatures on demand\nscriptPubKeys of the following form are used instead:\n\n    IF\n        \u003cservice pubkey\u003e CHECKSIGVERIFY\n    ELSE\n        \u003cexpiry time\u003e CHECKLOCKTIMEVERIFY DROP\n    ENDIF\n    \u003cuser pubkey\u003e CHECKSIG\n\nNow the user is always able to spend their funds without the co-operation of\nthe service by waiting for the expiry time to be reached.\n\n\n====Micropayment Channels====\n\nJeremy Spilman style micropayment channels first setup a deposit controlled by\n2-of-2 multisig, tx1, and then adjust a second transaction, tx2, that spends\nthe output of tx1 to payor and payee. Prior to publishing tx1 a refund\ntransaction is created, tx3, to ensure that should the payee vanish the payor\ncan get their deposit back. The process by which the refund transaction is\ncreated is currently vulnerable to transaction mutability attacks, and\nadditionally, requires the payor to store the refund. Using the same\nscriptPubKey from as in the Two-factor wallets example solves both these issues.\n\n\n===Trustless Payments for Publishing Data===\n\nThe PayPub protocol makes it possible to pay for information in a trustless way\nby first proving that an encrypted file contains the desired data, and secondly\ncrafting scriptPubKeys used for payment such that spending them reveals the\nencryption keys to the data. However the existing implementation has a\nsignificant flaw: the publisher can delay the release of the keys indefinitely.\n\nThis problem can be solved interactively with the refund transaction technique;\nwith CHECKLOCKTIMEVERIFY the problem can be non-interactively solved using\nscriptPubKeys of the following form:\n\n    IF\n        HASH160 \u003cHash160(encryption key)\u003e EQUALVERIFY\n        \u003cpublisher pubkey\u003e CHECKSIG\n    ELSE\n        \u003cexpiry time\u003e CHECKLOCKTIMEVERIFY DROP\n        \u003cbuyer pubkey\u003e CHECKSIG\n    ENDIF\n\nThe buyer of the data is now making a secure offer with an expiry time. If the\npublisher fails to accept the offer before the expiry time is reached the buyer\ncan cancel the offer by spending the output.\n\n\n===Proving sacrifice to miners' fees===\n\nProving the sacrifice of some limited resource is a common technique in a\nvariety of cryptographic protocols. Proving sacrifices of coins to mining fees\nhas been proposed as a ''universal public good'' to which the sacrifice could\nbe directed, rather than simply destroying the coins. However doing so is\nnon-trivial, and even the best existing technqiue - announce-commit sacrifices\n- could encourage mining centralization. CHECKLOCKTIMEVERIFY can be used to\ncreate outputs that are provably spendable by anyone (thus to mining fees\nassuming miners behave optimally and rationally) but only at a time\nsufficiently far into the future that large miners profitably can't sell the\nsacrifices at a discount.\n\n\n===Replacing the nLockTime field entirely===\n\nAs an aside, note how if the SignatureHash() algorithm could optionally cover\npart of the scriptSig the signature could require that the scriptSig contain\nCHECKLOCKTIMEVERIFY opcodes, and additionally, require that they be executed.\n(the CODESEPARATOR opcode came very close to making this possible in v0.1 of\nBitcoin) This per-signature capability could replace the per-transaction\nnLockTime field entirely as a valid signature would now be the proof that a\ntransaction output ''can'' be spent.\n\n\n==Detailed Specification==\n\nRefer to the reference implementation, reproduced below, for the precise\nsemantics and detailed rationale for those semantics.\n\n    case OP_NOP2:\n    {\n        // CHECKLOCKTIMEVERIFY\n        //\n        // (nLockTime -- nLockTime )\n    \n        if (!(flags \u0026 SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY))\n            break; // not enabled; treat as a NOP\n    \n        if (stack.size() \u003c 1)\n            return false;\n    \n        // Note that elsewhere numeric opcodes are limited to\n        // operands in the range -2**31+1 to 2**31-1, however it is\n        // legal for opcodes to produce results exceeding that\n        // range. This limitation is implemented by CScriptNum's\n        // default 4-byte limit.\n        //\n        // If we kept to that limit we'd have a year 2038 problem,\n        // even though the nLockTime field in transactions\n        // themselves is uint32 which only becomes meaningless\n        // after the year 2106.\n        //\n        // Thus as a special case we tell CScriptNum to accept up\n        // to 5-byte bignums, which are good until 2**32-1, the\n        // same limit as the nLockTime field itself.\n        const CScriptNum nLockTime(stacktop(-1), 5);\n    \n        // In the rare event that the argument may be \u003c 0 due to\n        // some arithmetic being done first, you can always use\n        // 0 MAX CHECKLOCKTIMEVERIFY.\n        if (nLockTime \u003c 0)\n            return false;\n    \n        // There are two times of nLockTime: lock-by-blockheight\n        // and lock-by-blocktime, distinguished by whether\n        // nLockTime \u003c LOCKTIME_THRESHOLD.\n        //\n        // We want to compare apples to apples, so fail the script\n        // unless the type of nLockTime being tested is the same as\n        // the nLockTime in the transaction.\n        if (!(\n              (txTo.nLockTime \u003c  LOCKTIME_THRESHOLD \u0026\u0026 nLockTime \u003c  LOCKTIME_THRESHOLD) ||\n              (txTo.nLockTime \u003e= LOCKTIME_THRESHOLD \u0026\u0026 nLockTime \u003e= LOCKTIME_THRESHOLD)\n             ))\n            return false;\n    \n        // Now that we know we're comparing apples-to-apples, the\n        // comparison is a simple numeric one.\n        if (nLockTime \u003e (int64_t)txTo.nLockTime)\n            return false;\n    \n        // Finally the nLockTime feature can be disabled and thus\n        // CHECKLOCKTIMEVERIFY bypassed if every txin has been\n        // finalized by setting nSequence to maxint. The\n        // transaction would be allowed into the blockchain, making\n        // the opcode ineffective.\n        //\n        // Testing if this vin is not final is sufficient to\n        // prevent this condition. Alternatively we could test all\n        // inputs, but testing just this input minimizes the data\n        // required to prove correct CHECKLOCKTIMEVERIFY execution.\n        if (txTo.vin[nIn].IsFinal())\n            return false;\n    \n        break;\n    \n    }\n\nhttps://github.com/petertodd/bitcoin/commit/ab0f54f38e08ee1e50ff72f801680ee84d0f1bf4\n\n\n==Upgrade and Testing Plan==\n\nTBD\n\n\n==Credits==\n\nThanks goes to Gregory Maxwell for suggesting that the argument be compared\nagainst the per-transaction nLockTime, rather than the current block height and\ntime.\n\n\n==References==\n\nPayPub - https://github.com/unsystem/paypub\n\nJeremy Spilman Micropayment Channels - http://www.mail-archive.com/bitcoin-development%40lists.sourceforge.net/msg02028.html\n\n\n==Copyright==\n\nThis document is placed in the public domain.\n\n-- \n'peter'[:-1]@petertodd.org\n000000000000000009012f16fe9db21abbba5025453a9b7b589a807b21cec318\n-------------- next part --------------\nA non-text attachment was scrubbed...\nName: signature.asc\nType: application/pgp-signature\nSize: 650 bytes\nDesc: Digital signature\nURL: \u003chttp://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20141001/e8e4213b/attachment.sig\u003e"}
