Skip to content

Commit

Permalink
Merge pull request #972 from qiaopengjun5162/task3
Browse files Browse the repository at this point in the history
task3: qiaopengjun5162
  • Loading branch information
linghuccc authored Jul 1, 2024
2 parents 250e2ff + 0ee194e commit e54f2c6
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 0 deletions.
22 changes: 22 additions & 0 deletions members/qiaopengjun5162/task3/ERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";

contract MyToken is ERC20, ERC20Burnable, Ownable, ERC20Permit {
constructor(
address initialOwner
)
ERC20("MyERC20Token", "MTK")
Ownable(initialOwner)
ERC20Permit("MyERC20Token")
{}

function mint(address to, uint256 amount) public onlyOwner {
_mint(to, amount);
}
}
59 changes: 59 additions & 0 deletions members/qiaopengjun5162/task3/ERC721.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";

contract MyToken is
ERC721,
ERC721URIStorage,
ERC721Pausable,
Ownable,
ERC721Burnable
{
uint256 private _nextTokenId;

constructor(
address initialOwner
) ERC721("MyERC721Token", "MTKERC721") Ownable(initialOwner) {}

function pause() public onlyOwner {
_pause();
}

function unpause() public onlyOwner {
_unpause();
}

function safeMint(address to, string memory uri) public onlyOwner {
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}

// The following functions are overrides required by Solidity.

function _update(
address to,
uint256 tokenId,
address auth
) internal override(ERC721, ERC721Pausable) returns (address) {
return super._update(to, tokenId, auth);
}

function tokenURI(
uint256 tokenId
) public view override(ERC721, ERC721URIStorage) returns (string memory) {
return super.tokenURI(tokenId);
}

function supportsInterface(
bytes4 interfaceId
) public view override(ERC721, ERC721URIStorage) returns (bool) {
return super.supportsInterface(interfaceId);
}
}
82 changes: 82 additions & 0 deletions members/qiaopengjun5162/task3/NFTMarket.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/interfaces/IERC721.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

contract Market is ReentrancyGuard {
struct Listing {
address seller;
address nftContract;
uint256 tokenId;
uint256 price;
bool isActive;
}

IERC20 public paymentToken;
mapping(address => mapping(uint256 => Listing)) public listings;

event NFTListed(
address indexed seller,
address indexed nftContract,
uint256 indexed tokenId,
uint256 price
);

event NFTPurchased(
address indexed buyer,
address indexed nftContract,
uint256 indexed tokenId,
uint256 price
);

constructor(address _paymentToken) {
paymentToken = IERC20(_paymentToken);
}

function listNFT(
address _nftContract,
uint256 _tokenId,
uint256 _price
) external {
IERC721 nft = IERC721(_nftContract);
require(nft.ownerOf(_tokenId) == msg.sender, "NFT not owned by you");
require(
nft.isApprovedForAll(msg.sender, address(this)),
"Not approved for this contract"
);
listings[_nftContract][_tokenId] = Listing(
msg.sender,
_nftContract,
_tokenId,
_price,
true
);
emit NFTListed(msg.sender, _nftContract, _tokenId, _price);
}

function buyNFT(
address _nftContract,
uint256 _tokenId
) external nonReentrant {
Listing storage listing = listings[_nftContract][_tokenId];
require(listing.price > 0, "NFT not listed for sale");
require(listing.isActive, "NFT not active");

IERC721 nft = IERC721(_nftContract);

require(
paymentToken.transferFrom(
msg.sender,
listing.seller,
listing.price
),
"payment failed"
);
nft.safeTransferFrom(listing.seller, msg.sender, _tokenId);
listing.isActive = false;

emit NFTPurchased(msg.sender, _nftContract, _tokenId, listing.price);
}
}
30 changes: 30 additions & 0 deletions members/qiaopengjun5162/task3/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Deploy addresses

## ERC20

- 0x283C7CF39Eff3B09A8C92509825Eb4A58c96D1a7
- 0xd89C5C99B854470a3ea68b533441898Dee74B681

## ERC721

- 0xA09833270D095b51799c79a8071eA3C9A04d52Ea
- 0x70a306D731d5249F5ce56EFe4FA1F625A521709C

## Market

- 0xB40AdaCeA1Bf2f1a181621C50D84e2f165cDBB0e
- 0xa006cD3172Ef04D0199F4df9682E8297c133D69e

## 浏览器查看

