In TON (The Open Network) smart contracts, the management of Non-Fungible Tokens (NFTs) and TON tokens is a core feature. This tutorial aims to provide you with a comprehensive guide, helping you understand how to use a set of utility functions to manage the sending of NFTs, conduct NFT lotteries, check specific conditions, and send TON tokens.
Tutorial Overview
- Sending NFTs: An introduction to sending NFTs to a specified recipient.
- Conducting NFT Lottery: Demonstrating how to randomly allocate NFTs.
- Checking Specific Conditions: Explaining how to verify that transaction conditions are met.
- Sending TON Tokens: A description of how to send TON tokens to a recipient.
- Supplementary Code: Additional utility functions to enhance the contract.
1. Sending NFTs
Function Definition
The utils::send_nft
function is used to send NFTs.
Parameters
mode
: The sending mode.amount
: The amount to be sent.to
: The recipient’s address.nft_addr
: The NFT address.
Steps
- Verify Ownership: Ensure the sender owns the NFT.
- Construct Message: Create a message containing operation codes, query IDs, etc.
- Send Message: Send the message via the
send_raw_message
function.
Supplementary Code: Ownership Verification
() utils::send_nft(int mode, int amount, slice to, int nft_addr) impure inline_ref {
builder body = begin_cell()
.store_uint(op::transfer(), 32) ;; op
.store_uint(cur_lt(), 64) ;; query id
.store_slice(to) ;; new owner
.store_slice(to) ;; response destination
.store_int(0, 1) ;; custom payload
.store_coins(0) ;; fwd ton amount
.store_int(0, 1); ;; fwd custom payload
builder msg = begin_cell()
.store_uint(0x18, 6)
.store_uint(2, 2) ;; addr std
.store_uint(0, 1) ;; anycast
.store_uint(0, 8) ;; wc
.store_uint(nft_addr, 256)
.store_coins(amount)
.store_uint(1, 1 + 4 + 4 + 64 + 32 + 1 + 1)
.store_ref(body.end_cell());
send_raw_message(msg.end_cell(), mode);
}
2. Conducting NFT Lottery
Function Definition
The utils::raffle_nfts
function randomly assigns NFTs.
Parameters
raffled_nfts
: A dictionary to store the lottery results.nfts
: A dictionary containing all NFTs.
Steps
- Iterate Over NFT Dictionary: Loop through all NFTs.
- Random Allocation: Use a random number to decide the NFT allocation.
- Record Results: Store the results in the
raffled_nfts
dictionary.
cell utils::raffle_nfts(cell raffled_nfts, cell nfts) inline_ref {
int key = -1;
do {
(key, slice data, int found) = nfts.udict_get_next?(256, key);
if (found) {
if (rand(2) == 0) {
raffled_nfts~udict_set(256, key, begin_cell().store_uint(1, 1).end_cell().begin_parse());
} else {
raffled_nfts~udict_set(256, key, begin_cell().store_uint(0, 1).end_cell().begin_parse());
}
}
} until (~ found)
return raffled_nfts;
}
3. Checking Specific Conditions
Function Definition
The utils::check_conditions
function verifies transaction conditions.
Steps
- Initialize Data: Prepare the data needed for the checks.
- Verify Conditions: Check if the conditions for NFT count, token amount, etc., are met.
int utils::check_conditions() inline_ref method_id {
init_data();
return ((db::right_nfts_count == db::right_nfts_received) & (db::left_nfts_count == db::left_nfts_received) &
(db::left_coins_got >= db::left_commission) & (db::right_coins_got >= db::right_commission));
}
4. Sending TON Tokens
Function Definition
The utils::send_tons
function is used to send TON tokens.
Parameters
to
: The recipient’s address.amount
: The amount to be sent.message
: The message content.mode
: The sending mode.
Steps
- Construct Message: Create a message containing the recipient’s address, amount, and message.
- Send Message: Send the message via the
send_raw_message
function.
Supplementary Code: Handling Send Failure
() utils::send_tons(slice to, int amount, slice message, int mode) impure inline_ref {
var msg = begin_cell()
.store_uint(0x18, 6)
.store_slice(to)
.store_coins(amount)
.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
.store_uint(0, 32)
.store_slice(message);
send_raw_message(msg.end_cell(), mode);
}
Supplementary Code
The following are additional features to enhance the robustness and functionality of your smart contract.
Recording NFT Transfer History
(cell, int, int) utils::add_nft(cell dict, int nft_addr) inline_ref {
int left_success = 0;
int right_success = 0;
(slice data, int found) = dict.udict_get?(256, nft_addr);
if (found == 0) {
return (dict, 0, 0);
}
if (data~load_uint(4) == 0) {
dict~udict_set(256, nft_addr, begin_cell().store_uint(2, 4).end_cell().begin_parse());
left_success = -1;
} else {
dict~udict_set(256, nft_addr, begin_cell().store_uint(3, 4).end_cell().begin_parse());
right_success = -1;
}
return(dict, left_success, right_success);
}
Checking if NFT Has Been Sent
int utils::is_nft_sent(int nft_addr) inline_ref {
// Check if NFT has been sent
}
Summary
Throughout this tutorial, we have delved into the key steps involved in handling NFTs and TON tokens within TON smart contracts. By implementing these supplementary codes, you can ensure the robustness of your contract and provide a richer user experience. In practical applications, adjust and optimize these code snippets according to your specific needs. Remember that security, scalability, user experience, compliance, legal considerations, testing, and deployment are all important factors to consider when designing smart contracts.
Extending the Contract
As your smart contract grows and evolves, you may find the need to extend its functionality. Ensure that your contract’s architecture allows for easy integration of new features without compromising existing ones. This could involve modular design, abstraction layers, or the use of libraries to manage complexity.
Community and Collaboration
Participating in the TON community can be invaluable for your contract’s success. Collaborate with other developers, share best practices, and learn from their experiences. Engaging with the community can help you stay up-to-date with the latest developments in the TON ecosystem and ensure that your contract remains relevant.
Monitoring and Maintenance
Once your smart contract is live, ongoing monitoring and maintenance are essential. Set up mechanisms to track the contract’s performance, handle any issues that arise, and apply updates as needed. This may involve setting up alerts for suspicious activity, implementing self-healing mechanisms, or periodic audits to ensure the contract’s integrity.
Conclusion
In conclusion, this tutorial has provided you with a detailed guide on how to handle NFTs and TON tokens within TON smart contracts. By following these steps and considering the additional factors mentioned, you can create a secure, scalable, and user-friendly contract that meets the needs of your application. Remember to continuously learn and adapt to the evolving landscape of smart contract development to stay ahead of the curve.