지갑에대한 이록적인 내용
# 지갑 구성 및 지갑의 역할
- 기본적인 역할로 암호화폐를 안전하게 보관할수있고 암호화폐를 전달하거나 받을수있다.
- 자산의 소유권을 암호화 방식으로 증명 지갑의 개인키를 사용해서 거래의 서명을 검증하고<br>
본인의 자산을 관리
- 본인의 암호화폐의 보유량 확인
- 지갑의 거래내역확인
- 복구 문구를 사용해서 지갑 복원(복구 문구를 가지고 특정 알고리즘을 거쳐서 개인키를 추출한다.)
## 금융
- 금융쪽에서는 장부를 가지고 모든 거래내역을 기록하는방식
- 은행이라는 금융기관은 장부에 거래 내역으로 의존 할수 밖에 없는 중앙 집권 방식
# 분산 원장
- 분산원장은 금융과 반대로 거래에 참여하는 모든 참여자가 장부를 가지고있고 거래가 발생했을때 해당 거래 내역을 각자의 장부에 기록하는 방식
- 중앙에서 가지고있는게 아니라 모두 장부를 가지고 관리한다.
# 신원 인증 방식 분산 원장 기술로 개인키, 공개키,서명(영수증)
## 암호화 방식
- 대칭형 : 암호화 복호화 할때 사용하는 키가 동일한 키 1개를 사용한다. <br>
암호화한 사람과 수신하는 사람이 같은 키를 사용한다.
- 비대칭형 : 사용하는 키와 복호화 할때 사용하는 키가 다른것. 키 2개 <br>
다른사람에게 공개되어서는 절대 안되는 키 (비밀키) 비밀키를 토대로 만든 공캐기 한쌍.
## 대칭형
- 나 -> 원본 -> 대칭키로 원본 암호화 -> 암호문
- 너 -> 암호문 -> 대칭키로 복호화 -> 원본
- 대칭형의 형태는 암호문을 대칭키를 가지고있는 사람은 누구나 전달이 가능하다.
## 비대칭형
- 비대칭형의 경우는 암호화 할때 공개키로 암호화
- 나 -> 원본 -> 너의 공개키로 암호화 -> 암호문
- 너 -> 암호문 -> 너의 비밀키로 복호화 -> 원본
# 지갑의 공개키, 비밀키
- 공개키 : 사람들에게 공개할 키 정보를 암호화할때 사용
- 비밀키 : 본인만 알고있어야 하는 키 암호문을 복호화할대 사용
# 비밀키와 공개키의 역할
비밀키 소유자가 비밀키로 데이터를 암호화 하고 공개키를 같이 전달한다.
<br> 공개키와 암호문을 받은 사람은 공개키를 이용해서 검증이 가능하고
<br> 이렇게 위험성이 있어 보이는 방법을 사용하는 이유가 데이터의 보호 목적 보다는
<br> 공개키 데이터를 제공한 사람의 신원을 보장해주기 위해서
<br> 암호화된 데이터가 공캐리로 복호하 된다는 것이 공개키와 쌍으로 이루는 비밀키에 의해서
<br> 암호화가 되었다는 뜻 데이터의 제공자가 맞는지 이사람이 이 서명을 한사람인지 검증
<br> 이 방법이 공인 인증 체계의 기본 바탕의 전자 서명
# 개인키
- 실제 블록체 네트워크에 개인키를 생성하는 방식은 <br>
2 진수로 랜던값을 64 자리의 16진수 값으로 만든것이 개인키
- 개인키가 겹칠수는있는데 불가능한건 아닌데 확률이 천문학적으로 낮아서
- 겹치는수가 나올 확률이 개인키의 경우의 수는 2^256개의 개인키(자구상의 전체 원자수 보다 많다.)
# 순서
- 1. 암호화 하고싶은 데이를 SHA 256 방식으로 해싱하고
- 2. 개인키를 사용해서 해시값으로 서명을 생성
- 3. 서명이랑 공개키는 제 3자에게 전달이되고
- 4. 받은 제 3자는 공개키를 이용해서 서명을 검증
# 개인키 공개키 한쌍 키를 생성할떄 ECC 타원 곡선을 사용
- 타원 곡선 수학을 기반으로 디지털 서명으로 보호하기위해 사용하는 암호화 기술
- 공개키와 개인키의 개념이 있고, 공개키는 암호화와 검증에 사용, 개인키는 복호화와 서명을 만들때 사용한다.
- 디지털 서명은 본인이 개인키로 메시지로 서명을 할수있고 공개키는 받은사람이 누구나 서명을 확인해볼수있따.
- 쉽게 말해서 암호화 및 해독에 사용 <br>
- 다른사람의 공개키로 암호화해서 전달을 하면 그사람의 개인키로만 복호화가 가능하고 <br>
당사자끼리의 데이터 기밀성 보장
- 디지털 서명을 본인의 개인키로 생성하고 다른 사람한테 전달해서 공개키와 함꼐 서명을 검증할수있는 무결성 보장
- y^2= x^3+ax+b
- 기준점이있고 기준점에서 개인키를 가지고 공개키를 구하는데 기준점조가 공개키로 개인키를 역산하기 힘들다. 일고있으면된다.
class Wallet
import { randomBytes } from "crypto";
import elliptic from "elliptic";
import { SHA256 } from "crypto-js";
import fs from "fs";
import path from "path";
// 자갑 클래스 만들고 페이지에서 지갑생성을 한번 확인해보기
// elliptic 인스터스 생성
const ec = new elliptic.ec("secp256k1");
// 기본 지갑 정보 저장 경로
const dir = path.join(__dirname, "../../data");
export class Wallet {
public account: string;
public privatekey: string;
public publickey: string;
public balance: number;
constructor(privatekey: string = "") {
// 생성 단계에서 개인키값이 없으면 만들어넣자
this.privatekey = privatekey || this.getPrivatekey();
this.publickey = this.getPublickey();
this.account = this.getAccout();
this.balance = 0;
if (privatekey == "") Wallet.createWallet(this);
}
static createWallet(myWallet: Wallet) {
// fs 모듈로 파일 생성
// 지갑을 생성하면 주소를 저장할 것.
// 주소안에는 개인키 넣어보기
const filename = path.join(dir, myWallet.account);
const filecontents = myWallet.privatekey;
fs.writeFileSync(filename, filecontents, "utf-8");
}
static getWalletList(): string[] {
// 폴더를 읽어서 안에있는 파일내용을 문자열로 가져온다.
const files: string[] = fs.readdirSync(dir);
return files;
}
public getPrivatekey(): string {
return randomBytes(32).toString("hex");
}
public getPublickey(): string {
const keypair = ec.keyFromPrivate(this.privatekey);
return keypair.getPublic().encode("hex", false);
}
// data 폴더안에 해당하는 지갑 주소를 찾아서 반환
static getWalletprivatekey(accout: string): string {
const filename = path.join(dir, accout);
const filecontents = fs.readFileSync(filename);
return filecontents.toString();
}
public getAccout(): string {
return `0x${this.publickey.slice(26).toString()}`;
}
}
this.privateKey = privateKey || this.getPrivateKey();
이 코드 줄은 클래스 인스턴스의 privateKey 속성에 값을 할당합니다. 할당을 위해 논리 OR(||) 연산자를 사용하며, 목적은 제공된 인수 또는 getPrivateKey() 메서드에서 생성된 값을 기반으로 privateKey 값을 결정하는 것입니다.
이 줄이 단계별로 작동하는 방법은 다음과 같습니다.
- privateKey: 개인 키가 저장될 클래스의 속성입니다.
- privatekey: string = "": 이 클래스의 인스턴스를 생성할 때 privatekey 문자열이 전달될 수 있음을 나타내는 생성자의 매개변수입니다. 인스턴스 생성 중에 값이 제공되지 않으면 기본값은 빈 문자열("")입니다.
- this.privateKey = ...: 줄의 이 부분은 클래스 인스턴스의 privateKey 속성에 값을 할당합니다.
- 개인키 || this.getPrivateKey(): 이는 할당의 오른쪽입니다. privateKey에 할당할 값을 결정하는 표현식입니다.
- privateKey: 클래스의 인스턴스를 생성할 때 제공되었을 수 있는 privatekey 인수의 값입니다. 비어 있지 않은 문자열이 제공되면 진실한 값을 갖습니다. 빈 문자열이 제공된 경우(또는 기본값을 사용하여 값이 제공되지 않은 경우) 잘못된 값을 갖게 됩니다.
- this.getPrivateKey(): getPrivateKey()에 대한 메서드 호출로, 개인 키를 생성하는 것으로 추정됩니다. 이 방법의 목적은 개인 키가 명시적으로 제공되지 않은 경우 개인 키를 생성하는 것입니다.
이제 이 할당이 어떻게 작동하는지 이해해 보겠습니다.
- 클래스 인스턴스 생성 시 privatekey 인수로 비어 있지 않은 문자열 값이 제공된 경우 this.privateKey에 할당됩니다. 이는 제공된 개인 키가 사용된다는 의미입니다.
- 클래스 인스턴스를 생성하는 동안 privatekey 인수로 빈 문자열(또는 값 없음)이 제공된 경우 논리 OR(||) 연산자는 표현식을 왼쪽에서 오른쪽으로 평가합니다. 왼쪽 피연산자(privateKey)가 거짓이므로 오른쪽 피연산자(this.getPrivateKey())를 평가합니다.
- this.getPrivateKey()는 개인 키(구체적인 구현 세부 정보는 코드 조각에 제공되지 않음)를 생성하고 반환합니다. 이렇게 생성된 개인 키는 this.privateKey에 할당됩니다.
요약하면, 이 코드 줄은 인스턴스 생성 중에 값이 제공되었는지 여부에 따라 클래스 인스턴스의 privateKey 속성이 제공된 개인 키 또는 생성된 개인 키로 설정되도록 합니다.
ecc 타원곡선을 이용한 공개키 생성

