-
블록체인을 생성하고 서로 공유하기카테고리 없음 2022. 6. 16. 13:55
70 블록체인 연결 방법 thunder로 연결
config.ts 에서 제네시스 코드 맞추고
peer.json ip설정
block.ts 에 제네시스 코드도 변경순서 : addPeers> mineBlock> chains
서버 연결
- post http://192.168.0.108:3000/addPeers
메인 아이피 주소
{
“peer”:“ws://192.168.0.160:7545”
}
블록 만들기
{
“data”:[“다들 보이시나요?”]
}체인 확인
./serve/p2p.ts
// 1. 서버 2. 클라이언트 /// import { WebSocket } from 'ws' import { Chain } from '@core/blockchain/chain' enum MessageType { //enum : interface에 특정 값만 넣고싶을때 ex)gender -> '남자' / '여자' latest_block = 0, all_block = 1, receivedChain = 2, } interface Message { type: MessageType payload: any } export class P2PServer extends Chain { private sockets: WebSocket[] constructor() { super() this.sockets = [] } getSockets() { return this.sockets } //서버시작 실행코드 listen() { const server = new WebSocket.Server({ port: 7545 }) server.on('connection', (socket) => { console.log(` websocket connection `) this.connectSocket(socket) }) } //client 연결코드 connectTopeer(newPeer: string) { const socket = new WebSocket(newPeer) socket.on('open', () => { this.connectSocket(socket) }) } connectSocket(socket: WebSocket) { this.sockets.push(socket) this.messageHandler(socket) const data: Message = { type: MessageType.latest_block, payload: {}, } this.errorHandler(socket) const send = this.send(socket) send(data) //this.send(socket)(data) } messageHandler(socket: WebSocket) { const callback = (data: string) => { const result: Message = P2PServer.dataParse<Message>(data) const send = this.send(socket) // const block: IBlock = message.payload; // console.log('블럭 콘솔 테스트', block); switch (result.type) { case MessageType.latest_block: { const message: Message = { type: MessageType.all_block, payload: [this.getLatestBlock()], } send(message) break } case MessageType.all_block: { const message: Message = { type: MessageType.receivedChain, payload: this.getChain(), } //블록검증이후 내 체인에 블럭을 넣을지말지 //내 최신블럭과 다른이에게 받은 블럭을 비교해서 이상없을시 내 체인에 블럭추가 //내 hash와 상대블럭의 previoushash값이 같으면 //내 체인에 상대방 블럭을 넣으면된다. const [receivedBlock] = result.payload const isValid = this.addToChain(receivedBlock) // addToChain이 성공하면 굳이 체인을 안불러와도되서 break if (!isValid.isError) break send(message) //체인을 요청하는 코드 break } case MessageType.receivedChain: { const receivedChain: IBlock[] = result.payload console.log(receivedChain) //체인 바꿔주는 코드 //긴체인 선택하기 this.handleChainResponse(receivedChain) break } } } socket.on('message', callback) } errorHandler(socket: WebSocket) { const close = () => { this.sockets.splice(this.sockets.indexOf(socket), 1) } socket.on('close', close) socket.on('error', close) } send(_socket: WebSocket) { return (_data: Message) => { _socket.send(JSON.stringify(_data)) } } broadcast(message: Message): void { this.sockets.forEach((socket) => this.send(socket)(message)) } handleChainResponse(receivedChain: IBlock[]): Failable<Message | undefined, string> { //전달받은 체인이 올바른가? const isValidChain = this.isValidChain(receivedChain) if (isValidChain.isError) return { isError: true, error: isValidChain.error } //내 체인과 상대방 체인에 대해서 검사 //1.'받은 체인의 길이 === 0' (이러면 제네시스밖에없다는 뜻,내 체인이 더 길다) 면 return //2.'받은 체인의 최신블록의 높이 < 내 체인의 최신블록의 높이' 면 return //3.'받은 체인의 최신블록의 이전 해시 === 내 체인의 최신블록의 해시' 면 return // 위 3조건이 충족이 안되면 내 체인이 더 짧다는 의미(내 체인을 상대꺼로 바꿔야함) const isValid = this.replaceChain(receivedChain) if (isValid.isError) return { isError: true, error: isValid.error } //broadcast const message: Message = { type: MessageType.receivedChain, payload: receivedChain, } this.broadcast(message) return { isError: false, value: undefined } } static dataParse<T>(_data: string): T { return JSON.parse(Buffer.from(_data).toString()) } }
peer.json
[ "ws://타인의 와이파이 아이피", "ws://?", "ws://?", "ws://?", "ws://?", "ws://?", "ws://?", "ws://?" ]
index.ts
import { BlockChain } from '@core/index' import express from 'express' import { P2PServer } from './src/serve/p2p' import peers from './peer.json' const app = express() const ws = new P2PServer() const bc = new BlockChain() app.use(express.json()) app.get('/', (req, res) => { res.send('domChain') }) //블록내용 app.get('/chains', (req, res) => { res.json(ws.getChain()) }) //블록채굴 app.post('/mineBlock', (req, res) => { const { data } = req.body console.log('minBlock 데이터입니다 : ', data) const newBlock = ws.addBlock(data) if (newBlock.isError) return res.status(500).send(newBlock.error) res.json(newBlock.value) }) app.post('/addToPeer', (req, res) => { // console.log(req.body) const { peer } = req.body ws.connectTopeer(peer) }) app.post('/addPeers', (req, res) => { peers.forEach((peer) => { ws.connectTopeer(peer) }) }) app.get('/peers', (req, res) => { const sockets = ws.getSockets().map((s: any) => s._socket.remoteAddress + ':' + s._socket) res.json(sockets) }) app.listen(3000, () => { console.log('서버 시작 3000') ws.listen() })
- post http://192.168.0.108:3000/addPeers