Skip to content

Commit b85b719

Browse files
committed
Initial commit
0 parents  commit b85b719

11 files changed

+11125
-0
lines changed

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto detect text files and perform LF normalization
2+
* text=auto

.gitignore

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
node_modules
2+
.env
3+
coverage
4+
coverage.json
5+
typechain
6+
typechain-types
7+
8+
# Hardhat files
9+
cache
10+
artifacts
11+

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CardNFT

contracts/SimpleCardNFTFactory.sol

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >0.8.0;
3+
4+
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
5+
6+
//Errors
7+
error No_Simple_Card_NFTs_To_Transfer();
8+
9+
10+
contract SimpleCardNFTFactory is ERC721 {
11+
//State Variables
12+
uint public tokenId; //처음 선언할 때 tokenId=0
13+
14+
struct SimpleCardInfo { //내 명함에 들어가는 기본적인 정보들로 구조체(여러 개의 변수를 하나의 단위로 묶어서 관리할 수 있게 해주는 데이터 타입)를 만듦
15+
//essential
16+
string name;
17+
string email;
18+
address issuer; //발급한 사람. 즉 명함 정보의 주인
19+
20+
//optional
21+
string company;
22+
string university;
23+
string major;
24+
string phone;
25+
string portfolio;
26+
}
27+
28+
mapping(address => SimpleCardInfo ) private _infos; //issuer가 발급한 명함 정보
29+
mapping(address => uint[]) private _tokenIdsMadeByIssuer; //issuer가 발급한 명함의 tokenId들
30+
mapping(address => mapping(uint=> bool)) private _isTokenStillOwnedByIssuer; //issuer가 발급한 tokenId들이 현재 issuer에게 있는지. 있으면 true, 없으면 false
31+
mapping(uint => address) private _issuerOfToken; //tokenId의 issuer
32+
mapping(address => uint) private _amountOfTokenOwnedByIssuer; //issuer가 현재 가지고 있는 자신의 명함 개수(발급한 양 - 남들에게 transfer한 양) //ERC721의 _balances는 자신의 명함 개수 뿐만 아니라 자신이 받은 명함 개수까지 value값으로 가진다는 점에서 이 mapping과 차이점을 가짐.
33+
34+
35+
//Events
36+
event SimpleCardInfoRegistered(
37+
address indexed issuer,
38+
string name,
39+
string email,
40+
string company,
41+
string university,
42+
string major,
43+
string phone,
44+
string portfolio
45+
);
46+
47+
event SimpleCardNFTMinted(
48+
uint indexed tokenId,
49+
address issuer,
50+
uint amountOfTokenOwnedByIssuer
51+
);
52+
53+
event SimpleCardNFTTransfered(
54+
address indexed to,
55+
address from,
56+
uint tokenId,
57+
uint amountOfTokenOwnedByIssuer
58+
);
59+
60+
61+
//Modifiers
62+
modifier isSimpleCardInfoRegistered(){
63+
SimpleCardInfo memory mySimpleCardInfo = _infos[msg.sender];
64+
require(
65+
keccak256(abi.encodePacked(mySimpleCardInfo.name)) != keccak256(abi.encodePacked("")),
66+
"Register your Simple Card info First"
67+
);
68+
_;
69+
}
70+
71+
72+
//Constructors
73+
constructor() ERC721("SimpleCardNFT", "SCard") {}
74+
75+
76+
//Functions
77+
function registerSimpleCardInfo (//자신의 명함 NFT 정보 작성
78+
string memory _name,
79+
string memory _email,
80+
string memory _company,
81+
string memory _university,
82+
string memory _major,
83+
string memory _phone,
84+
string memory _portfolio
85+
)public{
86+
SimpleCardInfo memory simpleCardInfo = SimpleCardInfo({
87+
name:_name,
88+
email:_email,
89+
issuer: msg.sender,
90+
company:_company,
91+
university:_university,
92+
major:_major,
93+
phone:_phone,
94+
portfolio:_portfolio
95+
});
96+
97+
_infos[msg.sender] = simpleCardInfo;
98+
99+
emit SimpleCardInfoRegistered(msg.sender, _name, _email, _company, _university, _major, _phone, _portfolio);
100+
}
101+
102+
function mintSimpleCardNFT () public payable isSimpleCardInfoRegistered{ //자신의 명함 NFT 한 개 발급
103+
tokenId++;
104+
105+
_mint(msg.sender, tokenId);
106+
107+
//tokenIds 관련 매핑 업데이트
108+
uint[] storage tokenIdsMadeByIssuer = _tokenIdsMadeByIssuer[msg.sender];
109+
tokenIdsMadeByIssuer.push(tokenId);
110+
_isTokenStillOwnedByIssuer[msg.sender][tokenId] = true;
111+
_issuerOfToken[tokenId] = msg.sender;
112+
_amountOfTokenOwnedByIssuer[msg.sender]++;
113+
114+
emit SimpleCardNFTMinted(tokenId,msg.sender, _amountOfTokenOwnedByIssuer[msg.sender]);
115+
}
116+
117+
function transferSimpleCardNFT (address to) public isSimpleCardInfoRegistered{
118+
require(_amountOfTokenOwnedByIssuer[msg.sender]!=0,"Mint your Simple Card NFT first");
119+
120+
uint _tokenIdToTransfer;
121+
uint[] memory tokenIdsMadeByIssuer =_tokenIdsMadeByIssuer[msg.sender];
122+
for (uint i=0;i<tokenIdsMadeByIssuer.length;i++) {
123+
uint _tokenIdMadeByIssuer = tokenIdsMadeByIssuer[i];
124+
if (_isTokenStillOwnedByIssuer[msg.sender][_tokenIdMadeByIssuer]==true) {
125+
_tokenIdToTransfer = _tokenIdMadeByIssuer;
126+
break;
127+
}
128+
if ((i==tokenIdsMadeByIssuer.length-1)&&(_isTokenStillOwnedByIssuer[msg.sender][_tokenIdMadeByIssuer]==false)){
129+
revert No_Simple_Card_NFTs_To_Transfer();
130+
}
131+
}
132+
133+
safeTransferFrom(msg.sender, to, _tokenIdToTransfer);
134+
135+
//tokenIds 관련 매핑 업데이트
136+
_isTokenStillOwnedByIssuer[msg.sender][_tokenIdToTransfer]= false;
137+
_amountOfTokenOwnedByIssuer[msg.sender] --;
138+
139+
emit SimpleCardNFTTransfered(to, msg.sender, _tokenIdToTransfer, _amountOfTokenOwnedByIssuer[msg.sender]);
140+
}
141+
142+
143+
//getter 함수
144+
function getSimpleCardInfo(address issuer) external view returns (SimpleCardInfo memory){
145+
return _infos[issuer];
146+
}
147+
148+
function getAmountOfTokenOwnedByIssuer(address issuer) external view returns (uint){
149+
return _amountOfTokenOwnedByIssuer[issuer];
150+
}
151+
152+
}

hardhat.config.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { HardhatUserConfig } from "hardhat/config";
2+
import "@nomicfoundation/hardhat-toolbox";
3+
require("@nomicfoundation/hardhat-toolbox");
4+
require("dotenv").config();
5+
6+
const METAMASK_PRIVATE_KEY = process.env.METAMASK_PRIVATE_KEY;
7+
const SEPOLIA_API_URL = process.env.SEPOLIA_API_URL;
8+
9+
const config: HardhatUserConfig = {
10+
solidity: "0.8.19",
11+
networks: {
12+
sepolia: {
13+
url: SEPOLIA_API_URL,
14+
accounts: [`0x${METAMASK_PRIVATE_KEY}`],
15+
},
16+
},
17+
};
18+
19+
export default config;

0 commit comments

Comments
 (0)