Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 콜백함수this
- blockchain
- github
- 2021정보처리기사실기
- node.js
- 카카오페이지클론
- ETH
- 솔리디티
- 페이지클론
- 이더리움
- 노개북
- git
- Non-Blocking
- 정보처리기사실기요약
- 노마드코더
- Klaytn
- it5
- npm
- React
- ERC721
- 클레이튼
- 블록체인
- 카카오홈페이지클론
- web3.js
- it5분잡학사전
- ERC-721
- solidity
- 정보처리기사실기
- 정보처리기사
- 비트코인
Archives
- Today
- Total
Be lazy, Be crazy
Toy Project - DAPP(WATTO)(2) 본문
728x90
반응형
안녕하세요! 이번시간에는 Smart Contrac 함수와 / web3.js를 살펴보도록 하겠습니다.
서버에서 트랜잭션을 보내는 방식을 사용하고있습니다.(오프체인 방식)
한번만 학습하면 트랜잭션을 보내는 형식은 거의 똑같아서 금방 학습할 수 있을거라고 생각합니다.
목차
1. setToken 함수와 web3.js
2. mintNFT함수와 web3.js
3. setForSale함수와 web3.js
4. approveSale함수
5. purchaseToken함수와 web3.js
🌟 전체코드는 아래 접혀있는 글을 확인해 주세요!
💧 setToken 함수와 web3.js
nftContract에서 erc20토큰을 보내고 받을려면 erc20 셋팅을 해주어야 합니다.
nftContract에서 setToken이라는 함수를 통해서 사용가능하게 구현
서버에서 트랜잭션을 전송하기 위해서는 Tx를 직접 제작해주어야 한다.
참조순서 => 1) TX구성(nonce,gasLimit,gas, data(사용하려는 함수), from 등등 밑에 참조)
2) 직접 구성한 TX에 개인키를 통해서 서명을 추가해주는 부분
3) 서명된 TX를 sendSignedTransaction 함수를 통해서 트랜잭션을 전송하는부분
solidity
setToken erc20컨트랙주소를 가져와서 IERC20에 접근하여 IERC20의 함수를 사용가능
function setToken (address tokenAddress) public returns (bool) {
require(tokenAddress != address(0x0));
token = IERC20(tokenAddress);
return true;
}
-----------------------------------------------------------------------------------
node.js
const token = async (req, res) => {
1.TX구성(nonce,gasLimit,gas, data(사용하려는 함수), from 등등 밑에 참조)
const data = await nftContract.methods.setToken(process.env.NWTTOKENCA).encodeABI();
const nonce = await web3.eth.getTransactionCount(
serverAddress,
'latest'
);
const gasprice = await web3.eth.getGasPrice();
const gasPrice = Math.round(Number(gasprice) + Number(gasprice / 3));
const tx = {
from: serverAddress,
to: process.env.NFTTOKENCA,
nonce: nonce,
gasPrice: gasPrice, // maximum price of gas you are willing to pay for this transaction
gasLimit: 5000000,
data: data,
};
2.직접 구성한 TX에 개인키를 통해서 서명을 추가해주는 부분
const signedTx = await web3.eth.accounts.signTransaction(tx,serverPrivateKey);
3) 서명된 TX를 sendSignedTransaction 함수를 통해서 트랜잭션을 전송하는부분
const hash = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
if (hash) {
res.json({ success: true });
}
💧 mintNFT함수와 web3.js
nftContract에서 NFT를 발행하기 위한 함수입니다.
오픈제플린에서 구현된 mint함수를 우리 프로젝트에 맞게 변형시켜서 사용했습니다.
프로젝트 구조상 mint된 NFT를 서버주소가 소유하고 user에게 판매하는 형식이므로 파라미터가 tokenURI만 들어갑니다.
tokenURI는 프론트 부분에서 IPFS를 사용해서 IPFS해쉬값이 들어가게 됩니다.
참조순서 => 1) TX구성(nonce,gasLimit,gas, data(사용하려는 함수), from 등등 밑에 참조)
2) 직접 구성한 TX에 개인키를 통해서 서명을 추가해주는 부분
3) 서명된 TX를 sendSignedTransaction 함수를 통해서 트랜잭션을 전송하는부분
solidity
mintNFT erc721에 있는 _mint함수를 이용해서 유일한 토큰을 생성하는 함수
// 밑에 nft발행방식은 누군가에게 발헹해주는 방식이 아닌 서버계정 자체에 nft를 발행해주는 함수.
function mintNFT(string memory tokenURI) public returns (uint256) {
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(msg.sender, newItemId);
_setTokenURI(newItemId, tokenURI);
emit NewNft(msg.sender,newItemId,tokenURI);
return newItemId;
}
-----------------------------------------------------------------------------------
node.js
const nftCreate = async (req, res) => {
const { contentTitle, nftName, nftDescription, imgURI, tokenURI } =
req.body.result;
try {
const data = await nftContract.methods.mintNFT(tokenURI).encodeABI();
const nonce = await web3.eth.getTransactionCount(serverAddress,'latest');
const gasprice = await web3.eth.getGasPrice();
const gasPrice = Math.round(Number(gasprice) + Number(gasprice / 10));
const tx = {
from: serverAddress,
to: process.env.NFTTOKENCA,
nonce: nonce,
gasPrice: gasPrice, // maximum price of gas you are willing to pay for this transaction
gasLimit: 5000000,
data: data,
};
const signedTx = await web3.eth.accounts.signTransaction(tx,serverPrivateKey);
const hash = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
} catch (e) {
console.log('err' + e);
res.json({ failed: false, reason: '블록체인에 문제가있습니다' });
}
},
💧 setForSale함수와 web3.js
nftContract에서 발행된 NFT의 tokenId에 원하는 가격을 설정하기 위한 함수입니다.
nft에 가격을 설정하기 위해서 tokenPrice라는 mapping 변수를 만들었습니다.
가격을 설정하는 주소가 서버계정 주소인지 확인하고 서버계정과 user계정을 다르게 진행합니다.
대납계정이 서버주소가 되기때문에 토큰소유자는 서버계정이 대납계정이 되도록 허락했는지 확인해봐야합니다.
참조순서 => 1) TX구성(nonce,gasLimit,gas, data(사용하려는 함수), from 등등 밑에 참조)
2) 직접 구성한 TX에 개인키를 통해서 서명을 추가해주는 부분
3) 서명된 TX를 sendSignedTransaction 함수를 통해서 트랜잭션을 전송하는부분
solidity
// setForSale함수를 이용해서 소유자가 tokenId에 가격을 지정할 수 있다.
function setForSale(uint256 _tokenId, uint256 _price) public {
//토큰의 소유자 계정만 판매하도록 만드는 함수
address tokenOwner = ownerOf(_tokenId);
require(tokenOwner != address(0x0));
if(tokenOwner == msg.sender){
require(_price > 0,'price is zero or lower');
tokenPrice[_tokenId] = _price;
}else{
require(_price > 0,'price is zero or lower');
require(isApprovedForAll(tokenOwner, msg.sender),'token owner did not approve');
tokenPrice[_tokenId] = _price;
}
}
-----------------------------------------------------------------------------------
node.js
const setForSell = async (req, res) => {
//가격에 숫자이외의 문자가 들어오지 않게 하기위한 정규식
var regexp = /^[0-9]*$/;
if (!regexp.test(sellPrice)) {
res.json({
fail : false,
detail: '정확한 가격을 작성해주세요!!',
});
return
}
const tx = {
from: serverAddress,
to: process.env.NFTTOKENCA,
nonce: await web3.eth.getTransactionCount(serverAddress,'latest');,
gasPrice: web3.eth.getGasPrice();, // maximum price of gas you are willing to pay for this transaction
gasLimit: 5000000,
data: nftContract.methods.setForSale(tokenId, web3.utils.toWei(sellPrice, 'ether')).encodeABI();,
};
try {
const signedTx = await web3.eth.accounts.signTransaction(tx,serverPrivateKey);
const hash = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
} catch (e) {
console.log(e);
}
},
💧 approveSale함수
nftContract에서 tokenId 소유자가 서버계정주소에게 대납소유권을 허락해주는 함수
safeTransferFrom을 사용하기위함
오픈제플린 참조
approveSale함수를 사용해서 소유자가 msg.seder(서버계정)에게 대납소유권을 허락해주는 방식. 그래야지 safeTransferFrom을 사용할 수 가 있다.
function approveSale(address receipent)public {
_setApprovalForAll(receipent, msg.sender, true);
}
💧 purchaseToken함수와 web3.js
nftContract에서 nft구매를 원하는 buyer가 erc20토큰으로 값을 지불
tokenId 소유자는 원하는 가격이 지불되면 tokenId소유권을 buyer로 바뀌게 됨.
지금 판매방식은 지정가 / 밑에 옥션과 비교해보자.
주의해서 볼 함수 (token.transferFrom(ERC-20), safeTransferFrom(ERC-721))
솔리디티 doc 참조
solidity
// 5. purchaseToken함수를 사용해서 seller 와 buyer간에 교환이 이루어 질 수 있다.
function purchaseToken(uint256 _tokenId,address buyer) public onlyAuthorized {
uint bal = token.balanceOf(buyer);
uint256 price = tokenPrice[_tokenId];
address tokenSeller = ownerOf(_tokenId);
require(buyer != address(0x0));
require(tokenSeller != address(0x0));
require(bal >= price,"buyer is not enough money");
require(tokenSeller != buyer,"owner not buy itself"); //본인은 구매를 못함
token.transferFrom(buyer,tokenSeller,price); // 구매자가 판매자게에 erc20토큰을 보내는 함수.
safeTransferFrom(tokenSeller, buyer, _tokenId); // 판매자가 구매자에게 tokenId를 넘기는 함수.
}
--------------------------------------------- ---------------------------------------------
node. js
const buyNFT = async (req, res) => {
try {
const tx = {
from: serverAddress,
to: process.env.NFTTOKENCA,
nonce: await web3.eth.getTransactionCount(serverAddress,'latest');,
gasPrice: web3.eth.getGasPrice();, // maximum price of gas you are willing to pay for this transaction
gasLimit: 5000000,
data: nftContract.methods.purchaseToken(tokenId, buyer).encodeABI();,
};
const signedTx = await web3.eth.accounts.signTransaction(tx,serverPrivateKey);
console.log('----- purchaseToken function start ----');
const sellHash = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
} catch (e) {
console.log(e);
res.json({ failed: false, reason: 'i do not know' });
}
},
반응형
'BlockChain > 이더리움' 카테고리의 다른 글
Toy Project - DAPP(WATTO)(1) (0) | 2022.02.07 |
---|---|
web3 및 erc721 사용한 NFT 민팅 프로젝트 일기 (2) (1) | 2022.02.05 |
web3 및 erc721 사용한 NFT 민팅 프로젝트 일기 (1) (0) | 2022.01.05 |
니모닉(Mnemonic) 지갑 개발 (0) | 2021.12.10 |
Comments