#36 [서버 프로그래밍] (06.26)

sookyoung.k·2023년 6월 26일
1
post-thumbnail

🐨 클레이튼으로 ERC-20(KIP7) 토큰을 발행해보자!

📍 토큰 발행 환경 세팅 (kip7.js)

✔️ KAS = Klaytn API Service
→ 클레이튼 블록체인 네트워크를 API로 제공하는 서비스
* KAS는 내장함수의 형태이고 caver-js는 우리가 커스텀해서 함수를 만들어 사용하기 위해서 사용 (web3랑 비슷함)

https://velog.io/@citron03/KASKlaytn-API-Service%EB%9E%80


API 호출하려면 ACCESS KEY 필요하니까 다운받아주기 (JSON 파일로 다운받아짐)

  • KAS.json 폴더 생성 후 파일 저장

  • kip7.js 파일 생성

* ERC20 = KIP7
그냥 이름만 바꿔둔 것...

// caver-js-ext-kas 모듈을 로드 (KAS를 연동시키기 위한 모듈 이름)
const CaverExtKAS = require("caver-js-ext-kas");
// class 생성 
const caver = new CaverExtKAS();
// fs 모듈 로드 
const fs = require('fs');
// dotenv 로드 (환경변수 설정 - 따로 변수 설정 해주지 않아도 됨)
require('dotenv').config(); 


// KAS에 접속하기 위한 ID, PASSWORD의 파일을 로드
const kas_info = require('./KAS.json');
console.log(kass_info);

➡️ caver-js-ext-kas: KAS에서 만든 caver-js 자바스크립트 API 라이브러리! HTTP 또는 웹소켓 연결을 사용하여 Klaytn 노드와 상호작용 할 수 있도록 해 준다
https://velog.io/@syapeach4/Caver-js
➡️ fs: File System = fs, 파일 처리와 관련된 작업을 한다
https://inpa.tistory.com/entry/NODE-%F0%9F%93%9A-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C-fs-%EB%AA%A8%EB%93%88

* 환경변수 설정을 왜 할까?
1. window 운영체제에서 환경변수를 설정하는 것은 c드라이브든 d드라이브든 어떤 폴더 내에서든 사용할 수 있는 변수를 만들겠다는 것이다. (= 경로가 어디든 상관 없이 공통적으로 사용할 수 있는 변수 설정)
2. 외부에 노출되면 안되는 정보들

  • npm install caver-js-ext-kas fs 명령어를 통해 라이브러리 설치

  • node kip7.js로 콘솔에 찍어보기

    콘솔에 지갑 주소와 비밀번호가 아주 잘 업로드 되었다^^ 전격 대공개!

  • .env 파일 생성

kaikas 지갑에서 개인키 가져오고 환경변수에 저장! (지갑 키 관리 → 개인키)

private_key = '0x/**/692'
  • kip7.js
// accesskeyID 변수, secretAccessKey 생성
const accesskeyID = kas_info.accessKeyId;
const secretAccessKey = kas_info.secretAccessKey;
// testnet의 chainid 지정
const chainid = 1001;

// 생성자 함수 호출
caver.initKASAPI(chainid, accesskeyID, secretAccessKey);

// KAS에서 외부의 지갑을 사용하기 위해선 지갑 등록 
const keyringContainer = new caver.keyringContainer();
const keyring = keyringContainer.keyring.createFromPrivateKey(
    process.env.private_key
);
keyringContainer.add(keyring);

➡️ initKASAPI(chainId, accesskeyID, secretAccessKey): KAS API를 사용하기 위해서는 기본 계정 생성하고 권한을 설정해야 한다. KAS API 서비스의 초기화 방식
https://www.klaytnapi.com/en/resource/docs/getting-started/sdk-api/
➡️ caver.wallet → keyring 인스턴스를 관리하는 곳 (in-memory wallet에서 관리)
➡️ caver.wallet의 클래스인 keyringContainer → keyring의 인스턴스들을 관리하는 곳
➡️ caver.wallet.keyring.createFromPrivateKey: 전달된 privateKey로 SingleKeyring 인스턴스를 생성한다
https://velog.io/@syapeach4/caver-js-API-%EC%B0%B8%EC%A1%B0-%EB%AC%B8%EC%84%9C-2

