**npm run dev:ts index.ts npm run dev:ts ./wallet/server.ts
런타임이 없다==실행할수있는 환경, 실행시켜줄수있는 실행기 typescript는 컴퓨터가 알아먹을수 있는 언어는 아니다 작성후 번들링을 통해 js언어로 바꿔준후 브라우저나 nodejs환경에서 실행해줘야된다
-
npm init -y
-
npm install -D typescript ts-node @types/node(Node.js에서 typescript를 사용하기 위해 필요한 것)
-
npx tsc index.ts(ts를 js로 번들링해주는 명령어)
번들/빌드하기너무 기찬다 ..
-
npx ts-node 파일명 (배포할떄는 사용하면안되고 개발테스트할때만사용) (Typescript는 코드작성을 마친후, javascript로 변환(컴파일)되는데, Node.js에서는 javascript만 사용하므로, 변환 => 실행해야 하는 번거로움이 있다. ts-node는, 이 변환 => 실행 작업을 한번에 해준다.) 터미널에서 바로찍어볼수있다
-
tsconfig.json생성 ( 타입스크립트를 작성할 때 어떤 규칙을 설정할 것인지 적는 문서 )
{
"compilerOptions": {
"outDir": "./dist/", //밑에index.js바로생기는게 싫어서 여기에 따로 생성되게 해주는 속성( 해당 디렉토리로 결과 구조를 보냅니다. )
"esModuleInterop": true, //import문법을 사용할수있게 해주는 속성 import React from 'react'
"moduleResolution": "node",
"resolveJsonModule": true,
"strict": true, // /* 모든 엄격한 타입-체킹 옵션 활성화 여부 */
"baseUrl": ".", // /* non-absolute한 모듈 이름을 처리할 기준 디렉토리 */
"typeRoots": ["./node_modules/@types", "./@types"], //typeRoots를 지정하면 typeRoots 아래에 있는 패키지만 포함
"paths": {
"@core/*": ["src/core/*"], //core안에있는 경로를 현재위치서부터가아닌 src디렉토리안의 core디렉토리부터 시작(../../ 를 최소화할수있다)
"*": ["@types/*"] //core를 제외한 모든경로를 @type에서 시작
}
}
}
- npx tsc --build 모든ts파일을 위설정을 적용해서 js언어로 번들링해주는 명령어
//경로쓴거 되나해보쟈
index.ts
import { a } from '@core/utils/utils.ts'
utils.ts
export const a = 10
-
npm install -D tsconfig-paths (tsconfig.json에서 paths에 적어둔설정을 사용하기 위한 명령어)
-
npx ts-node -r tsconfig-paths/register [파일명] (경로에 별칭이 사용된 ts파일을 실행할 수 있다.)
매번치기 기찬으니 package.json에 설정해두기 "dev:ts":"ts-node -r tsconfig-paths/register" (npm run dev:ts)
//이명령어로 @core사용한 파일실행 // npm run dev:ts ./wallet/server.ts //@core때문에 // npx ts-node -r tsconfig-paths/register ./wallet/server.ts
//@core별칭을 안쓰면 npx ts-node만 써주면 된다
*test파일을 위한 npx jest명령어를 사용하기위해 npm install -D ts-jest를 깔아줌
외부라이브러리가져올때 개빡침
- npm i --save-dev @types/express //큰것들은 이거설치
- npm i -D @types/express
//작은것들은 머해줄지 안떠서 @types디렉토리에 hex-to-binary 처럼 별칭 설정
- eslint ->배열의 반복문을 돌릴 때 일반 for문을 돌릴 수도 있지만, forEach, map 등 Array 내장 함수를 사용할 수도 있다.
이처럼 여러 방식의 코드 작성법이 있는데, 이러한 방식을 일관성 있는 방식으로 구현할 수 있도록 잡아주는 것이 eslint가 하는 역할
- prettier
-> prettier는 eslint처럼 '코드 구현 방식'이 아닌, 줄 바꿈, 공백, 들여 쓰기 등 에디터에서 '텍스트'를 일관되게 작성되도록 도와주는 것이다.
- npm install -D eslint prettier eslint-plugin-prettier eslint-config-prettier -->D를 쓰는이유는? package.json에 개발모드(devDependencies)로 저장하기위해---나중에 배포할때 dev 붙은건 설치 안되도록 build 하고 배포할겁니다
--->eslint-config-prettier 는 prettier 의 설정 중 eslint 의 설정과 충돌이 나는 설정들을 비활성화 해주는 라이브러리이다.
---> eslint-plugin-prettier는 Prettier의 규칙을 eslint에 적용시킬 수 있게끔 해주는 plugin이다.
{
"extends": ["plugin:prettier/reccommend"]
}
{
"printWidth": 120,
"tabWdith": 4,
"singleQuote": true,
"trailingComma": "all",
"semi": false
}
설정들가는법 Ctrl + , --->Format On Save 체크 ---> Default Formatter에서 prettier-code formatter바까주기
객체지향적 작은것부터 만들면서 큰거를 만들기 근데 테스트가 힘들다 테스트코드를 작성하는 프레임워크를 설치하려고함
javascript ->jest typescript -> jest
- npm install -D ts-jest @types/jest babel -core
- npm isntall -D @babel/preset-typescript @babel/preset-env
babel.config.js (node환경에서 typescript언어를 읽을수 있게 도와주는 아이)
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: { node: 'current' },
},
],
'@babel/preset-typescript',
],
}
jest.config.ts
import type { Config } from '@jest/types'
const config: Config.InitialOptions = {
moduleFileExtensions: ['ts', 'js'],
testMatch: ['<rootDir>/**/*.test.(js|ts)'],
moduleNameMapper: {
//별칭
},
testEnvironment: 'node',
verbose: true,
preset: 'ts-jest',
}
export default config
//터미널에 npx jest쓰면 실행됨
- 마이닝
마이닝을 하기위해서: 블럭이 생성되는 평균시간을 구해야됨 평균적으로 블럭을 생성할때 10분 정도 걸리게 하고싶다 평균시간을 구하는 블럭갯수를 10개로 하겠다 그럼 블럭을 담을수있는공간필요
#작업순서 ##목적은 마이닝구현 ->마이닝을 구현하려면 난이도가 필요하고 난이도를 구현하려면 체인필요
1.체인구현 2.난이도 구현 3.마이닝 구현
해쉬값은 16진수로 구성되어있다(64글자) 16진수를 2진수로 바꾼다면 1개의글자를 4글자로 치환할수있다 (64*4 글자)
16진수는 2진수(0,1)랑 친구다
16진수 1글자 4 bit 16진수 2글자 8 bit
8bit=1byte
왜16진수를 2진수로 바꾸려고 하는가 작업증명중 pow는 hash값을 통해서 앞에있는 자릿수0이 몇개들어갔는가를 찾는거
difficulty=4 라면
hash값으로 변환했을때
0이 앞에 4개있는걸 찾는거
0000
첫번쨰 순서는 hash에서 2진수로 바꿀줄 알아야됨
core
blockchain
-block
-chain
serve
-http
-websocket
//옵션값 public, private
//class문법에서는 default로 옵션값이 public으로 설정되어있다
//public 접근 제한자: class P2PServer extends Chain 이런식으로 extends로 클래스를 가져왔을때 //Chain class안에있는 값을 복사해서 다 가져오는건데 그럼 현재 P2PServer에 Chain내용이 다 들어있는거라 //Chain안에 있는 public이 붙은 모든것은 this.connectSocket 이런식으로 가져와서 쓸수 있다 //(P2PServer.connectSocket또는 Chain.connectSocket으로도 쓸수없고 this. 으로 써줘야 한다 ) //그런데 private가 붙은 것들은 가져와서 쓸수없다
//private 접근 제한자: 단어 뜻 그대로 개인적인 것이라 외부에서 사용될 수 없도록 합니다. //**************************************____************************************** //단방향이란 client는 요청만 서버는 응답만 할수있다 //양방향이란 client, server둘다 요청, 응답을 할수있다.
//그래서 client,server가 딱 정해져있지않고 하는역할에따라서 client도 될수있고 server도 될수있다 //p2p는 양방향이다 //우리는 그 네트워킹 방법중 p2p네트워킹을 블록체인에 사용할것이다 //왜 양방향인 p2p네트워킹을 이용하는가? //중앙화=단방향, 탈중앙화= 양방향 //중앙화는 중앙에서 관리(중앙을 통해서만 요청과응답 가능) 그럼 거기만 털리면 다털림 //탈중앙화는 개인들이 관리 (하는역할에 따라 server도 되고 client도 될수있음) 그럼 털려면 그이전해쉬필요,그걸털려면 또그이전해쉬필요 해킹힘듬,보안강화 //그리고 모두가 같은 정보를 가지고 있기때문에 한사람께 털렸다고 해도 문제가 되지않음 //그리고 조작을 하려고 해도 전부거를 다해야됨 그건 불가능 //컴퓨터는 클라이언트 ,서버 둘다가능 //vs code는 컴퓨터가 어떤역할(client, server)을 할지 알려주는 메모장 같은역할 //브라우저는 client //********************************_******************************** //p2p란? (peer-to-peer network) 혹은 동등 계층간 통신망
//동등계층간 연결구조, 여러대의 컴퓨터가 동등한 개념으로 망을 이룹니다
//우리에게 익숙한 구조는 다수의 컴퓨터가 서버컴퓨터에 요청하면 요청에 맞는 응답을 해주는 구조이다
//P2P는 컴퓨터끼리 서로 연결되어 데이터를 주고 받는 구조이다 //요청하는 컴퓨터와 서비스를 제공하는 컴퓨터가 따로 존재하지 않는다 //누구든 서버와 클라이언트역할을 둘다한다고 보면 된다 //********************************_********************************
//체인은 그냥 배열임 이름을 체인이라고 정한거 그안에 블럭이 들어가는거임 //블럭을 넣는행위를 체이닝이라고함 //블럭은 예를들면 현재 100번까지 만들어져있다 그럼 거기까지의 블럭을 가져오는거고 그이후 101번째부터 내가만드는거임 //근데 내컴이 느리면 게속못만들고 단사람이 만들수도있음 연산을 빠르게해주는 gpu를 이용하기위해서 그래픽카드를 사서 컴에 꽂아서 하는거 //그리고 내가 5번쨰 블럭을 만들었는데 최신으로만들어진 블럭이 100번쨰이다 그럼 100번쨰까지 덮어씌우고 그이후블록을 만드는거 //******************************___******************************
//difficulty를 10으로 했다 그럼 nonce값을 1부터 넣어보면서 hash값을 hex를 통해 2진수로 바꾼값에서 0이 10개가 될떄 까지 찾는데 //10개이상이면 되고 즉 11개 12개 여도 노상관 10개보다 적으면 안되는거 // 찾으면 마이닝(채굴)한거!! //******************************_****************************** //static
//static은 매서드앞에만 쓸수있다 //static은 외부에서 가져다쓸수있냐 없냐 그차이가 아니라 시점의 차이이다 //static이 붙은 매서드는 시점을 인스턴스가 생성되기 전으로 보고 안붙은 매서드는 시점을 인스턴스가 생성된 이후로 본다
//**new생성자를 사용해서 new Block을 하면 인스턴스가 생성되는건 맞는데 //Block class 안에 코드를 첨부터 쭉읽고 constructor(){}가 되는 시점에 인스턴스가 생성되는 것이다 //**new생성자를 붙이지 않고 Block만 써주면 Block class를 가져와서 코드를 첨부터 읽는데 인스턴스를 생성시키지 않기 때문에 //constructor(){}부분은 실행하지않는다
//그래서 static이 붙은 매서드호출은 constructor(){}에서 해줄게 아니면 new 클래스를 붙이지 않고 Block 만 써줘서 Block class를 //가져와서도 가능한데 static이 안붙은 매서드 호출은 this객체가 생성된 이후만 가능해서 무조건 new생성자를 써줘서 //constructor(){}가 실행되야 하고 그이후에만 호출이 가능하다
//static이 붙은 매서드를 호출할때는 constructor(){}이후에 써줘도 this(인스턴스)가 생성되기 전으로 보기때문에 //this.getMerkleRoot() 이아닌 Block.getMerkleRoot()로 호출한다(근데 constructor(){}이후에서 호출해줘도 마찬가지) //static이 안붙은 매서드는 this(인스턴스)가 생성되고 실행되기 때문에 constructor(){}가 끝나기전에서는 호출해줄수없고 //그이후에 호출이가능하다 그래서 호출할때도 this.getMerkleRoot() 으로 호출해주게 된다
//static이 붙건 안붙건 public이 붙은 매서드는 extends 한 class안에서도 사용가능한데 //그땐 둘다 this.으로 사용해주게 된다 //대신 static이 붙은 매서드 호출은 this.으로 해주더라도 시점이 인스턴스 생성전이란걸 기억하자 //********************************___******************************** //클래스에 포함된 매서드는 클래스에 포함된거라 export해주는개념이 아니라 클래스를 export해주는 거다 //********************************___******************************** // 마이닝
// 마이닝을 하기위해서: // 블럭이 생성되는 평균시간을 구해야됨 // 평균적으로 블럭을 생성할때 10분 정도 걸리게 하고싶다 // 평균시간을 구하는 블럭갯수를 10개로 하겠다 // 그럼 블럭을 담을수있는공간필요
// #작업순서 ##목적은 마이닝구현 // ->마이닝을 구현하려면 난이도가 필요하고 난이도를 구현하려면 체인필요
// 1.체인구현 2.난이도 구현 3.마이닝 구현
// 해쉬값은 16진수(09, af)로 구성되어있다(64글자)
// 16진수를 2진수로 바꾼다면 1개의글자를 4글자로 치환할수있다 (64*4 글자)
// 16진수는 2진수(0,1)랑 친구다
// 16진수 1글자 4 bit // 16진수 2글자 8 bit
// 8bit=1byte=2nible
// 왜16진수를 2진수로 바꾸려고 하는가 // 작업증명중 pow는 hash값을 통해서 // 앞에있는 자릿수0이 몇개들어갔는가를 찾는거
// difficulty=4 라면 // hash값으로 변환했을때 // 0이 앞에 4개있는걸 찾는거 // 0000
// 첫번쨰 순서는 hash에서 2진수로 바꿀줄 알아야됨 //************************************_************************************ //작업증명
//difficulty를 만족하는 논스값을 찾는것 //논스값을 1부터 넣어서 difficulty로정해준 0의 갯수와 일치하게되면 논스값을 찾은것으로 채굴(마이닝)성공=블록생성 //채굴(마이닝)은 블록체인네트워크를 유지시키기위해시키는데 중요, 채굴한 사람에게는 작업증명의 대가로 일정한 개수의 암호화폐를 지급
//-->ex)16진수로 되어있는 해쉬값을 2진수로 바꿨을떄 앞자리가 4개가 0 이상인 해시값을 만들수 있도록 하는 논스값을 찾아라 //즉 논스값을 몇으로 설정해야 앞자리 4개가 0인 값을 찾느냐 하는것
//채굴(마이닝)=블럭생성 //difficulty 난이도를 이용해 블럭생성을 쉽게못하게 하는게 작업증명:POW=16진수를 2진수로 바깟을때 앞에 0이 몇개 붙었는가 찾는거 //작업증명의 대가로 일정한 개수의 암호화폐를 지급받는 것을 채굴(採掘) 또는 마이닝 //********************************___********************************
- 비트코인과 같은 암호화폐를 보관하거나 주고 받을 수 있도록 만들어진 소프트웨어
- 공개키, 개인키 개인키(계좌의 비밀번호) 공개키(은행들에서 암묵적으로쓰는 코드분류번호) 이 개인키를 가지고 특정알고리즘(타원곡선 암호 알고리즘)을 사용하여 공개키라는 걸 만든다 생성된 공개키를 가지고 다시한번 해쉬함수(=임의의 길이를 가진 값을 고정된 길이의 문자로 만들어주는 역할)를 이용해서 최종적으로 지갑주소(내가만든 편리한 계좌번호)를 생성하게 된다
개인키 -> (타원곡선 알고리즘) -> 공개키 ->(해시) ->계정주소(지갑) ->서명 ->검증
- 공통점: 알파벳과 숫자를 조합한 아주 긴 나열
- 차이점: 퍼블릭 키는 공개가능, 프라이빗 키는 비밀번호처럼 절대 유출되면 안됨
- 서명
- 나의 지갑이 유효하는 것인지 검증하는 용도 서명을 만들때 필요한값으로는 개인키,해쉬값(transaction hash)이 있다 개인키값에 해쉬값을 넣어서 만든다
지갑은 토스와비슷 토스는 어떤은행이든 연결되면 잔액을 볼수있었다 지감은 내가 지갑에 나의 계좌번호를 넣으면 지갑이라는 프로그램이 나의 잔액을 보여줄수있는 프로그램 거래에 있어서 중요한 정보는 누가누구에게 얼마를 보냈느냐 그 내용을 확인하려면 인증절차를 걸침
블록체인도 이 보내는이와 받는이를 만들어낼수있어야하고 얼마가 있는지와 인증이라는 절차기능도 들어가야됨
지갑은 보내는이와 받는이의 계좌번호만 모아서 관리하는 프로그램이다
지갑을 만드는 방법은 랜덤값으로 0,1이 뜨게하는걸 256번하면 256숫자 그럼 256bit로 돌여서 32byte로 바까서 나오는 64자리의 해쉬값
동전을 256번던지는 값을 계좌번호 비밀번호=개인키 개인키를 넣고 해쉬를 써서 돌리면 공개키가 된다 공개키를 가지고2번정도의 암호화를 진행 그게 공개키의 주소/계정
즉 처음에 개인키(=otp같은거, 혼자만알고있어야됨)를 만듬 개인키를 가지고 공개키(은행들에서 암묵적으로쓰는 코드분류번호)를 만듬 공개키를 가지고 계정(계좌번호, 즉 단사람도 알수있음)을 만듬
즉 지갑은 개인키를 16진수 즉 64자리 숫자를 로컬에 저장하는 시스템+공개키,계정등을 관리해주는 프로그램 개인키자체를 네트워크자체에 실어서주면안되고 해쉬로 만들어서 줘야됨 내가 나임을 인증하는방법이 서명 개인키는 누구나 만들수있다 개인키로 공개키를 만든다 계정은 공개키에서 앞자리 12바이트를 빼서 만드는거다
https://brunch.co.kr/@nujabes403/13- 개인키에 관련된 내용
우리가 만든거 여러가지 node들(프로세스)-core, http서버, p2p 하나더 만들게 월넷(지갑) 근데 지갑은 만드는게 선택조건임 그래서 비트코인이든 이더리움이든 지갑은 따로 구현해서 만들어있음
트랜잭션에 들어갈 속성으로는 input(signature를 만듬),output(돈의 내용이 들어감)
8bit=1byte=2nible
1nible=4bit 4bit=2의4승=16글자
1byte는 2글자로 표현 16진수로 표현했을때 32byte는 64글자
개인키를 가지고 뽑앚진 결과물이 서명 ㅡ 서명을 블록체인에 던져줌 블록체인은 그서명을 가지고 +공개키를 가지고 그값이 트루인지 펄스인지만 구별해주면된다
///너가보낸 트랜잭션맞아?
트랜잭션(송신자, 수신사, 보낼금액)적힘 이 트랜잭션의 진위여부가 중요 =송신자의 개인키로 서명을 만들어야하고 그 서명이 송신자의 것이 맞다는 것을 확인할수 있어야 한다 그리고 이 형태의 싸인을 만들수 있는 기술이 타원곡선이다
맞다는 것을 확인할수 있으려면 모든사람들은 공통적으로 타원곡선위의 어느한점을 알고있어야 한다 이점을 타원곡선의 기준점, G라고 부른다 그리고 G의 좌표가 무엇이냐에 따라 별명이 있다
타원곡선 방정식은 y2=x3+ax+b 이더리움과 비트코인에 사용되는 타원곡선은 a가0 b가 7이며 기준점 G가 "02 70~~~~98"인 타원곡선을 말한다 = y2=x3+7 얘의 별명은 SECP256K1이다
이제 SECP256K1를 가지고 이 트랜잭션 너가 보낸것 맞니?를 할것이다 서명을 보내는쪽과 받아서 검증하는 쪽의 스텝으로 나눠서 해야된다
-
보내는 사람의 절차 (서명을 만들어서 트랜잭션과 함꼐 보낸다)
- 트랜잭션을 만든다
- 개인키(단순한 숫자)(1~n-1까지의 정수에서 랜덤하게 뽑음)를 타원곡선이 지정해주는 범위 내에서 정한다
- 첫번째서명r, 두번쨰 서명s찾기
- 개인키를 골랐을때처럼 1~n-1범위의 정수를 랜덤하게 고른다
- 개인키는 한번고르면 평생 그키만 쓰는데 이값은 트랜잭션을 보낼때마다 랜덤하게 선정해서 골라야 한다
- 내가 고르는건 아니고 컴터가 랜덤하게 뽑아서 넣어준다
- 이제 트랜잭션+서명r과 서명s를 전송하면 된다
-
받는사람의 절차
- 이거진짜 너가 보낸거 맞아를 확인
지갑이 보내는 사람,받는사람, 금액데이터를 보내주면 블록체인은 트랜잭션을 만드는게 아니라 그걸받아서 블록에 넣는 역할임 즉 블록체인은 데이터를 가지고있지 않고 지갑이 보내주면 그걸 보관하고있다가 블럭이 생성되면 거기에 넣어줌
지갑과 블록체인은 포트가 다르다 그래서 지갑에서 블록체인에 요청을 보내면 cors오류가 터진다
- Authorization a[Token]--->a가먼가
@기준으로 자르고 앞에걸 가져오면 Authorization :basic web7722
web7722이걸 인코딩한게 나타나고 다시이러케나타내려면 티코딩해줌된다
오늘 이걸실습할거다 근데 토큰방식이아닌 옛날방식이라 구글브라우저에서는 안된다
지갑 구현하는데 필요한 요소
tx- 블럭들안에 있는 tx의 맨처음내용은 채굴한사람의 거래내용이고 그사람한테 코인을 주는데 첫번쨰 거래내용을 코인베이스(모든블럭의 첫번쨰 거래내역)라고 하고 우리는 그것을 구현 -코인베이스는 인풋의 내역은 존재하지 않음
tx pool
wallet
*UTXO
입금출금-transaction(입금은 input, 출금은output) -거래내역은 두가지 속성이 있다 들어올돈과 나갈돈
잔액-unspentTransactionOutput(utxo)(미사용트랜잭션)
모든거래내역을 가지고 하는게 아니라 돈의 이동이 있을때마다 잔액을 표시해서 잔액을 가지고 계산한다
- tx0000
input ------------------ output x ------------------------이동훈 50btc(코인베이스)-채굴로 받은 코인(사용)
- tx0001 (근데 인구한테 1btc를 주기로함)
0000:0(50 btc) ---------------인구 1 btc(사용), 이동훈 49btc(미사용) sign
- tx0002 (근데 인구가 재원한테 0.5btc를 주기로함)
txOutId+ txOutIndex ------인구 0.5btc(미사용), 재원 0.5btc(미사용) (그전거래내력 tx0001참고-바로전은 아니고 그냥 전에거 tx:0001:0(1btc))
sign
*미사용만 다더하면 원래 50btc가 나온다 그래서 미사용항목만 넣을것도 구현해야된다
이동훈 49.9 인구 0.085 재원 0.005 지현 0.010
동훈이 각각 10 씩주고 재원과 지현이 인구한테 2씩주고 인구가 마지막에 잔액을 다 동훈에게 넘긴다
tx0004 (49.9) 0003:0 ----------------------동훈 19.9, 안규 0.085, 10 재원 0.005, 10 지현 0.010, 10
tx0005 (재원 10, 지현 10) 0004:1 ------------------------안규 0.085,10 ,2, 2 재원 0.005,8(미사용) 지현 0.010,8(미사용) 0004:2
tx0006 (안규 0.085,10 ,2, 2) 0005:0 ------------------------안규 0, 동훈 19.9, 0.085, 10 ,2, 2(미사용)
*마이닝(코인베이스) 기능구현-특징은 인풋이없다
output이 만들어짐과동시에 거래내역(transaction)(input, output내용과 그걸합쳐서 만든 해쉬)이 만들어지고 utxo(txOutId(거래내역에서 만들어진 해쉬값),txOutIndex(인덱스),account(계정),amount(output돈))도 만들어진다 이렇게 utxo에 모든사람의 (계정, 인덱스, 돈)정보가 쌓이게 된다 우리는 이 utxo를 가지고 다음 거래의 input을 만든다
예를 들어 tx0001번쨰 거래내역을 만들려고한다 그럼 먼저 input을 만들어야 된다 input을 만들기위해 utxo를 확인한다 a계정의 사람이 b한테 10btc를 보내려고 한다면 utxo에 담긴 a계정사람에 대한걸 쫙모은다 거기서 우선 balance(총합산액)를 확인해서 내가 보내려는 값보다 더큰 금액을 가지고 있는지 확인한다 더작은 금액을 가지고 있다면 그냥 종료되고 더큰 금액을 가지고 있다면 10btc이상이 뾥힐떄까지 돌려서 input에 넣어준다
3, 5, 3 btc 가 각각 뽑혓다고 치면 여기에대한 txOutId, txOutIndex값이 다 각각 다를것이다 이정보들을 배열에 담아주고 서명도 넣어준다 이렇게 utxo에서 사용된정보들은 사용과동시에 사라진다 그리고 input도 만들어진것이다 그다음 output에 a의 account, amount(1btc), b의 account, amount(3,5,2btc)의 내용이 담기고 output이 만들어짐과 동시에 또 거래내역이 만들어지고 utxo에 output내용이 담기게 된다
- 마이닝되어야 거래내역이 생기고 utxo도 추가되는거
- balance=총액(wallet.ts)
- 비트코인은 풀에 쌓는 트랜잭션이 10분단위 이더리움은 숫자단위
<매서드 정리>
*배열 매서드filter(걸러낸다)
이 함수의 인수는 element, index, array index와 array는 생략이 가능 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환한다. 다시 말해서 대상인 배열에서 요소 하나씩 뽑아온 다음에 필터링 콜백함수에 전달해서 결과가 true인 요소들만 모아놓은 배열을 반환해주는 메서드이다. 단, 어떤 요소도 통과하지 못하면 빈 배열을 반환한다.
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; console.log( arr.filter((v) => { // return v % 5 === 0; if (v % 5 === 0) { return v; } }), );
/***배열 매서드 reduce(누적한다)
첫 번째 인자로 콜백함수가 들어오고, (생략가능한) 두 번째 인자는 콜백의 첫 호출에서 accumulator값으로 적용될 값입니다. 그럼 2번쨰 인자값을 0으로 정해주면 v=0, k=0번쨰 인덱스값, 1로 정해주면 v=1, k=0번쨰 인덱스값이 된다 일반적으로 reduce 메서드는 배열 요소들의 평균을 구할 때 많이 쓴다.
const array1 = [20, 35, 1, 98, 46, 5]; array1.reduce((a, b) => return(a += b)) //a=20, b=35 //결과 : 205
(1) a : 20, b : 35 (2) a : 55(20 + 35), b : 1 (3) a : 56(20 + 35 + 1), b : 98 (4) a : 154(20 + 35 + 1 + 98), b : 46 (5) a : 200(20 + 35 + 1 + 98 + 46), b : 5 (6) array1.reduce((a, b) => (a + b)) 에서 return 되는 값 = a + b = 205 (7) 205 / 6 = 34.166666666666664
---->reduce 메서드의 첫번째 인수인 콜백함수의 a는 누적 값, b 는 현재 값이다. reduce 를 호출했을 때 return 되는 값은 마지막 최종 누적값이다.
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; console.log( arr.reduce((v, k) => { console.log("v =?", v); console.log("k =?", k); return (v += k); // v = v + k // return k; }, 0), // default option );
***배열 map(맵핑, 매치해준다) 매서드 배열의 길이를 유지하면서 기존의 배열을 활용한 새로운 배열을 만드는데 유용한 메서드
let arr = [1, 2, 3, 4, 5] console.log( arr.map((v) => { return v * 2 }), )
**배열 join매서드
arr.join() 메서드는 배열의 모든 요소를 연결해 하나의 문자열로 만든다. 매개변수로, 배열의 각 요소를 구분할 문자열이 들어간다. 이 구분자는 필요한 경우 문자열로 변환되고, 생략하면 배열의 원소들의 쉼표로 구분된다.
예제 const arr = ['바람', '비', '물'];
console.log(arr.join()); // 바람,비,물
console.log(arr.join('')); // 바람비물
console.log(arr.join('-')); // 바람-비-물
**배열 push매서드
push()메서드는 배열 끝에 요소를 추가하는 데 사용됩니다
const arr =[1,2,3]; const arr2 = [8,9,10]; arr.push(4);// single item //arr=1234 arr.push(5,6,7);// multiple items //arr=1234567 arr.push(...arr2);// spread operator //arr=12345678910 //배열에 담겨있으니 ...으로 구조분해할당을해서 배열에서 꺼내서 넣어준다 //12345678910 console.log(arr); //12345678910
//
const arr = [1, 2, 3]
const arr2 = arr.push(4, 5)
console.log(arr)//[1,2,3,4,5] ---push매서드는 다른곳에 안담아줘도 바로 배열에 추가됨
console.log(arr2)//5 -------push매서드는 다른곳에 담아주게되면 length값이 뜬다
**배열 concat매서드
const myArr = [1, 2, 3];
console.log(myArr.concat(4, 5)); // [1, 2, 3, 4, 5] console.log(myArr.concat('육', '칠')); // [1, 2, 3, '육', '칠'] console.log(myArr.concat(true, false)); // [1, 2, 3, true, false] console.log(myArr.concat({name: 'bigtop'})); // [1, 2, 3, {...}]
**concat과 push의 차이
-push에 배열을 통쨰로 넣음 const arr = [1, 2, 3] const arr2 = [4, 5]
arr.push(arr2) //[ 1, 2, 3, [ 4, 5 ] ] console.log(arr)
-push에 배열에서 데이터만 꺼내서 넣음 const arr3 = [1, 2, 3] const arr4 = [4, 5] arr3.push(...arr4) //[ 1, 2, 3, 4, 5 ] console.log(arr3)
const arr1 = [1, 2, 3] const arr2 = [4, 5] console.log(arr1.concat(arr2)) //[ 1, 2, 3, 4, 5 ]
const arr1 = [1, 2, 3] const arr2 = [4, 5] console.log(arr1.concat(...arr2)) //[ 1, 2, 3, 4, 5 ]
1.push는 원래있던 배열에 마지막 요소로 데이터를 추가해서 기존배열을 변형 concat은 slice처럼 기존배열에 아무런 영향을 주지않고 새로운 배열을 만들어준다 아무런 값도 전달하지 않을 경우에는 이 부분도 slice와 마찬가지로 기존의 배열 전체가 그대로 반환된다. 사실 concat메서드는 배열에 값을 추가하는 용도보다는 주로 배열과 배열을 합치는데 사용된다.
2.원본 배열이 변환되도 상관 없는 경우에는 push() 함수를 사용하는 것이 더 나을수도 있다. 하지만 원본의 배열을 그대로 유지하면서 새로운 요소가 포함되는 배열을 만드는 경우에는 concat() 함수를 사용하는것이 좋다.
***배열 find매서드
const arr = [1, 2, 4, 8, 20, 30]
return console.log(arr.find((v) => v > 10)) //20 //???왜30은 반환을 안할까 //find메소드는 주어진 매서드를 만족하는 첫번쨰 요소의 값을 반환한다 //만약 만족하는 요소가 없다면 undefinde를 반환한다
**string repeat매서드
문자열을 반복한 값을 반환하는 메서드
const string = 'abc' const string2 = string.repeat(5)
console.log(string2) //abcabcabcabcabc
//또는 console.log('123'.repeat(10)) //123123123123123123123123123123
*******원래배열에 추가만해주는 매서드는 새로 안담아줘도 되지만 새로배열을 생성하는건 담아줘야 적용이 된다*********** */
//if문 break; //const,let //파람스 //첫번쨰 마이닝은 거래내역없이 빈배열로진행?
//거래내역을 받아서 마이닝하는 코든느 어디에 //엽데이트 트랜잭션
채굴로번 코인은 utxo에는 들가지만 거래가 아니라 트랜잭션이 안생기고 트랜잭션풀에도 들가지 않고 주고받는 거래가 있어야 트랜잭션이 발생하고 풀에들감
**addToChain 과정 ex) a노드 체인안에 블럭수 2개 , b노드 체인안에 블럭수4개 a노드가 마이닝하고 체이닝함 latestBlock을 브로드 캐스트함 b노드가 받음 근데 utxo비교했을떄 b가 더 많음 그럼 받은거 추가안하고 자기 체인을 보냄 a노드가 그체인을 받아서 교체 //이게아니라 블럭수가 2이상 차이가 날떄는 통쨰로 다른노드의 체인을 가져와서 덮어씌워지는거같다
ex)
a노드 체인안에 블럭수 2개 , b노드 체인안에 블럭수2개
a노드가 마이닝하고 체이닝함 latestBlock을 브로드 캐스트함
b노드가 받음 비교했을때 utxo가 a가 더 많으니까 받은 블록을 체이닝함
끗
**거래내역이 생기면 브로드캐스트된다