Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

week1_decentralized(wdshin) - SuperSweetShin #23

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added week1/img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added week1/img_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added week1/img_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions week1/week1_wdshin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# 1st-EVM-Assignment

# Done

## 1. 지갑을 만드는 과정에서의 궁금증?

* 지갑을 만든지는 오래 되어서 당시의 궁금증을 회상하여 적겠습니다.

* passphase 가 매우 생소 했습니다.
* 단순한 암호 몇자로는 지갑을 보호하기 어렵기 때문이라고 생각했습니다.
* 그러나, 여전히 passphase 로는 지갑을 보호하기 어렵다고 생각합니다.
* 또한, 오프라인에 적어둔 것을 잃어버린다면 매우 위험해질 것입니다.
* 지갑이 아닌 거래소 계정에서는 보인 인증 및 OTP와 같은 2차 인증을 사용합니다.
* 크롬 플러그인을 통해서 지갑을 열고 사용하는 것 또한 매우 생소했습니다.
* 익숙해지면 편리하긴 합니다만, 처음 사용자에게는 크롬 플러그인 자체라는 것을 이해하지 못할 것입니다.
* 출금 및 송금이 초보자에게는 매우 쉽지 않았던 과정으로 기억합니다.
* 출금 주소/입금 주소라는 개념도 어렵고, 토큰의 프로토콜에 맞춰야 하는 것도 어렵습니다.
* 결론 : 잃어버려도 본인 인증을 통해서 찾아주는 서비스와 은행처럼 입출금이 쉬운 서비스가 생겨야 한다고 생각합니다.

## 2. 구매한 이더리움으로 폴리곤으로 스왑

* 매우 쉽습니다.
* 처음에 지갑이 연결이 안되었는지, 기다리는 메시지가 길었습니다. 다시 리로드 해서 성공했습니다.
* 인증샷
* ![img.png](img.png)
* ![img_1.png](img_1.png)

### 3. OpenSea에서 Polygon 기반 NFT 구매하기

* 이미 ETH로 구매 많이 해 봤습니다. ㅠㅠ
* 많은 NFT 사이트에서 디스코드도 활동하고 구매도 많이 했었습니다.
* ETH 400만원일때 비싸게 많이 샀었네요. ㅠㅠ
* 스캠도 많이 당했습니다. 1ETH 에 산 것을 지갑에서 탈취당하기도 했습니다.
* 인증샷
* ![img_2.png](img_2.png)

### 4.기존 예치와 대출 시스템에 비해 DeFi를 활용한 방법은 어떤 점이 다른 것 같은가요?

* 지갑에서 직접 연결하여 예치할 수 있다는 점이 매력적입니다.
* ETH보다 Polygon기반이라 가스비가 싸다는 점이 매력적입니다.
* 왜냐하면, 아직 Defi는 위험하다고 생각했습니다.
* 많이 맡기기엔 위험해 보였습니다.
* 어떤 것을 믿고 맡겨도 될 지, 아직 잘 모르겠습니다.
* 바이낸스의 Cefi 정도 경험었습니다. ADA기반 Defi인 MINSWAP으로 예치한 경험이 있습니다.
* Insight를 가지려면 더 경험을 해 봐야 할 것 같습니다. 이번 기회에 더 해 보겠습니다.

# Todo

