Cute Bow Tie Hearts Blinking Pink Pointer

블록체인

[Typescript] 타입스크립트로 블록체인 P2P 구현해보기(찍먹)

청포도 에이드 2022. 6. 14. 17:41
728x90

타입스크립트로 블록체인에 이용되는 p2p를 찍먹해보겠다.

 

index.ts
import { BlockChain } from '@core/index'
//블록정보가 담겨있는 객체임. 전 글에서 확인가능합니다
import express from 'express'
import { P2PServer } from './src/serve/p2p'
const app = express()
const bc = new BlockChain()
const ws = new P2PServer()
app.use(express.json())

app.get('/', (req, res) => {
    res.send('Chain')
})

app.get('/chains', (req, res) => {
    res.json(bc.chain.getChian())
})

app.post('/mineBlock', (req, res) => {
    const { data } = req.body
    const newBlock = bc.chain.addBlock(data)
    if (newBlock.isError) return res.status(500).json(newBlock.error)

    res.json(newBlock.value)
})

app.post('/addToPeer', (req, res) => {
    const { peer } = req.body
    const url = `ws://${peer}`
    console.log()
    ws.connectToPeer(url)
})
app.listen(3000, () => {
    console.log('서버시작')
    ws.listen()
})

 

 

 

src/serve/p2p.ts
import { Chain } from '@core/blockchain/chain'
import { WebSocket } from 'ws'

enum MessageType {
    latest_block = 0,
    all_block = 1,
    receivedChain = 2,
}

interface Message {
    type: MessageType
    payload: any
}

export class P2PServer extends Chain {
    public sockets: WebSocket[]
    constructor() {
        super()
        this.sockets = []
    }
    // 서버 시작하는 실행 코드, 내가 받을 때, 서버. -> 다른 학원생이 내 ip로 post 쏠때
    listen() {
        const server = new WebSocket.Server({ port: 7545 })
        server.on('connection', (socket) => {
            console.log(`Websocket connection`)

            this.connectSocket(socket)
        })
    }

    // Client 연결 코드 내가 client 입장일때, 내가 보낼 때-> 내가 다른 학원생 ip로 post 쏠 때
    connectToPeer(newPeer: string) {
        //ws://
        const socket = new WebSocket(newPeer)
        socket.on('open', () => {
            this.connectSocket(socket)
            // console.log('client open')
        })
    }
    connectSocket(socket: WebSocket) {
        this.sockets.push(socket)
        this.messageHandler(socket)
        const data: Message = {
            type: MessageType.latest_block,
            payload: {},
        }
        const send = P2PServer.send(socket)
        send(data)

        // {type:"", data:""}
        // 응답 string -> object 요청 string
        // socket.send(JSON.stringify(this.getLatestBlock()))
    }

    messageHandler(socket: WebSocket) {
        const callback = (data: string) => {
            console.log(data) //buffer
            const message: Message = P2PServer.dataParse<Message>(data)
            const send = P2PServer.send(socket)
            switch (message.type) {
                case MessageType.latest_block: {
                    //send
                    const message: Message = {
                        type: 1,
                        payload: [this.getLatestBlock()],
                    }
                    send(message)
                    break
                }
                case MessageType.all_block: {
                    const message: Message = {
                        type: MessageType.receivedChain,
                        payload: this.getChian(),
                    }
                    send(message)
                    break
                }
                case MessageType.receivedChain: {
                    const receivedChain: IBlock[] = message.payload
                    console.log(receivedChain)
                    //체인바꿔주는 코드
                    break
                }
            }
        }
        socket.on('message', callback)
    }

    static send(_socket: WebSocket) {
        return (_data: Message) => {
            _socket.send(JSON.stringify(_data))
        }
    }
    static dataParse<T>(_data: string): T {

        return JSON.parse(Buffer.from(_data).toString())
    }
}

 

터미널에 ifconfig 친 뒤, ip주소를 알아낸다 (IPv4)

 

포스트맨 접속 후,

위에는 내 ip주소와 포트, 링크 치고,

body에는 연결할 사용자 ip를 입력하면된다.(같이 수업한 학원생의 ip를 넣었다. 둘다 서버 켜져 있어야하고, ip가 동일해야한다. -> 동일 와이파이사용)

 

터미널에 이렇게 찍힌다.

 

내가 서버일 때(받을 때, 다른 사람이 내 ip로 ping을 던질 때)와 내가 클라이언트일 때(내가 요청을 보낼 때, 내가 다른 사람 ip로 ping 던질 때) 실행되는 코드가 다른 것이다.

728x90