Git Product home page Git Product logo

near-examples / nft Goto Github PK

View Code? Open in Web Editor NEW
346.0 13.0 267.0 1.51 MB

Example implementations of tokens to represent unique assets, such as collectibles or deeds, using the NEP-171 spec (similar to ERC-721)

Home Page: https://nomicon.io/Standards/NonFungibleToken/Core.html

License: MIT License

Shell 1.07% Rust 68.49% Batchfile 0.29% JavaScript 0.43% TypeScript 29.72%
ready-to-use rust cli

nft's Introduction

Non-fungible Token (NFT)

Note: If you'd like to learn how to create an NFT contract from scratch that explores every aspect of the NEP-171 standard including an NFT marketplace, check out the NFT Zero to Hero Tutorial.

Open in Gitpod

This repository includes an example implementation of a non-fungible token contract which uses near-contract-standards and workspaces-js and -rs tests.


Prerequisites

If you're using Gitpod, you can skip this step.

  • Make sure Rust is installed per the prerequisites in near-sdk-rs.
  • Make sure near-cli is installed.

Explore this contract

The source for this contract is in nft/src/lib.rs. It provides methods to manage access to tokens, transfer tokens, check access, and get token owner. Note, some further exploration inside the rust macros is needed to see how the NonFungibleToken contract is implemented.

Building this contract

Run the following, and we'll build our rust project up via cargo. This will generate our WASM binaries into our res/ directory. This is the smart contract we'll be deploying onto the NEAR blockchain later.

./scripts/build.sh

Testing this contract

We have some tests that you can run. For example, the following will run our simple tests to verify that our contract code is working.

Unit Tests

cd nft
cargo test -- --nocapture

Integration Tests Rust

cd integration-tests/rs
cargo run --example integration-tests

TypeScript

cd integration-tests/ts
yarn && yarn test 

Using this contract

Quickest deploy

You can build and deploy this smart contract to a development account. Dev Accounts are auto-generated accounts to assist in developing and testing smart contracts. Please see the Standard deploy section for creating a more personalized account to deploy to.

near dev-deploy --wasmFile res/non_fungible_token.wasm

Behind the scenes, this is creating an account and deploying a contract to it. On the console, notice a message like:

Done deploying to dev-1234567890123

In this instance, the account is dev-1234567890123. A file has been created containing a key pair to the account, located at neardev/dev-account. To make the next few steps easier, we're going to set an environment variable containing this development account id and use that when copy/pasting commands. Run this command to set the environment variable:

source neardev/dev-account.env

You can tell if the environment variable is set correctly if your command line prints the account name after this command:

echo $CONTRACT_NAME

The next command will initialize the contract using the new method:

near call $CONTRACT_NAME new_default_meta '{"owner_id": "'$CONTRACT_NAME'"}' --accountId $CONTRACT_NAME

To view the NFT metadata:

near view $CONTRACT_NAME nft_metadata

Standard deploy

This smart contract will get deployed to your NEAR account. For this example, please create a new NEAR account. Because NEAR allows the ability to upgrade contracts on the same account, initialization functions must be cleared. If you'd like to run this example on a NEAR account that has had prior contracts deployed, please use the near-cli command near delete, and then recreate it in Wallet. To create (or recreate) an account, please follow the directions in Test Wallet or (NEAR Wallet if we're using mainnet).

In the project root, log in to your newly created account with near-cli by following the instructions after this command.

near login

To make this tutorial easier to copy/paste, we're going to set an environment variable for our account id. In the below command, replace MY_ACCOUNT_NAME with the account name we just logged in with, including the .testnet (or .near for mainnet):

ID=MY_ACCOUNT_NAME

We can tell if the environment variable is set correctly if our command line prints the account name after this command:

echo $ID

Now we can deploy the compiled contract in this example to your account:

near deploy --wasmFile res/non_fungible_token.wasm --accountId $ID

NFT contract should be initialized before usage. More info about the metadata at nomicon.io. But for now, we'll initialize with the default metadata.

near call $ID new_default_meta '{"owner_id": "'$ID'"}' --accountId $ID

We'll be able to view our metadata right after:

near view $ID nft_metadata

Then, let's mint our first token. This will create a NFT based on Olympus Mons where only one copy exists:

near call $ID nft_mint '{"token_id": "0", "receiver_id": "'$ID'", "token_metadata": { "title": "Olympus Mons", "description": "Tallest mountain in charted solar system", "media": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Olympus_Mons_alt.jpg/1024px-Olympus_Mons_alt.jpg", "copies": 1}}' --accountId $ID --deposit 0.1

Transferring our NFT

Let's set up an account to transfer our freshly minted token to. This account will be a sub-account of the NEAR account we logged in with originally via near login.

near create-account alice.$ID --masterAccount $ID --initialBalance 10

Checking Alice's account for tokens:

near view $ID nft_tokens_for_owner '{"account_id": "'alice.$ID'"}'

