summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Greenwood <zachgrw@gmail.com>2021-07-31 22:01:49 +0200
committerbitcoindev <bitcoindev@gnusha.org>2021-07-31 20:02:03 +0000
commit4a3bc80b04e41c8972f4619a439644d5a0707077 (patch)
tree8445cbf349ff455dd3ef9d3f0da225b09cdf6b78
parent2f6e8ff2f06ea97d284c2a7016f751885f9ee9ab (diff)
downloadpi-bitcoindev-4a3bc80b04e41c8972f4619a439644d5a0707077.tar.gz
pi-bitcoindev-4a3bc80b04e41c8972f4619a439644d5a0707077.zip
[bitcoin-dev] Exploring: limiting transaction output amount as a function of total input value
-rw-r--r--a1/b986cd6589e118c8e8e4c161bb0e5ba29d62db344
1 files changed, 344 insertions, 0 deletions
diff --git a/a1/b986cd6589e118c8e8e4c161bb0e5ba29d62db b/a1/b986cd6589e118c8e8e4c161bb0e5ba29d62db
new file mode 100644
index 000000000..57c6c8bd8
--- /dev/null
+++ b/a1/b986cd6589e118c8e8e4c161bb0e5ba29d62db
@@ -0,0 +1,344 @@
+Return-Path: <zachgrw@gmail.com>
+Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133])
+ by lists.linuxfoundation.org (Postfix) with ESMTP id 2B51CC000E
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Sat, 31 Jul 2021 20:02:03 +0000 (UTC)
+Received: from localhost (localhost [127.0.0.1])
+ by smtp2.osuosl.org (Postfix) with ESMTP id 034B140240
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Sat, 31 Jul 2021 20:02:03 +0000 (UTC)
+X-Virus-Scanned: amavisd-new at osuosl.org
+X-Spam-Flag: NO
+X-Spam-Score: 0.602
+X-Spam-Level:
+X-Spam-Status: No, score=0.602 tagged_above=-999 required=5
+ tests=[BAYES_50=0.8, DKIM_SIGNED=0.1, DKIM_VALID=-0.1,
+ DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,
+ HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,
+ SPF_PASS=-0.001] autolearn=ham autolearn_force=no
+Authentication-Results: smtp2.osuosl.org (amavisd-new);
+ dkim=pass (2048-bit key) header.d=gmail.com
+Received: from smtp2.osuosl.org ([127.0.0.1])
+ by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
+ with ESMTP id rG48BDfLQu-F
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Sat, 31 Jul 2021 20:02:01 +0000 (UTC)
+X-Greylist: whitelisted by SQLgrey-1.8.0
+Received: from mail-io1-xd36.google.com (mail-io1-xd36.google.com
+ [IPv6:2607:f8b0:4864:20::d36])
+ by smtp2.osuosl.org (Postfix) with ESMTPS id 3F6B2400C3
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Sat, 31 Jul 2021 20:02:01 +0000 (UTC)
+Received: by mail-io1-xd36.google.com with SMTP id y9so15668740iox.2
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Sat, 31 Jul 2021 13:02:01 -0700 (PDT)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
+ h=mime-version:references:in-reply-to:from:date:message-id:subject:to;
+ bh=OkM6PLv0GL1SBzMy5ghqei4UygikJahTaGSzbGDTN5k=;
+ b=kYLd+ZMv1dG2T4UC6szT3iI7cRjagVE8TGi1wDSCyb865ugs3t1VVeaU36mgR9Wp9x
+ j3D1Ce/tuOvZ8Dx0T7/NokLvlcCCEA7nfRkJ9mlYM2FToFiHRH3SpR7mLiecLnD2bLCm
+ jyh89zkAEYqQ6vh18vp8m7GXo7V7Li7sndHF5/JnfDWRphjF4ppi+A07kseob6fjA0hH
+ y6fye3ImneBu3NkKk+zUPjQ3156nwATQV9Ky38tOomjSTA9Q5KCOB7ZqQctcOtkBsnTy
+ xUMnvvgXwc3peVf3SCBFZ6SeGMQpqwQZZwrLl4sicbPWmL3wDTJzgdd2pM2iWQ9ZhENY
+ GpTg==
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+ d=1e100.net; s=20161025;
+ h=x-gm-message-state:mime-version:references:in-reply-to:from:date
+ :message-id:subject:to;
+ bh=OkM6PLv0GL1SBzMy5ghqei4UygikJahTaGSzbGDTN5k=;
+ b=S0YdeYUTUI9qy/lMtA8MLRERH++kU24gvgYcgAKCjj7GodvQ4Xcymaw2X0Ji68/hRH
+ GMzLR9qp3Wh+yq0a7/9a6MPkfOb3NFL4ffQL2eYqhBrfrcXX+Jy2FHE/0FZiidZBjVgr
+ CdrRXpQ69LAZFAa/mqzycwc7Y6IyM/lBexzNIA7gwel+9W83jUpJA7I9AEETr8vOMV3i
+ N8RsLyNPgAnckYRfniDz7UooUtqIC2QmtPGsvwurnnSpRjz6b19V8B0sB84K/tbCl2vD
+ I1lZklQigLLbwbanabsViaEmHlBklrolhhWT4itiAAmguEWRAy3aYY3TE3iRhs+l4QEH
+ hZjQ==
+X-Gm-Message-State: AOAM532hIGHBQEhrf+5FBXOtTmNc4tYEzheI1vSWeLQ/u83jwulYi0G9
+ NAmXPBHGEGCQAI7kOytS13+DdFCk6uxhKVrH0vLm1Z3BYCY=
+X-Google-Smtp-Source: ABdhPJyPJ57Jl/ohP6NWXUc68j48aO9nMujc8ccEuiBDihMjpOzAmT/8wymj0haR45j9JcAqpvSWyaq+9rRbzr8SB+o=
+X-Received: by 2002:a5d:89d6:: with SMTP id a22mr4674229iot.178.1627761720222;
+ Sat, 31 Jul 2021 13:02:00 -0700 (PDT)
+MIME-Version: 1.0
+References: <CAGpPWDZ0aos5qHw2=popCpjuH7OXC0geEj8i3dwDTfP0j=or4w@mail.gmail.com>
+ <20210725053803.fnmd6etv3f7x3u3p@ganymede>
+ <CAGpPWDZ8EWd7kGV5pFZadQM1kqETrTK2zybsGF1hW9fx2oZb7w@mail.gmail.com>
+ <CAH+Axy7cPufMUCMQbCz2MUgRqQbgenAozPBFD8kPYrSjwcRG8w@mail.gmail.com>
+ <CAGpPWDb8yzGO-VtCO-x09e-phKHT7ezOms+DzeWc9vS3rN1AAw@mail.gmail.com>
+ <CAJ4-pEDWuNfdE4NXkZBsOnuSQ4YOv28YVwGavyiU+FPvpC6y1w@mail.gmail.com>
+ <CAGpPWDZL6BpzoNa0Qgf-Ux60fyWPjZH=NESkgbhEQO_My=XiAg@mail.gmail.com>
+ <CAJ4-pEBwdUJ3kg=yb-kWZLoaX5f_2t353K7Tr+dJy+JpAoKTmQ@mail.gmail.com>
+ <CAGpPWDYMZ+w3VSaLhR68f4WVq7NCUp3SedwW2e8QnRHOgLQqQg@mail.gmail.com>
+In-Reply-To: <CAGpPWDYMZ+w3VSaLhR68f4WVq7NCUp3SedwW2e8QnRHOgLQqQg@mail.gmail.com>
+From: Zac Greenwood <zachgrw@gmail.com>
+Date: Sat, 31 Jul 2021 22:01:49 +0200
+Message-ID: <CAJ4-pEAT8Rrf7dN9A+F2SUvaRz0-DqgDw45whtZcWCTPeQ+uxA@mail.gmail.com>
+To: Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>
+Content-Type: multipart/alternative; boundary="0000000000001ce7e405c870cf42"
+X-Mailman-Approved-At: Sat, 31 Jul 2021 21:50:57 +0000
+Subject: [bitcoin-dev] Exploring: limiting transaction output amount as a
+ function of total input value
+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: Sat, 31 Jul 2021 20:02:03 -0000
+
+--0000000000001ce7e405c870cf42
+Content-Type: text/plain; charset="UTF-8"
+
+Hi list,
+
+I'd like to explore whether it is feasible to implement new scripting
+capabilities in Bitcoin that enable limiting the output amount of a
+transaction based on the total value of its inputs. In other words, to
+implement the ability to limit the maximum amount that can be sent from an
+address.
+
+Two use cases come to mind:
+
+UC1: enable a user to add additional protection their funds by
+rate-limiting the amount they are able to send during a certain period
+(measured in blocks). A typical use case might be a user that intends to
+hodl their bitcoin, but still wishes to occasionally send small amounts.
+This avoids an attacker from sweeping all their funds in a single
+transaction, allowing the user to become aware of the theft and intervene
+to prevent further theft.
+
+UC2: exchanges may wish to rate-limit addresses containing large amounts of
+bitcoin, adding warm- or hot-wallet functionality to a cold-storage
+address. This would enable an exchange to drastically reduce the number of
+times a cold wallet must be accessed with private keys that enable access
+to the full amount.
+
+In a typical setup, I'd envision using multisig such that the user has two
+sets of private keys to their encumbered address (with a "set" of keys
+meaning "one or more" keys). One set of private keys allows only for
+sending with rate-limiting restrictions in place, and a s second set of
+private keys allowing for sending any amount without rate-limiting,
+effectively overriding such restriction.
+
+The parameters that define in what way an output is rate-limited might be
+defined as follows:
+
+Param 1: a block height "h0" indicating the first block height of an epoch;
+Param 2: a block height "h1" indicating the last block height of an epoch;
+Param 3: an amount "a" in satoshi indicating the maximum amount that is
+allowed to be sent in any epoch;
+Param 4: an amount "a_remaining" (in satoshi) indicating the maximum amount
+that is allowed to be sent within the current epoch.
+
+For example, consider an input containing 100m sats (1 BTC) which has been
+rate-limited with parameters (h0, h1, a, a_remaning) of (800000, 800143,
+500k, 500k). These parameters define that the address is rate-limited to
+sending a maximum of 500k sats in the current epoch that starts at block
+height 800000 and ends at height 800143 (or about one day ignoring block
+time variance) and that the full amount of 500k is still sendable. These
+rate-limiting parameters ensure that it takes at minimum 100m / 500k = 200
+transactions and 200 x 144 blocks or about 200 days to spend the full 100m
+sats. As noted earlier, in a typical setup a user should retain the option
+to transact the entire amount using a second (set of) private key(s).
+
+For rate-limiting to work, any change output created by a transaction from
+a rate-limited address must itself be rate-limited as well. For instance,
+expanding on the above example, assume that the user spends 200k sats from
+a rate-limited address a1 containing 100m sats:
+
+Start situation:
+At block height 800000: rate-limited address a1 is created;
+Value of a1: 100.0m sats;
+Rate limiting params of a1: h0=800000, h1=800143, a=500k, a_remaining=500k;
+
+Transaction t1:
+Included at block height 800100;
+Spend: 200k + fee;
+Rate limiting params: h0=800000, h1=800143, a=500k, a_remaining=300k.
+
+Result:
+Value at destination address: 200k sats;
+Rate limiting params at destination address: none;
+Value at change address a2: 99.8m sats;
+Rate limiting params at change address a2: h0=800000, h1=800143, a=500k,
+a_remaining=300k.
+
+In order to properly enforce rate limiting, the change address must be
+rate-limited such that the original rate limit of 500k sats per 144 blocks
+cannot be exceeded. In this example, the change address a2 were given the
+same rate limiting parameters as the transaction that served as its input.
+As a result, from block 800100 up until and including block 800143, a
+maximum amount of 300k sats is allowed to be spent from the change address.
+
+Example continued:
+a2: 99.8 sats at height 800100;
+Rate-limit params: h0=800000, h1=800143, a=500k, a_remaining=300k;
+
+Transaction t2:
+Included at block height 800200
+Spend: 400k + fees.
+Rate-limiting params: h0=800144, h1=800287, a=500k, a_remaining=100k.
+
+Result:
+Value at destination address: 400k sats;
+Rate limiting params at destination address: none;
+Value at change address a3: 99.4m sats;
+Rate limiting params at change address a3: h0=800144, h1=800287, a=500k,
+a_remaining=100k.
+
+Transaction t2 is allowed because it falls within the next epoch (running
+from 800144 to 800287) so a spend of 400k does not violate the constraint
+of 500k per epoch.
+
+As could be seen, the rate limiting parameters are part of the transaction
+and chosen by the user (or their wallet). This means that the parameters
+must be validated to ensure that they do not violate the intended
+constraints.
+
+For instance, this transaction should not be allowed:
+a2: 99.8 sats at height 800100;
+Rate-limit params of a2: h0=800000, h1=800143, a=500k, a_remaining=300k;
+
+Transaction t2a:
+Included at block height 800200;
+Spend: 400k + fees;
+Rate-limit params: h0=800124, h1=800267, a=500k, a_remaining=100k.
+
+This transaction t2a attempts to shift the epoch forward by 20 blocks such
+that it starts at 800124 instead of 800144. Shifting the epoch forward like
+this must not be allowed because it enables spending more that the rate
+limit allows, which is 500k in any epoch of 144 blocks. It would enable
+overspending:
+
+t1: spend 200k at 800100 (epoch 1: total: 200k);
+t2a: spend 400k at 800200 (epoch 2: total: 400k);
+t3a: spend 100k at 800201 (epoch 2: total: 500k);
+t4a: spend 500k at 800268 (epoch 2: total: 1000k, overspending for epoch 2).
+
+Specifying the rate-limiting parameters explicitly at every transaction
+allows the user to tighten the spending limit by setting tighter limits or
+for instance by setting a_remainder to 0 if they wish to enforce not
+spending more during an epoch.
+
+I will stop here because I would like to gauge interest in this idea first
+before continuing work on other aspects. Two main pieces of work jump to
+mind:
+
+Define all validations;
+Describe aggregate behaviour of multiple (rate-limited) inputs, proof that
+two rate-limited addresses cannot spend more than the sum of their
+individual limits.
+
+Zac
+
+--0000000000001ce7e405c870cf42
+Content-Type: text/html; charset="UTF-8"
+Content-Transfer-Encoding: quoted-printable
+
+<div dir=3D"ltr"><div>Hi list,</div><div><br></div><div>I&#39;d like to exp=
+lore whether it is feasible to implement new scripting capabilities in Bitc=
+oin that enable limiting the output amount of a transaction based on the to=
+tal value of its inputs. In other words, to implement the ability to limit =
+the maximum amount that can be sent from an address.</div><div><br></div><d=
+iv>Two use cases come to mind:</div><div><br></div><div>UC1: enable a user =
+to add additional protection their funds by rate-limiting the amount they a=
+re able to send during a certain period (measured in blocks). A typical use=
+ case might be a user that intends to hodl their bitcoin, but still wishes =
+to occasionally send small amounts. This avoids an attacker from sweeping a=
+ll their funds in a single transaction, allowing the user to become aware o=
+f the theft and intervene to prevent further theft.</div><div><br></div><di=
+v>UC2: exchanges may wish to rate-limit addresses containing large amounts =
+of bitcoin, adding warm- or hot-wallet functionality to a cold-storage addr=
+ess. This would enable an exchange to drastically reduce the number of time=
+s a cold wallet must be accessed with private keys that enable access to th=
+e full amount.</div><div><br></div><div>In a typical setup, I&#39;d envisio=
+n using multisig such that the user has two sets of private keys to their e=
+ncumbered address (with a &quot;set&quot; of keys meaning &quot;one or more=
+&quot; keys). One set of private keys allows only for sending with rate-lim=
+iting restrictions in place, and a s second set of private keys allowing fo=
+r sending any amount without rate-limiting, effectively overriding such res=
+triction.</div><div><br></div><div>The parameters that define in what way a=
+n output is rate-limited might be defined as follows:</div><div><br></div><=
+div>Param 1: a block height &quot;h0&quot; indicating the first block heigh=
+t of an epoch;</div><div><div>Param 2: a block height &quot;h1&quot; indica=
+ting the last block height of an epoch;</div><div>Param 3: an amount &quot;=
+a&quot; in satoshi indicating the maximum amount that is allowed to be sent=
+ in any epoch;<br></div><div>Param 4: an amount &quot;a_remaining&quot; (in=
+ satoshi) indicating the maximum amount that is allowed to be sent within t=
+he current epoch.</div></div><div><br></div><div>For example, consider an i=
+nput containing 100m sats (1 BTC) which has been rate-limited with paramete=
+rs (h0, h1, a, a_remaning) of (800000, 800143, 500k, 500k). These parameter=
+s define that the address is rate-limited to sending a maximum of 500k sats=
+ in the current epoch that starts at block height 800000 and ends at height=
+ 800143 (or about one day ignoring block time variance) and that the full a=
+mount of 500k is still sendable. These rate-limiting parameters ensure that=
+ it takes at minimum 100m / 500k =3D 200 transactions and 200 x 144 blocks =
+or about 200 days to spend the full 100m sats. As noted earlier, in a typic=
+al setup a user should retain the option to transact the entire amount usin=
+g a second (set of) private key(s).</div><div><br></div><div>For rate-limit=
+ing to work, any change output created by a transaction from a rate-limited=
+ address must itself be rate-limited as well. For instance, expanding on th=
+e above example, assume that the user spends 200k sats from a rate-limited =
+address a1 containing 100m sats:</div><div><br></div><div>Start situation:<=
+/div><div>At block height 800000: rate-limited address a1 is created;</div>=
+<div>Value of a1: 100.0m sats;</div><div>Rate limiting params of a1: h0=3D8=
+00000, h1=3D800143, a=3D500k, a_remaining=3D500k;</div><div><br></div><div>=
+Transaction t1:</div><div>Included at block height 800100;</div><div>Spend:=
+ 200k + fee;</div><div>Rate limiting params: h0=3D800000, h1=3D800143, a=3D=
+500k, a_remaining=3D300k.</div><div><br></div><div>Result:</div><div>Value =
+at destination address: 200k sats;</div><div>Rate limiting params at destin=
+ation address: none;</div><div>Value at change address a2: 99.8m sats;</div=
+><div>Rate limiting params at change address a2: h0=3D800000, h1=3D800143, =
+a=3D500k, a_remaining=3D300k.</div><div><br></div><div>In order to properly=
+ enforce rate limiting, the change address must be rate-limited such that t=
+he original rate limit of 500k sats per 144 blocks cannot be exceeded. In t=
+his example, the change address a2 were given the same rate limiting parame=
+ters as the transaction that served as its input. As a result, from block 8=
+00100 up until and including block 800143, a maximum amount of 300k sats is=
+ allowed to be spent from the change address.</div><div><br></div><div>Exam=
+ple continued:</div><div>a2: 99.8 sats at height=C2=A0800100;</div><div>Rat=
+e-limit params: h0=3D800000, h1=3D800143, a=3D500k, a_remaining=3D300k;</di=
+v><div><br></div><div>Transaction t2:</div><div>Included at block height 80=
+0200</div><div>Spend: 400k=C2=A0+ fees.</div><div>Rate-limiting params: h0=
+=3D800144, h1=3D800287, a=3D500k, a_remaining=3D100k.<br></div><div><br></d=
+iv><div><div>Result:</div><div>Value at destination address: 400k sats;</di=
+v><div>Rate limiting params at destination address: none;</div><div>Value a=
+t change address a3: 99.4m sats;</div><div>Rate limiting params at change a=
+ddress a3: h0=3D800144, h1=3D800287, a=3D500k, a_remaining=3D100k.</div><di=
+v><br></div><div>Transaction t2 is allowed because it falls within the next=
+ epoch (running from 800144 to 800287) so a spend of 400k does not violate =
+the constraint of 500k per epoch.</div><div><br></div><div>As could be seen=
+, the rate limiting parameters are part of the transaction and chosen by th=
+e user (or their wallet). This means that the parameters must be validated =
+to ensure that they do not violate the intended constraints.</div><div><br>=
+</div><div>For instance, this transaction should not be allowed:</div><div>=
+<div>a2: 99.8 sats at height=C2=A0800100;</div><div>Rate-limit params of a2=
+: h0=3D800000, h1=3D800143, a=3D500k, a_remaining=3D300k;</div><div><br></d=
+iv><div>Transaction t2a:</div><div>Included at block height 800200;</div><d=
+iv>Spend: 400k=C2=A0+ fees;</div><div><div>Rate-limit params: h0=3D800124, =
+h1=3D800267, a=3D500k, a_remaining=3D100k.</div><div><br></div></div><div>T=
+his transaction t2a attempts to shift the epoch forward by 20 blocks such t=
+hat it starts at 800124 instead of 800144. Shifting the epoch forward like =
+this must not be allowed because it enables spending more that the rate lim=
+it allows, which is 500k in any epoch of 144 blocks. It would enable oversp=
+ending:</div></div><div><br></div><div>t1: spend 200k at 800100 (epoch 1: t=
+otal: 200k);</div><div>t2a: spend 400k at 800200 (epoch 2: total: 400k);</d=
+iv><div>t3a: spend 100k at 800201 (epoch 2: total: 500k);</div><div>t4a: sp=
+end 500k at 800268 (epoch 2: total: 1000k, overspending for epoch 2).</div>=
+<div><br></div><div>Specifying the rate-limiting parameters explicitly at e=
+very transaction allows the user to tighten the spending limit by setting t=
+ighter limits or for instance by setting a_remainder to 0 if they wish to e=
+nforce not spending more during an epoch.</div><div><br></div><div>I will s=
+top here because I would like to gauge interest in this idea first before c=
+ontinuing work on other aspects. Two main pieces of work jump to mind:</div=
+><div><br></div><div>Define all validations;</div><div>Describe aggregate b=
+ehaviour of multiple (rate-limited) inputs, proof that two rate-limited add=
+resses cannot spend more than the sum of their individual limits.</div><div=
+><br></div><div>Zac</div><div><br></div><div><br></div><div><br></div><div>=
+<br></div><div><br></div><div><br></div></div></div>
+
+--0000000000001ce7e405c870cf42--
+