암호화
블록체인
탈중앙화
분산원장관리
무결성 : 정보는 일반적으로 수정이 가능한데, 이는 권한이 있는 사용자에게만 허가
기밀성 : 정보를 저장하고 전송하면서 부적절한 노출을 방지, 정보 보안의 주된 목적
가용성 : 활용되어야 할 정보에 접근할 수 없다면, 기밀성과 무결성이 훼손된 것만큼이나 무의미하다.
지갑
프라이빗키 으로 퍼블릭키를 만들수 있지만 퍼블릭키로 프라이빗키를 유추할수 없다
private Key
public Key
타원 곡선 디지털 서명 알고리즘 (ECDSA)
영지식증명 (Zero Knowledge Proof)
증명하는 사람(A), 증명을 원하는 사람(B)
A와 B는 증명된 내용에 합의
그 외의 사람들은 동의하지 않는다.
증명하는 과정에서 A는 B에게 아무런 정보도 주지 않는다.
main.js
import { initHttpServer } from "./httpServer.js";
import { initP2PServer } from "./p2pServer.js";
import { initWallet } from "./wallet.js";
const httpPort = parseInt(process.env.HTTP_PORT) || 3001;
const p2pPort = parseInt(process.env.P2P_PORT) || 6001;
initWallet()
initHttpServer(httpPort);
initP2PServer(p2pPort);
httpServer.js
import express from 'express';
import bodyParser from 'body-parser';
import { getBlocks, createBlock } from './block.js';
import { connectionToPeer, getPeers, mineBlock } from './p2pServer.js';
import { getPublicKeyFromWallet } from './wallet.js'
const initHttpServer = (myHttpPoryt) => {
const app = express();
app.use(bodyParser.json());
app.get('/', (req, res) => {
res.send('Hello, World!');;
})
app.get('/blocks', (req, res) => {
res.send(getBlocks());
})
app.post('/createblock', (req, res) => {
res.send(createBlock(req.body.data));
})
app.post('/mineBlock', (req, res) => {
res.send(mineBlock(req.body.data));
})
app.post('/peers', (req, res) => {
res.send(getPeers())
})
app.post('/addPeer', (req, res) => {
console.log('/addrPeer : ', req.body.message);
res.send(connectionToPeer(req.body.data));
})
app.post('/allblocks', (req, res) => {
res.send(queryAllMessage(req.body.data))
})
app.use('/latestblock', (req, res) => {
res.send(queryLatestMessage(req.body.data))
})
app.get('/address', (req, res) => {
const address = getPublicKeyFromWallet();
res.send( {'address' : address } );
})
app.listen(myHttpPoryt, () => {
console.log('listening httpServer Port : ', myHttpPoryt);
})
}
export { initHttpServer }
wallet.js
import ecdsa from 'elliptic'
import fs from 'fs';
const ec = new ecdsa.ec('secp256k1');
const privateKeyLocation = 'wallet/' + (process.env.PRIVATE_KEY || 'defalut' );
const privateKeyFile = privateKeyLocation + '/private_key';
const createPrivateKey = () => {
const keyPair = ec.genKeyPair();
const privateKey = keyPair.getPrivate();
return privateKey.toString(16)
}
const initWallet = () => {
if (fs.existsSync(privateKeyFile)) {
console.log('지갑에 비밀키가 만들어져 있음');
return;
}
if (!fs.existsSync('wallet/')) { fs.mkdirSync('wallet/'); }
if (!fs.existsSync(privateKeyLocation)) { fs.mkdirSync(privateKeyLocation); }
const privateKey = createPrivateKey();
fs.writeFileSync(privateKeyFile, privateKey);
}
const getPrivateKeyFromWallt = () => {
const buffer = fs.readFileSync(privateKeyFile, 'utf-8');
return buffer.toString();
}
const getPublicKeyFromWallet = () => {
const privateKey = getPrivateKeyFromWallt();
const publicKey = ec.keyFromPrivate(privateKey, 'hex');
return publicKey.getPublic().encode('hex')
}
export { initWallet, getPublicKeyFromWallet }
transation.js
import CryptoJS from 'crypto-js'
const COINBASE_AMOUNT = 50;
class TxOut {
constructor(address, amount ) {
this.address = address;
this.amount = amount;
}
}
class TxIn {
constructor(txOutId, txOutIndex, sign) {
this.txOutId = txOutId;
this.txOutIndex = txOutIndex;
this.sign = sign;
}
}
class Transaction {
constructor(id, txIns, txOuts) {
this.id = id;
this.txIns = txIns;
this.txOuts = txOuts;
}
}
const getTransactionID = (transaction) => {
const txInsContent = transaction.txIns
.map((txIn) => txIn.txOutId + txIn.txOutIndex)
.reduce((a, b) => a + b, '');
const txOutsContent = transaction.txOuts
.map((txOut) => txOut.address + txOut.amount)
.reduce((a, b) => a + b, '');
return CryptoJS.SHA256(txInsContent + txOutsContent).toString()
}
const signTxIn = (transaction, txInIndex, privateKey) => {
const signature = toHexString(privateKey, transaction.id).toDER();
return signature;
}
const getCoinbaseTransaction = (address, blockIndex) => {
const tr = new Transaction();
const txIn = new TxIn();
txIn.sign = '';
txIn.txOutId = '';
txIn.txOutIndex = blockIndex;
const txOut = new TxOut();
txOut.address = address;
txOut.amount = COINBASE_AMOUNT;
tr.txIns = [txIn];
tr.txOuts = [txOut];
tr.id = getTransactionID(tr);
return tr;
}