Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add from parameter in the style of other entrypoints and add tests for operators #396

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
e446785
Part 1: simple contract and test, deploy with mockup mode
timothymcmackin Apr 19, 2024
110a138
hide admin for now
timothymcmackin Apr 19, 2024
d0dd173
links to completed contracts and TODOs for troubleshooting
timothymcmackin Apr 19, 2024
5685ac1
not sure about naming
timothymcmackin Apr 19, 2024
792afd1
Adding mint and burn entrypoints
timothymcmackin Apr 19, 2024
f9f6818
Metadata
timothymcmackin Apr 19, 2024
2404b02
Adding a custom entrypoint
timothymcmackin Apr 19, 2024
66013dc
deploying the contract WIP
timothymcmackin Apr 19, 2024
c657fc9
some fixes
timothymcmackin Apr 19, 2024
0e1ac14
Temp links to completed contracts
timothymcmackin Apr 19, 2024
0a2d7ba
Add instructions for adding the custom token to Temple
timothymcmackin Apr 22, 2024
a01b785
Screencap for minting tokens in BCD
timothymcmackin Apr 22, 2024
9954f16
Next steps
timothymcmackin Apr 22, 2024
d2b7432
Simplify initial ledger
timothymcmackin Apr 22, 2024
190da20
Try out minting in mockup mode
timothymcmackin Apr 22, 2024
96aaf82
Simplify
timothymcmackin Apr 22, 2024
8b865d7
clarify
timothymcmackin Apr 22, 2024
970cc5c
clarify
timothymcmackin Apr 22, 2024
63a43ba
Intro
timothymcmackin Apr 22, 2024
c67ee59
Hide todo in a comment
timothymcmackin May 7, 2024
477d6c7
Simplify minting
timothymcmackin May 7, 2024
2b10fff
Clarify customizing entrypoints
timothymcmackin May 7, 2024
1b34722
typo
timothymcmackin May 7, 2024
b72c980
Clarify upload and pin
timothymcmackin May 7, 2024
dccb375
Handle conversions in a batch
timothymcmackin May 7, 2024
eeed841
Clarify pinning
timothymcmackin May 7, 2024
7249e46
link to main branch of contracts
timothymcmackin May 7, 2024
cc0a60a
link to completed contracts
timothymcmackin May 7, 2024
c0f322e
Typo: By contrast...
timothymcmackin May 10, 2024
40724e5
Warning about NFTs and fungibles
timothymcmackin May 10, 2024
db51897
Distinguish contract and token metadata
timothymcmackin May 10, 2024
c7df094
Clarify verifying files by hash
timothymcmackin May 10, 2024
9663198
Pin to ensure that it remains available
timothymcmackin May 10, 2024
42f2e3a
Save your own copy of the data
timothymcmackin May 10, 2024
7ea5289
Capitalization
timothymcmackin May 10, 2024
aeeb970
By convention, two spaces before inline comment
timothymcmackin May 10, 2024
9f3499c
Add from parameter in the style of other entrypoints and add tests fo…
timothymcmackin May 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions docs/tutorials/smartpy-fa2-fungible.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
title: Create a fungible token with the SmartPy FA2 library
authors: Tim McMackin
last_update:
date: 10 May 2024
---

This tutorial shows you how to use SmartPy's FA2 library to create standards-compliant tokens.

In this tutorial you will learn:

- What a fungible token is and how its contract works
- What the FA2 standard is and why token standards are important
- How to use the SmartPy FA2 library to create token contracts
- How to use a local sandbox to test contracts
- How to write custom token behaviors
- How to deploy the contract
- How to interact with tokens directly in wallet apps

## Prerequisites

To run this tutorial, you should have a basic understanding of how Tezos works, what blockchain tokens are, and the ability to use the command-line terminal on your computer.

If you haven't worked with smart contracts before, start with the tutorial https://docs.tezos.com/tutorials/smart-contract.

## What is a fungible token?

Fungible tokens are collections of identical, interchangeable tokens, just like one US dollar or Euro is the same as any other US dollar or Euro.
Any number of different accounts can each have a quantity of a certain fungible token.