Then we'll transfer over the NFT into Alice's account. Exactly 1 yoctoNEAR of deposit should be attached:

near call $ID nft_transfer '{"token_id": "0", "receiver_id": "alice.'$ID'", "memo": "transfer ownership"}' --accountId $ID --depositYocto 1

Checking Alice's account again shows us that she has the Olympus Mons token.

Notes

  • The maximum balance value is limited by U128 (2**128 - 1).
  • JSON calls should pass U128 as a base-10 string. E.g. "100".
  • This does not include escrow functionality, as ft_transfer_call provides a superior approach. An escrow system can, of course, be added as a separate contract or additional functionality within this contract.

nft's People

Contributors

adi-igit avatar amgando avatar benkurrek avatar bucanero avatar buckram123 avatar chadoh avatar chaotictempest avatar dependabot-preview[bot] avatar flmel avatar gagdiez avatar gorbunov79 avatar idea404 avatar janedegtiareva avatar mikedotexe avatar nikurt avatar pablolion avatar petersalomonsen avatar teddywaweru avatar thisisjoshford avatar vgrichina avatar volovyks avatar zavodil avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nft's Issues

wasm files outdated

The wasm files in the res folder are outdated. Personally, I think they should be created when the contracts are built and not kept in this repo.

readme changes

  • Currently, when minting an NFT, the user is attaching 10 NEAR, which is too much in my opinion. It only costs around 0.01 NEAR for storage. I've changed the value to 0.1 NEAR to be safe.

  • When attaching 1 yocto, i've changed the parameter to --depositYocto 1 insted of --deposit 0.000...01

  • I added some grammar fixes as well.

NFT did not appear in the wallet

Hey)

If I understand correctly, this is an example of how to design NTF contracts according to the standard. If the contract is designed according to the standard, then the minted tokens should appear in the wallet. Right?

I deployed the contract and followed all the commands from Readme.md, but I cannot see nft in my wallet.

Network: testnet
Contract: market2.plumb.testnet
Account: vkkliq24.testnet

Doesn't build

Follow README to build and get an error.

Error:

error: no matching package named `parity-secp256k1` found
location searched: registry `crates-io`
required by package `near-crypto v0.14.0`
    ... which satisfies dependency `near-crypto = "^0.14"` of package `near-sdk v4.1.1`
    ... which satisfies dependency `near-sdk = "^4.1.1"` of package `approval-receiver v0.0.1 (/Users/mikepurvis/near/NFT/test-approval-receiver)`

Just need to follow the FT example in this same GitHub org

Make sure NFT is not susceptible to the common vulnerabilities that were found in fungible token example

Bug by reusing Set with the same prefix

In the following line the contract reuses the Set, by using the same prefix for all users

Set::new(b"new-access-set".to_vec())

The prefix should uniquely identify the collection. Right now it uses the same prefix for access for all users.

One option is to use prefix like like access-<account_id_hash>

Unable to build project

My command:

./scripts/build.rs

Result:

error: no matching package named `parity-secp256k1` found
location searched: registry `crates-io`
required by package `near-crypto v0.14.0`
    ... which satisfies dependency `near-crypto = "^0.14"` of package `near-sdk v4.1.1`

nft transfer call GAS

When deploying the token receiver contract and the NFT contract, minting a token and calling nft_transfer_call results in an exceeded prepaid GAS error.

STEPS TO REPRODUCE:

  • build and deploy NFT contract and test-token-receiver
  • Call new methods on both contracts
  • Mint an NFT
  • Call nft_transfer_call passing in the test-token-receiver contract as the receiver.

This will result in an exceeded prepaid GAS error as shown here:

Possible solution / where the problem might stem from:
In the core standards repo, the GAS attached to the cross contract call is 30 TGas which can be seen here. This might not be enough.

As an aside - 30 TGas seems like an awful lot of gas and i'm not sure why it would exceed that. In the explorer link here where I only call nft_transfer_call, it uses up 26 TGas before failing at the exceeded prepaid GAS which seems strange to me.

cleanup punchlist

tests fail on M1 Mac with error[E0425]: cannot find function `get_fault_info` in this scope

Hi,

I'm trying to build the NEP171 example contract (ver 5d9f516) from scratch on MacOS 11.6, M1 CPU.
Build succeeds, but tests fail here:

   Compiling clang-sys v0.29.3
error[E0425]: cannot find function `get_fault_info` in this scope
   --> /Volumes/External/mykle/Documents/near/figment/flarn2.0/registry/src/github.com-1ecc6299db9ec823/wasmer-runtime-core-near-0.17.1/src/fault.rs:289:21
    |
289 |         let fault = get_fault_info(siginfo as _, ucontext);
    |                     ^^^^^^^^^^^^^^ not found in this scope

An online search for this error string suggested that this might be an issue with the wasm package requiring rust 'nightly' instead of 'stable'. But 'nightly' wasn't able to compile or test the build.

