Can src20,src7 mint only mint to the contract address?

contract

contract;
mod interface;
use ::interface::MintEvent;
use ::interface::Constructor;

use asset::{
    base::{
    _total_assets, 
    _total_supply,
    _name,
    _symbol,
    _decimals
    },
    };

use asset::mint::{_mint, _burn};
use src20::SRC20;
use src3::SRC3;
use std::{asset::mint_to,hash::{Hash, sha256}, string::String, storage::storage_string::*};

storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        _total_assets(storage.total_assets)
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        _total_supply(storage.total_supply, asset)
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        _name(storage.name, asset)
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        _symbol(storage.symbol, asset)
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        _decimals(storage.decimals, asset)
    }

}

impl SRC3 for Contract {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: SubId, amount: u64) {
        // 记录参数信息
        // let asset_id = _mint(storage.total_assets, storage.total_supply, recipient, sub_id, amount);
        let asset_id = AssetId::new(ContractId::this(), sub_id);
        log(MintEvent{
            asset_id: asset_id,
        });
        storage.total_supply.insert(asset_id, storage.total_supply.get(asset_id).try_read()
                    .unwrap_or(0) + amount);
        storage.total_assets.write(storage.total_assets.read() + amount);
        // mint_to(recipient, sub_id, amount);
        // _mint(storage.total_assets, storage.total_supply, recipient, sub_id, amount);
        mint_to(recipient, sub_id, amount);
       
    }

    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        _burn(storage.total_supply, sub_id, amount);
    }
}

impl Constructor for Contract {
    /// Sets the defaults for the contract.
    ///
    /// # Arguments
    ///
    /// * `owner`: [Identity] - The `Identity` that will be the first owner.
    ///
    /// # Reverts
    ///
    /// * When ownership has been set before.
    ///
    /// # Number of Storage Acesses
    ///
    /// * Reads: `1`
    /// * Write: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use standards::src5::SRC5;
    /// use native_asset::Constructor;
    ///
    /// fn foo(contract: ContractId, owner: Identity) {
    ///     let src_5_abi = abi(SRC5, contract.bits());
    ///     assert(src_5_abi.owner() == State::Uninitialized);
    ///
    ///     let constructor_abi = abi(Constructor, contract.bits());
    ///     constructor_abi.constructor(owner);
    ///     assert(src_5_abi.owner() == State::Initialized(owner));
    /// }
    /// ```

    #[storage(read, write)]
    fn constructor(owner: Identity) {
        
    }   

    fn asset_id(sub_id: SubId) -> AssetId {
        AssetId::new(ContractId::this(), sub_id)
    }
}


test

 let (instance, instance1, contract_id, wallet, wallet1) = get_contract_instance().await;

    // Check initial total assets
    let total_assets = instance.methods().total_assets().call().await.unwrap();
    println!("Initial total assets: {:?}", total_assets.value);

    let my_asset = AssetId::default();
    let sub_id_array = [0u8; 32];
    let sub_id = Bits256(sub_id_array);
    let asset_id = AssetId::new(sub_id_array);

    println!("asset_id = {:?}",asset_id);
    println!("my_asset = {:?}",my_asset);
    let asset_id1 = instance.methods().asset_id(sub_id).call().await.unwrap();
    let asset = asset_id1.value;
    println!("asset_id1: {:?}", asset);
    
    let recipient = Identity::Address(wallet.address().into());
    // let recipient = Identity::ContractId(contract_id);
    
     println!("Minting: recipient = {:?}, sub_id = {:?}, amount = {:?}", recipient, sub_id, 10);

// Mint new assets
    // Mint new assets
    let mint_result = instance.methods().mint(recipient.clone(), sub_id, 10).call().await;
    match mint_result {
        Ok(response) => {
            println!("Mint successful: {:?}", response);
        }
        Err(e) => {
            println!("Mint failed: {:?}", e);
        }
    }

errors

RevertTransactionError { reason: "failed transfer to address.", revert_id: 18446744073709486081, receipts: [Call { id: 0000000000000000000000000000000000000000000000000000000000000000, to: 3f6706ce575cb04a0cf2006970dd4b21a90584e2eaad782db6b538d1d5779144, amount: 0, asset_id: 0000000000000000000000000000000000000000000000000000000000000000, gas: 3074, param1: 3596839292, param2: 10448, pc: 11712, is: 11712 }, LogData { id: 3f6706ce575cb04a0cf2006970dd4b21a90584e2eaad782db6b538d1d5779144, ra: 0, rb: 1, ptr: 20968, len: 32, digest: c0f6188233585fd45935bc5302baa35e1dae00a0aa7d51d557669f14738777f3, pc: 16552, is: 11712, data: Some(826e200e92829be36da056be23...) }, Mint { sub_id: 0000000000000000000000000000000000000000000000000000000000000000, contract_id: 3f6706ce575cb04a0cf2006970dd4b21a90584e2eaad782db6b538d1d5779144, val: 10, pc: 18364, is: 11712 }, Revert { id: 3f6706ce575cb04a0cf2006970dd4b21a90584e2eaad782db6b538d1d5779144, ra: 18446744073709486081, pc: 18652, is: 11712 }, ScriptResult { result: Revert, gas_used: 3110 }] }

But you can succeed with conntract address.

  let recipient = Identity::ContractId(contract_id);

Hi @lopo1 ,

Without getting too deep into your example specifically, minting is typically standardized to be able to mint either to the contract itself or externally to other owners outside of the contract.

It may be the case that the transaction itself is not setup correctly (i.e. you haven’t included the appropriate output to represent the minted value from the smart contract).

It may be the case you need an additional variable output here in order to make this work.

I’d consider looking at the Sway Standards tests and examples. We will also be including many more examples and documentation to support developers using these native asset features coming up.

Please be sure to add .append_variable_outputs(1) to your contract call in the SDK when sending to an address.

let mint_result = instance
    .methods()
    .mint(recipient.clone(), sub_id, 10)
    .append_variable_outputs(1)
    .call()
    .await;
3 Likes