Page MenuHomePhabricator

[Cashtab] Add functions to build and broadcast NFT1 parent fan-out txs
ClosedPublic

Authored by bytesofman on Apr 16 2024, 17:13.

Details

Summary

Minting NFTs requires spending a qty of exactly 1 "NFT Parent" tokens. Most collections are expected to be minted with size > 1. This means Cashtab will need to "fan out" this NFT parent to create token utxos with qty of exactly 1, which can be used to mint NFTs.

Add

  • function to collect SLP1 NFT parent utxos that need to be split out.
  • function to create targetOutputs for a fan-out tx
  • unit tests to create these txs and confirm practicality of input/output collection functions

When NFTs go live in Cashtab, we will probably do this manually. For example, if Cashtab detects that the user has no NFT 1 parent utxos with qty = 1, the "Mint NFT" option will be disabled, and there will be an option "Enable NFT Mints" or something like this. Then the user will click this button and Cashtab will broadcast a tx that creates up to 19 qty 1 utxos.

Will probably be manual because it is challenging to handle the "what if the user goes offline" condition, and very easy to click a button that instantly enables minting. We could do this in the background, for example on app startup or in the useWallet hook, but I don't really want to get in the habit of sending txs without the user's explicit OK. The logic of "does the user need more minting ammo" will be fairly straightforward to hook up with the UI (disable minting if no qty 1 utxos available, enable fan-out tx; disable fan-out tx if no inputs available).

Test Plan

npm test

Diff Detail

Repository
rABC Bitcoin ABC
Branch
nft1-next
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 28611
Build 56763: Build Diffcashtab-tests
Build 56762: arc lint + arc unit

Event Timeline

add functions for getting outputs and for building the txs

bytesofman retitled this revision from [Cashtab] Add function to get desired token inputs for an NFT1 parent fan tx to [Cashtab] Add functions to build and broadcast NFT1 parent fan-out txs.
emack requested changes to this revision.Apr 17 2024, 07:09
emack added a subscriber: emack.
emack added inline comments.
cashtab/src/slpv1/index.js
549–564 ↗(On Diff #47209)

Fabien will point this out as an anti-pattern. Just return the block

578 ↗(On Diff #47209)

can you reference the spec where this maximum 19 dust outputs figure is derived from? And the calculation behind it.

600 ↗(On Diff #47209)

theoretically there shouldn't be any change expected right? Since there are no decimals at play for NFT parents then under what scenario would Cashtab be adding more slp inputs than slp outputs?

This revision now requires changes to proceed.Apr 17 2024, 07:09
bytesofman marked 3 inline comments as done.

improve input selection function, better comments on the max output of 19 param

cashtab/src/slpv1/index.js
578 ↗(On Diff #47209)

added link and explanation where the constant is defined at top of file

The spec does not go into much detail as to why 19 was selected, but I assume it's because this is the most that will fit in a 223-byte OP_RETURN. An SLP1 send tx with 19 outputs has 217 bytes in the OP_RETURN. 20 outputs would be 236 bytes, over the 223 allowed.

Defined in spec as no way to know if OP_RETURN field could be expanded later on. Were this to happen, other parts of SLP may be worth redesigning. Probably was a good idea to keep the spec constant independent of potential protocol changes, at least in this version.

600 ↗(On Diff #47209)

Lots of confusing things about these NFTs from the dev perspective.

  • Per spec, when you mint an SLP1 token, you can only mint to one output (the output at index 1)
  • So, if you want to mint more than 1, all the qty can only be in 1 utxo
  • To "genesis" a child NFT though, we need a utxo of qty exactly 1

So we will have to fan out.

Now, say you have qty 100 of NFT parent. You want to make as many qty 1 utxos as possible.

Your only available input is this qty 100 utxo.

So, 1 input, 100.

As for outputs, you can only have 19 of those. So, at most, you can make 19 qty-1 outputs. However, if you make 19 qty-1 outputs from an input utxo of 100....well, you just burned 81 of the parent token (inputs = 100 and outputs = 19x1 = 19).

So -- we need a change output to keep from burning any of the original qty.

Input 100 -- 18 outputs of 1 -- and a change output of 82. Now inputs === outputs and we can use the new utxo of 82 to create more fan txs in the future.

So, we can only create exactly 19 qty-1 outputs if our input amount happens to be exactly 19.

Function has to handle 3 cases

  • Input utxo(s) of exactly 19 --> create 19 qty-1 outputs and no change
  • Input utxo(s) of more than 19 --> create 18 qty-1 outputs and change
  • Input utxo(s) of less than 19 (say, "n") --> create "n" qty-1 outputs and no change

These 3 cases are the test vectors for this function.

This revision is now accepted and ready to land.Apr 17 2024, 13:02