summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Towns <aj@erisian.com.au>2023-01-10 22:29:52 +1000
committerbitcoindev <bitcoindev@gnusha.org>2023-01-10 12:30:03 +0000
commit77e915ac240f327abf488b5c2454e3c86a9ea913 (patch)
treeb1d5c0eef37d31b563a01fb7c150b6f092fc80b7
parent1128f6c1a2b352048fe08a589dfc7fbaa09205e9 (diff)
downloadpi-bitcoindev-77e915ac240f327abf488b5c2454e3c86a9ea913.tar.gz
pi-bitcoindev-77e915ac240f327abf488b5c2454e3c86a9ea913.zip
Re: [bitcoin-dev] OP_VAULT: a new vault proposal
-rw-r--r--00/b21622d1382e8fbde8d303a2561a6df5a84941243
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
+