Smart contract costing CCDs

I am trying to create a function which mints a token and charges 20CCD for it. Different documentation seems to describe the process differently and I cannot quite get any of them to work. Do I need to do anything other than simply record the tokenID and owner inside my smart contract? Or do I need to call an external minting function? I have seen both done and am not sure if I am misreading things.

Also, when charging the sender 20 CCDs: what is the code required to convert the Account parameter (20) to an actual CCD value? Which example I follow seems to result in compiler errors. I am assuming these basics are well established and cannot be complicated but I do not seem to be able to find the correct information (or I am just reading it wrong!)

Hi.

If we take this example concordium-rust-smart-contracts/lib.rs at main · Concordium/concordium-rust-smart-contracts · GitHub

This function currently requires that the person minting is the creator concordium-rust-smart-contracts/lib.rs at main · Concordium/concordium-rust-smart-contracts · GitHub

If you want to change that you would make this entrypoint payable receive in concordium_std - Rust

Then you would have someting like

#[receive(contract = "my_contract", name = "mint", payable)]
fn mint<S: HasStateApi>(
    ctx: &impl HasReceiveContext,
    host: &HasHost<MyState, StateApiType = S>,
    amount: Amount
) -> ReceiveResult<MyReturnValue> {...} {
    if amount >= Amount::from_ccd(20) {
         // mint, or do further checks
    } else {
        Err(not enought CCD transferrred for minting)
    }
}

Does that make sense?

Note that with this approach the person wanting to mint the token would have to be the one invoking this entrypoint.

If you have other requirements that can be accommodated as well, but let us know.

That is great, thanks. For some reason I simply could not nail down that syntax, something always seemed to complain!

In this tutorial: Writing the piggy bank smart contract — Concordium documentation

They explain that the blockchain keeps track of the CCD and there is no need to explicitly reference it in the contract. Is the idea that in situations where, for example, I wanted a function which cost 20 CCD to run I would check that the amount was exactly 20CCD, reject any other amount and let the blockchain handle what would happen if the sender did not have enough in their wallet etc?

Yes. That is the idea. If the sender does not have enought the blockchain will handle that case and your entrypoint will not even be called.

What if they put in 25CCD, do I just accept that or do I reject it because it is not 20CCD?

That depends on what you want to do. You could reject if the amount is not exactly 20, or not.

If your entrypoint terminates with success then the amount that was sent will be added to the contract’s account.