- <https://sepolia.etherscan.io/address/0x750Ea21c1e98CcED0d4557196B6f4a5974CCB6f5>
- <https://sepolia.etherscan.io/tx/0x54ff55a4fac5ec5d61013cee2d020c9a794965cee0c5cab036513592ab463681>

## 上架NFT

- <https://sepolia.etherscan.io/tx/0xcce55d9c1c328cb91069d8c233a0b14159d066bfba3811a711631c17ad89cce7>
- <https://sepolia.etherscan.io/tx/0xd616550d4ef3d7df17c1bcf3acc3b49976690bebe01a96b53a919e560c0dd119>

## 购买NFT

- <https://sepolia.etherscan.io/tx/0x1b5fa299b41c8312e6d6667b9988010e41d85bc0bf0b625f8a1eeba192bbe3e1>
80 changes: 80 additions & 0 deletions members/qiaopengjun5162/task3/studyNotes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Solidity 学习笔记

## 实操

### 1. 安装

```zsh
curl -L https://foundry.paradigm.xyz | bash
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 167 100 167 0 0 143 0 0:00:01 0:00:01 --:--:-- 143
100 2189 100 2189 0 0 1271 0 0:00:01 0:00:01 --:--:-- 1271
Installing foundryup...

Detected your preferred shell is zsh and added foundryup to PATH.
Run 'source /Users/qiaopengjun/.zshenv' or start a new terminal session to use foundryup.
Then, simply run 'foundryup' to install Foundry.

fofoundryup



.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx

╔═╗ ╔═╗ ╦ ╦ ╔╗╔ ╔╦╗ ╦═╗ ╦ ╦ Portable and modular toolkit
╠╣ ║ ║ ║ ║ ║║║ ║║ ╠╦╝ ╚╦╝ for Ethereum Application Development
╚ ╚═╝ ╚═╝ ╝╚╝ ═╩╝ ╩╚═ ╩ written in Rust.

.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx

Repo : https://github.com/foundry-rs/
Book : https://book.getfoundry.sh/
Chat : https://t.me/foundry_rs/
Support : https://t.me/foundry_support/
Contribute : https://github.com/orgs/foundry-rs/projects/2/

.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx

foundryup: installing foundry (version nightly, tag nightly)
foundryup: downloading latest forge, cast, anvil, and chisel
############################################################################################################## 100.0%
foundryup: downloading manpages
############################################################################################################## 100.0%
foundryup: installed - forge 0.2.0 (d7eac74 2024-06-21T00:18:59.645698000Z)
foundryup: installed - cast 0.2.0 (d7eac74 2024-06-21T00:18:59.579897000Z)
foundryup: installed - anvil 0.2.0 (d7eac74 2024-06-21T00:18:59.673963000Z)
foundryup: installed - chisel 0.2.0 (d7eac74 2024-06-21T00:18:59.642077000Z)
foundryup: done!
```

## Deployment steps

1. 部署 `ERC20` 合约
2. 部署 `ERC721` 合约
3. 使用`ERC20` 合约地址作为初始化参数部署 `NFTMarket` 合约
4. 账户1 在 `ERC20` 合约上 mint token
5. 账户1 在 `ERC721` 合约上 safeMint NFT
6. 账户1 在 `ERC721` 合约上调用 `setApprovalForAll` 授权 `NFTMarket` 合约,参数为 `NFTMarket` 合约地址和 `true`
7. 账户1 在 `NFTMarket` 合约上调用 `listNFT` 挂单(上架 tokenId 为 0 的 NFT)
8. 账户1 在 `ERC20` 合约上调用 `transfer` 转移 10个 ERC20 token 给 账户2
9. 账户2 在 `ERC20` 合约上调用 `approve` 方法授权 `NFTMarket` 合约使用1个ERC20token,参数为 `NFTMarket` 合约地址 和数量 1,000,000,000,000,000,000
10. 账户2 在 `NFTMarket` 合约上调用 `buyNFT` 购买 tokenId 为 0 的 NFT
11. 查看账户1 和账户2 的 ERC20 和 ERC721 余额 (`balanceOf`

## 学习目标

- 掌握 Solidity 语法
- 掌握 Solidity 合约开发
- 掌握 Solidity 合约部署
- 掌握 Solidity 合约调用
- 掌握 Solidity 合约测试

## 学习笔记

## 参考

- <https://getfoundry.sh/>
- <https://book.getfoundry.sh/getting-started/first-steps>
- <https://docs.soliditylang.org/en/v0.8.26/installing-solidity.html>
- <https://learnblockchain.cn/docs/solidity/index.html>

0 comments on commit e54f2c6

Please sign in to comment.