✔️ 그래서 Keyring이 뭔데!!!!!!!!
→ API 키, 비밀번호, 사용자 이름과 같은 중요한 정보를 안전하게 저장하고 관리하는 도구
→ 코드 내에 하드코딩이 되어 있으면 보안상 취약하기 때문에 keyring을 사용하여 이러한 정보를 저장하고 불러오는 것이 좋다

📍 create_token: 토큰 발행 함수 생성

  • 토큰 만들기 -> kip7.js
   async function create_token(_name, _symbol, _decimal, _amount) {
   const kip7 = await caver.kct.kip7.deploy(
      {
         name: _name, // 토큰의 이름
         symbol: _symbol, // 토큰의 심볼
         decimal: _decimal, // 토큰의 소수점 자리수
         initialSupply: _amount, // 토큰의 초기 발행량
      },
      keyring.address,
      keyringContainer,
   );
   const addr = kip7._address;
   console.log(addr);
   return '토큰 발행 완료';
}

create_token('Test', 'TT', 0, 1000000);

create_token이라는 토큰 발행 함수를 만들어보자!
➡️ caver.kct.kip7.deploy(tokenInfo, deployer): KIP7 토큰 컨트랙트를 Klaytn 블록체인에 배포하는 함수
* keyringContainer가 붙은건 배포된 토큰도 컨테이너에 저장해주기 위해서인 것 같다
➡️ kip7._address: kip7토큰이 배포되고 난 후 생성되는 토큰의 주소값 (우리는 그 주소값을 addr이라는 변수명으로 저장하는 것)

  • 콘솔로 확인 node kip7.js

* 에러주의...

.env 파일에.... 세미콜론 제발 쓰지 말기... 세미콜론... 여기선 아니야!!!

지난번과 같은 실수... 읽어오지 못한다고 한다 ㅠ

토큰 주소는 자주 사용하기 때문에 따로 파일로 만들어주기

  • 토큰 주소를 파일로 따로 만들어주자! (매번 주소값을 복사하지 않기 위해서... 귀찮으니깐!) kip7.js
   const addr = kip7._address;
   console.log(addr);
   // 토큰의 주소 값을 json 파일 안에 대입
   const kip7_address = {
    address : addr 
   }
   // json을 문자형으로 변환 (파일로 저장하기 위해서)
   const data = JSON.stringify(kip7_address);
   // JSON 파일의 형태로 저장
   fs.writeFileSync('kip7.json', data);
   return '토큰 발행 완료';

다시 서버를 실행시키면 주소값이 바뀌어 있는 것을 확인할 수 있다 (새로 토큰을 만든거니까)

📍 kaikas 지갑에 토큰 불러오기

  • 지갑에 만들어 둔 토큰 불러오기

kaikas 지갑 접속해서 토큰 목록토큰 추가 누르고 주소 복붙해주면 뜬다!

트와이스같당~

📍 토큰 이동

  • 지갑 하나를 더 만들어줍시다!

계정관리에서 하나 새로 생성~!

➡️ transfer(): 토큰 거래 함수 생성

  • 토큰 거래 함수 생성 kip7.js
// 주석처리 안 하면 에러가 남! 자꾸 다시 생성하니까! 
// create_token('Test', 'TT', 0, 1000000);

// 토큰을 거래하는 함수 선언
async function transfer(_address, _amount) {
   // 발행한 토큰을 wallet에 추가
   const token_info = require('./kip7.json');
   const kip7 = await new caver.kct.kip7(token_info.address);
   kip7.setWallet(keyringContainer);

   const receipt = await kip7.transfer(_address, _amount, {
      from: keyring.address,
   });
   console.log(receipt);
   return '토큰 거래 완료';
}
console.log(transfer('0xE50630d20332714602842C6e91a4ac401571003B', 100 ))

➡️ setWallet(): 사용할 지갑 지정
➡️ kip7.transfer(recipient, amount[, sendParam]): 주어진 amount만큼의 토큰을 토큰 소유자 잔액에서 recipient에게 보낸다! 반드시 토큰 소유자가 직접 토큰 전송을 실행해야 하기 때문에 sendParam.from 또는 kip7.option.from에 주어져야 한다! (아니면 에러)

