CounterpartyXCP / counterparty-core

Counterparty Protocol Reference Implementation
http://counterparty.io
MIT License
284 stars 206 forks source link

Fair Minting #1843

Closed adamkrellenstein closed 1 month ago

adamkrellenstein commented 4 months ago

It'd be great if we could have a decentralized token minting process, sort of like opening a dispenser on a burn address (which will not be possible after #1785). See https://github.com/mikeinspace/Glyphs/blob/main/README.md

There would be a new transaction which takes two arguments:

  1. fair_minter_id
  2. quantity

The asset associated with the fair minter would be destroyed in quantity quantity, and the asset would be credited to the source. Note: this would allow for fair minting only with XCP and Counterparty assets—not with BTC (as is currently possible with dispensers on unspendable addresses). However, with this method the sent asset supply would be correctly recorded, and it'd be overall a lot cleaner.

reinamora137 commented 4 months ago

Great plan. Or some sort of technique to keep the xcp-20 method of fair minting going

mikeinspace commented 4 months ago

What about a hard-coded set of addresses that are deterministic in some way which can be used for Fair Minting?

Maybe we just need one address. Could be the Counterparty burn address: 1CounterpartyXXXXXXXXXXXXXXXUWLpVr

If anyone can set-up a dispenser on that address alone, I think Fair Minting would still work and it would be a nice homage to the original Counterparty Fair Mint.

DerpHerpenstein commented 3 months ago

I really like this idea.

One good aspect of fair minting is that one tx means one token distribution, ensuring that if one person wants many mints, they must manually mint each one.

Perhaps when you open a dispenser on the burn address, the dispenser will dispense only dispenseAmount regardless of the bitcoin received per tx? Or perhaps a fair mint flag that will allow for this type of distribution?

This would ensure a fair mint and that a couple of users cant clear out the dispenser in a few txs.

mikeinspace commented 3 months ago

@DerpHerpenstein the initial Counterparty burn limited tokens per address, so its certainly possible.

pinnate-modo commented 3 months ago

It seems like the consensus is that using a dispenser burn address was a way to shoehorn minting functionality into Counterparty, but that ideally no BTC would be burned as part of the minting process. This greatly simplifies the implementation of the minting feature, which I've outlined below, based on conversations I've had with folks in the community:

def deploy_mint(source: str
                asset: str,
                quantity_minted: float,
                max_quantity: float,
                max_quantity_per_tx: float,
                max_quantity_per_addr: float,
                royalty: float=0,
                premine: float=0,
                start_block: Optional[int],
                end_block: Optional[int]):

    validate_deploy()

    if not start_block or start_block == util.CURRENT_BLOCK_INDEX:
        credit(source, asset, premine)

def do_mint(source: str,
            asset: str,
            quantity: float
            mint_id: str):

    validate_mint()

    mint_info = get_mint(mint_id)

    royalty_quantity = quantity * mint_info['royalty']
    minter_quantity = quantity - royalty_quantity

    credit(source, asset, minter_quantity)
    credit(mint_info["source"], asset, royalty_quantity)

Open questions:

Curious to hear others' thoughts on the above @mikeinspace @reinamora137 @DerpHerpenstein @adamkrellenstein @Ouziel @droplister @wasthatawolf @adamkrellenstein

valperez715 commented 3 months ago

Hi, all, good to meet you here virtually.

Some quick thoughts:

def deploy_mint(source: str asset: str, quantity_minted: float, max_quantity: float, max_quantity_per_tx: float, max_quantity_per_addr: float, royalty: float=0, premine: float=0, start_block: Optional[int], end_block: Optional[int])

(1) quantity_minted: float: => what is this? (2) max_quantity: float: => I would strongly recommend we change the type from "float" to "bigint", and then introduce "decimal", float type is very tricky, do you consider 12.999999999999999999999999999(many digit after ".") valid? The fact that float number is is not 100% accurately represented in computer system may result in problems. (3) premine: FYI, Casey mentioned that he actually regret to have a "premine" option. I understand Casey's opinion is only his own and may not mean anything. Since there is already a "royalty" option, I am wondering if it is better to just get rid of "premine"?(Don't have a strong opinion on this one). (4)max_quantity_per_addr: I strongly recommend remove this. Looks like it aims to prevent one user from having too many tokens? but user can just use multiple addresses. So i see zero upside on this. The big downside is: some big whale will lose tokens because of this without knowing what happened. And Cex will def hate this. Because they consolidate all the deposit to one address usually. This is adding extra work for them..

def do_mint(source: str, asset: str, quantity: float mint_id: str)

(5) for a mint option: I think user should just get max_quantity_per_tx automatically, not need to provide quantity. I don't see any upside having this option. But the downside is that user may have a lower quantity due to manual errors/typos. Why would someone want to mint less than the max_quantity_per_mint?

(6)We do not want to credit deployer with premine until start_block. What's the best way of watching for start_block? => Can I ask why is this? If there is a "premine", personally I think credit the deployer immediately after deployment makes more sense and less confusing for users.

pinnate-modo commented 3 months ago

Hey @valperez715 thanks for the thoughtful and thorough reply!

(1) quantity_minted: float: => what is this?

Good catch. This would be incremented with each do_mint() rather than as part of the deploy_mint()

(2) max_quantity: float: => I would strongly recommend we change the type from "float" to "bigint" [...]

So all quantities will be denominated in satoshis (or counts, if you will) as it is everywhere else in Counterparty. I was just being sloppy.

(3) premine:

I have no opinion on premine; seems harmless but others know this use-case better than I.

(4) max_quantity_per_addr: I strongly recommend remove this. [...]

So I think there's a bit of confusion here. This doesn't signify how much of an asset an address can hold, but only how much it can mint. I do not see how it can result in loss of funds for users, but maybe I'm missing something? In any case, you're right that it's only a weak deterrent to overminting, but I think it's better than nothing, and I've gathered there's some desire for it. In any case, it can be made optional, I suppose.

(5) for a mint option: I think user should just get max_quantity_per_tx automatically, not need to provide quantity. I don't see any upside having this option. But the downside is that user may have a lower quantity due to manual errors/typos. Why would someone want to mint less than the max_quantity_per_mint?

This sounds totally reasonable to me. I was working by false analogy with proof-of-burn (to which minting is in some respects quite similar). @mikeinspace @adamkrellenstein @ouziel-slama etc. thoughts?

(6)We do not want to credit deployer with premine until start_block. What's the best way of watching for start_block? => Can I ask why is this? If there is a "premine", personally I think credit the deployer immediately after deployment makes more sense and less confusing for users.

I don't have a very strong opinion here but it seems weird for any amount of the asset to exist before its minting period has started. Again, curious to hear others' thoughts.

ouziel-slama commented 1 month ago

@reinamora137 @mikeinspace @DerpHerpenstein @valperez715 @droplister

https://github.com/CounterpartyXCP/counterparty-core/pull/2142