TZombies
  • ℹ️Introduction
    • The TZombies Tutorial
    • Architecture
  • 🛠️Setup
    • Development environment setup
    • Completium
  • 🤖Smart Contracts
    • FA2 Contract
      • Deploying and testing
    • Marketplace contract
      • Deploying and testing
    • Better testing
    • Token metadata
  • 📖Front-end
    • Architecture
    • Layout
    • Beacon wallet
      • Connect button
    • Contracts
      • Metadata provider
      • Zombies provider
      • Marketplace provider
    • Token display
    • Drops
      • 💳Buy with credit card
    • Inventory
      • Transfer dialog
      • Listing dialog
      • Inventory page
    • Market
      • Buy dialog
      • Market page
  • 🎁Wrap up
    • Conclusion
Powered by GitBook
On this page
  • Template
  • Adjustments
  • Rename the contract
  • Remove token metadata initialisation
  • Remove permits update
  • The mint function
  1. Smart Contracts

FA2 Contract

Archetype multi-asset FA2 contract

PreviousCompletiumNextDeploying and testing

Last updated 1 year ago

Template

The archetype-lang developers published some . The one we're interested in is the FA2 multi-asset contract, that can be found on their .

We'll use the base that we'll adjust according to our needs.

The completium team maintains on the FA2 template and the archetype language. I recommend taking some time to read and understand the contract logic before moving on.

Go to the .

Create a new contracts folder within the tzombies folder and add a copy of permits.arl and fa2_multi.arl

The main logic is in fa2_multi, whereas the permits contract implements special features for the NFT (such as transfer with a permit, that allows the owner to sign a message to allow another account or contract to transfer its NFT).

Adjustments

We will make the following changes to the FA2 template to suit our project:

  • Rename the contract

  • Remove token metadata initialisation

  • Remove permits update

  • Customise the mint function

Rename the contract

The first line is the contract declaration, we'll rename it to fit our project:

archetype tzombies(owner : address, permits : address) with metadata ""

We keep the rest of the declaration defines the parameters required for contract initialization. We can see here that a contract owner, and an address for a permits contract must be given at deployment.

Completium-cli requires the file name to match the contract name. Rename fa2_multi.arl to tzombies.arl

Remove token metadata initialisation

The template comes with a default token metadata for a token with id 0. Let's remove that. Look for section TOKEN METADATA and remove the constants and the initialized by arguments. It should now look like this:

/* TOKEN METADATA ------------------------------------------------------------ */

asset token_metadata to big_map {
  ftoken_metadata : nat;
  token_id        : nat;
  token_info      : map<string, bytes>;
}

Note that it could be a good idea to change the set_token_metadata entrypoint to allow setting it only once, and prevent the update. This would be if you'd want to have immutable metadata for your tokens.

entry set_token_metadata (tid : nat, tdata: map<string, bytes>) {
  no transfer
  called by owner
  require { tmd_r1: is_not_paused() }
  effect {
    token_metadata.add({ ftoken_metadata = tid; token_id = tid; token_info = tdata });
  }
}

Remove permits update

In the default template, the contract owner has the ability to change the permits contract associated. Even though that's a practical solution if the permits contract needs to be updated or fixed, it creates a hazard risk, as the owner could perform a malicious change.

// Remove this section: 
/* PERMITS ----------------------------------------------------------------- */

entry set_permits(p : address) {
  no transfer
  called by owner
  require { p_r1 : is_not_paused() }
  effect {
    permits := p
  }
}

The mint function

We'll customise the mint function that comes with the template.

  1. In the effect section, we'll transfer the sale product for the payable token to the contract owner.

entry mint (tow : address, tid : nat, nbt : nat) {
  require {
     fa2_r5: is_not_paused();
     fa2_r6: token_metadata.contains(tid) otherwise FA2_TOKEN_UNDEFINED;
  }
  effect {
    if tid = 1 then begin
      do_require(transferred = nbt * 2tz, "This token costs 2tz");
      transfer transferred to owner;
    end;

    ledger.add_update((tow, tid), { lamount += nbt });
  }
}

with metadata is an optional key for defining contract metadata. Contract metadata is used to identify the contract on block explorers and wallets, (not to be confused with token metadata). Here, we leave it out with "" but the whole key can be removed. Detailed information on contract metadata can be found in the .

We'd like to have an "open mint" NFT, where anyone can mint. Also, all mints are free, except for token id 1 that will cost 2 ꜩ. See the chapter.

🤖
templates for common or standardised contracts
GitHub
fa2_multi
comprehensive documentation
Archetype FA2 Contract Repo
TZIP-16 proposal
design