kip7.js
)✔️ KAS = Klaytn API Service
→ 클레이튼 블록체인 네트워크를 API로 제공하는 서비스
KAS
는 내장함수의 형태이고caver-js
는 우리가 커스텀해서 함수를 만들어 사용하기 위해서 사용 (web3
랑 비슷함)
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 지갑 접속해서 토큰 목록
→ 토큰 추가
누르고 주소 복붙해주면 뜬다!
트와이스같당~
계정관리
에서 하나 새로 생성~!
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()
: 지갑 생성// 지갑을 생성하는 함수
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에 생성됨
지갑과 계정은 다른 것이다
- 계정: 주소 1개와 [publicKey - privateKey] 쌍이 매핑된 객체 / KAS 계정은 KAS 서비스를 사용하기 위해서 가입한 계정
- 지갑: 여러 개의 계정을 관리할 수 있는 구조 / 계정을 여러 개 저장하고 관리하는 구조
https://forum.klaytn.foundation/t/createaccount-keyring-generate/1016/8
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) 토큰 생성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);
이런식으로 라우트 처리를 해주는 것이 좋다!
()
이거 안 넣어주면... 안 돼요...
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>
.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창에 데이터를 넣어주면 잘 넘어감 ^~^ 오타 파티 오짐
겨우겨우 무사히 넘어감...
워크벤치에도 데이터가 잘 들어왔는지 확인해주기~
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>
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 파일은 두 부류로 나뉨
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/