두 번째 지갑 주소 복붙해오고 100개를 보내봅시다!

  • 콘솔로 잘 보내졌는지 확인! (node kip7.js)

➡️ transferFrom(): 토큰 가져오는 함수 생성

  • 다른 지갑에서 토큰 가져오기

* transferFrom() - 남의 지갑에서 토큰 쌔벼오기

// console.log(transfer('0xE50630d20332714602842C6e91a4ac401571003B', 100));

// 유저가 토큰 발행자에게 토큰을 보내는 함수 (transaction의 주체자가 발행자)
async function transfer_from(_private, _amount) {
   // 발행한 토큰을 wallet에 추가
   const token_info = require('./kip7.json');
   const kip7 = await new caver.kct.kip7(token_info.address);
   kip7.setWallet(keyringContainer);

   // 토큰 발행자의 지갑 주소
   const owner = keyring.address;
   console.log(owner);

   // 유저의 지갑 주소를 keyringContainer에 등록 (외부지갑)
   const keyring2 = keyringContainer.keyring.createFromPrivateKey(_private);
   keyringContainer.add(keyring2);

   // 누구의 지갑에서 누구의 지갑으로 보내줄 것인지를 인자로 써줘야 한다
   const receipt = await kip7.transferFrom(keyring2.address, owner, _amount, {
      from: owner,
   });
   console.log(receipt);

   return '토큰 이동 완료';
}

transfer_from('0x53586ab0109243d938a9468427749c2e4a35929350269aed40ddc04070daa985', 10);

https://ko.docs.klaytn.foundation/content/dapp/sdk/caver-js/api-references/caver.kct/kip7

이렇게 하면... 일단 에러가 납니다
* 왜?! 이유가 있음...

그럼 왜 존재하는 걸까? 필요하니까... 찾아보기 ㅎㅎ...

✔️ 사전 작업이 필요하다!
B라는 사람의 토큰의 일정 부분 권한을 A에게 넘겨주어야 정상적으로 함수가 작동한다

우선 테스트 계정 (testROZ)에다가 클레이 보내놓기

* approve() 함수를 통해서 권한을 줘야transferFrom()이 가능하다 (kip7.js에 코드 추가)

   // approve() 함수를 호출: 내 지갑에 있는 일정 토큰을 다른 사람이 이동 시킬 수 있도록 관리를 부여
   // approve(권한을 받을 지갑의 주소, 토큰의 양, from)
   await kip7.approve(owner, _amount, {
      from: keyring2.address,
   });

✔️ approve()까지 합친 전체 코드

// 유저가 토큰 발행자에게 토큰을 보내는 함수 (transaction의 주체자가 발행자)
async function transfer_from(_private, _amount) {
   // 발행한 토큰을 wallet에 추가
   const token_info = require('./kip7.json');
   const kip7 = await new caver.kct.kip7(token_info.address);
   kip7.setWallet(keyringContainer);

   // 토큰 발행자의 지갑 주소
   const owner = keyring.address;
   console.log(owner);

   // 유저의 지갑 주소를 keyringContainer에 등록 (외부지갑)
   const keyring2 = keyringContainer.keyring.createFromPrivateKey(_private);
   keyringContainer.add(keyring2);

   // approve() 함수를 호출: 내 지갑에 있는 일정 토큰을 다른 사람이 이동 시킬 수 있도록 관리를 부여
   // approve(권한을 받을 지갑의 주소, 토큰의 양, from)
   await kip7.approve(owner, _amount, {
      from: keyring2.address,
   });

   // 누구의 지갑에서 누구의 지갑으로 보내줄 것인지를 인자로 써줘야 한다
   const receipt = await kip7.transferFrom(keyring2.address, owner, _amount, {
      from: owner,
   });
   console.log(receipt);

   return '토큰 이동 완료';
}

그리고 서버를 재실행하면

정상적으로 함수가 실행되는 것을 확인!

📍 balance_of(): 토큰 수량 확인

  • 토큰이 잘 전달되었는지 balance_of() 함수로 확인
async function balance_of(_address) {
   const token_info = require('./kip7.json');
   const kip7 = await new caver.kct.kip7(token_info.address);
   kip7.setWallet(keyringContainer);

   const balance = await kip7.balanceOf(_address);

   console.log(balance);
   return balance;
}

