Skip to content

Commit

Permalink
completed the basic structure of NFT contract
Browse files Browse the repository at this point in the history
  • Loading branch information
getjake committed Nov 19, 2021
1 parent d2bd002 commit 2c66fe2
Show file tree
Hide file tree
Showing 7 changed files with 27,739 additions and 2 deletions.
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# secrets

# Logs
logs
*.log
Expand Down Expand Up @@ -102,3 +104,13 @@ dist

# TernJS port file
.tern-port

node_modules
.env
coverage
coverage.json
typechain

#Hardhat files
cache
artifacts
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
# project_nft
An NFT project
# Basic Sample Hardhat Project

This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, a sample script that deploys that contract, and an example of a task implementation, which simply lists the available accounts.

Try running some of the following tasks:

```shell
npx hardhat accounts
npx hardhat compile
npx hardhat clean
npx hardhat test
npx hardhat node
node scripts/sample-script.js
npx hardhat help
```
96 changes: 96 additions & 0 deletions contracts/ERC721.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
pragma solidity ^0.8.2;

contract ERC721 {
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 tokenId); // 允许动用单个NFT
event ApprovalForAll(address indexed _owner, address indexed _opeator, bool _approved); // 允许动用这个人下的所有NFT

mapping(address => uint256) internal _balances; // nft 余额数量
mapping(uint256 => address) internal _owners;
mapping(address => mapping(address => bool)) private _operatorApprovals;
mapping(uint256 => address) private _tokenApprovals;



// Returns the num of NFTs assigned to an owner
function balanceOf(address owner) public view returns(uint256){
require(owner != address(0), 'Address is zero');
return _balances[owner];
}

// Finds the owner of an NFT
function ownerOf(uint256 tokenId) public view returns(address){
address owner = _owners[tokenId];
require(owner != address(0), 'TokenID does not exist');
return owner;
}

// Enable / disable an operator to manage all of msg.senders' asset
function setApprovalForAll(address operator, bool approved) public {
_operatorApprovals[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}

// Check if an addr is an operator for an other address
function isApprovedForAll(address owner, address operator) public view returns(bool) {
return _operatorApprovals[owner][operator];
}

// Update an approved address for an NFT 允许这个人搞这个nft 只允许一个人
function approve(address to, uint256 tokenId) public {
address owner = ownerOf(tokenId);
require(msg.sender == owner || isApprovedForAll(owner, msg.sender), 'Msg.sender is not the owner or the approved operator.');
_tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId);
}

// Get the approved address for the single NFT.
function getApproved(uint256 tokenId) public view returns(address) {
require(_owners[tokenId] != address(0), 'TokenID not exist');
return _tokenApprovals[tokenId];
}

// Transfer ownership of an NFT 需要 owner 或者授权代理人操作
function transferFrom(address from, address to, uint tokenId) public {
address owner = ownerOf(tokenId);
require(
msg.sender == owner ||
getApproved(tokenId) == msg.sender ||
isApprovedForAll(owner, msg.sender),
'Msg.sender is not the owner or approved for the transfer'
);

require(owner == from, 'From address is not the owner');
require(to != address(0), 'Address is zero');
require(_owners[tokenId] != address(0), 'TokenID does not exist');
approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;

emit Transfer(from, to, tokenId);
}

// Standard transferFrom
// Check if onERC721Received is implemented WHEN sending to smart contracts
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
transferFrom(from, to, tokenId);
require(_checkOnERC721Received(), 'Receiver not implemented');
}

function safeTransferFrom(address from, address to, uint256 tokenId) public {
safeTransferFrom(from, to, tokenId, "");
}

// Oversimplified
function _checkOnERC721Received() private pure returns(bool) {
return true;
}

// EIP165: Query if the contract implements another interface 确定另一个contract有一个implement.
function supportsInterface(bytes4 interfaceId) public pure virtual returns(bool) {
return interfaceId == 0x80ac58cd;
}


}
21 changes: 21 additions & 0 deletions hardhat.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require("@nomiclabs/hardhat-waffle");

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();

for (const account of accounts) {
console.log(account.address);
}
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
* @type import('hardhat/config').HardhatUserConfig
*/
module.exports = {
solidity: "0.8.4",
};
Loading

0 comments on commit 2c66fe2

Please sign in to comment.