APTOS Developer’s Guide | Your first NFT using SDK | Python

This guide describes step by step how to create and transfer NFTs on the Aptos blockchain. The Aptos implementation for basic NFTs or tokens can be found in the token.move file.

Step 1: The Aptos Python SDK.

Aptos has an official, lightly supported Python SDK. It is available on PyPi with source code in the Aptos-core repository on github. Much of the functionality replicates our Typescript SDK. The main purpose of this SDK is to help Python developers get up to speed quickly with Aptos and become an extension of our handbook.

The Python SDK can be installed via pip<###code>, from source, or embedded:

To install via pip:

pip3 install aptos-sdk
Enter fullscreen mode Exit fullscreen mode

To install from pip or builtin: Enter fullscreen mode:

git clone https://github.com/aptos-labs/aptos-core
cd aptos-core/ecosystem/python/sdk
python3 setup.py install
Enter fullscreen mode Exit fullscreen mode

For embedding:

cd /path/to/python/project
cp -r /path/to/aptos-core/ecosystem/python/sdk/aptos-sdk aptos-sdk
Enter fullscreen mode Exit fullscreen mode

Step 2: Execute the example

Every SDK has a directory of examples. This tutorial takes a look at the simple-nft example.

In the SDK directory, run: python -m examples.simple-nft

Step 3. Result

After running the example simple-nft you should see the following result, although some values will be different:

=== Addresses ===
Alice: 0x9df0f527f3a0b445e4d5c320cfa269cdefafc7cd1ed17ffce4b3fd485b17aafb
Bob: 0xfcc74af84dde26b0050dce35d6b3d11c60f5c8c58728ca3a0b11035942a0b1de

=== Initial Balances ===
Alice: 20000
Bob: 20000

=== Creating Collection and Token ===
Alice's collection: {
    "description": "Alice's simple collection",
    "maximum": "18446744073709551615",
    "mutability_config": {
        "description": false,
        "maximum": false,
        "uri": false
    },
    "name": "Alice's",
    "supply": "1",
    "uri": "https://aptos.dev"
}
Alice's token balance: 1
Alice's token data: {
    "default_properties": {
        "map": {
            "data": []
        }
    },
    "description": "Alice's simple token",
    "largest_property_version": "0",
    "maximum": "1",
    "mutability_config": {
        "description": false,
        "maximum": false,
        "properties": false,
        "royalty": false,
        "uri": false
    },
    "name": "Alice's first token",
    "royalty": {
        "payee_address": "0x9df0f527f3a0b445e4d5c320cfa269cdefafc7cd1ed17ffce4b3fd485b17aafb",
        "royalty_points_denominator": "1000000",
        "royalty_points_numerator": "0"
    },
    "supply": "1",
    "uri": "https://aptos.dev/img/nyan.jpeg"
}

=== Transferring the token to Bob ===
Alice's token balance: 0
Bob's token balance: 1

=== Transferring the token back to Alice using MultiAgent ===
Alice's token balance: 1
Bob's token balance: 0
Enter fullscreen mode Exit fullscreen mode

This example shows:

  • Initializing REST and Faucet clients
  • Creating two accounts: Alice and Bob
  • Funding and Creating Alice and Bob Accounts
  • Creating a collection and token using an Alice account
  • Alice offers a token and Bob accepts it
  • Bob unilaterally sends the token to Alice via a multi-agent transaction

Step 4: SDK in details

Step 4.1. Initializing Clients

The first step in the example initializes the REST and Faucet clients. The REST client interacts with the REST API, while the Faucet client interacts with the devnet Faucet service to create and refill accounts.

rest_client = RestClient(NODE_URL)
faucet_client = FaucetClient(FAUCET_URL, rest_client)
Enter fullscreen mode Exit fullscreen mode

common.py initializes these values this way:

NODE_URL = os.getenv("APTOS_NODE_URL", "https://fullnode.devnet.aptoslabs.com/v1")
FAUCET_URL = os.getenv("APTOS_FAUCET_URL", "https://faucet.devnet.aptoslabs.com")
Enter fullscreen mode Exit fullscreen mode

TIP
The default URLs of both services point to our devnet services. However they can be configured with the following variables: APTOS_NODE_URL and APTOS_FAUCET_URL.

Step 4.2. Creating local accounts

The next step is to create two local accounts. The accounts represent the in-network and out-of-network state. The offline state consists of an address and a pair of public and private keys used to authenticate the owner. This step demonstrates how to generate an offline state.

alice = Account.generate()
bob = Account.generate()
Enter fullscreen mode Exit fullscreen mode.

Step 4.3. Creating blockchain accounts

In Aptos, every account must have a representation on the network to support receiving tokens and Coins as well as interacting with other dApps. An account is a medium for storing assets, so it must be explicitly created. This example uses Faucet to create and top up an Alice account and only to create a Bob account:

faucet_client.fund_account(alice.address(), 20_000)
faucet_client.fund_account(bob.address(), 20_000)
Enter fullscreen mode Exit fullscreen mode

Step 4.4. Creating a collection

Now the process of token creation begins. The creator must first create a collection to store the tokens. The collection can contain zero, one, or many individual tokens. The collection does not limit the attributes of the tokens, as it is only a repository.

Your application will call create_collection:

txn_hash = rest_client.create_collection(
    alice, collection_name, "Alice's simple collection", "https://aptos.dev"
)
Enter fullscreen mode Exit fullscreen mode

The create_collection API, which returns the hash of the transaction:

def create_collection(
    self, account: Account, name: str, description: str, uri: str
) -> str:
Enter fullscreen mode Exit fullscreen mode

Step 4.5. Creating token

To create a token, the creator must specify a collection associated with it. The token must be associated with a collection, and this collection must contain the remaining tokens that can be mined. There are many attributes associated with a token, but the API helper reveals only the minimum number needed to create static content.

Your application will call create_token:

txn_hash = rest_client.create_token(
    alice,
    collection_name,
    token_name,
    "Alice's simple token",
    1,
    "https://aptos.dev/img/nyan.jpeg",
    0,
)
Enter fullscreen mode Exit fullscreen mode

The create_token API which returns the hash of the transaction:

def create_token(
    self,
    account: Account,
    collection_name: str,
    name: str,
    description: str,
    supply: int,
    uri: str,
    royalty_points_per_million: int,
) -> str:
Enter fullscreen mode Exit fullscreen mode

Step 4.6. Reading token and collection metadata

Collection and token metadata are stored on the creator account in the Collections table. The SDKs provide convenient shells for queries to these specific areas:

To read collection metadata:

collection_data = rest_client.get_collection(alice.address(), collection_name)
print(f"Alice's collection: {json.dumps(collection_data, indent=4, sort_keys=True)}")
Enter fullscreen mode Exit fullscreen mode.

To read token metadata:

token_data = rest_client.get_token_data(alice.address(), collection_name, token_name, 0)
print(f"Alice's token data: {json.dumps(token_data, indent=4, sort_keys=True)}")
Enter fullscreen mode Exit fullscreen mode

This is how get_token_data queries the token metadata:

def get_token_data(
    self,
    creator: AccountAddress,
    collection_name: str,
    token_name: str,
    property_version: int,
) -> Any:
    token_data = self.account_resource(creator, "0x3::token::Collections")["data"][
        "token_data"
    ]["handle"]

    token_data_id = {
        "creator": creator.hex(),
        "collection": collection_name,
        "name": token_name,
    }

    return self.get_table_item(
        token_data,
        "0x3::token::TokenDataId",
        "0x3::token::TokenData",
        token_data_id,
    )
Enter fullscreen mode Exit fullscreen mode

Step 4.7. Reading token balance

Each token in Aptos is a separate asset, the assets belonging to the user are stored in his TokenStore. To find out the balance:

balance = rest_client.get_token_balance(alice.address(), alice.address(), collection_name, token_name, 0)
print(f"Alice's token balance: {balance}")
Enter fullscreen mode Exit fullscreen mode

Step 4.8. Offering and claiming token rights

Many users have received unwanted tokens, which can cause both minimal discomfort and serious consequences. Aptos gives each account owner the right to decide whether or not to accept one-way transfers. By default, one-way transfers are not supported. Thus, Aptos provides a framework for offering and claiming rights to a token.

To offer a token:

txn_hash = rest_client.offer_token(
    alice,
    bob.address(),
    alice.address(),
    collection_name,
    token_name,
    0,
    1,
)
Enter fullscreen mode Exit fullscreen mode.

To claim a token:

txn_hash = rest_client.claim_token(
    bob,
    alice.address(),
    alice.address(),
    collection_name,
    token_name,
    0,
)
Enter fullscreen mode Exit fullscreen mode

Step 4.9. Secure one-way token transfer

To support a secure one-way token transfer, the sender can first ask the recipient to confirm offline about the upcoming transfer. This takes the form of a multi-agent transaction request. Multi-agent transactions contain multiple signatures, one for each account on the network. Move can then use this to grant signature-level permissions to all signers. For token transfers, this ensures that the receiving party actually wants the token, without requiring the token transfer structure described above.

txn_hash = rest_client.direct_transfer_token(
    bob, alice, alice.address(), collection_name, token_name, 0, 1
)
Enter fullscreen mode Exit fullscreen mode

Оцените статью
devanswers.ru
Добавить комментарий