balance_of('0xE50630d20332714602842C6e91a4ac401571003B');

➡️ kip7.balanceOf(address): 주어진 계정 주소의 잔액 반환
https://ko.docs.klaytn.foundation/content/dapp/sdk/caver-js/api-references/caver.kct/kip7

콘솔로 잘 확인!

📍 create_wallet(): 지갑 생성

  • 지갑을 만들어보자!
    * KAS는 지갑을 유저가 관리하지 않게 한다 (private_key를 그냥 KAS가 다 가지고 관리해줌)
// 지갑을 생성하는 함수 
async function create_wallet() {
   const wallet = await caver.kas.wallet.createAccount();
   console.log(wallet);
   return wallet.address;
}

* wallet.address로 지갑 주소만 가져올 수 있게 해줘야 함!

* createAccount() → pirvateKey가 생성되지 않음 / KAS Wallet API 서비스에 계정을 생성하는 것 (privateKey가 KAS에서 관리된다) = 지갑 서비스

* keyring.generate() → pirvateKey가 생성됨 / 랜덤으로 키링 인스턴스를 생성하는 것 (KAS를 사용하지 않고 직접 키링을 관리하는 경우에 사용할 수 있다) = 계정을 하나 랜덤으로 생성하는 것!! 계정이 KAS Wallet API에 생성됨

* 지갑계정은 다른 것이다

🐨 웹 페이지와 연결해보자!

📍 토큰 관련 함수, 폴더 정리

  • kip7.js에 만들어 둔 함수를 외부에서 사용할 수 있도록 module.export에 담아둔다
// 위에서 만들어 둔 함수들을 외부에서 사용할 수 있게 설정
module.exports = {
   create_token,
   transfer,
   transfer_from,
   balance_of,
};
  • token 폴더 생성 후 토큰 관련 파일들을 넣어준다.

📍 서버 열기

  • npm init -y, npm install express ejs 기본 명령어 입력

  • index.js 파일 생성
// express 로드
const express = require('express');
const app = express();

// port 번호 설정
const port = 3000;

// view 파일들의 기본 경로 설정
app.set('views', __dirname + '/views');
// view engine 설정
app.set('view engine', 'ejs');

// post 방식으로 들어오는 데이터를 json 형태로 변환
app.use(express.urlencoded({ extended: false }));

// dotenv 설정
require('dotenv').config();

const server = app.listen(port, function () {
   console.log(port, 'Server Start');
});

메인이 되는 index.js 파일에는 서버에 대한 정보(설정), 세팅하는 정보들, env 설정, session 설정 등을 해주면 된다

📍 경로 정리

  • 라우트 작업하기 위한 routes 폴더 생성 + view 폴더 생성

공통의 기능을 모듈화 시켜서 파일별로 나눠서 저장하는 것 = 라우트

token 관련 정보를 불러올 수 있게 요청하기 (index.js)

const token = require('./routes/token.js')();
app.use("/token", token);

* 함수 형태로 만들었는데 괄호를 왜 적었을까? → 그래야 실행이 된다

📍 token.js → 토큰 관련 api 관리 (1) 토큰 생성

  • routes 폴더에 token.js 파일 생성
// express 로드
const express = require('express');
const router = express.Router();

// kip7.js 로드
// 해당하는 파일의 경로에서 kip7.js를 로드하려면
// 상위 폴더 이동 → token 하위폴더 이동 → kip7.js
const token = require('../token/kip7.js');

module.exports = function () {
   // api 생성
   // token.js 파일의 기본 경로는 localhost:3000/token

   router.get('/', function (req, res) {
      res.render('create_token.ejs');
   });
};
  • create_token.ejs 파일 생성
<!DOCTYPE html>
<html lang="ko">
   <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Document</title>
   </head>
   <body>
      <!-- 토큰의 이름, 심볼, 소수점, 발행량을 입력하는 공간 -->
      <form action="/token/create" method="get">
         <label>Name</label>
         <input type="text" name="_name" /><br />
         <label>Symbol</label>
         <input type="text" name="_symbol" /><br />
         <label>Decimal</label>
         <input type="number" name="_decimal" /><br />
         <label>Amount</label>
         <input type="number" name="_amount" /><br />
         <input type="submit" value="토큰 발행" />
      </form>
   </body>