1. ****암호화폐 거래소에서 0.01 이더리움 내외(2022년 4월 8일 기준 4만원 내외)을 구매하고, 자신만의 메타마스크 지갑을 만든 뒤 이를 본인의 메타마스크 지갑으로 송금해보세요. 그리고 무언가 하나의 지갑을 만드는 과정에서, 어떤 궁금증이 생기셨나요? 의문을 던져보고, 설명해주세요.****
- [암호화폐 지갑을 사용해야 하는 이유](https://dcrypto.tistory.com/876)
- [암호화폐 지갑 사용 방법: 메타마스크](https://dcrypto.tistory.com/888)
- [코인 출금 전에 알아야 할 필수 기초 상식](https://dcrypto.tistory.com/902)
- [거래소에서 메타마스크로 코인 송금하는 방법](https://www.steemcoinpan.com/hive-101145/@donekim/38qazr)
- [NFT 101 메타마스크에서 입출금 해보기](https://m.post.naver.com/viewer/postView.naver?volumeNo=33335828&memberNo=15388801)
2. 구매한 Ethereum을 가지고 Polygon으로 스왑해보기, 스왑을 해보면서 어떤 것이 힘들었나요? 해당 부분에 대해서 느낀 점을 설명해주세요.
- [유니스왑 사용법](https://talken.io/board/post/INFO/66992)
3. Opensea에서 Polygon 기반 NFT 구매해보기 (optional)
4. Polygon 기반 Lending protocol으로 예치하고, 대출해보기, 기존 예치와 대출 시스템에 비해 DeFi를 활용한 방법은 어떤 점이 다른 것 같은가요?
- [AAVE](https://app.aave.com/)
- [AAVE 사용법](https://zephyrnet.com/ko/aave-%ED%94%8C%EB%9E%AB%ED%8F%BC-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95-%EC%A0%84%EC%B2%B4-%EA%B0%80%EC%9D%B4%EB%93%9C/)

## **과제 제출하기 전에!**

- 레포지토리를 Fork해주세요. Markdown 파일로 답변을 작성한 후 week1 폴더에 저장해서 Pull Request를 보내주세요.
- 파일 이름은 `week1_본인아이디.md` 로 부탁드립니다!
- 7월 22일(금) 00:00까지 작성 후, main 브랜치로 Pull Request를 보내주세요.
- 도움이 필요하시면 언제든지 디스코드 내 `1ST-EVM-COHORT` 채널로 연락주세요 :)
107 changes: 107 additions & 0 deletions week3/contracts/myNFT.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//SPDX-License-Identifier: MIT

// Solidity 0.8.14 is not fully supported yet. You can still use Hardhat, but some features, like stack traces, might not work correctly.
// 0.8.14 는 hardhat 에서 모두 지원이 안되어서 0.8.9 로 바꿨습니다.
pragma solidity ^0.8.9;

// 아래 항목들을 import 하기 위해서 hardhat-upgrades 를 install 해야 했습니다.
// 참고 : https://docs.openzeppelin.com/upgrades-plugins/1.x/hardhat-upgrades
// 참고 : https://forum.openzeppelin.com/t/importing-oz-contracts-with-hardhat/8588
// npm install --save-dev @openzeppelin/hardhat-upgrades
// npm install --save-dev @nomiclabs/hardhat-ethers ethers
// npm install --save-dev @openzeppelin/contracts
// https://github.com/theNvN/hardhat-test-utils
// npm install --save-dev hardhat-test-utils hardhat ethers @nomiclabs/hardhat-ethers
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

// 참고 : https://bitofanibble.com/how-to-create-an-nft-contract-with-solidity/

contract myNFT is ERC721, ERC721URIStorage, Ownable {
using Counters for Counters.Counter;

Counters.Counter private _tokenIdCounter;

uint256 private _mintPrice = 0.001 ether;// finney; //0.001 ether;

// 민팅 횟수 기록하기 위한 매핑 변수
// ( 민팅 여부만 기록하는 것보다 나중에 2회 이상 허용하기 위해서 uint로 사용 )
mapping(address => uint) private _mintCounts;

constructor(string memory name, string memory symbol)
ERC721(name, symbol) {
// 여기서 owner() 등이 자동으로 설정 됨
//address public _owner; 를 만들 필요 없음.
}

// 민트 성공 메시지
event Minted(address _minter,uint256 _tokenId);

modifier oneMintOnly {
// 이미 1번이상 민팅한 사람인지 확인
require(_mintCounts[msg.sender]<1, "not allowed to mint more than once");
_;
}
modifier costs(uint _amount) {
// 0.001 eth 있는지 확인
require(msg.value > _amount, "not enough balance to mint");
_;
}
// - itemMint라는 함수를 생성해주세요.
// - 이 함수는 오직 TokenURI 데이터만을 받는 함수입니다.
// - 이 함수를 호출한 사람의 주소로 NFT가 민팅되게 설정해주세요.
// - 한 번 민팅될 때 수수료를 제외하고 0.001 이더가 같이 차감되게 설정해주세요.
// - 민팅은 누구나 가능하지만, 최대 1번까지만 민팅할 수 있게 작성해주세요.
function itemMint(string memory uri) public payable oneMintOnly costs(_mintPrice) {

// 민팅 횟수 기록
_mintCounts[msg.sender] += 1;
// TODO 민팅한 사람을 기록해 두면 관리상 용이할 것 같은데... 그럴 필요 있을까?
// 0.001 eth 차감
// 사용자에게 잔돈 전달 ㅎ ( return change to the sender )
// ( change 를 계산해서 transfer 하는 방식 넘 어색하다.;; )
// 이렇게 하는게 맞는지 아직 모르겠다.
uint256 change = msg.value - _mintPrice;
payable(msg.sender).transfer(change);

_tokenIdCounter.increment();
uint256 tokenId = _tokenIdCounter.current();
// TODO tokenId 가 발급 제한 MAX를 넘지 않는지 체크해야 할 것 같다.

// safeMint가 더 좋은 것 같아서...( 차이는 아직 모름 )
_safeMint(msg.sender, tokenId);
_setTokenURI(tokenId, uri);

emit Minted(msg.sender,tokenId);
}

// test 를 위해서 민트 여부 체크 함수 추가
function minted() public view returns(bool) {
if ( _mintCounts[msg.sender]>=1 ) {
return true;
}
return false;
}

// override 를 해야 합니다.
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}

// override 를 해야 합니다.
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}

// TODO 수익금 챙기는 거. 그냥 해 봄
function withdraw() public payable onlyOwner {
payable(msg.sender).transfer(address(this).balance);
}
}
8 changes: 8 additions & 0 deletions week3/hardhat.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require("@nomicfoundation/hardhat-toolbox");
require("@openzeppelin/hardhat-upgrades");
require('hardhat-test-utils');

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.9",
};
22 changes: 22 additions & 0 deletions week3/scripts/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
async function main() {
const [deployer] = await ethers.getSigners();

console.log("Deploying contracts with the account:", deployer.address);

console.log("Account balance:", (await deployer.getBalance()).toString());

const contractFactory = await ethers.getContractFactory("myNFT");
const contract = await contractFactory.deploy("MyNFT","MYN");

console.log("myNFT address:", contract.address);



}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Binary file added week3/test-result-2022-08-04-5.42.18.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 108 additions & 0 deletions week3/test/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
const { expect } = require("chai");

const { testUtils } = require('hardhat');

const { time, address, constants } = testUtils;

describe("myNFT contract", function () {
let contractFactory;
let contract;
let _name = "myNFT";
let _symbol = "MYN";
let owner;
let account1;
let account2;
let tokenURI1 = "https://gateway.pinata.cloud/ipfs/QmNY9AsKWAjm4QLppztGUJxJjofpD6qQQEaQnj9ktWaxTE"

const FINNEY = 10**15;
const ETHER = 10**18;

before(async function () {
contractFactory = await hre.ethers.getContractFactory("myNFT");
[owner, account1, account2] = await hre.ethers.getSigners();

contract = await contractFactory.deploy(_name, _symbol);
await contract.deployed();

//console.log('ownerBalance:',ownerBalance);
//console.log('owner:',owner);
//console.log('account1:',account1);
//console.log('account2:',account2);

console.log("Deploying contracts with the account:", owner.address);

console.log("Owner Account balance:", (await owner.getBalance()).toString());

console.log("Account1 balance:", (await account1.getBalance()).toString());
console.log("Account2 balance:", (await account2.getBalance()).toString());

//console.log("Contract Account balance:", (await contract.getBalance()).toString());

});

describe("Deployment", function () {

it("Should return the right name and symbol", async function () {
expect(await contract.name()).to.equal(_name);
expect(await contract.symbol()).to.equal(_symbol);
});

it("Mint for Account1", async function () {

console.log("account1 balance:", (await account1.getBalance()).toString());

// 테스트를 위해 특정 어드레스에 ether 주는 방식 1
await expect(() =>
owner.sendTransaction({ to: account1.address, value: FINNEY })).
to.changeEtherBalance(owner, -FINNEY);

console.log("account1 balance:", (await account1.getBalance()).toString());

// 테스트를 위해 특정 어드레스에 ether 주는 방식 2
// 넉넉하게 2 ether 로 세팅
await address.setBalance(account1.address, hre.ethers.utils.parseEther("2"));

console.log("account1 balance:", (await account1.getBalance()).toString());

//await contract.transfer(account1.address, 50);
//expect(await contract.balanceOf(account1.address)).to.equal(50);
// 0.001 로 전달하면 gas fee가 부족해서 실패한다.
const amt = hre.ethers.utils.parseEther("0.0011");

await contract.connect(account1).itemMint(tokenURI1,{value:amt});
// expect(await DSRVNFT.ownerOf(1)).to.equal(minter);
console.log("account1 balance:", (await account1.getBalance()).toString());

console.log("account1 minted :",(await contract.connect(account1).minted()));

});

it("Mint for Account2", async function () {

console.log("account2 balance:", (await account2.getBalance()).toString());
await address.setBalance(account2.address, hre.ethers.utils.parseEther("2"));
console.log("account2 balance:", (await account2.getBalance()).toString());

const amt = hre.ethers.utils.parseEther("0.0011");

await contract.connect(account2).itemMint(tokenURI1,{value:amt});
console.log("account2 balance:", (await account2.getBalance()).toString());

console.log("account2 minted :",(await contract.connect(account2).minted()));

});

it("Withdrawl balanace", async function () {

console.log(" owner balance:", (await owner.getBalance()).toString());

await contract.connect(owner).withdraw();

console.log(" owner balance:", (await owner.getBalance()).toString());

});

});


});