diff --git a/CHIPs/chip-0053.md b/CHIPs/chip-0053.md new file mode 100644 index 00000000..674ffd15 --- /dev/null +++ b/CHIPs/chip-0053.md @@ -0,0 +1,314 @@ +CHIP Number | 0053 +:-------------|:---- +Title | Secure the Bag for distributed payouts +Description | An algorithm and implementation for creating a secured bag that optimizes for maximum distribution of payouts +Author | [Dan Perry](https://github.com/danieljperry), [Brandon Haggstrom](https://github.com/Rigidity) +Editor | [Jude Allred](https://github.com/judeallred) +Comments-URI | [CHIPs repo, PR #183](https://github.com/Chia-Network/chips/pull/183) +Status | Draft +Category | Informational +Sub-Category | Guideline +Created | 2025-10-29 +Requires | None + +## Abstract +`Secure the Bag`, originally proposed by [Jeremy Rubin](https://rubin.io) for Bitcoin around 2019, and later renamed to [OP_CHECKTEMPLATEVERIFY](https://github.com/bitcoin/bips/blob/master/bip-0119.mediawiki), is a proposal to create "tree" payments to multiple recipients. [Permuto Capital](https://www.permuto.capital/) will use Secure the Bag to initiate dividend payments to its holders. The optimal structure of a secured bag for making these payments is one in which each intermediate coin contains both large and small payment amounts. This CHIP describes an algorithm for creating this type of secured bag. Ecosystem applications can use the same algorithm to verify that a tree of destination addresses is accurately represented in a secured bag. + +## Motivation +This CHIP gets its motivation from the Permuto Capital trusts, which will make periodic payments to holders of Dividend Certificates (DCs). The exact mechanics of the various Permuto Capital trusts is outside of the scope of this CHIP. See Permuto's website for more info. + +While the examples from this CHIP will deal specifically with Permuto, the CHIP itself provides a generalized solution. One alternative use case would be to air-drop a coin to every holder of an NFT collection. + +### Permuto's Use of Secure the Bag +All addresses that hold a given trust's DCs at the first transaction block after the Record Date (as outlined in the trust's SEC filings) for that trust will later receive a dividend payment. One method of paying these dividends would be to send the funds individually to each address. While this would satisfy the requirement of paying dividends to all holders, its CLVM cost could be quite high. For example, if one million addresses needed to receive a payment, then this method would require at least one million coin spends and creations. In addition, the trust administrator (and not the dividend recipients) would need to pay any associated blockchain fees. + +A more efficient way of making these payments is with Secure the Bag. A certain number of payments (e.g. 100) will be bundled into a single "intermediate" coin. The same number of intermediate coins (100) can then be bundled into another intermediate coin, which can then be bundled into a single coin. As a result, a tree of coins is created. This is known as a "secured bag". + +### Advantages to Using Secure the Bag +This section will list several reasons for using the Secure the Bag technique for making bundled payments. + +#### Distributed Transaction Fees +In example of [Permuto's Use of Secure the Bag](#permutos-use-of-secure-the-bag), in order to distribute the payments, the top coin is spent. This creates 100 intermediate coins, each of which needs to be spent in order to create 100 more intermediate coins apiece, each of which is then spent in order to create the destination coins. If there are 1 million total recipients, then the number of spend bundles that need to be created is `1 + 100 + 100^2 = 10,101`. This is about a 99% reduction from the solution that doesn't use Secure the Bag, in which 1 million individual spend bundles would be needed. + +However, this solution is not a panacea. Even though the number of coins to be spent has been reduced, the total CLVM cost has actually _increased_ by a bit versus sending the coins individually. This increase is due to the requirement that the intermediate coins also be spent. The main advantage to grouping the payments is therefore that anyone can pay the transaction fee to distribute them. The entity that creates the secured bag only needs to create the top coin in the tree, so the fees are more evenly distributed among the holders. + +#### Anyone Can Spend +Another advantage of Secure the Bag is that _anyone_ can spend the top coin and the intermediate coins. This is possible because the intermediate and destination coins are pre-configured in the top coin's Chialisp puzzle. If a user knows that their payment is contained within one of the intermediate coins, then that user can spend the coin, which will distribute the payments to all 100 addresses in this example. + +#### Delayed Unrolling +Once the entity creates a secured bag, their job is done. In the case of Permuto, a secured bag will contain all of the payments for a particular DC for that cycle's dividend distribution. This is true regardless of how many DC holders exist. Permuto only needs to create one coin on the blockchain, and the payments can be unwound at the recipients' leisure. + +This is in stark contrast to the alternative, where Permuto would need to create a new coin for each DC holder. This process might take multiple days if there are millions of holders, not to mention the meticulous accounting that would be involved. + +#### Lazy Unrolling +From an individual's perspective, it is not strictly necessary to spend the coin that contains their payment in order to think of the payment as complete. This is because the coin that contains their payment cannot be modified. Wallets therefore can optionally choose to display a payment that is contained within an intermediate coin as if it were included in the spendable balance. If a user attempts to send those funds elsewhere, the wallet could spend the coin containing the payment in order to unlock its value, and then use identical spend deduplication in order to send the funds elsewhere. Two coin spends would therefore be needed, but they would both occur within the same block. + +In the case of Permuto, this `lazy unrolling` is not likely to be a common occurrence because the dividends will hold substantial value. It is therefore optional for wallets to display the balance of a payment that has not yet been unwound. + +It is also worth noting that if a wallet does implement `lazy unrolling`, it will take on the risk of griefing attacks. If a user attempts to send their portion of the funds from a shared bag, and a griefer simultaneously spends the shared bag, then the original user's spend could be temporarily disrupted. The user would then need to wait to receive their funds from the bag before reattempting the spend. The user wouldn't lose any funds permanently, so the consequences of this attack are minimal. Nevertheless, wallet developers should consider it when deciding whether to implement `lazy unrolling`. + +#### Certainty of Funds +Per the pervious sections, a secured bag might take some time to be unwound. However, the bag is guaranteed to be funded. There is no scenario where the last parts of the bag are unwound several months later, only to discover that the funds were missing. This CHIP provides wallets with a method of reconstructing a secured bag for auditing purposes. As long as both the wallet and the creator of the secured bag follow this CHIP, they will come up with the same coin ID for the top coin in the tree, and the funds contained within will be guaranteed. + +### Key Questions +The primary motivation for this CHIP consists of two questions: + +1. How can the recipient discern which intermediate coin contains their payment? + +There are at least two potential ways to obtain this info. + +#### Primary Method +If the recipient's wallet supports Secure the Bag payments, then it obtains any pending payments from an API call to the issuer when the wallet is syncing. In this case, the wallet could display the payment as "pending" in the transaction history, and it could give the user the opportunity to complete the payment by adding a transaction fee in order to spend the intermediate coin. The wallet could also display the payment as if it were complete, as detailed in the [Lazy Unrolling](#lazy-unrolling) section. + +This method will be detailed in the [Specification](#specification) section once the Wallet SDK implementation is complete. + +#### Alternative Method +The issuer creates a website where users can search for pending payments. If a user wants to complete any of the pending payments, they can do so by clicking a button to connect their wallet via WalletConnect or OAuth. _Anyone_ could use this method to make altruistic spends of any intermediate coin because no signature is needed to spend these coins. + +Ideally, both of these methods will be used. Other methods could be developed as well, as long as the issuer publishes the metadata structure of the tree of coins publicly. This information would most likely be published off chain, but on-chain publication might also make sense in certain cases. + +2. If one of the intermediate coins consists entirely of payments that are lower than the cost of a single blockchain transaction, then who would be willing to spend the coin? + +Either someone would lose money on the transaction, or multiple users would need to pool their funds together to pay the fee. This is a situation we should avoid if at all possible. + +### Additional Considerations +Beyond answering the two [Key Questions](#key-questions), this CHIP could have some additional use cases. For completeness, these are detailed below. However, their implementation details are outside the scope of this CHIP. + +#### Secure the Mint +While this CHIP focuses on the Secure the Bag primitive, the same sorting technique could be used with other distribution types. For example, [Secure the Mint](https://github.com/mintgarden-io/secure-the-mint) provides a way to mint NFTs on demand. If the collection has some pre-conceived notion of ranking the NFTs, then it's possible to distribute them using this CHIP's algorithm. However, beyond noting this possibility, Secure the Mint, as well as similar mechanisms, are outside the scope of this CHIP. + +#### Other Coin Types +This CHIP focuses on distributing tokens created with the CAT2 and Revocable CAT standards. The same technique could also be applied to XCH, as well as other asset types. This includes puzzles that have yet to be invented as of this CHIP's creation. + +#### Tax Implications +The timing of when a payment that uses Secure the Bag is considered "owned" could have implications regarding one's taxes. However, taxation and the timing of ownership are outside of the scope of this CHIP. Taxes depend on the jurisdiction of the payer and payee, and this CHIP does not take any stance on how taxes are to be calculated. Please consult with a professional tax advisor with any questions regarding taxation. + +## Backwards Compatibility +This CHIP doesn't make changes to Chia's consensus, and it is optional for ecosystem developers to implement. It is fully backwards compatible. + +## Rationale +This CHIP was designed to maximize the probability that the intermediate coins in a secured bag will be spent in a timely manner. Each intermediate coin only needs to provide a single blockchain fee, after which several destination coins will be created. This implies that only a small subset of the recipients will need to provide a blockchain fee. It therefore is logical to organize a secured bag with the goal of distributing the value held within as much as possible, so that those with the largest incoming payouts (AKA those most motivated to pay the fee) will have those payouts held within separate coins. + +## Specification + +### Mempool +The specification uses the reference mempool, which has a maximum size of 110 billion cost (10 blocks). However, it is important to note that the Chia blockchain consensus doesn't specify any mempool requirements. Each individual node can run any type, and size, of mempool. In fact, nodes can choose not to run a mempool at all. + +### Input +In order to implement Secure the Bag, at a minimum we need to input a list of destination addresses and amounts. For this CHIP, this input must be a `.csv` (comma-separated value) file where each line uses the following format: + +`
,` + +This file contains 1 or more lines. The `
` can be an address on a Chia testnet (prefix `txch`) or mainnet (prefix `xch`). This file must pertain to only one of the network types, so including both `txch` and `xch` addresses in the same file is not permitted. + +If the `
` is a clawback address (see [CHIP-44](https://github.com/Chia-Network/chips/blob/main/CHIPs/chip-0044.md) for more info), then the initiator might be able to claw back the payment after it is received. However, this depends on the timer specified in the clawback coin. Due to the potential for confusion from both the sender and the receiver, clawback payments are not recommended with this standard. + +The `` should be of either type `CAT2` or `revocable CAT`. Both of these standards use a 64-bit number that is maximally divisible by 1000. Thus, the smallest possible value is `1/1000 = 0.001` and the largest possible value is `(2^64-1)/1000 = 18,446,744,073,709,551.615`. The `` on each line must correspond to the same asset, though this type is not specified in the `.csv` file. + +It is recommended to organize the lines in this file by ``, in descending order (the first line should be the largest amount). The reason for this recommendation is that it will cause the amounts to be distributed evenly when the secured bag is later created. + +If the same `
` were to appear in the `.csv` file multiple times, then the recipient might not receive all of their funds at the same time. This would make it overly complex for both parties to track payments. In addition, the recipient might need to pay multiple transaction fees to receive their whole payment. It would also make the `.csv` file larger than it needs to be, with little benefit. Therefore, this CHIP does not permit duplicate recipient addresses. If a single address is set to receive multiple payments, then the amounts must be combined into a single line in the `.csv` file. + +Finally, there is an edge case where the `.csv` file contains a single line. This is permitted, with the caveat that a root coin is still required. As long as the algorithm listed below is followed, this will already be the case. However, if the sender wants to send the payment directly to the single recipient without a root coin, then they must not use this CHIP. + +### Variables +If the structure of the input `.csv` file is valid, then securing the bag may proceed. Four variables are needed: + +1. `d` -- the number of lines in the input `.csv` file + * This will correspond to the number of destination addresses + * In order to keep the process simple, duplicate addresses are allowed, but are discouraged (they can be consolidated prior to securing the bag) +2. `i1`, `i2`, `i3`, etc -- the **maximum** number of coins to create at the intermediate levels + * `i1` is the number of coins that will be created when the secured bag is spent (ie, the first intermediate level) + * `i2`, `i3`, etc are the number of coins in the subsequent intermediate levels + * The maximum allowed for any any `i` value is `300`; however, because of the risk of incurring high fees when the mempool is busy or full, a smaller number is recommended + * `100` should work in most cases, but could result in more coin spends than are strictly necessary + * Note that for asset types other than CAT2 and Revocable CAT, the CLVM cost could be different enough that the recommended number would be larger or smaller + + Some recommendations for choosing `i1`, `i2`, `i3`, etc: + * If `d <= 10'000`, then `i1` is recommended to be `100` + * Because `sqrt(d) <= 100`, if `i1 = 100`, there will only need to be one level of intermediate coins (`i2` is not needed) + * Each intermediate coin spend will need to pay for less than 1% of a block's space, which should keep transaction fees reasonable, even with a busy (but not full) mempool + * If the mempool is expected to be completely full, then it's possible to set `i1` to a lower value in order to minimize the transaction fee for the intermediate spends, but this comes with tradeoffs: + * The intermediate coins will contain fewer destination coins, so there will be a smaller pool of candidates to pay the fee to spend them + * Another level of intermediate coins will be needed if `sqrt(d) > i1`, which will necessitate paying additional fees + * If `10'000 < d <= 1'000'000`, then using both `i1` and `i2` is recommended + * `i1` is recommended to be `ceiling(d/10'000)` + * `i2` is recommended to be `ceiling((d/i1)/100)` + * If the mempool is expected to be completely full, then either or both of these numbers could deviate from the formula, with the same analysis as shown above + * If `1'000'000 < d <= 100'000'000`, then using `i1`, `i2`, and `i3` is recommended + * `i1` is recommended to be `ceiling(d/1'000'000)` + * `i2` is recommended to be `ceiling((d/i1)/10'000)` + * `i3` is recommended to be `ceiling(((d/i1)/i2)/100)` + * If the mempool is expected to be completely full, then any of these numbers could deviate from the formula, with the same analysis as shown above +3. `c` -- the maximum number of destination coins that will be bundled together + * `c` is recommended to be `100`, regardless of `d` + * If the mempool is expected to be completely full, then `c` can be smaller, with the tradeoffs of having a smaller pool of candidates to pay the final fee, and the possibility of requiring more intermediate levels +4. `n` -- the total number of coins to be created in the final level of intermediate coins + * This number will always be `ceiling(d/c)` + * This number needs to be calculated separately from the highest `i` number because of possible rounding errors + +### Higher n Values +If `n > 100'000'000`, then at least one additional intermediate level will be needed. Follow the same algorithm using these additional levels to create a secured bag with a greater number of addresses. This algorithm scales logarithmically, it should rarely be necessary to use more than three intermediate levels. However, doing so is permitted in this CHIP. + +### Securing the bag + +#### Step 1: Bundle the destination addresses into intermediate coins +Iterate through the input file, and assign each line to a coin number, using ` mod n`. (The intermediate coins won't necessarily each have an identical number of destination coins.) The resulting coins are used in the highest `i` number available (`i1`, `i2`, or `i3`). + +#### Step 2: Bundle intermediate level(s) into the secured bag +If the highest available `i` number is `i1`, then + * Bundle each of the `i1` coins into the secured bag + +Else, if the highest available `i` number is `i2`, then + * Iterate through each coin in `i2` and bundle them to the `i1` coins, using ` mod ` + * Bundle each of the `i1` coins into the secured bag + +Else, if the highest available `i` number is `i3`, then + * Iterate through each coin in `i3` and bundle them to the `i2` coins, using ` mod ` + * Iterate through each coin in `i2` and bundle them to the `i1` coins, using ` mod `. + * Bundle each of the `i1` coins into the secured bag + +### Examples + +This section will give a few examples of how the secured bag is structured using various input values with the above formula. + +#### Example 1 +This is a basic scenario where there are fewer than 10'000 destination coins, and where the number is evenly divisible by 100. + +* `d` = 5000 +* `i1` = 100 +* `c` = 100 +* `n` = 50 + +##### Securing the bag +Step 1: +* Iterate through the 5000 lines (`d`), creating 50 intermediate coins (`n`), each of which contain 100 destination coins (`c`). + +Step 2: +* Bundle the 50 intermediate coins into the secured bag. + +As a result, each of the `n` coins will contain one of the 50 largest destination coins. The idea is that whoever is set to receive the largest payments will be most likely to supply a transaction fee to spend the intermediate coins. + +##### Unrolling the bag +Step 1: +* Anyone can spend the secured bag, which will create 50 intermediate coins + +Step 2: +* Anyone can spend one of the 50 intermediate coins to create 100 destination coins +* Anyone can spend another of the 50 intermediate coins to create 100 destination coins +* Repeat this process until all 50 intermediate coins have been spent + +#### Example 2 +In this example, we barely need to use `i2`, and the number of destination coins is not evenly divisible by 100. + +* `d` = 10'001 +* `i1` = 2 +* `i2` = 51 +* `c` = 100 +* `n` = 101 + +##### Securing the bag +Step 1: +* Iterate through the 10'001 lines (`d`), creating a total of 101 intermediate coins (`n`) in `i2`, 2 of which contain 100 coins, and 99 of which contain 99 coins. + +Step 2: +* Iterate through each of the 101 coins in `i2` and bundle them to the 2 `i1` coins, using ` mod 2` + * One of the `i1` coins will contain 51 `i2` coins, and the other will contain 50 `i2` coins + +Step 3: +* Bundle both of the `i1` coins into the secured bag + +##### Unrolling the bag +Step 1: +* Anyone can spend the secured bag, which will create 2 `i1` intermediate coins + +Step 2: +* Anyone can spend one of the `i1` intermediate coins to create 51 `i2` intermediate coins +* Anyone can spend the other `i1` intermediate coins to create 50 `i2` intermediate coins + +Step 3: +* Anyone can spend one of the 101 `i2` intermediate coins to create either 99 or 100 destination coins +* Anyone can spend another of the 101 `i2` intermediate coins to create either 99 or 100 destination coins +* Repeat this process until all 101 `i2` intermediate coins have been spent + +#### Example 3 +In this example, the number of destination coins is an order of magnitude larger than in Example 1. + +* `d` = 100'000 +* `i1` = 10 +* `i2` = 100 +* `c` = 100 +* `n` = 1000 + +##### Securing the bag +Step 1: +* Iterate through the 100'000 lines (`d`), creating a total of 1000 intermediate coins (`n`) in `i2`, each of which contains destination 100 coins. + +Step 2: +* Iterate through each of the 1000 coins in `i2` and bundle them to the 10 `i1` coins, using ` mod 10` +* Bundle each of the `i1` coins into the secured bag + +##### Unrolling the bag +Step 1: +* Anyone can spend the secured bag, which will create 10 `i1` intermediate coins + +Step 2: +* Anyone can spend one of the 10 `i1` intermediate coins to create 100 `i2` intermediate coins +* Anyone can spend another 10 `i1` intermediate coins to create 100 `i2` intermediate coins +* Repeat this process until all 10 `i1` intermediate coins have been spent + +Step 3: +* Anyone can spend one of the 1000 `i2` intermediate coins to create 100 destination coins +* Anyone can spend another 1000 `i2` intermediate coins to create 100 destination coins +* Repeat this process until all 1000 `i2` intermediate coins have been spent + +### Recreating a Secured Bag +In order to satisfy the first [Key Question](#key-questions) from earlier in this CHIP, there needs to be a way to recreate a secured bag. The difficulty involved with doing this depends on how much information is available. + +#### Memos +It is optional to include a URL in the top level coin (the coin that contains the entire secured bag). If included, then this URL should point to the metadata involved with the original secured bag's creation. Typically, this metadata will include the .csv file, as well as the [variables](#variables) used. + +The URL memo will help wallets to recreate the secured bag, though its inclusion is strictly optional because an individual use case may have a valid rationale against providing it. + +If used, the URL should point to somewhere that is unlikely to be taken down or modified. One example platform for such a URL is the Decentralized Internet Gateway ([DIG Network](https://dig.net/)), which runs on the Chia blockchain. Another example is the InterPlanetary File System ([IPFS](https://www.ipfs.com/)). + +While any memo could contain the URL, it is recommended to use the second memo. This is because the first memo typically is used for hinting. + +#### With the CSV File +Once the .csv file is obtained, it is possible to recreate the secured bag by following the [Securing the Bag](#securing-the-bag) section of this CHIP. To verify the accuracy of the recreated secured bag, compare its simulated coin ID with that of the on-chain equivalent. If the two values don't match, then the recreated secured bag is inaccurate. + +#### Without the CSV File +If the .csv file cannot be obtained, then it could be quite difficult to recreate the secured bag from on-chain data only. Per the [alternative method](#alternative-method) discussed above, the issuer could create a website that shows the structure of the secured bag. + +### Wallet Discovery +In order for the algorithm from this CHIP to be useful, wallets will need to be able to discover pending payments that are currently held in secured bags or destination coins. Below are a few techniques that might be used. + +#### Bulletins +Prior to this CHIP's completion, we will likely release another CHIP to standardize how wallets can send messages to each other, which we are currently calling _bulletins_. + +The bulletin protocol will use the wallet SDK in a publish/subscribe model. Wallet platforms can use the bulletin protocol to send messages to all holders of subscribed coins, for example to inform them that they have a pending payment that is currently held in a secured bag or an intermediate coin. + +We will provide additional information about how bulletins will work for this use case before finishing this CHIP. + +#### Centralized API +The issuer of a secured bag can create an API for wallets to use for discovery. The input value would be an xch or txch address, and the output would be a list of every bag (or intermediate coin) that contains a coins with that address as its destination. + +We may or may not provide such an API as part of this CHIP along with the reference implementation. + +## Test Cases +We will add testcases as the reference implementation is created. + +## Reference Implementation +This CHIP has yet to be implemented. It will be added to the Wallet SDK. + +## Security +This CHIP presents an optional algorithm for bundling coins in a secured bag. Secure the Bag itself has already been used in the CAT2 rollout. The method of bundling coins presented here does not introduce any additional risks beyond those which have already been incurred by Secure the Bag. + +## Additional Assets +None + +## Copyright +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + + +