This should work. I don't see any obvious ways of tampering with it. As long as you are checking against the token name, not the currency symbol, these tokens would be non-fungible and unique.
To build this minting smart contract, I would write 2 scripts (and include a 3rd): a minting policy and a validator to hold the counter datum (and use
Plutus.Contracts.Currency to build your "dummy" NFT).
The validator holds the "dummy" + datum and does all the logic you mentioned above:
- Check that 1 token is minted of designated currency symbol
- Check that the token name is the datum value + 1
- Check that the dummy NFT is returned to the validator with the datum counter bumped
The minting policy just checks that the dummy NFT is included in the transaction.
It's organized this way because Minting Policies don't have datums for storing state (like your counter). It's a fairly common pattern in the Plutus examples. I've been calling it the "Access Control Token" pattern or variations on that. But "dummy NFT" works fine too :). I don't know what the core devs refer to it as.