지갑은 개인키를 보관하고 키를 관리하는 keychain.
-> 이더 또는 토큰을 보유하는 게 아니다.
비결정적(nondeterministic) 지갑
: 각각의 키를 무작위적으로 추출
결정적(deterministic) 지갑
: seed라고 하는 단일 마스터 키로부터 파생.
HD 지갑 (hierachical deterministic)
: BIP(Bitcoin Improvement Proposal)-32를 따르는 지갑.
mnemonic code
: 데이터 분실 등의 사고에 대비하여 시드를 단어 목록으로 인코딩.
FCCF1AB3329FD5DA3DA9577511F8F137
wolf juice proud gown wool unfair
wall cliff insect more detail hub
BIP(Bitcoin Improvement Proposal)-32를 따르는 deterministic 지갑.
키는 확장 가능하다.
트리 계층 구조에서, 어느 키든 부모 키가 되어 자식 키를 파생시킬 수 있다.
키 확장은 키에 특수 체인 코드를 추가하는 것을 말한다.
- 체인 코드란 자식 키를 생성하기 위해 공개키/개인키와 혼합된 256비트 이진 문자열이다.
- 개인키라면, 접두어 xprv로 구분되는 확장된 개인키가 된다.
- 공개키라면, 접두어 xpub으로 구분되는 확장된 공개키가 된다.
개인키가 없는 공개키에서도 자식 공개키를 파생할 수 있다.
- 자식 공개키는 자식 개인키에서 직접 파생하거나 부모 공개키에서 파생할 수 있다.
- 따라서 확장된 공개키는 자기 브런치에서 모든 공개키를 파생시키는데 사용 가능하다.
- 공개키만을 파생시킬 수도 있다.
이걸 이용해서 공개키 전용 배포를 만들 수 있다. 웹서버에서 입금받을 일이 있을때마다 공개키를 확장시켜 새로운 주소를 만드는 것이다. 괜히 개인키까지 같이 만들어서 도난 걱정을 할 필요도 없어서 좋다.
이처럼 확장된 공개키에서 공개키를 파생하는 것은 유용하지만, 잠재적 위험이 있다.
이런 위험성 때문에, 강화 파생(hardend derivation)이라고 하는 대체 가능 파생 함수가 사용된다.
0 ~ 2^31 - 1사이의 인덱스 번호
: 일반 파생 함수를 통해 파생된 키
2^31 ~ 2^32 - 1 사이의 인덱스 번호
: 강화 파생 함수를 통해 파생된 키
강화된 자식의 인덱스 번호가 읽기 어려우므로 0x80000000을 0'으로 표기.
-> 2^31 + i == i'
m / purpose' / coin_type' / account' / change / address_index
purpose': 항상 44'
coin_type': 암호화폐 유형 ex) 이더리움은 60', 비트코인은 0'
account’: 지갑을 여러 목적에 따라 하위 계좌로 분리 가능
change: 강화 파생 x, 입금 주소 작성용 / 잔액 주소 작성용 --> BIP-44가 비트코인을 위해 작성된 것이어서 이더리움에서는 사용하지 않는다.
address_index’: 사용 가능 주소가 파생되는 레벨
트랜잭션은 상태 변경이나 컨트랙트를 실행할 유일한 방법.
아래 데이터를 포함하는 serialize된 binary message
--> 이중 지불 문제 방지
노드가 작업을 처리함에 있어서 우선 순위를 정할려면 이더리움의 작업을 수치화해야 한다. gas price가 높을 수록 우선 순위가 높게 처리된다.
튜링 완전 계산 모델은 DoS 공격이나 막대한 자원을 소모하는 트랜잭션을 피해야 하는데, 이를 위해 트랜잭션에 gas limit을 지정하는 것.
20바이트 이더리움 주소(EOA or contract)가 포함되는데 모든 20바이트 값은 유효한 것으로 간주하므로 없는 주소로 보내서 이더가 연소될 수 있다.
새로운 컨트랙트를 만들기 위해 배포하는 트랜잭션이 있는데 이 트랜잭션은 zero address라고 하는 주소로 전송된다. 해당 주소는 0x0를 포함한다.
이더리움에서는 타원곡선을 사용한 ECDSA가 사용된다. 전자 서명은 이더리움에서 개인키의 소유주, 즉 계정의 소유주가 트랜잭션을 실행했다는 것을 공인하고 트랜잭션이 사인된 후에는 변경되지 않았다는 것을 검증한다.
전자 서명은 개인키를 바탕으로 서명을 만드는 알고리즘과 메시지(트랜잭션)와 공개키 만으로 서명을 검증 가능하게 해주는 알고리즘으로 이루어진다.
Sig=F_sig(F_keccak256(m),k)
K는 서명하는 개인키, m은 RLP로 인코딩된 트랜잭션, Fkeccak256 은 keccak256, Fsig 은 서명 알고리즘, Sig 는 생성된 전자서명이다. 이로 생성된 Sig 는 r, s 두가지 값으로 이루어진다.
서명 검증 알고리즘은 메시지, 서명자의 공개키, 전자서명을 input으로 받고 참 거짓 여부를 반환한다.
서명하기 전 트랜잭션 데이터에 chain identifier를 포함한다.
네트워크에 따라 ID 부여. 예를 들면 메인넷은 1, Ropsten은 3
이를 통해 한 블록체인 네트워크에서 생성된 트랜잭션을 다른 블록체인 네트워크에 올릴 수 없게 하여 반복 공격을 막는다. Chain identifier와 0, 0 총 3가지 필드를 추가하는데 이들은 인코딩 전에 트랜잭션 데이터에 포함되어 트랜잭션 데이터의 해시값이 변한다.
이더리움에서 트랜잭션 전파는 시작 노드에서 다른 노드들로 P2P 방식으로 전파된다.
전파과정은 다음과 같다.
트랜잭션이 생성되면 생성한 노드로부터 직접적으로 연결되어 있는 노드들로 (평균 13개 정도) 전파된다. 해당 노드들이 검증한 후에 복사본을 만들어 저장하고 그들의 이웃으로 전파한다. 그 결과 네트워크 전체로 파도처럼 퍼지게 된다. 수초 만에 전세계의 노드들로 트랜잭션은 퍼지게 되고 공격자는 상당한 양의 노드를 소유하고 있지 않은 이상 트랜잭션의 발원지를 찾을 수 없다.
검증된 트랜잭션은 블록에 담겨 이더리움 블록체인 위에 기록되게 된다.