</html>

action 어디로 보낼 것인지 주소
method 어떻게 보낼 것인지 방식

  • token.js에 새로 주소를 만들어줘야 함
module.exports = function () {
   // api 생성
   // token.js 파일의 기본 경로는 localhost:3000/token

   router.get('/', function (req, res) {
      res.render('create_token.ejs');
   });

   // 토큰을 발행하는 api
   // localhost:3000/token/create [get]
   router.get('/create', async function (req, res) {
      // 유저가 보낸 데이터를 변수에 대입, 확인
      const input_name = req.query._name;
      const input_symbol = req.query._symbol;
      const input_decimal = req.query._decimal;
      const input_amount = req.query._amount;
      console.log(input_name, input_symbol, input_decimal, input_amount);
     
      // 토큰 발행 함수를 가져와보자! (token > kip7.js)
      const receipt = await token.create_token(input_name, input_symbol, input_decimal, input_amount);
      console.log(receipt);
      res.send(receipt);
   });
   return router;
};

return router; 해줘야 함! 꼭 추가해주기
→ 왜? 함수를 실행하는데 되돌려주는 부분이 없음!

그리고 서버 재실행 후

토큰을 발행해보면...!

무사히 발행 완료!

콘솔창도 확인해보면 발행이 잘 되었음을 확인할 수 있다.

📍 main.js → 페이지 이동 api 관리 (1) 회원가입/ 로그인

  • 메인 페이지 주소값 만들기 (index.js)
const main = require('./routes/main.js')();
app.use('/', main);

이런식으로 라우트 처리를 해주는 것이 좋다!
* () 이거 안 넣어주면... 안 돼요...

1. 회원 정보 DB에 저장

  • main.js → 회원가입 / 로그인 기능을 만들자

회원가입 기능을 만들자! 데이터는
1. DB에 저장
2. 세션에 저장

DB와 연결시켜준다

const express = require('express');
const router = express.Router();

const mysql = require('mysql2');

const connection = mysql.createConnection({
   host: process.env.host,
   port: process.env.port,
   user: process.env.user,
   password: process.env.password,
   database: process.env.database,
});

// kip7.js 로드
const token = require('./token/kip7.js');

module.exports = function () {
   // 기본 경로? localhost:3000/

   router.get('/', function (req, res) {
      res.render('login.ejs');
   });
};
  • login.ejs 파일 생성
<!DOCTYPE html>
<html lang="ko">
   <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Document</title>
   </head>
   <body>
      <!-- login에 필요한 정보를 입력할 수 있는 공간 -->
      <form action="/signin" method="post">
         <label>Phone</label>
         <input type="text" name="_phone" /><br />
         <label>password</label>
         <input type="password" name="_pass" /><br />
         <input type="submit" value="로그인" />
      </form>
      <button onclick="location.href='/signup'">회원가입</button>
   </body>
</html>
  • signup.ejs 파일 생성
<!DOCTYPE html>
<html lang="ko">
   <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Document</title>
   </head>
   <body>
      <h1>Signup Page</h1>
      <form action="/signup" method="post">
         <label>Phone</label>
         <input type="text" name="_phone" /><br />
         <label>password</label>
         <input type="password" name="_pass" /><br />
         <input type="submit" value="회원가입" />
      </form>
   </body>
</html>
  • 워크벤치에 필요한 테이블과 컬럼 생성 (user 테이블)

  • .env에 DB 정보 저장
# mysql server 정보
host = 'localhost'
port = 3306
user = 'root'
password = '1234'
database = 'new_deal2'
  • main.js → 회원가입 경로 만들기