reporting error in AssemblyScript build

via km1tz on Discord

"The issue is that build script is targeting non existent file (compile.js:18-36)"

Error Message

node:internal/fs/utils:323
    throw err;
    ^

Error: ENOENT: no such file or directory, stat 'out/ts-as.wasm'
    at Object.statSync (node:fs:1132:3)
    at reportFilesize (H:\Programming\NEAR Protocol\NFT-example\contracts\assemblyscript\compile.js:55:20)
    at compileContract (H:\Programming\NEAR Protocol\NFT-example\contracts\assemblyscript\compile.js:38:3)
    at Array.map (<anonymous>)
    at Object.<anonymous> (H:\Programming\NEAR Protocol\NFT-example\contracts\assemblyscript\compile.js:5:16)
    at Module._compile (node:internal/modules/cjs/loader:1091:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1120:10)
    at Module.load (node:internal/modules/cjs/loader:971:32)
    at Function.Module._load (node:internal/modules/cjs/loader:812:14)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12) {
  errno: -4058,
  syscall: 'stat',
  code: 'ENOENT',
  path: 'out/ts-as.wasm'
}

Replicated Locally

yarn build:as
yarn run v1.22.5
$ node ./contracts/assemblyscript/compile.js

compiling contract [ nep4-basic/main.ts ] to [ out/nep4-basic-as.wasm ]
 asconfig.js is deprecated use `asb`to build files.  NOTE: output now in ./build/release/ 
asc /Users/jlwaugh/Desktop/NFT/contracts/assemblyscript/nep4-basic/main.ts -O3z --debug --validate --measure --runPasses inlining-optimizing,dce --optimizeLevel 3 --shrinkLevel 3 --target release --binaryFile build/release/main.wasm
WARNING Unknown option '--validate'
I/O Read   :    13.880 ms  n=320
I/O Write  :     3.245 ms  n=1
Parse      :   918.623 ms  n=133
Initialize :    40.810 ms  n=1
Compile    :   327.185 ms  n=1
Emit       :   139.840 ms  n=1
Validate   :   130.952 ms  n=1
Optimize   :  8465.619 ms  n=1
Transform  :          n/a  n=0
internal/fs/utils.js:269
    throw err;
    ^

Error: ENOENT: no such file or directory, stat 'out/nep4-basic-as.wasm'
    at Object.statSync (fs.js:1016:3)
    at reportFilesize (/Users/jlwaugh/Desktop/NFT/contracts/assemblyscript/compile.js:55:20)
    at compileContract (/Users/jlwaugh/Desktop/NFT/contracts/assemblyscript/compile.js:38:3)
    at Array.map (<anonymous>)
    at Object.<anonymous> (/Users/jlwaugh/Desktop/NFT/contracts/assemblyscript/compile.js:5:16)
    at Module._compile (internal/modules/cjs/loader.js:1015:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1035:10)
    at Module.load (internal/modules/cjs/loader.js:879:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12) {
  errno: -2,
  syscall: 'stat',
  code: 'ENOENT',
  path: 'out/nep4-basic-as.wasm'
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Your .dependabot/config.yml contained invalid details

Dependabot encountered the following error when parsing your .dependabot/config.yml:

Automerging is not enabled for this account. You can enable it from the [account settings](https://app.dependabot.com/accounts/near-examples/settings) screen in your Dependabot dashboard.
Automerging is not enabled for this account. You can enable it from the [account settings](https://app.dependabot.com/accounts/near-examples/settings) screen in your Dependabot dashboard.

Please update the config file to conform with Dependabot's specification using our docs and online validator.

Error when calling new_default_meta: Unknown argument

My contract was deployed successfully, but I am having issues with the JSON file.

When I run this command:

near call $ID new_default_meta '{"owner_id": "'$ID'"}' --accountId $ID

I get this errors:

Unknown argument

or

SyntaxError: Unexpected token in JSON at position 0 or 1

Any idea? Thanks

`NEP4::check_access` isn't to spec

Been looking through the library and had noticed that the NFT example technically isn't to spec on the check_access method.

As per spec it states:
export function check_access(token_id: TokenId): boolean;

which translates to:
fn check_access(&self, token_id: TokenId) -> bool;
in Rust.

However, the NFT example has fn check_access(&self, account_id: AccountId) -> bool; as its method.

References:

Running the Rust NFT example contract throws errors

I am on Ubuntu and have Rust already installed.

Here are the steps I followed:

  • Cloning the repository
  • Going into the rust folder
  • Following the README.md
  • running npm run build:rs throws the following errors
    Screenshot from 2020-07-14 18-44-21
  • I then went to the prerequisites as detailed here but they are for when Rust is not installed so not helpful in this particular case

@janedegtiareva told me to run the following: rustup target add wasm32-unknown-unknown then running npm run build:rs worked like expected.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.