By contrast, non-fungible tokens are unique and not interchangeable.
Therefore, only one account can own a specific NFT at one time.

The term "NFT" is often misused when assets are represented on blockchains, and is often confused with a fungible token.
Make sure that you understand the difference.

For more information about types of tokens, see [Tokens](../architecture/tokens).

## What is the FA2 standard?

FA2 is a standard interface for tokens on Tezos.
It supports several different token types, including fungible and non-fungible tokens.

Adhering to the FA2 standard allows developers to create new types of tokens while ensuring that the tokens work with existing wallets and applications.
The FA2 standard leaves enough freedom for developers to define rules for transferring tokens and for how tokens behave.

For more information about FA2 tokens, see [FA2 tokens](../architecture/tokens/FA2).

## What is the SmartPy FA2 library?

The SmartPy FA2 library provides classes and other tools to simplify creating FA2-compliant tokens in the SmartPy language.
You create a contract that inherits from a base class in the library to select a kind of token (fungible, single-asset, or non-fungible).
Then you inherit mixins to customize how the token works.

For more information about the SmartPy FA2 library, see [FA2 lib](https://smartpy.io/guides/FA2-lib/overview) in the SmartPy documentation.

## Tutorial application

In this tutorial, you use the SmartPy FA2 library to create a contract that manages multiple fungible tokens.
You add automated tests to the token, deploy it to a local sandbox, customize it further, and deploy it to a test network.
Finally, you work with the token in your own Tezos wallet.

The completed smart contracts are available here: https://github.com/trilitech/tutorial-applications/tree/main/smartpy_fa2_fungible

When you're ready, move to the next section to start setting up your token.
145 changes: 145 additions & 0 deletions docs/tutorials/smartpy-fa2-fungible/adding-metadata.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
title: "Part 3: Adding metadata"
authors: Tim McMackin
last_update:
date: 10 May 2024
---

In this part, you configure the metadata for the contract.

Contract metadata provides details about the contract itself, including its name, description, and what standards it follows.
This information lets off-chain applications like wallets and block explorers show information about the contract.
Contracts can also store other information in metadata, including the code for off-chain views and information about error messages.

Contracts that manage tokens also store metadata about those tokens, including descriptions of the tokens and links to preview media.

Generally, contracts store their metadata and token metadata off-chain and include only a link to it in their storage.
Storing the metadata off-chain saves space and makes it easier for off-chain applications to access it.

## Storing metadata with IPFS

Many contracts store metadata with the InterPlanetary File System (IPFS) protocol.
This protocol stores files in a decentralized peer-to-peer network and indexes them by their hash.
That way, users can access media by its hash, and the hash allows them to verify that the files have not changed.
As long as one IPFS user has a copy of the data, they can re-upload it to IPFS with the same hash so it is seamlessly available again.

Therefore, uploading data to IPFS doesn't mean that it will be available forever; at least one user must keep a copy of it.
Instructing an IPFS node to keep a copy of a file is called _pinning_ the file.
SmartPy provides a function that uploads data to IPFS via the Pinata service and instructs Pinata to pin it.

## Tutorial contract

The completed contract that you create in this part is at [part_3_complete.py](https://github.com/trilitech/tutorial-applications/blob/main/smartpy_fa2_fungible/part_3_complete.py).

## Getting a Pinata API key

SmartPy test scenarios can upload files to IPFS with [Pinata](https://www.pinata.cloud/), so to follow this part of the tutorial, you need a free account on https://www.pinata.cloud and an API key.

Follow these steps to create a Pinata API key:

1. Create a free Pinata account at https://app.pinata.cloud/developers/api-keys.

1. Go to the API Keys tab and click **New Key**.

1. On the Create New API Key page, expand API Endpoint Access and enable the `pinFileToIPFS` permission, as in this picture:

<img src="/img/tutorials/pinata-key-permissions.png" alt="Selecting the permissions for the Pinata key" style={{width: 300}} />

1. In the **Key Name** field, give the key a name, such as "My Key."

1. Click **Create Key**.

The API Key Info window shows the API key and secret, which you must copy immediately, because it is not shown again.

1. Copy the API Key and API Secret fields and save the values on your computer.
You need these values in the next section.

You can see the new API key on the API Keys tab:

![The new Pinata API key in the Pinata web app](/img/tutorials/created-pinata-key.png)

## Uploading metadata

The SmartPy `sp.pin_on_ipfs` function uploads metadata to IPFS via your Pinata account and "pins" it to ensure that it remains available until you remove it.
In this section, you add code to use this function to upload and pin contract metadata to IPFS when the test scenario runs.
It is still advisable to save a local copy of your metadata, just as you would with any upload service.

1. After the code that instantiates the contract in the test scenario, use the `sp.create_tzip16_metadata` function to create a metadata object that is compatible with the [TZIP-16](https://gitlab.com/tezos/tzip/-/blob/master/proposals/tzip-16/tzip-16.md) standard for contract metadata:

```smartpy
# Build contract metadata content
contract_metadata = sp.create_tzip16_metadata(
name="My FA2 fungible token contract",
description="This is an FA2 fungible token contract using SmartPy.",
version="1.0.0",
license_name="CC-BY-SA",
license_details="Creative Commons Attribution Share Alike license 4.0 https://creativecommons.org/licenses/by/4.0/",
interfaces=["TZIP-012", "TZIP-016"],
authors=["SmartPy <https://smartpy.io/#contact>"],
homepage="https://smartpy.io/ide?template=fa2_lib_fungible.py",
# Optionally, upload the source code to IPFS and add the URI here
source_uri=None,
offchain_views=contract.get_offchain_views(),
)
```

This code must come after you create the contract because it uses the `contract.get_offchain_views` function to retrieve the contract's off-chain views.
Off-chain views are stored in metadata, not in the contract code or storage.

1. Optional: Edit the metadata fields with information about your contract.

1. Add permission information to the metadata with this code:

```smartpy
# Add the info specific to FA2 permissions
contract_metadata["permissions"] = {
# The operator policy chosen:
# owner-or-operator-transfer is the default.
"operator": "owner-or-operator-transfer",
# Those two options should always have these values.
# It means that the contract doesn't use the hook mechanism.
"receiver": "owner-no-hook",
"sender": "owner-no-hook",
}
```

This metadata describes who is allowed to transfer tokens.
The permissions in this code allow token owners and operators to transfer tokens.
For more information about operators, see [FA2 tokens](../../architecture/tokens/FA2).

1. Pin the metadata to IPFS and get its URI with this code:

```smartpy
# Upload the metadata to IPFS and get its URI
metadata_uri = sp.pin_on_ipfs(contract_metadata, api_key=None, secret_key=None)
```

1. Update the `None` values in the `sp.pin_on_ipfs` function with your Pinata API key and secret key.
You can also put them in the `PINATA_KEY` and `PINATA_SECRET` environment variables and remove the `api_key` and `secret_key` parameters from the function call.

1. Create the contract metadata and add it to the contract with this code:

```smartpy
# Create the metadata big map based on the IPFS URI
contract_metadata = sp.scenario_utils.metadata_of_url(metadata_uri)

# Update the scenario instance with the new metadata
contract.data.metadata = contract_metadata
```

This code creates a big map that has a single entry that points to the metadata URI.

1. Run the `python fa2_fungible.py` command to compile and test your contract.
Now, SmartPy uploads the metadata as part of the compilation process.

1. In your Pinata account, verify that the metadata file uploaded correctly.
By default, the file is named "No name set" and looks like this in your Pinata files:

![The uploaded file on Pinata](/img/tutorials/pinata-pinned-file.png)

You can click this file to see it and verify that the name and description at the top of the file match the name and description of your contract.
The rest of the file is the code of off-chain views that the FA2 library adds automatically.

The completed contract is at [part_3_complete.py](https://github.com/trilitech/tutorial-applications/blob/main/smartpy_fa2_fungible/part_3_complete.py).

Now when you deploy the completed contract, wallets and block explorers can show information about it.
Loading
Loading