Skip to content

Commit

Permalink
task3: Georgiafab
Browse files Browse the repository at this point in the history
  • Loading branch information
Georgiafab committed Jun 13, 2024
1 parent 7f6c4a7 commit 9bd9303
Show file tree
Hide file tree
Showing 49 changed files with 160,311 additions and 0 deletions.
3 changes: 3 additions & 0 deletions members/Georgiafab/task3/.env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID="2c01535b38b05886544b0c8c2b544d28"
NEXT_PUBLIC_APP_NAME="nft collection"
NEXT_PUBLIC_EVN="test"
3 changes: 3 additions & 0 deletions members/Georgiafab/task3/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
51 changes: 51 additions & 0 deletions members/Georgiafab/task3/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

node_modules
.env

# Hardhat files
/cache
/artifacts

# TypeChain files
/typechain
/typechain-types

# solidity-coverage files
/coverage
/coverage.json
52 changes: 52 additions & 0 deletions members/Georgiafab/task3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
## task3 介绍

1. 部署在 Sepolia 测试网上
![bind-wallet](./readme/deploy.png "deploy")
2. 提交全部合约文件(ERC20、ERC721、NFTMarket)
在 contract 文件夹中,其他文件用来测试的,忽略掉
3. 提交上架 NFT、购买 NFT 的交易哈希
提交上架 NFT: 0x754e73598b6b0059510532a5b53dd6068dcd81ac3a7cdf9d2ed5d06b1662562d
购买 NFT: 0xf937159ae007f8de3cd163752d66b33a8ad8897926f8e619c9b436c689d864e0

## 环境搭建:

- Hardhat
- react

## 钱包与合约访问

- wagmi
- metamask
- Ethersjs

---

- 编译合约:
`npx hardhat compile`
- 开启本地网络:
`npx hardhat node`
- 在本地网络上测试合约:
`npx hardhat test --network localhost`
- 在本地网络上部署合约:
`npx hardhat ignition deploy ./ignition/modules/ERC20Token.ts --network localhost`

---

开启前端服务:
`npx run dev`

## 合约

# Sample Hardhat Project

This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a Hardhat Ignition module that deploys that contract.

Try running some of the following tasks:

```shell
npx hardhat help
npx hardhat test
REPORT_GAS=true npx hardhat test
npx hardhat node
npx hardhat ignition deploy ./ignition/modules/NFTMarket.ts
```
67 changes: 67 additions & 0 deletions members/Georgiafab/task3/contracts/ERC20Token.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.2 <0.9.0;

contract ERC20Token {
string public name;
string public symbol;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;

event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);

constructor(
string memory _name,
string memory _symbol,
uint256 _totalSupply
) {
name = _name;
symbol = _symbol;
totalSupply = _totalSupply;
balanceOf[msg.sender] = _totalSupply;
}

function transfer(
address _to,
uint256 _value
) external returns (bool success) {
require(balanceOf[msg.sender] >= _value, "Insufficient balance");
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value;
emit Transfer(msg.sender, _to, _value);
return true;
}

function approval(
address _spender,
uint256 _value
) external returns (bool success) {
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}

function transferFrom(
address _from,
address _to,
uint256 _value
) external returns (bool success) {
require(_value <= balanceOf[_from], "Insufficient balance");
require(_value <= allowance[_from][msg.sender], "Allowance exceeded");
balanceOf[_from] -= _value;
balanceOf[_to] += _value;
allowance[_from][msg.sender] -= _value;
emit Transfer(_from, _to, _value);
return true;
}
}

// 0x2AF374aA4DE0559be70b254a49F1A8B7edc23689

// localhost: 0x5FbDB2315678afecb367f032d93F642f64180aa3
73 changes: 73 additions & 0 deletions members/Georgiafab/task3/contracts/ERC721Token.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;

