diff options
author | Anthony Towns <aj@erisian.com.au> | 2023-01-10 22:29:52 +1000 |
---|---|---|
committer | bitcoindev <bitcoindev@gnusha.org> | 2023-01-10 12:30:03 +0000 |
commit | 77e915ac240f327abf488b5c2454e3c86a9ea913 (patch) | |
tree | b1d5c0eef37d31b563a01fb7c150b6f092fc80b7 | |
parent | 1128f6c1a2b352048fe08a589dfc7fbaa09205e9 (diff) | |
download | pi-bitcoindev-77e915ac240f327abf488b5c2454e3c86a9ea913.tar.gz pi-bitcoindev-77e915ac240f327abf488b5c2454e3c86a9ea913.zip |
Re: [bitcoin-dev] OP_VAULT: a new vault proposal
-rw-r--r-- | 00/b21622d1382e8fbde8d303a2561a6df5a84941 | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/00/b21622d1382e8fbde8d303a2561a6df5a84941 b/00/b21622d1382e8fbde8d303a2561a6df5a84941 new file mode 100644 index 000000000..15816f518 --- /dev/null +++ b/00/b21622d1382e8fbde8d303a2561a6df5a84941 @@ -0,0 +1,243 @@ +Return-Path: <aj@erisian.com.au> +Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) + by lists.linuxfoundation.org (Postfix) with ESMTP id C9216C002D + for <bitcoin-dev@lists.linuxfoundation.org>; + Tue, 10 Jan 2023 12:30:03 +0000 (UTC) +Received: from localhost (localhost [127.0.0.1]) + by smtp4.osuosl.org (Postfix) with ESMTP id 9FC3240A00 + for <bitcoin-dev@lists.linuxfoundation.org>; + Tue, 10 Jan 2023 12:30:03 +0000 (UTC) +DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 9FC3240A00 +X-Virus-Scanned: amavisd-new at osuosl.org +X-Spam-Flag: NO +X-Spam-Score: 0.599 +X-Spam-Level: +X-Spam-Status: No, score=0.599 tagged_above=-999 required=5 + tests=[BAYES_00=-1.9, LOTS_OF_MONEY=0.001, MONEY_NOHTML=2.499, + SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=0.001] + autolearn=no autolearn_force=no +Received: from smtp4.osuosl.org ([127.0.0.1]) + by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id THI-r9--Uibk + for <bitcoin-dev@lists.linuxfoundation.org>; + Tue, 10 Jan 2023 12:30:02 +0000 (UTC) +X-Greylist: from auto-whitelisted by SQLgrey-1.8.0 +DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 2DC3340985 +Received: from azure.erisian.com.au (azure.erisian.com.au [172.104.61.193]) + by smtp4.osuosl.org (Postfix) with ESMTPS id 2DC3340985 + for <bitcoin-dev@lists.linuxfoundation.org>; + Tue, 10 Jan 2023 12:30:02 +0000 (UTC) +Received: from aj@azure.erisian.com.au (helo=sapphire.erisian.com.au) + by azure.erisian.com.au with esmtpsa (Exim 4.92 #3 (Debian)) + id 1pFDlN-0004Ak-Ol; Tue, 10 Jan 2023 22:29:58 +1000 +Received: by sapphire.erisian.com.au (sSMTP sendmail emulation); + Tue, 10 Jan 2023 22:29:52 +1000 +Date: Tue, 10 Jan 2023 22:29:52 +1000 +From: Anthony Towns <aj@erisian.com.au> +To: James O'Beirne <james.obeirne@gmail.com>, + Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org> +Message-ID: <Y71aQAxPXI+9C7rd@erisian.com.au> +References: <CAPfvXfL65cneOabmxfOzTZq14xN4vXNaGboq_g15-frM14RqGA@mail.gmail.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=us-ascii +Content-Disposition: inline +In-Reply-To: <CAPfvXfL65cneOabmxfOzTZq14xN4vXNaGboq_g15-frM14RqGA@mail.gmail.com> +Subject: Re: [bitcoin-dev] OP_VAULT: a new vault proposal +X-BeenThere: bitcoin-dev@lists.linuxfoundation.org +X-Mailman-Version: 2.1.15 +Precedence: list +List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org> +List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>, + <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe> +List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/> +List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org> +List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help> +List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>, + <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe> +X-List-Received-Date: Tue, 10 Jan 2023 12:30:03 -0000 + +On Mon, Jan 09, 2023 at 11:07:54AM -0500, James O'Beirne via bitcoin-dev wrote: +> But I also found proposed "general" covenant schemes to be +> unsuitable for this use. The bloated scriptPubKeys, + +I don't think that makes sense? With a general scheme, you'd only be +bloating the witness data (perhaps including the witness script) not +the scriptPubKey? + + + +Terminology suggestion: instead of calling it the "recovery" path, +call it "freezing your funds". Then you're using your "hot wallet" (aka +unvault-spk-hash) for the unvault path for all your normal transactions, +but if there's a problem, you freeze your funds, and they're now only +accessible via your "cold wallet" (aka recovery-spk-hash). + + + +As I understand it, your scheme is: + + scriptPubKey: <vault tag> <#recovery> (<delay> <#unvault>) + +where #recovery is the sha256 hashes of an arbitrary scriptPubKey, +#unvault is the sha256 hash of a witness script, and delay is a relative +block count. + +This scriptPubKey allows for two spend paths: + + recovery: spends directly to <recovery>; verified by checking it + the hash of the sPK matches <#recovery> and the amount it preserved + + unvaulting: + spends to a scriptPubKey of <unvault tag> <#recovery> (<delay> <#target>) + verified by checking that the witness script hashes to #unvault and + is satisfied, and #target is a CTV-ish commitment of the eventual + withdrawal (any CHECKSIG operations in the unvault witness script will + commit to the sPK output, preventing this from being modified by + third parties). #recovery and delay must match the values from the + vault scriptPubKey. + +The unvault scriptPubKey likewise likewise allows for two spend paths: + + recovery: same as above + + withdrawal: + verifies that all the outputs hash to #target, and that nSequence + is set to a relative timelock of at least delay. + + + +This means that as soon as your recovery address (the preimage to +#recovery) is revealed, anyone can move all your funds into cold storage +(presuming they're willing to pay the going feerate to do so). I think +this is a feature, not a bug, though: if your hot wallet is compromised, +moving all your funds to cold storage is desirable; and if you want to +have different hot wallets with a single cold wallet, then you can use +a HD cold-wallet so that revealing one address corresponding to one hot +wallet, doesn't reveal the addresses corresponding to other hot wallets. +(This is addressed in the "Denial-of-service protection" section) + +It does however mean that the public key for your cold wallet needs to +be handled secretly though -- if you take the cold wallet xpub and send +it to a random electrum server to check your cold wallet balance, that +would allow a malicious party to lock up all your funds. + +I think it might be better to use a pay-to-contract construction for +the recovery path, rather than an empty witness. That is, take your +recovery address R, and calculate #recovery=sha256(R, sha256(secret)) +(where "secret" is something derived from the R's private key, so that +it can be easily recovered if you only have your cold wallet and lose +all your metadata). When you want to recover all your funds to address R, +you reveal sha256(secret) in the witness data and R in the scriptPubKey, +OP_VAULT hashes these together and checks the result matches #recovery, +and only then allows it. That would allow you to treat R as public +knowledge, without risking your funds getting randomly frozen. + + + +This construct allows delayed withdrawals (ie "the cold wallet can +withdraw instantly, the hot wallet can withdraw only after delay blocks"), +but I don't think it provides any way to cap withdrawals ("the cold +wallet can withdraw all funds, the hot wallet can only withdraw up to +X funds per day/week"). Having a fixed limit probably isn't compatible +with having a multi-utxo vault ("you can withdraw $10k per day" doesn't +help if your $5M is split across 500 $10k utxos, and the limit is only +enforced per-utxo), but I think a percentage limit would be. + + + +I think a generic OP_UNVAULT can be used to simulate OP_CTV: replace +"<h> OP_CTV" with "<000..0> 0 <h> OP_UNVAULT". The paper seems to put +"OP_UNVAULT" first, but the code seems to expect it to come last, not +sure what's up with that inconsistency. + +I'm not sure why you'd want a generic opcode though; if you want the +data to be visible in the scriptPubKey, you need to use a new segwit +version with structured data, anyway; so why not just do that? + + + +I think there's maybe a cleverer way of batching / generalising checking +that input/output amounts match. That is, rather than just checking that +"the input's a vault; so the corresponding output must be one of these +possibilities, and the input/output values must exactly match", that +it's generalised to be: + + * set A = the sum of each input that's taking the unvaulting path + from a vault scriptPubKey with #recovery=X + * set B = the sum of each output that has an unvault tag with + #recovery=X + * set C = the sum of each output that has a vault tag with + #recovery=X + * check that A=B+C + +(That allows consolidation of your vault via your hot wallet, just by not +having any unvault outputs, so B=0. I suspect that if you allowed for +keyless consolidation of your vault, that that would be a griefing/DoS +vector) + +This differs from the actual proposal, AIUI, which instead requires that +there are just two outputs - an ephemeral anchor for attaching fees, and +the primary vault or unvault output, and that all the inputs are +vaulting/unvaulting txs. + +I think one meaningful difference between these two approaches is that +the current proposal means unvaulting locks up the entire utxo for the +delay period, rather than just the amount you're trying to unvault. eg, +if you have a single vault utxo X with 1000 BTC, you have delay set to +1008 blocks (1 week), and you decide on Tuesday that you wish to withdraw +50 BTC, creating an unvault tx spending 50 BTC somewhere and 950 BTC back +to your vault, you can't spend any of the 950 BTC for another two weeks: +one week for the unvault to confirm and it to go back into your vault, +and another week for the next unvault to confirm. + +Changing the unvault construction to have an optional OP_VAULT output +would remedy that, I think. + + + +It would be fairly dangerous to combine a construction like this (which +encourages the vault sPK to be reused) with APO signatures on the hot +wallet -- in that case the signature could just be replayed against a +different vault utxo, and you'd be paying for things twice. But provided +that vault spends are only (1) signed by the hot wallet, or (2) being +frozen and moved to the recovery sPK, then you should have complete +control over your utxos/coins, and using APO probably isn't interesting +anyway. + + + +What would it look like to just hide all this under taproot? + +First you'd just leave the internal pubkey as your cold wallet key +(or a NUMS point if your cold wallet is complicated). + +Working backwards, your unvault output needs two script paths: + + 1) move_funds_to(recovery-spk) + 2) <D> OP_CSV; move_funds_to(X) + +Your vault output also needs two paths: + + 1) move_funds_to(recovery-spk) + 2) hot-wallet-script; move_funds_to(unvault[X]) + +That obviously requires a "move_funds_to" operator, which, using +liquid's operators (roughly), could be something like: + + PUSHCURRENTINPUTINDEX + DUP2 INSPECTINPUTVALUE SWAP INSPECTOUTVALUE EQUALVERIFY + INSPECTOUTPUTSCRIPTPUBKEY "x" EQUAL + +which is just ~8 bytes overhead, or could perhaps be something fancier +that supports the batching/consolidation abilities discussed above. + +It also needs some way of constructing "unvault[X]", which could be a +TLUV-like construction. + +That all seems possible to me; though certainly needs more work/thought +than just having dedicated opcodes and stuffing the data directly in +the sPK. + +Cheers, +aj + |