module.exports = function () {
   // 기본 경로? localhost:3000/

   router.get('/', function (req, res) {
      res.render('login.ejs');
   });

   // 회원가입 페이지로 이동하는 api 생성
   router.get('/signup', function (req, res) {
      res.render('signup.ejs');
   });

   // 유저가 입력한 정보를 mysql에 삽입
   router.post('/signup', async function (req, res) {
      // 유저가 입력한 정보를 변수에 대입, 확인
      const input_phone = req.body._phone;
      const input_pass = req.body.input_pass;
      console.log(input_phone, input_pass);
      // kip7.js에 있는 지갑을 생성하는 함수를 호출
      const wallet = await token.createWallet();
      console.log(wallet);

      // DB에 데이터를 삽입
      const sql = `
        insert
        into
        user
        values 
        (?, ?, ?)
      `;
      const values = [input_phone, input_pass, wallet];

      connection.query(sql, values, function (err, result) {
         if (err) {
            console.log(err);
            res.send(err);
         } else {
            console.log(result);
            res.redirect('/');
         }
      });
   });
};
  • 결과를 확인하려면 우선 npm install mysql2로 라이브러리 설치를 해줘야 한다!

  • 회원가입 결과 확인!

input창에 데이터를 넣어주면 잘 넘어감 ^~^ 오타 파티 오짐

겨우겨우 무사히 넘어감...

워크벤치에도 데이터가 잘 들어왔는지 확인해주기~

  • 뭔가.. 계정을 만들어줌

2. 로그인 정보를 세션에 저장

  • index.js에 라이브러리 설치
// express-session 모듈 로드
const session = require('express-session');
  • npm install express-session

  • 세션 설정 → index.js

// express-session 모듈 로드
const session = require('express-session');
// session 설정
app.use(
    session(
        {
            secret: process.env.secret,
            resave: false,
            saveUninitialized: false,
            cookie: {
                maxAge: 60000 // 1000당 1초
            }
        }
    )
)

.env

# session secret key
secret = 'rosencrantz'

✔️ 로그인 됐을 떼 세션 생성, 로그아웃 했을 때 세션 소멸하게 만들어보자

  • 로그인 시 세션 데이터 저장 → main.js
   // 로그인 api
   router.post('signin', function (req, res) {
      // 유저가 보낸 데이터를 변수에 대입, 확인
      const input_phone = req.body._phone;
      const input_pass = req.body._pass;
      console.log(input_phone, input_pass);

      // mysql 데이터와 비교
      const sql = `
        select 
        * 
        from 
        user 
        where 
        phone = ?
        and 
        password = ?
    `;
      const values = [input_phone, input_pass];

      connection.query(sql, values, function (err, result) {
         if (err) {
            console.log(err);
            res.send(err);
         } else {
            // 로그인이 성공하는 조건 → 데이터가 존재
            // result는 배열이고 해당하는 배열의 길이가 0이 아닌 경우
            if (result.length != 0) {
               // session 데이터를 저장 (session은 유저가 가지고 있다)
               req.session.logined = result[0];
            }
            res.redirect('/');
         }
      });
   });
  • 로그인 했는데 다시 메인으로 돌아간다고?! 알아서 처리를 해줄거임 ㅇㅇ → main.js
   // 기본 경로 설정 수정
   router.get('/', function (req, res) {
    // session.logined에 데이터가 존재하지 않는다면 login.ejs 보여준다 
    if(!req.session.logined) {
        res.render('login.ejs');
    } else {
        res.redirect('/main');
    }
   });

/* 생략 */ 

   router.get('/main', function(req, res) {
    if (!req.session.logined) {
        res.redirect('/');
    } else {
        console.log(req.session);
        res.render('main.ejs');
    }
   })
  • main.ejs
<!DOCTYPE html>
<html lang="ko">
   <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Document</title>
   </head>
   <body>
      <h1>Main Page</h1>
   </body>
</html>
  • 결과 확인!

하... 어디는 password라고 쓰고 어디는 _pass라고 쓰고... 폼태그에 경로 안 써주고... signin을 singin으로... 오늘 오타 개많다... 오늘 정신 나간듯...

콘솔에 잘 뜨는지도 확인을 해줍시당~

📍 token.js → 토큰 관련 api 관리 (2) 토큰 충전

  • 메인 페이지에 토큰 충전 공간을 만들어봅시다 → main.ejs
<!DOCTYPE html>
<html lang="ko">
   <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Document</title>
   </head>
   <body>
      <h1>Main Page</h1>
      <h3>토큰 충전</h3>
      <form action="/token/charge" method="get">
         <!-- 토큰의 충전량을 입력 -->
         <label>Amount</label>
         <input type="number" name="_amount" /><br />
         <input type="submit" value="토큰 충전" />
      </form>
      <button onclick="location.href='/info'">마이 페이지</button>
   </body>
