Skip to content

Commit

Permalink
Add NFT How To
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr-Electron authored Mar 27, 2024
1 parent d3adc85 commit da31e4e
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
description: How to handle native NFTs on L2 and use them as ERC721
image: /img/logo/WASP_logo_dark.png
tags:
- native
- NFT
- EVM
- how-to
---
import DocCardList from '@theme/DocCardList';

# Native NFT and ERC721

The IOTA L1 can create NFTs, also called native NFTs. To use these NFTs on L2, you have
an ERC20 contract called `ERC721NFTs`, which contains all L1 NFTs owned by the chain. The following guides will show you how to [mint your own L1 NFT from L2](./mint-nft.md) and [use](./use-as-erc721.md) it with the `ERC721NFTs` contract.

<DocCardList />
152 changes: 152 additions & 0 deletions docs/build/isc/v1.0.0-rc.6/docs/how-tos/core-contracts/nft/mint-nft.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
---
description: How to mint L1 NFT
image: /img/logo/WASP_logo_dark.png
tags:
- NFT
- EVM
- how-to
---
import ExampleCodeIntro from '../../../_partials/how-tos/token/_example_code_intro.md';

# Mint an NFT
## About NFTs

The Stardust update allows you to create your own NFTs. You can also use [IRC27](/tips/tips/TIP-0027) for NFTs. This guide will show you how to create an IRC27 L1 NFT using a L2 smart contract.

## Example Code

<ExampleCodeIntro/>

2. Get the senders AgentID:

```solidity
ISCAgentID memory agentID = ISC.sandbox.getSenderAccount();
```

3. Create an `IRC27Metadata` struct with all the needed data:

```solidity
IRC27NFTMetadata memory metadata = IRC27NFTMetadata({
standard: "IRC27",
version: "v1.0",
mimeType: _mimeType,
uri: _uri,
name: _name
});
```

4. Create all the data for the core contract call. To do so, you should create a new `ISCDict` with 2 parameters like specified in the reference docs for [`mintNFT`](../../../reference/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint)
* `I` is the immutable metadata we fill with the IRC27 metadata and
* `a` is the AgendID of the owner of the NFT

```solidity
ISCDict memory params = ISCDict(new ISCDictItem[](2));
params.items[0] = ISCDictItem("I", bytes(IRC27NFTMetadataToString(metadata)));
params.items[1] = ISCDictItem("a", agentID.data);
```

:::info IRC27NFTMetadataToString

The full example below calls the `IRC27NFTMetadataToString` function, which simply converts the IRC27Metadata struct into a string.

:::

5. Call the magic contract `call` function with all the parameters. You should specify the core contract you want to call, which in this case is the [`account`](../../../reference/core-contracts/accounts.md) contract, and the function for [minting an NFT](../../../reference/core-contracts/accounts.md#mintnfti-immutabledata-a-agentid-c-collectionid-w-withdrawonmint)

```solidity
ISCDict memory ret = ISC.sandbox.call(
ISC.util.hn("accounts"),
ISC.util.hn("mintNFT"),
params,
allowance
);
```

6. The call return value will contain a `mintID` which we can use in, for example, another contract function to get the actual L1 NFT ID once it is created using the [`accounts.NFTIDbyMintID`](../../../reference/core-contracts/accounts.md#nftidbymintidd-mintid) function

```solidity
function getNFTIDFromMintID(bytes memory mintID) public view returns (bytes memory) {
ISCDict memory params = ISCDict(new ISCDictItem[](1));
params.items[0] = ISCDictItem("D", mintID);
ISCDict memory ret = ISC.sandbox.callView(
ISC.util.hn("accounts"),
ISC.util.hn("NFTIDbyMintID"),
params
);
return ret.items[0].value;
}
```

### Full Example Code

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@iota/iscmagic/ISC.sol";
contract NFTContract {
event MintedNFT(bytes mintID);
function mintNFT(string memory _name, string memory _mimeType, string memory _uri, uint64 _storageDeposit) public payable {
require(msg.value == _storageDeposit*(10**12), "Please send exact funds to pay for storage deposit");
ISCAssets memory allowance;
allowance.baseTokens = _storageDeposit;
ISCAgentID memory agentID = ISC.sandbox.getSenderAccount();
IRC27NFTMetadata memory metadata = IRC27NFTMetadata({
standard: "IRC27",
version: "v1.0",
mimeType: _mimeType,
uri: _uri,
name: _name
});
ISCDict memory params = ISCDict(new ISCDictItem[](2));
params.items[0] = ISCDictItem("I", bytes(IRC27NFTMetadataToString(metadata)));
params.items[1] = ISCDictItem("a", agentID.data);
ISCDict memory ret = ISC.sandbox.call(
ISC.util.hn("accounts"),
ISC.util.hn("mintNFT"),
params,
allowance
);
emit MintedNFT(ret.items[0].value);
}
function getNFTIDFromMintID(bytes memory mintID) public view returns (bytes memory) {
ISCDict memory params = ISCDict(new ISCDictItem[](1));
params.items[0] = ISCDictItem("D", mintID);
ISCDict memory ret = ISC.sandbox.callView(
ISC.util.hn("accounts"),
ISC.util.hn("NFTIDbyMintID"),
params
);
return ret.items[0].value;
}
function IRC27NFTMetadataToString(IRC27NFTMetadata memory metadata)
public
pure
returns (string memory)
{
return string.concat(
'{"standard": "',
metadata.standard,
'", "version": "',
metadata.version,
'", "type": "',
metadata.mimeType,
'", "uri": "',
metadata.uri,
'", "name": "',
metadata.name,
'"}');
}
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
description: How to use a native NFT like an ERC721 NFT
image: /img/logo/WASP_logo_dark.png
tags:
- NFT
- EVM
- how-to
---

# Use as ERC721
## About the `ERC721NFTs` contract

The `ERC721NFTs` contract is a hardcoded contract at address `0x1074030000000000000000000000000000000000`. Every L1 NFT owned by the chain can be accessed through it. In this example, we will show you how to use it by using `transferFrom`.

## Example Code

1. ERC721 uses the `tokenID` for almost all interactions with it. So first, you should convert the `NFTID` to a `tokenID`:

```solidity
uint256 tokenID = uint256(NFTID.unwrap(nftID));
```

:::info Token ID to NFT ID

You can use the ISCTypes.asNFTID() function to convert a Token ID to an NFT ID, by either using it on a token ID `tokenID.asNFTID();` or passing it to function `ISCTypes.asNFTID(tokenID)`.

:::

2. Transfer the token with ID `tokenID`, by using the `ERC20NFTs` contract, which is exposed in the library as `ISC.nfts`, and calling the standard `transferFrom` function:

```solidity
ISC.nfts.transferFrom(msg.sender, _destination, tokenID);
```
21 changes: 21 additions & 0 deletions docs/build/isc/v1.0.0-rc.6/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,27 @@ module.exports = {
},
],
},
{
type: 'category',
label: 'NFT',
items: [
{
label: 'Introduction',
type: 'doc',
id: 'how-tos/core-contracts/nft/introduction',
},
{
type: 'doc',
label: 'Mint an NFT',
id: 'how-tos/core-contracts/nft/mint-nft',
},
{
type: 'doc',
label: 'Use as ERC721',
id: 'how-tos/core-contracts/nft/use-as-erc721',
},
],
},
{
type: 'doc',
label: 'Get Randomness on L2',
Expand Down

0 comments on commit da31e4e

Please sign in to comment.