Block Chain 웹서버 구축

YU YU·2021년 9월 3일

p2p 통신을 알아야 블록체인을 알 수 있다.

websocket

  • socket.io: 기본 기능 외의 여러가지 기능이 만ㄷ르어져 잇다.
  • ws : 접속에 대한 것만 제공해줌. 그밖의 기능들은 우리가 만들어야함.
    broadcast, to
  • 블록체인도 2대의 서버가 필요함.

01. 블록체인 웹서버 구축의 기본작업

//server.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const {getBlock,getLastBlock,addBlock,getVersion} =require('./non')
const bodyParser = require('body-parser')

app.use(bodyParser.json());


app.get("/blocks",(req,res)=>{
    res.send(getBlock())
})

app.listen(port,()=>{
    console.log(`server start port ${port}`)
})

위와 같이 server.js 파일을 만들어준다.
그리고 $ npm install express body-parser 을 터미널에 입력해 패키지들을 설치해준다.

wsl으로 가서 터미널에 다음과 같은 명령어를 입력해준다.

$ curl -X GET http://localhost:3000/blocks
그러면 화면이 다음과 같이 나온다.

만약 컴퓨터에 파이썬이 깔려있다면 zsh에 다음과 같이 입력해준다.

$ curl -X GET http://localhost:3000/blocks | python3 -m json.tool

postman을 활용해서 알아볼 수도 있다.

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const {getBlock,getLastBlock,addBlock,getVersion} =require('./non')
const bodyParser = require('body-parser')

app.use(bodyParser.json());

app.get('/version',(req,res)=>{
    res.send(getVersion())
})
app.get("/blocks",(req,res)=>{
    res.send(getBlock())
})

app.listen(port,()=>{
    console.log(`server start port ${port}`)
})

/*
window
set 변수명 = 값
linuix mac
export 변수명  값
window 변수 확인
set 변수명
env | grep 변수명
*/

/*블록 가져오기
간단한 기록들이나 버전 바꾸기 중단 같은 거를 peer
*/

http://localhost:3000/version으로 들어가면 다음과 같이 블록체인의 버전이 나온다.

리눅스 터미널에
$ curl -X GET http://localhost:3000/version 이라고 입력하면 다음과 같이 바로 결과물이 나온다.

블록을 추가하는 것을 web에서 해보자.

1-02블록 마이닝 해보기

기존 작업의 addBlock 함수를 다음과 같이 수정해준다.
!
그리고 서버를 다시 껐다가 켠다. 그리고 포스트맨으로 한번 확인해보자.

postman


결과가 잘 뜸을 알 수 있다.

linux

$ curl -X POST -H "Content-Type:application/json" -d "{\"data\":[\"sssss\"]}" http://localhost:3000/mineBlock
다음과 같이 입력하면 똑같은 결과가 뜸을 알 수 있다.

💥json파일은 작은따옴표를 인식하지 못해 오류가 난다.💥
$ curl -X POST -H "Content-Type:application/json" -d "{'data':['sssss']}" http:localhost:3000/mineBlock
이와 같이 쓴다면 이상이 없어 보이지만 json에서 인식을 못하기 때문에 오류가 날 수 밖에 없다.

//헤더내용 두개 보내고 싶다면 -H 명령어는 2번 써서 해야함
//안에 넣을 data는 -d를 써준다.
"{\"data\":[\"hello wolrd\"]}"

1-03.프로세스 종료

원격으로 끄고 싶을 때 precoess.exit(0)코드를 입력해준다.

app.get('/stop',(req,res)=>{
    res.send("Server Stop");
    process.exit(0);
})


브라우저에는 이렇게 나온다.

자연스럽게 서버가 종료되는것을 알 수 있다.

Nginx와 Next의 관계와 같이 하나의 컴퓨터에서 2가지 포트를 여는 것임.

02.WebSocket

express 가 실행되면 우베소켓도 같이 실행되게금 한다.

여기서 failed가 나는 이유는 웹소켓이 돌아가는 서버가 없기 대문이다. 실제로 웹소켓이 돌아가는 서버가 잇어야 한다.


//network.js
const WebSocket = require('ws');
const wsPORT = process.env.WS_PORT || 6005;

let sockets =[];

function getSockets(){
    return sockets
}

function wsInit(){
    const server = new WebSocket.Server({fort:wsPORT})
    server.on("connection",(ws)=>{
        //도대체 여기서 ws가 뭐야?
        init(ws)
    })
}

function init(ws){
    sockets.push(ws)
}
//여기서 받는 메세지는 뭐지?
function broadcast(message){
    sockets.forEach(socket=>{
        write(socket,message)
    })
}

function write(ws,message){
    ws.send(JSON.stringify(message))
}

function connectionToPeers(newPeers){
    newPeers.forEach(peer=>{
        const ws = new WebSocket(peer)//peer라는 도메인주소를 받는다.
        ws.on("open",()=>{
            //Emitted when the connection is established.
            //연결이 구성되면 방출된다.
            init(ws)//여기서 ws는? 도메인주소!
        ws.on("error",()=>{
            console.log("connection failed")
        })
        })
    })
}

module.exports = {
    wsInit, getSockets,broadcast,connectionToPeers
}

server.js도 다음과 같이 바꿔준다.

//server.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const {getBlock,getLastBlock,addBlock,getVersion} =require('./non')
const bodyParser = require('body-parser')
const { wsInit, getSockets,broadcast,connectionToPeers} = require('./network')


app.use(bodyParser.json());

app.get('/version',(req,res)=>{
    res.send(getVersion())
})
app.get("/blocks",(req,res)=>{
    res.send(getBlock())
})

app.post('/mineBlock',(req,res)=>{
    const aaa =req.body.data;
    const result = addBlock(aaa); //{} or false 반환될 거임
    if(result ===false){
        res.send(`mineBlock failed`)
    }else{
        res.send(result)
    }
    // res.send(addBlock(`[${aaa}]`))
})
//culr http:
app.get('/stop',(req,res)=>{
    res.send("Server Stop");
    process.exit(0);
})


//peers> 현재 가지고 있는 소켓 리스트 getSockets /get
app.get('/peers',(req,res)=>{
    res.send(getSockets().map(socket=>{
        return `${socket._socket.remoteAddress}:
        ${socket._socket.remotePort}`//내가 소켓에 접속한 주소/ 접속한 포트 
        //다시 배열로 반환해줌.
    }))
})

//addPeers => 내가 보낼 주소값에 소켓ㅇ르 생성하는 작업 connectToPeers /post

app.post('/addPeers',(req,res)=>{
    const peers = req.body.peers || [];
    connectionToPeers(peers);
    res.send('success');
})

// crul -X POST -H "Content-Type:application/json" -d "{\"peers\":[\"ws://localhost:7001\",\"ws://localhost:7002\"]"}" http://localhost:3000/


wsInit()//오후에 추가
//express는 클라이언트가 해주는 역할 sebsocket은 서버측 코ㄷ,ㅡ


app.listen(port,()=>{
    console.log(`server start port ${port}`)
})
profile
코딩 재밌어요!

0개의 댓글