</html>
  • 토큰 거래 관련 api 생성 token.js
   // 로그인을 한 유저의 지갑에 토큰을 거래하는 api
   router.get('/charge', async function (req, res) {
      if (!req.session.logined) {
         res.redirect('/');
      } else {
         // 유저가 보낸 데이터를 변수에 대입, 확인
         const input_amount = Number(req.query._amount);
         console.log(input_amount);

         const wallet = req.session.logined.wallet;
         console.log(wallet);

         // kip7.js에 있는 transfer() 호출
         const receipt = token.transfer(wallet, input_amount);
         console.log(receipt);
         res.redirect('/');
      }
   });
  • 결과 확인!

이렇게 토큰 충전을 해주면

콘솔 창에도 잘 떴당 가스비도 나감

📍 마이페이지를 만들자! → 토큰 잔량 정보 확인

  • 마이페이지를 만들어보자! 먼저 main.js에서 라우터 만들어주기!
router.get('/info', async function (req, res) {
      // 로그인을 한 지갑의 토큰 양을 로드
      // kip7.js에 있는 balance_of() 함수를 호출
      if (!req.session.logined) {
         res.redirect('/');
      } else {
         const wallet = req.session.logined.wallet;
         console.log(wallet);
         const balance = await token.balance_of(wallet);
         console.log(balance);
         res.render('info.ejs', {
            // 유저의 phone, wallet, 토큰의 양
            user: req.session.logined,
            balance: balance,
         });
      }
   });
  • 화면 만들기 → info.ejs
<!DOCTYPE html>
<html lang="ko">
   <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Document</title>
   </head>
   <body>
      <h1>My Page</h1>
      <ol>
         <li>유저의 휴대폰 번호: <%=user['phone']%></li>
         <li>유저의 지갑 주소: <%=user['wallet']%></li>
         <li>토큰의 양: <%=balance%></li>
      </ol>
   </body>
</html>

user 안에 있는 정보를 까줘야 함! user.phone이나 user.wallet으로 해도 호출 됨

user 변수에 session안에 있는 logined 정보가 담겨있으니까!!! 거기에서 하나하나 까서 보여주는거임

  • 결과 확인!


메인이 되는 index.js(혹은 app.js) 파일에는 서버에 대한 정보(설정), 세팅하는 정보들, env 설정, session 설정 등을 해주면 된다 → 그리고 나서 서버 실행! (중계 서버, bridge라고 함! 다른 js랑 연결, 주소를 기준으로 연결해줌)
* api는 여기에 안 만들어놔요... 한 파일에 api를 전부 만들어두면 헷갈리기 때문에!

➡️ [정리] js 파일은 두 부류로 나뉨

  • api를 모듈화해주는 (index.js)
  • 함수들을 export 해주는 (우리가 만든거로 보면 main.js - 유저에 대한 부분, token.js - 토큰을 생성하고 transfer하는 부분 두 가지)
profile
영차영차 😎

1개의 댓글

comment-user-thumbnail
2023년 7월 2일

https://melonplaymods.com/2023/06/10/train-mod-for-melon-playground-2/
https://melonplaymods.com/2023/06/10/overwatch-mod-for-melon-playground/
https://melonplaymods.com/2023/06/10/pizza-tower-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/items-to-create-an-office-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/tank-kv-2-mod-for-melon-playground/
https://melonplaymods.com/2023/06/10/infected-melonnpc-mod-for-melon-playground/
https://melonplaymods.com/2023/06/10/dragon-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/melon-double-storey-building-mod-for-melon-playground/
https://melonplaymods.com/2023/06/10/ww2-packlarik_lol-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/terminator-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/desert-soldiers-mod-for-melon-playground/
https://melonplaymods.com/2023/06/10/clubbox-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/old-memes-mod-for-melon-playground/
https://melonplaymods.com/2023/06/10/minecraft-item-pack-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/the-man-from-the-windowrostishca-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/five-storey-building-mod-for-melon-playground/
https://melonplaymods.com/2023/06/10/marshmello-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/f35-lightning-ii-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/scenery-scenery-pack-mod-for-melon-playground/
https://melonplaymods.com/2023/06/11/donuts-mod-for-melon-playground/

답글 달기