contract ERC721Token {
string public name;
string public symbol;
uint256 public totalSupply;

mapping(uint256 => address) public ownerOf;
mapping(address => uint256[]) public ownedTokens;
mapping(uint256 => address) public approved;
mapping(address => mapping(address => bool)) public operatorApprovals;

event Transfer(address indexed from, address indexed to, uint256 tokenId);
event Approval(
address indexed owner,
address indexed approved,
uint256 tokenId
);

constructor(string memory _name, string memory _symbol) {
name = _name;
symbol = _symbol;
}

function mint(address _to, uint256 _tokenId) external {
require(ownerOf[_tokenId] == address(0), "Token already exists");
ownerOf[_tokenId] = _to;
ownedTokens[_to].push(_tokenId);
totalSupply++;
emit Transfer(address(0), _to, _tokenId);
}

function approve(address _to, uint256 _tokenId) external {
require(msg.sender == ownerOf[_tokenId], "Not token owner");
approved[_tokenId] = _to;
emit Approval(msg.sender, _to, _tokenId);
}

function transferFrom(
address _from,
address _to,
uint256 _tokenId
) external {
require(ownerOf[_tokenId] == _from, "Not token owner");
require(
msg.sender == _from ||
msg.sender == approved[_tokenId] ||
operatorApprovals[_from][msg.sender],
"Not approved"
);
ownerOf[_tokenId] = _to;
// Update owner's token list
uint256[] storage fromTokens = ownedTokens[_from];
for (uint256 i = 0; i < fromTokens.length; i++) {
if (fromTokens[i] == _tokenId) {
fromTokens[i] = fromTokens[fromTokens.length - 1];
fromTokens.pop();
break;
}
}
ownedTokens[_to].push(_tokenId);

emit Transfer(_from, _to, _tokenId);
}

function setApprovalForAll(address _operator, bool _approved) external {
operatorApprovals[msg.sender][_operator] = _approved;
}
}

// 0x6F817c5d3ccd451fd38B4cB77E78d85FD1F0810d
// localhost: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
113 changes: 113 additions & 0 deletions members/Georgiafab/task3/contracts/NFTMarket.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.2 <0.9.0;

import "./ERC20Token.sol";
import "./ERC721Token.sol";

contract NFTMarket {
ERC20Token public tokenContract;
ERC721Token public nftContract;

struct Listing {
address seller; // 上架者地址
address nftContract; // NFT 合约地址
uint256 tokenId; // NFT的Token ID
uint256 price; // 上架价格(使用ERC20代币)
bool active; // 上架状态
}

// 存储所有上架的NFT信息
Listing[] public listings;

// 上架NFT事件
event NFTListed(
uint256 indexed listingId,
address indexed seller,
address indexed nftContract,
uint256 tokenId,
uint256 price
);
// 购买NFT事件
event NFTSold(
uint256 indexed listingId,
address indexed buyer,
address indexed seller,
address nftContract,
uint256 tokenId,
uint256 price
);

// 合约构造函数,初始化ERC20代币合约和ERC721 NFT合约地址
constructor(address _tokenContractAddress, address _nftContractAddress) {
tokenContract = ERC20Token(_tokenContractAddress);
nftContract = ERC721Token(_nftContractAddress);
}
function getTokenContract() external view returns (ERC20Token) {
return tokenContract;
}

function getNftContract() external view returns (ERC721Token) {
return nftContract;
}

// 上架NFT
function listNFT(
address _nftContract,
uint256 _tokenId,
uint256 _price
) external {
// 确保上架者是NFT的所有者
require(nftContract.ownerOf(_tokenId) == msg.sender, "Not token owner");
// 确保上架价格大于零
require(_price > 0, "Price must be greater than zero");

// 将NFT信息添加到上架列表中
listings.push(
Listing(msg.sender, _nftContract, _tokenId, _price, true)
);

// 触发上架NFT事件
emit NFTListed(
listings.length - 1,
msg.sender,
_nftContract,
_tokenId,
_price
);
}

// 购买NFT
function buyNFT(uint256 _listingId) external {
// 获取上架信息
Listing storage listing = listings[_listingId];
// 确保上架状态为激活
require(listing.active, "Listing not active");

// 确保买家拥有足够的ERC20代币用于购买
require(
tokenContract.balanceOf(msg.sender) >= listing.price,
"Insufficient balance"
);

// 从买家转移ERC20代币给卖家
tokenContract.transferFrom(msg.sender, listing.seller, listing.price);
// 从卖家转移NFT给买家
nftContract.transferFrom(listing.seller, msg.sender, listing.tokenId);

// 更新上架状态为非激活
listing.active = false;
// 触发购买NFT事件
emit NFTSold(
_listingId,
msg.sender,
listing.seller,
listing.nftContract,
listing.tokenId,
listing.price
);
}
}

// 0x804D1F8eDcd0dC5F87D25F2B36D0655a7CABf50A
// localhost: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
Loading

0 comments on commit 9bd9303

Please sign in to comment.