테스트를 위한 서버
// 지갑 서버
import express from "express";
import { Wallet } from "./index";
import path from "path";
import fs from "fs";
const app = express();
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
// 지갑페이지 접속했을때
app.get(`/`, (req, res) => {
const page = fs.readFileSync(
path.join(__dirname, "/view/index.html"),
"utf8"
);
res.send(page);
});
// app.use(express.static(path.join(__dirname,)));
// 지갑을생성 요청
app.post("/newWallet", (req, res) => {
res.json(new Wallet());
});
// 지갑들 정보 불러오기
app.post("/walletList", (req, res) => {
const list = Wallet.getWalletList();
res.json(list);
});
//해당 지갑 주소로 지갑 찾기
app.post("/walletSelect/", (req, res) => {
const { account } = req.body;
const privatekey = Wallet.getWalletprivatekey(account);
res.json(new Wallet(privatekey));
});
app.listen(4000, () => {
console.log("server listening on");
});
테스트 화면

'backend > blockchain' 카테고리의 다른 글
| 20231005 블록체인 baseball (1) | 2023.10.05 |
|---|---|
| 20231005 블록체인 (0) | 2023.10.05 |
| 블록체인 (0) | 2023.09.05 |
| 블록체인 블록생성, 검증,테스트 ts (0) | 2023.09.04 |