티스토리 뷰
728x90

1. 이더리움이란 무엇인가?
- 이더리움(Ethereum)
- 월드 컴퓨터(World Computer)
- 결정론적(Deterministic)
- 한정되지 않은 머신(Unbounded State Machine)
- 전역적으로(Globally)
- 싱글톤(Singleton)
- 가상머신(Virtual Machine)
- 스마트 컨트랙트(smart contract)
- 이더(ether): 화폐; 실행 자원 비용을 측정하고 제한한다.
비트코인과의 비교
- 피어투피어(peer-to-peer) 네트워크
- 상태 변경을 동기화하는 비잔틴 결함 허용 합의(Byzantine fault-tolerant consensus) 알고리즘(작업증명 블록체인)
- 디지털 서명과 해시
- 디지털 화폐 (이더) 같은 암호학 기반 기술의 사용 등이 그런 공통 요소에 해당한다.
- 유틸리티 화폐(utility currency)
- 가상 머신(virtual machine)
- 튜링 완전(Turing complete) 언어
- 이더리움이 범용 컴퓨터로 직접 작동할 수 있음을 의미한다.
블록체인 구성요소
- '가십(gossip) 프로토콜'
- 피어투피어(P2P) 네트워크
- 트랜잭션 형식의 메시지
- 유효성을 판단하는 합의 규칙의 집합
- 상태 머신
- 장부(journal) 역할
- 모든 참여자가 협력할 수 있도록 가엦함으로써 블록체인의 통제 권한을 탈중앙화하는 합의 알고리즘
- 인센티브 매커니즘(작업증명 비용 + 블록 보상)
- 위에 언급된 것들을 구현한 하나 이상의 오픈 소스 소프트웨어(clients)
- 비트코인 코어(Bitcoin Core): bitcoind
- 기준 사양(reference specification)을 사용
- 황서(Yellow Paper)에서 밝히고 있는 시스템의 수하걱 기술이 바로 그것이다.
블록체인이 가지는 핵심적 성격
- 개방성(open)
- 공공성(public)
- 국제화(global)
- 탈중앙화(decentralized)
- 중립성(neutral)
- 검열 저항성(censorship-resistant)
오히려 사람들이 '블록체인'이라는 단어를 사용할 때 그 의미를 분명히 하기 우해서 여러분은 많은 질문을 해야 한다.
이더리움의 탄생
-비트코인 기반 위에 구축한다는 건, 네트워크의 의도적인 제약 조건들을 전제한 상태에서 해결책을 찾아야 한다는 뜻이었다.
- 그 밖의 것들은 부가적인 오프체인(off-chain) 계층을 필요로 했고,
- 이는 곧 공개 블록체인을 사용하는 많은 장점을 없애버렸다.
- 온체인(on-chain) 상태에서 더 많은 자유와 유연성이 필요한 프로젝트에는 새로운 블록체인이 유일한 옵션이었다.
- 인프라 요소의 부트스트래핑(bootstrapping)
- 철저한 시험 등의 수 많은 작업이 필요하다는 것을 의미했다.
- 비탈릭 부테린(Vitalik Buterin)은 비트코인과 마스터코인(Mastercoin, 비트코인을 확장하여 가장 기초적인 스마트 컨트랙트를 제공하는 오버레이 프로토콜)의 기능을 확장하는 방안을 생각하기 시작했다.
- 2013년 12월에 비탈릭 부테린은 튜링 완전한 범용 블록체인인 이더리움의 개념을 설명하는 화이트 페이퍼를 공유했다.
- 수십 명의 사람이 이 초기 초안을 살펴보고 비탈릭이 제안서를 발전 시킬 수 있도록 의견을 제시했다.
- 웹3(Web3)에 중점을 두면서 더욱 강해졌다.
- 위스퍼(Whisper)
- 스웜(Swarm)
- 창립자들은 수년간 비전을 구축하고 개선했다.
- 그리고 2015년 7월 30일, 첫 번째 이더리움 블록이 채굴되었다.
이더리움 개발 4단계
- 이전 버전과 호환되지 않는 방식으로 기능을 변경하는 하드 포크(hard fork)라고 하는 하위 버전이 포함될 수 있다.
- 프론티어(Frontier)
- 홈스테드(Homestead)
- 메트로폴리스(Metropolis)
- 세레니티(Serenity)
이더리움 개발 - 중간 하드 포크
- 아이스 에이지(Ice Age)
- DAO
- 텐저린 휘슬(Tangerine Whistle)
- 스퓨리어스 드래곤(Spurious Dragon)
- 비잔티움(Byzantium)
- 콘스탄티노플(Constantinople)
이더리움: 범용 블록체인
- 상태 전이(state transition)
- 상태 머신(state machine)
- 키-밸류 튜플(key-value tuple)
- 랜덤 액세스 메모리(Random Access Memory, RAM)
이더리움 구성요소
- 피어투피어 네트워크(P2P network)
- TCP 포트: 30303
- 이더리움 메인 네트워크(Ethereum main network)
- 합의 규칙(consensus rules)
- 황서(Yellow Paper)
- 트랜잭션(transactions)
- 상태 머신(state machine)
- 바이트코드(bytecode, 기계어 명령어)
- EVM(Ethereum Virtual Machine)
- 데이터 구조(data structures)
- 구글 LevelDB
- 합의 알고리즘(consensus algorithm)
- 나카모토 합의(Nakamoto Consensus)
- 작업증명(PoW) 중요도 가중치가 가장 긴 체인(현재 상태)을 결정
- 지분증명(PoS) 가중 투표 시스템인 코드명 캐스퍼(Casper)로 전환할 계획
- 경제적 보안성(economic security)
- 이대시(Ethash) PoW -> PoS 전환예정
- 클라이언트
- 게스(Go-Ethereum, Geth)
- 패리티(Parity)
이더리움과 튜링 완전
- 영국인 수학자 앨런 튜링(Alan Turing)
- 순차적 메모리(무한 길이의 종이 테이프와 유사)
- 보편적 계산 가능성(universal computability)
- 튜링 머신을 시뮬레이션하는 데 사용할 수 있다면 시스템이 튜링 완전하다(Turing complete)고 정의
- 프로그램을 싱행하지 않고서는 프로그램의 경로를 예측할 수 없다.
- 좋료되지 않은 프로그램 - 무한 루프
- 모든 트랜잭션을 검증하고, 그 트랜잭션이 호출하는 스마트 컨트랙트를 실행해야 한다.
- 사실상 서비스 거부 공격
- 단순히 자언을 낭비하고 점유하거나, 메모리 부하를 유발하고 중앙처리장치를 과열시키는 정도에 따라 분류될 수 있는 다양한 프로그램이 있을 수 있다.
- 세계 자원의 남용한다.
- 가스(gas)라는 과금 메커니즘을 도입
- 소비되는 가스의 총량이 트랜잭션에서의 가스 가용량을 초과한다면 EVM은 실행을 중지할 것이다.
- 리소스를 제한해서 이더리움 튜링 완전 계산을 허용하게 하는 메커니즘이다.
- 이더는 트랜잭션과 함께 보내야 하고, 사용하지 않은 가스는 발신자에게 반환된다.
2. 이더리움 기초
- 이더(ether) ETH
- 웨이(wei): 10^18 wei == 1 ether
- 이더리움은 시스템이고, 이더가 화폐다.
- SI(International System of Units)
- 학명(scientific name)
이더리움 지갑
- 지갑(wallet)
- 이더리움 시스템의 관문(gateway)
- 지갑은 사용자의 키를 보유하고, 사용자를 대신하여 트랜잭션을 생성하고 브로드캐스트(broadcast)
- 이더리움 플랫폼 자체는 여전히 개선되고 있으며, 최상의 지갑은 종종 플랫폼 업그레이드와 함께 발생하는 변화에 잘 적응하는 지갑이다.
- 자금을 보내거나 개인키를 내보내고 새 키로 가져오는 트랜잭션만 수행하면 된다.
- 이더리움 계정을 2개의 지갑에 분산시켜 놓는 것이 좋다.
- MetaMask
- Jaxx
- MyEtherWalet, MEW
- Emerald Wallet
통제와 책임
- 개인키를 분실, 누구도 접근 권한을 회복하도록 도와줄 수 없으며, 자금은 영원히 잠겨 있을 것이다.
- 계정이 더 중요할 수록, 더 높은 보안 조치가 취해져야 한다.
- 즉흥적으로 처리하지 마라.
- 니모닉(mnemonic) 단어 시퀀스로 백업하라는 메시지가 나타나면 펜과 종이를 사용하여 실제 백업을 하라.
- 그 일을 나중으로 미루지 마라
- 새 주소로 작은 테스트 트랜잭션만 보내는 것으로 시작하라.
- 계정 생성이 잘못될 수 있는 이유는 많으며, 잘못되었을 경우 작은 손실로 찾아내는 것이좋다.
- 이 책에 나와 있는 어떤 주소로든 돈을 보내지 마라.
- 해당 개인키는 책에 나와 있으므로 누군가가 즉시 그 돈을 가져갈 것이다.
네트워크
- 메인 이더리운 네트워크 (Main Ethereum Network)
- 롭스텐 테스트 네트워크 (Ropsten Test Network)
- 코반 테스트 네트워크 (Kovan Test Network)
- 테스트 네트워크는 패리티(Parity)에서만 지원된다.
- 클리크(Clique) 합의 프로토콜
- 린케비 테스트 네트워크 (Rinkeby Test Network)
- 클리크 합의 프로토콜
- 로컬 호스트(Localhost) 8545
- 개인 테스트넷
- 사용자 지정 RPC
- 게스(Geth) 호환 원격 프로시저 호출(Remote Procedure Call, RPC)
가스(gas) 비용
- 이더 트랜잭션은 모든 트랜잭션이 유효한지 확인하기 위해 채굴자에게 수수료를 지급해야 한다.
- 이더리움의 수수료는 가스라고 하는 암호화폐로 청구된다.
- 트랜잭션의 부분 구성요소로 가스를 포함하는데, 이더로 가스비를 지불한다.
월드 컴퓨터 소개
- 이더리움 가상 머신(Ethereum Virtual Machine, EVM)
- 스마트 컨트랙트(smart contract)
- EVM은 글로벌 싱글톤으로, 마치 전 세계에 걸친 단일 인스턴스 컴퓨터인 것처럼 작동하며 세상 어디에서든 실행된다.
- EVM의 로컬 사본을 실행하고, 트랜잭션과 스마트 컨트랙트를 처리할때 월드 컴퓨터의 변화하는 상태(state)를 기록한다.
외부 소유 계정(Externally Owned Account, EOA)
- 컨트랙트 계정(contract account)
- 실행된다(run)
- 데이터(data)
- 호출(call)
- EOA만 트랜잭션을 시작(initiate)
- 반응(react)
- 일반적인 댑(DApp) 프로그래밍 패턴은 컨트랙트 A가 컨트랙트 B를 호출하게 하는 것인데,
- 이렇게 하면 컨트랙트 A의 사용자들 간에 공유된 상태를 유지할 수 있게 된다.
contract Faucet {
function withdraw(unit withdraw_amount) public {
require(withdraw_amount <= 100000000000000);
msg.sender.transfer(withdraw_amount);
}
function () public payable {}
}
- 결함을 가진(flawed) 컨트랙트
- class 선언과 비슷하게 contract 객체를 선언한다.
- 범위(scope)를 정의하는 중괄호 사이의 모든 줄을 포함해서 정의하는데
- Remix IDE
3. 이더리움 클라이언트
- 서로 다른 이더리움 클라이언트끼리 상호운용(interoperate)이 가능하다.
- 이러한 서로 다른 클라이언트가 다른 팀과 다른 프로그래밍 언어로 구현되는 동안
- 이들은 모두 동일한 프로토콜로 소통하고 동일한 규칙을 따른다.
- 이더리움은 오픈 소스 프로젝트이며, 오픈 소스 라이선스 (LGPL v3.0)
- 공개 기여자 커뮤니티에 의해 개발되어 누구든지 수정할 수 있다.
- 참여자가 많을수록 신뢰할 수 있는 코드가 된다.
- 황서라는 공식 사양
- 구현해야 될 사양에 대해 명확한 기준을 제시하고 있기 때문에, 대부분 상호운용이 가능하다.
- 네트워크 공격을 바어하기 위한 훌륭한 방법으로 입증되었다.
- 구현 전략을 악용하는 것은 개발자가 공격을 패치하는 동안 개발자를 괴롭히지만 다른 클라이언트는 네트워크에 거의 영향을 주지 않기 때문이다.
이더리움 네트워크
- 이더리움
- 이더리움 클래식
- 엘라
- 익스팬스
- 유비크
- 뮤지코인
- 커맨드 라인 및 애플리케이션 프로그래밍 인터페이스 (Application Programming Interface, API) 중 일부를 탐색하는 방법을 학습한다.
풀 노드를 실행해야 하는가?
- 건전성(health)
- 복원력(resilience)
- 검열 저항(censorship resistance)
- 특성은 독립적으로 운용되고 지리적으로 분산된 풀 노드(full node)가 얼마나 많은지에 달려 있다.
- 부트스트랩(bootstrap)하고
- 모든 트랜잭션 및 컨트랙트에 대해 신뢰할 수 있고 독립적인 검증을 제공할 수 있도록 도와준다.
- 하드웨어 자원 및 대역폭 비용이 발생한다.
- 풀 노드는 많은 데이터를 다운로드 해야한다.
- 메인넷(mainnet) 네트워크, 테스트넷(testnet) 노드
- 메타 마스크(MetaMask)
- 지갑의 트랜잭션 기능 외에도 API(web3.js API)를 제공한다.
- 라이트 클라이언트(light client, 비트코인의 간이결제 확인(Simplified Payment Verification) 클라이언트와 유사함 개념과 혼동하면 안된다.
풀 노드의 장단점
- 장점
- 네트워크의 복원력과 검열 저항을 지원한다.
- 모든 트랜잭션을 정식으로 검증한다.
- 중개자 없이 공개 블록체인의 모든 컨트랙트와 상호작용할 수 있다.
- 중개자 없이 컨트랙트를 공개 블록체인에 직접 배포할 수 있다.
- 블록체인 상태(계정, 스마트 컨트랙트 등)를 오프라인에서 조회할 수 있다.
- 여러분이 읽은 정보를 제3자에게 노출하지 않고 가져올 수 있다.
- 단점
- 하드웨어와 대역폭 자원의 확대가 필요하다.
- 처음 시작할 때 전체 동기화를 위해 여러 날이 소요된다.
- 동기화를 유지하기 위해 관리하고, 업그레이드하고, 온라인 상태로 유지해야 한다.
로컬 블록체인 시뮬레이션 장단점
- 많은 테스트 목적에 가장 좋은 선택은 단일 인스턴스 사설 블록체인을 실행하는 것이다.
이더리움 클라이언트 실행
- 패리티(Parity)
- 게스(Geth)
- 다운로드 & 컴파일 & 실행
이더리움 기반 블록체인의 첫 번째 동기화
- 모든 블록 및 트랜잭션을 다운로드하고 유효성을 검사한다.
- 동기화는 매우 오래 걸리고 많은 자원을 필요로 한다.
- 2016년 말 서비스 거부 공격(Denial-of-Service, DoS)을 받았다.
- 공격을 받은 블록체인은 전체 동기화를 수행할 때 천천히 동기화되는 경향이 있다.
- 전체 유효성 검사로 동기화한다면, 클라이언트 속도가 느려지고 DoS 공격의 영향을 받는 블록을 확인하는 데만 며칠 혹은 더 오래 걸릴 수 있다.
JSON-RPC 인터페이스
- JSON(JavaScript Object Notation)
- RPC(Remote Procedure Call)
- 게이트웨이(gateway)
- RPC 인터페이스는 포트 8545에서 HTTP 서비스로 제공
- 스텁(stub) 함수 호출을 제공하는 특수 라이브러리
- 인코딩된 보내기/받기 요청을 수동으로 생성할 수 있다.
- jsonrpc
- method
- params
4. 암호학
- 암호학(cryptography)
- 암호화(encryption)
- 영 지식 증명(zero knowledge proof)
- 동형 암호화(homomorphicencryption)
- 같은 고급 암호화 도구를 사용하여 여전히 합의를 가능하게 하며서도 암호화된 계산을 블록체인에 기록할 수 있을 것이다.
- 공개키 암호화(Public Key Cryptography, PKC)
키와 주소
- 이더리움은 외부 소유 계정(Externally Owned Account, EOA)과 컨트랙트(contract)라는 두가지 유형 계정을 갖고 있다.
- 디지털 개인키(private key)
- 이더리움 주소(Ethereum address)
- 디지털 서명(digital signature)
- 계정(account)
- 단일 이더리움 주소를 고유하게 결정한다.
- 디지털 서명을 통해 자금의 접근과 통제가 이루어진다.
- 디지털 서명이 블록체인에 있어야 한다.
- 개인키의 사본을 가진 사람은 누구나 해당 꼐정과 해당 계정이 가진 이더를 제어할 수 있다.
- 실제 소유자임도 증명한다.
공개키 암호화와 암호화폐
- 공개키 암호화(비대칭 암호화라고도 함)
- 공개키 암호화는 고유한 키를 사용하여 정보를 보호한다.
- 특수한 속성을 가진 수학 함수를 바탕으로 한다.
- 이런 함수를 바탕으로한 암호화는 디지털 비밀과 위조 불가능한 디지털 서명을 만들 수 있으며,
- 이것은 수학 법칙에 의해 보장 받는다.
- 소인수분해(prime factorization)
- 트랩 도어 함수(trapdoor function)
- 이산 로그 문제(discrete logarithm problem)
- 타원 곡선 암호화(elliptic curve cryptography)
- 공개키는 개인키에서 파생되므로 '쌍'으로 간주한다.
- 디지털 서명(digital signature)
- 이더리움 프로토콜에는 암호화가 없기 때문에,
- 이더리움 네트워크 동작의 일부로 보내는 모든 메시지는 모든 사람이 불가피하게 읽을 수 있다.
- 따라서 개인키는 트랜잭션 인증을 위한 디지털 서명을 만드는 데에만 사용한다.
개인키
- 개인키는 단순히 무작위로 선택한 숫자다.
- 개인키는 항상 비밀로 유지해야 한다.
- 개인키로 확보한 컨트랙트와 이더에 대한 제어 접근 권한을 제3자에게 부여하는 것이나 마찬가지이기 때문이다.
- 한번 잃어버리면 되찾을 수 없으며, 해당 키로 확보한 자금도 영원히 잃어버리게 된다.
난수로 개인키 생성
- Keccak-256
- SHA-256
- 256비트 해시 알고리즘에 공급함으로써 이루어진다.
- 두 가지 알고리즘 모두 편리하게 256비트 수를 생성한다.
- 결과가 유효한 범위 내에 있으면 적절한 개인키가 된다.
- 여러분이 하나의 개인키를 무작위로 선택했을 때, 누군가가 그것을 추측하거나 스스로 같은 값을 선택할 수 있는 가능한 방법은 현재 없다.
- 16진수 형식의 개인키다.
공개키
- 타원 곡선에 있는 점(point)으로 타원 곡선 방정식을 만족하는 x와 y좌표의 집합을 의미한다.
- 개인키가 있는 경우 공개키를 계산하기는 쉽지만, 공개키에서 개인키를 계산할 수는 없다.
K = k * G
k: 개인키
G: 생성자 점(generator point) 상수점
K: 공개키
- 이산로그 찾기 역연산
- 공개키 암호화와 암호화폐
- 타원 곡선 곱셈은 공개키를 쉽게 생성하여 세상과 공유할 수 있다.
- 수학적 트릭은 이더리움 자금의 소유권과 계약 관리를 입증하는 위조 불가능하고 안전한 디지털 서명의 기초가 된다.
- secp256k1이라는 정확한 타원 곡선을 사용한다.
- 미국 표준 기술 연구소(National Institute of Standards and Technology, NIST)에서 제정한 표준
- p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 매우 큰 소수
- 지수(exponent)
공개키 생성
- 생성자 점(generator point) G
- k에서 K까지 한 방향으로만 계산할 수 있다.
- 이런 이유로 이더리움 주소(K에서 파생됨)를 모든 사람과 공유할 수 있으며 사용자의 개인키(k)는 공개하지 않는다.
- 개인키는 공개키로 변환할 수 있지만 공개키는 개인키로 다시 변환할 수 없다.
- 이는 수학이 한 방향으로만 작동하기 때문이다.
- 16진수 문자(65바이트) 130개의 시리얼라이제이션(serialization)으로 표시되는 공개키
- 능률 암호화 표준(Standards for Efficient Cryptography 1, SEC 1)에서 문서화된 산업 컨소시엄 능률 암호 그룹 표준
타원 곡선 라이브러리
- OpenSSL
- secp256k1 전체 구현을 포함하여 포괄적인 암호학적 기반요소(primitive)를 제공한다.
- 공개키를 생성하려면 EC_POINT_mul 함수를 사용할 수 있다.
- libsecp256k1
- 비트코인 코어(Bitcoin Core)의 libsecp256k1은 타원 곡선 및 기타 암호화 기초 요소를 C언어로 구현한 것이다.
- 비트코인 코어 소프트웨어에서 OpenSSL을 대체하기 위해 완전히 새로 작성해씅며,
- 성능과 보안 면에서 모두 뛰어난 것으로 여겨진다.
암호화 해시 함수
- 암호화 해시 함수(hash fucntion)
- 암호화 알고리즘보다 단방향 해시 함수들이 현대 안호학을 더 잘 이끄는 견인차다.
- 디지털 지문(digital fingerprints)
- 이미지(pre-image)
- 메시지(message)
- 입력 데이터(input data)
- 해시(hash)
- 암호화 해시 함수(cryptographic hash function)
- 단방향(one-way)
- 무차별 대입 검색: 검색 공간이 사실상 무한하다는 점을 고려할때, 불가능
- 해시충돌(hash collision)
- 해시 함수가 좋을수록 해시 총돌이 덜 발생한다.
- 이더리움에서는 사실상 해시 충돌이 불가능하다.
해시 함수 속성
- 결정론(determinism)
- 검증성(verifiability)
- 비상관성(noncorrelation)
- 비가역성(irreversibility)
- 충돌방지(collision protection)
해시 함수 애플리케이션
- 데이터 핑거프린팅
- 메시지 무결성(오류 감지)
- 작업증명
- 인증(암호 해싱 및 키 스트래칭)
- 의사 난수 생성기
- 메시지 커밋(커밋-공개 매커니즘)
- 고유 식별자
이더리움 암호화 해시 함수: Keccak-256
- Keccak은 우승한 알고리즘으로,
- 2015년 FIPS(Federal Information Processing Standard) 202로 표준화 되었다.
어떤 해시 함수를 사용하고 있는가?
- 테스트 벡터(test vector)
- 빈 입력(empty input)
- Keccak-256
이더리움 주소
- Keccaak-256 단방향 해시 함수를 사용하는 공개키 똔느 컨트랙트에서 파생한 고유 식별자(unique identifier)
이더리움 주소 형식
- 이더리움 주소는 16진수이며,
- 공개키 Keccak-256 해시의 마지막 20바이트에서 파생한 식별자다.
클라이언트 주소 상호교환 프로토콜
- Inter exchange Client Address Protocol, ICAP
- 직접(Direct): 최하위 비트 155개를 나타내는 최대 30자의 영숫자로 구성된 빅엔디안 base36 정수
- 기본(Basic): 31자리
- 간접(Indirect): 레지스트리 공급자를 통해 이더리움 주소로 확인되는 식별자를 인코딩; 자산 식별자(asset identifier, ETH)
대문자로 16진수 인코딩된 체크섬(EIP-55)
- 이더리움 주소는 대소문자를 구분하지 않으며,
- 모든 지갑은 해석의 차이 없이 대문자 똔느 소문자로 표현된 이더리움 주소를 수용해야 한다는 것이다.
- 99.986% 정확도로 오류를 감지할 수 있다.
5. 지갑
- 사용자 인터페이스를 제공하는 소프트웨어 애플리케이션이다.
- 돈에 대한 접근을 통제하고
- 키와 주소를 관리하며,
- 잔액을 추적하고,
- 트랜잭션 생성과 서명을 제어한다.
- ERC20 토큰처럼 컨트랙트와 상호작용할 수 있다.
지갑 (wallet)
- 사용자의 키를 보관하고 관리하기 위해 사용되는 시스템�
- 브라우저(Browser)
- 댑(DApp)
지갑 기술의 개요
- 편의성과 프라이버시 사이에 균형을 맞추는 것이다.
- 하나의 개인키와 주소를 가지고 이를 재사용해서 모든 것을 처리하는 지갑이다.
- 프라이버시에 대한 악몽이 될 수 있다.
- 사용자는 지갑에 있는 키로 트랜잭션을 서명함으로써 네트워크에서 토큰을 제어한다.
- 이더리움 지갑은 키체인(keychain)이다.
- 지갑은 개인키와 공개키가 쌍을 포함하는 키체인과 같은 것이다.
- 사용자는 개인키로 트랜잭션에 서명함으로써 이더가 자신의 소유임을 증명한다.
- 이더는 블록체인에 저장된다.
지갑 유형
- 비결정적 지갑(nondeterministic wallet): 그냥 열쇠뭉치(Just a Bunch Of Keys) JBOK
- 결정적 지갑(deterministic wallet): 시드(seed)
- 키 파생(key derivation): HD 지갑(BIP-32/BIP-44)
- 니모닉 코드 단어(mnemonic code words)
- 종이에 적어서 안전한 곳에 보관하기 바란다.
비결정적(무작위) 지갑
- 자금을 받을 때마다 새로운 주소를 사용한다.
- 키 목록을 증가시켜야 하는데, 이는 정기적인 백업이 필요하다는 뜻이다.
- 때마다(just int time)
- 개인키가 들어 있는, JSON 인코딩 파일인 키 저장소(keystore) 파일을 사용한다.
- 무차별(brute-force), 사전(dictionary) 및 레인보우 테이블(rainbow table) 공격을 대비해
- 암호 확장 알고리즘으로 알려진 키 파생 함수(key derivation function KDF)를 사용한다.
- 개인키는 암호문에 의해 직접적으로 암호화되지 않는다.
- 대신 방복적으로 해싱됨으로써 강화된다.
- 비결정적 지갑은 간단한 테스트 외에는 사용을 권장하지 않는다.
- 백업하고 사용하기가 매우 불편하기 때문이다.
- 대신 백업을 위해 니모닉 시드가 있는 산업계 표준인 HD(Hierarchical deterministic) 지갑을 사용하라.
결정적(시드) 지갑
- 시드 지갑은, 단일 시드로부터 파생된 개인키를 포함하고 있다.
- 시드는 개인키를 만들기 위해 인덱스 번호나 체인 코드(chain code) 같은 데이터와 결합된 무작위로 추출된 번호다.
- 시드는 또한 지갑을 내보내거나(export) 가져오기(import)에 활용되고 다른 지갑 간에 모든 키를 쉽게 이관할 수 있다.
HD 지갑(BIP-32/BIP-44)
- 단일 시드로부터 아주 많은 키를 쉽게 추출하기 위해 개발되었다.
- 비트코인의 BIP-32표준, HD(Hierarchical Deterministic) 지갑이다.
- 부모키가 자식키의 시퀀스(sequence)를 파생할 수 있다.
- 특정 분기(branch)는 입금을 받는 데 사용하고 다른 분기는 송금 후 잔액을 받는 데 사용할 수 있으며,
- 부서, 자회사, 특정 기능 혹은 회계 범주로 다른 분기를 할당하여 기업 환경 설정과 같은 구조적인 의미를 표현하는 데도 사용할 수 있다.
- 사용자가 공개키 시퀀스를 만들 수 있다는 것이다.
시드와 니모닉 코드(BIP-39)
- 개인키를 인코딩
- 단어 시퀀스
- 니모닉(mnemonic)
- 백업 및 복구를 위해 호환이 가능한 니모닉으로 시드 가져오기(import), 내보내기(export)를 할 수 있다.
- 16진수 시퀀스를 기록할 때는 오류가 발생할 확률이 매우 높다.
- 알려진 단어 목록은 단어들을 사용할 때 중복성이 커서 다루기가 매우 쉽다.
- 시드가 필요하므로 백업은 매우 중요하다.
- 종이에 써서 보관할 것을 추천한다.
- 요약하자면, HD 지갑의 인코딩을 위한 복구 단어 목록을 사용하는 것이 오류 없이 고쳐 쓰고,
- 종이에 기록하고, 읽고, 안전하게 내보내고, 개인키들을 다른 지갑으로 가져오는 가장 쉬운 방법이다.
지갑 종류
- 잭스(Jaxx)
- 메타마스크(MetaMask)
- 마이크립토(MyCrypto)
- 마이이더월렛(MyEtherWallet)
니모닉 코드 단어(BIP-39)
- 니모닉 단어는 지갑이 무작위로 생성해서 사용자에게 보여준다는 것이 가장 큰 차이점이다.
- 인간은 무작위성에 아주 약하기 때문이다.
- BIP-39에서 정의한 표준화된 절차에 따라 지갑에서 자동으로 생성된다.
- 지갑은 엔트로피의 원천에서 시작해서 체크섬을 추가하고 단어 목록에 엔트로피를 매핑한다.
니모닉 단어 생성
- 128~256 비트의 무작위 암호화 시퀀스 S를 생성한다.
- S를 SHA-256으로 해싱한 값을 32비트로 나눈 처음 길이를 체크섬으로 생성한다. (처음 4비트)
- 무작위 시퀀스 S의 끝에 체크섬을 추가한다. (132비트)
- 시퀀스와 체크섬을 연결한 것을 11비트 단위로 나눈다. (11 * 12)
- 각각의 11비트 값을 사전에 정의된 2,048단어 사전과 매핑한다. (11비트 == 2048)
- 단어의 시퀀스로부터 순서를 유지하면서 니모닉 코드를 생성한다.
니모닉에서 시드까지
- 엔트로피는 키 스트레칭 (key-stretching) 함수 PBKDF2를 사용하여 더 긴(512비트) 시드를 파생하는 데 사용되며,
- 생성된 시드는 결정론적 지갑을 구축하고 키를 파생하는 데 사용된다.
- 솔트(salt)라는 두 가지 파라미터가 있다: 조회 테이블(lookup table) 생성을 어렵게 하는 것
BIP-39 선택적 암호문
- 만약 암호문을 사용한다면 스트래칭 함수는 동일한 니모닉으로부터 다른 시드를 생성한다.
- 본질적으로 잘못된 암호문은 없다. 모든 암호문은 유효하다.
- 2^512 실제로 무차별 대입 혹은 우연히 사용 중인 것을 추측해 낼 가능성은 없다.
- BIP-39에는 잘못된 암호문이 있을 수 없다.
- 모든 암호문은 별개의 지갑을 생성하게 되는데 이전에 사용되지 않았던 것이라면 빈 지갑 상태가 된다.
선택적 암호문 특징
- 니모닉 자체만으로는 읨가 없도록 만들어서, 니모닉 백업이 도난으로부터 보호될 수 있도록 하는 2차 팩터로 가능한다.
- 공격자의 협박 때문에 암호문을 가르쳐 줭 ㅑ할 경우는 진짜 암호문 대신 그럴 듯한 가짜 암호문을 제공한다.
- 그러면 대부분의 자금을 담고 있는 real 지갑 대신 적은 양의 자금이 있는 지갑으로 공격자의 주의를 돌릴 수 있다.
선택적 암호문 위험
- 암호문을 알고 있는 사람이 없다면 시드는 쓸모없어지고 지갑에 저장된 모든 자금을 영원히 잃게 된다.
- 반대로, 소유자가 암호문을 시드와 동일한 위치에 백업하는 것은 2차 팩터를 사용하는 모적에 어긋난다.
시드로 HD 지갑 생성하기
- 128, 256, 512 임의의 숫자인 단일 루트 시드(root seed)
- 산업계의 사실상 표준인 BIP-32 표준을 따른다.
- 확장 키 (extended key) 강화 키(hardened key)
- 파생 (key-derivation) 구현을 공유
확장된 공개키와 개인키
- 확장(extended)
- 부모(parent)
- 자식(child)
- 체인 코드(chain code)를 추가
- xprv 확장된 개인키(extended private key)
- xpub 확장된 공개키(extended public key)
- 개인키가 없는 부모 공개키에서 자식 공개키를 파생할 수 있는 능력이다.
- 자식 공개키를 파생하기 위한 방법은 두가지가 있다.
- 자식 개인키로부터 직접 파생하는 방법
- 부모 공개키로부터 직접 파생하는 방법
- 무한복사 가능
- 보낸 돈 사용 불가능
강화된 자식 키의 파생
- 자식 개인키가 유출되는 경우 부모 개인키를 추론할 수 있다.
- 강화 파생(hardened derivation)
- 부모 공개키와 자식 체인 코드 간의 관계를 끊는다. (break)
- 자식 체인 코드를 생성하기 위해 부모 공개키 대신에 부모의 개인키를 사용한다.
- 이것은 체인 코드를 이용하여 부모/자식 시퀀스에 방화벽을 생성하며,
- 이때 체인 코드는 부모 또는 형제 개인키를 유출하는 데 사용할 수 없다.
일반 및 강화 파생을 위한 인덱스 번호
- 0 ~ 2^31 -1 일반 파생
- 2^31 ~ 2^32 -1 강화파생
HD 지갑 키 식별자(경로)
- path
- 마스터 개인키에서 파생된 개인키: m
- 마스터 개인키에서 파생된 공개키: M
- 0: 일반 파생
- 0': 강화 파생
- m/0/0/1
HD 지갑 트리 구조 탐색
- 대단히 유연하다.
- 무한한 복잡성을 허용한다는 뜻이다.
- 40억개의 자식을 ...
- BIP-43은 강화된 인덱스를 트리 구조의 목적(purpose)을 나타내는 특수 식별자로 사용하도록 제안한다.
- m/i'/... 분기만을 사용하는 HD 지갑은 특정 목적을 나타내기 위한 것이고 그 목적은 인덱스 번호 i로 식별된다.
- BIP-44는 목적 번호를 44로 설정하여 복수화폐 복수꼐정 구조를 제안한다.
- BIP-44를 따르는 모든 HD 지갑 구조는 단지 하나의 트리 분기 m/44'/*만을 사용한다는 사실에 의해 식별된다.
m / purpose' / coin_type' / account' / change / address_index
m/44'/60': 이더리움
m/44'/61': 이더리움 클래식
m/44'/0': 비트코인
m/44'/1': 모든 화폐의 테스트넷
6. 트랜잭션
- 트랜잭션은 외부 소유 계정(EOA)에 의해 서명된 메시지
- 이더리움 네트워크에 의해 전송되고 이더리움 블록체인에 기록된다.
- EVM에서 상태 변경을 유발하거나 컨트랙트를 실행할 수 있는 유일한 방법이라는 것이다.
- 이더리움은 글로벌 싱글톤 상태 머신이며, 머신을 움직여서 상태를 변경할 수 있도록 만든다.
- 모든 것은 트랜잭션으로부터 시작된다.
트랜잭션 구조
- 요소
- 시리얼라이즈(serialize)되어 저송되는 트랜잭션의 기본 구조를 살펴보자.
- 논스(nonce): 메시지 재사용을 방지하는 데 사용되는 일련번호
- 가스 가격(gas price): 발신자가 지급하는 가스의 가격(웨이)
- 가스 한도(gas limit): 트랜잭션을 위해 구입할 가스의 최대량
- 수신자(recipient): 목적지 이더리움 주소
- 값(value): 목적지에 보낼 이더의 양
- 데이터(data): 가변 길이 바이너리 데이터 페이로드
- v, r, s: EOA의 ECDSA 디지털 서명의 세 가지 구성요소
- RLP(Recursive Length Prefix) 인코딩 체계를 사용하여 시리얼라이즈된다.
- 이더리움의 모든 숫자는 8비트 배수 길이의 빅엔디안 정수로 인코딩 된다.
- 시리얼라이즈된 트랜잭션 데이터의 일부가 아니라는 점을 유의하자.
- EOA를 식별하는 주소에 발신자(from) 데이터가 없는데,
- 이것은 EOA의 공개키를 ECDSA 서명의 v,r,s 구성요소로부터 알아낼 수 있으며, 이는 공개키를 통해 주소를 알아낼 수 있음을 의미한다.
- 즉 주소는 공개키에서 파생될 수 있다.
- 트랜잭션에서 파생되며 트랜잭션 메시지 자체의 일부가 아니다.
트랜잭션 논스
- 논스: 해당 주소에서 보낸 트랜잭션 건수 또는 연결된 코드가 있는 계정의 경우 이 계정에서 만든 컨트랙트 생성 건수와 동일한 스칼라 값
- 발신 주소의 속성, 컨텍스트 안에서만 의미를 갖는다.
- 해당 주소에서 발생한 호가인된 트랜잭션 건수를 세어서 동적으로 계산되는 값이다.
- 사용성상의 기능(usability feature)이며, 다른 하나는 트랜잭션 복제 방지라는 주요 기능에서의 측면이다.
- 특정 노드가 다른 노드보다 특정한 트랜잭션을 먼저 받을 것이라는 보장은 없다.
- 논스가 없다면 어느 것이 받아들여지고 어떤 것이 거부될지는 알 수 없다.
- 그러면 0부터 3까지의 논스가 있는 트랜잭션이 처리될 때 가지 해당 트랜잭션은 무시된다.
- 각각의 개별 트랜잭션은 고유하다.
- 복제(duplicate)하는 행위를 막을 수 있다.
- 비트코인 프로토콜의 미사용 트랜잭션 아웃풋(Unspent Transaction Output, UTXO) 매커니즘과 달리,
- 계정 기반(account-based) 프로토콜은 논스를 사용하는 것이 실제로 필수적임을 유의해야 한다.
논스 추적
web3.eth.getTransactionCount("...")
40
- 시퀀스상 다음 차례 논스를 부여한다.
- 그러나 이것이 컨펌될 때까지는 getTransactionCount 합계에 포함되지 않는다.
- 대기중인 트랜잭션 건수를 계산하기 위해 사용할 때는 주의해야 한다.
- 연속해서 몇 개의 트랜잭션을 보내는 경우 문제가 발생할 수 있기 때문이다.
web3.eth.getTransactionCount("...", "pending")
41
- 멤풀(mempool)에 보류 중인 트랜잭션 3개가 있을 것이라고 생각하지만, 오직 하나의 트랜잭션만 대기 중이다.
- 다수의 트랜잭션이 대기 중임에도 불구하고 이를 확인할 수 없다.
- 패리티(Parity)의 JSON RPC 인터페이스는 트랜잭션에서 사용해야 하는 다음 논스를 반환하는 parity_nextNonce 함수를 제공한다.
curl --data '{"method":" parity_nextNonce", "params":["..."], "id":1, "jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST localhost:8545
{"jsonrpc":"2.0", "result":"0x32","id":1}
논스의 간격, 중복 논스 & 확인
- 논스가 같지만 수신자나 값이 다른 2개의 트랜잭션을 전송하는 것과 같은 논스의 중복이 일어나면, 그중 하나가 확정되고 하나는 거부된다.
- 그 트랜잭션이 첫 유효 노드에 도달하는 순서에 따라 결정된다.
동시 실행, 트랜잭션 생성 & 논스
- 동시 실행은 컴퓨터 과학이 다루어야 하는 복잡한 문제이며,
- 특히 이더리움처럼 탈중앙화되어 있고 분산되어 있는 실시간 시스템에서는 더욱 그러하다.
- 동시 실행을 허용하지만 합의를 통해 싱글톤 상태를 강제하는 시스템이다.
- 핫 월렛(hot wallet): 온라인에 키 저장
- 콜드 월렛(cold wallet): 오프라인에 키 저장
- 동시 실행 문제가 발생할 수 있다.
- 논스를 선택하는 것도 중요한 문제다.
- 컴퓨터가 트랜잭션을 생성, 서명 및 브로드캐스트하는 방식은 어떻게 조율될 수 있을까?
- 단일 컴퓨터를 사용하여 트랜잭션에 서명하는 컴퓨터에 선착순으로 논스를 할당할 수 있다.
- 그러나 이 컴퓨터는 이제 단일 실패 지점이다.
- 더욱이, 여러 논스가 할당되고 그중 하나가 사용되지 않으면 모든 후속 트랜잭션이 중단된다.
- 또 다른 방법은 트랜잭션을 생성하고 논스를 할당하지 않는 것이다.
- 서명하고 논스를 관리할 수 있게 하는 것이다.
- 물론, 이것이 프로세스상 병목 지점이 될 수는 있다.
- 서명하고 논스를 관리하는 작업은 시스템 부하가 늘어남에 따라 혼잡해질 수 있지만,
- 서명되지 않은 트랜잭션들을 생성하는 작업은 병렬 처리 문제를 고민하지 않아도 된다.
- 여전히 동시 실행 문제가 남아 있기는 하지만, 크리티컬한 프로세스 부분에서는 더 이상 존재하지 않게 된다.
- 이러한 동시 싱행 문제는 각각의 독립적인 프로세스들이 어카운트 밸런스를 추적하고 트랜잭션을 컨펌해야 하는 어려움이 가중된다.
- 따라서 대부분의 구현 솔루션들이 동시 실행을 피하고 거래소에서 출금 트랜잭션을 처리하는 단일 프로세스를 만드는 것처럼
- 병목 지점을 어쩔 수 없이 받아들이거나, 독립적으로 작동하는 다수의 출금 담당 핫 월렛을 설치하고
- 중간중간에 각 지갑의 밸런스를 다시 채워주는 형식으로 해결하게끔 만든다.
트랜잭션 가스
- 가스는 이더리움의 연료다.
- 전 세계 수천 대의 컴퓨터에서 처리되기 때문이다.
- 개방형(튜링 완전) 계산 모델은 DoS(Denial-of-Service) 공격이나 실수로 막대한 자원을 소모하는 트랜잭션을 피하기 위해 특정한 형태의 미터링(metering)이 필요하다.
- 다양한 자원(즉, 계산, 메모리 & 저장)의 비용 사이의 중요하고 민감한 비율을 관리하기 위해 가스를 이더와 분리한다.
- 가스 단위당 웨이 단위
- gasPrice가 높을수록 트랜잭션이 더 빨리 컨펌될 것이다.
- 우선순위가 낮은 트랜잭션은 낮은 가격을 설정해서 컨펌이 느려지게 할 수 있다.
- gasPrice가 설정될 수 있는 최솟값은 0이고
- 이것은 수수료 없는 트랜잭션을 의미한다.
- 블록 공간에 대한 수요가 낮은 기간에는 수수료가 0인 트랜잭션들도 블록에 포함될 수 있다.
- 완전히 무료 트랜잭션을 생성할 수 있음을 의미한다.
- 용량에 따라 이들은 영원히 컨펌되지 않을 수도 있지만, 프로토콜에 무료 트랜잭션을 금지하는 것은 없다.
- 이더리움 블록체인에 성공적으로 포함된 이와 같은 트랜잭션 사례들을 찾을 수 있다.
web3 인터페이스는 여러 블록에 걸친 중간 가격을 계산하여 getPrice를 제안하는 기능을 제공한다.
web3.eth.getGasPrice(console.log)
null BigNumber { s: 1, e: 10, c: [ 10000000000 ] }
- gasLimit이다.
- 가스양은 21,000개의 가스 단위로 고정된다.
web3.eth.getGasPrice(function(err, res) { console.log(res*21000) } )
210000000000000
- 여행에 필요한 만큼의 가스를 탱크에 채운다.
- 금액을 어느 정도 예측할 수 있찌만, 연료 소비를 증가시키는 우회 같은 예기치 않은 변경사항이 있을 수 있다.
- 주유 회사의 신용 계정
- 트랜잭션을 보내기 전에 지급할 의사가 있는 최대 금액만큼 충분한 잔액이 있어야 한다.
트랜잭션 수신자
- 모든 20바이트 값은 유효한 것으로 간주
- 이더리움은 주소가 공개키에서 올바르게 파생되었는지 여부를 알 수 있는 방법이 없다.
- 트랜잭션의 수신자 주소를 검증하지 않는다.
- 컨트랙트가 없는 주소로 보낼 수 있다.
- 그러면 이더가 연소(burning)되어 영구적으로 사용할 수 없게 된다.
- 유효성 검사는 사용자 인터페이스 수준에서 수행되어야 한다.
- 주소 확인은 사용자 인터페이스 수준에서 처리해야 한다고 가정한다.
- 부정행위를 저지하는 것이나, 이더의 양이 유한하므로 이더를 연소시키면 모든 이더 보유자에게 연소된 값을 효과적으로 분배한 것으로 이해할 수 있다.
트랜잭션 값과 데이터
- payload
- value
- data
- payment, invocation
src = web3.eth.accounts[0];
dst = web3.eth.accounts[1];
web3.eth.sendTransaction({from: src, to: dst, value: web3.toWei(0.01, "ether"), data: ""});
web3.eth.sendTransaction({from: src, to: dst, value: web3.toWei(0.01, "ether"), data: "0x1234"});
web3.eth.sendTransaction({from: src, to: dst, value: 0, data: "0x1234"});
web3.eth.sendTransaction({from: src, to: dst, value: 0, data: ""});
EOA 및 컨트랙트에 값 전달
- 지급 Payment 이러한 트랜잭션은 대상 주소가 컨트랙트인지 여부에 따라 다르게 작동한다.
- EOA 주소, 상태 변경을 기록하여 주소 잔액에 보낸 값을 추가한다.
- 주소(to)가 컨트랙트라면 EVM은 컨트랙트를 실행하고, 트랜잭션의 데이터 페이로드에 지정된 함수를 호출하려고 시도한다.
- 트랜잭션에 데이터가 없으면 EVM은 폴백(fallback) 함수를 호출하고,
- 해당 함수가 지급 가능하다면 다음에 수행할 작업을 결정하기 위해 함수를 실행한다.
- 폴백 함수가 없다면 트랜잭션의 효과는 지갑에 지급하는 것과 마찬가지로 컨트랙트의 잔액을 늘린다.
- 컨트랙트의 상태가 이더 잔액이 증가햇음을 반영하여 업데이트된다.
EOA 또는 컨트랙트에 데이터 페이로드 전달
- 트랜잭션에 데이터가 포함되어 있으면 받는 주소는 컨트랙트 주소가 될 가능성이 크다.
- 프로토콜에서 완전히 유효한 데이터 페이로드를 EOA에 보낼 수 없다는 뜻은 아니다.
- 대부분의 지갑은 자신이 제어하는 EOA에 대한 트랜잭션에서 수신된 모든 데이터를 무시한다.
- 컨트랙트 호출(contract invocation)
- 데이터를 함수 호출(function invocation)
- 함수 선택기(function selector)
- 프로토타입의 Keccak-256 해시의 처음 4바이트다.
- 컨트랙트에서 호출할 함수를 정확하게 식별할 수 있다.
- 함수 인수(function argument)
- 함수의 인수는 ABI 사양에 정의된 다양한 기본 유형에 대한 규칙에 따라 인코딩된다.
- 함수의 프로토타입(prototype)
withdraw(uint256)
web3.sha3("withdraw(uint256)");
withdraw_amount = web3.toWei(0.01, "ether");
withdraw_amount_hex = web3.toHex(withdraw_amount);
특별 트랜잭션: 컨트랙트 생성
- 새로운 컨트랙트를 만들어 향후 사용을 위해 배포하는 트랜잭션이다.
- 0x0 제로 어드레스: 생성 트랜잭션
- EOA 컨트랙트를 나타내지 않는다.
- 이 필드는 목적지로만 사용되며, 컨트랙트 작성
- 컨트랙트 생성에만 사용하려는 의도로 만들어졌지만, 목적지로 하는 다양한 트랜잭션이 있다.
- 실수로 인한 이더 손실이나 의도적인 이더 연소
- 그러나 이더의 의도적인 연소를 원한다면 네트워크에 의도를 분명히 하고 대신 지정된 주소를 사용해야 한다.
- 지정된 연소 주소로 보내진 이더는 영원히 사라질 것이다.
0x000000000000000000000000000000000000dEaD
- 컴파일된 바이트 코드를 포함하는 데이터 페이로드만 포함하면 된다.
- 특정 잔액으로 설정해서 시작하려면 값 필드에 이더 금액을 포함할 수 있지만, 이는 전적으로 선택사항이다.
- 이더 연소 주소로 전송하는 것과 같다.
- 트랜잭션이 일어날 컨트랙트가 없기 때문에 이더를 잃게 된다.
Faucet.sol
- 솔리티로 컴파일할 수 있다.
solc --bin Faucet.sol
- 리믹스(Remix) 온라인 컴파일러에서도 얻을 수 있다.
- 항상 to 파라미터를 지정하는 것이 좋다. (0)
src = web3.eth.accounts[0];
faucet_code = "...";
web3.eth.sendTransaction({from: src, to: 0, data: faucet_code, gas: 113558, gasPrice: 200000000000});
eth.getTransactionReceipt("...")
타원 곡선 디지털 서명 알고리즘
- ECDSA(Elliptic Curve Digital Signature Algorithm)
EIP-155
- 단순 재생 공격 방지(Simple Replay Attack Protection)
- 체인 식별자(chain identifier)
- 따라서 표준의 이름 그대로 한 네트워크에서 전파된 트랜잭션은 다른 네트워크에서 재생될 수 없다.
서명 접두어 값(v) 및 공개키 복구
- 서명자의 공개키를 복구하는 프로세스를 공개키 복구(public key recovery)라고 한다.
서명 및 전송 분리(오프라인 서명)
- 네트워크로 전송할 준비
- 트랜잭션 생성, 서명, 브로드캐스트
- 서명과 전송을 분리하려는 이유: 보안
- 오프라인 서명(offline signing)
트랜잭션 전파
- 플러드 라우팅(flood routing)
- 메시(mesh)
- 피어투피어(P2P)
- 노드(node)
- 이웃(neighbor)
- 각 이웃 노드 트랜잭션 수신하자마자 즉시 유효성을 검사
- 사본을 저장하고 모든 이웃에게 전파
- 물결이 퍼진다.(flooding)
- 기본 규칙은 전달받은 모든 유효한 트랜잭션 메시지를 전파하는 것
- 몇 초 내에 이더리움 트랜잭션이 전 세계의 모든 이더리움 노드로 전파된다.
블록체인에 기록하기
- 고성능 그래픽 처리 장치(Graphics Processing Unit, GPU)가 장착된 컴퓨터인 채굴 팜(mining farm)에 트랜잭션 및 블록을 제공
- 채굴 컴퓨터는 트랜잭션을 후보 블록에 추가하고 후보 블록을 유효하게 만드는 작업증명을 찾으려고 시도한다.
- 유효한 트랜잭션이 결국 트랜잭션 블록에 포함되어 이더리움 블록체인에 기록된다.
- 트랜잭션이 블록으로 채워지면 계정의 잔액을 수정하거나 내부 상태를 변경하는 컨트랙트를 호출하여 트랜잭션은 이더리움 싱글톤 상태를 수정한다.
- 트랜잭션 영수증(receipt) 형식으로 트랜잭션과 함께 기록된다.
다중 서명 트랜잭션
- 비트코인 다중 서명(multiple-signature, multisig)
- 스마트 컨트랙트를 사용해 임의의 서명 제한룰을 적용할 수 있다.
- 스마트 컨트랙트로 다중 서명 트랜잭션을 구현하는 기능은 유연성을 입증한다.
- 버그를 발생시킬 수 있으므로 양날의 검이다.
- 실제로 간단한 M-of-N 다중 서명 구성을 스마트 컨트랙트를 이용하지 않고 EVM에서 직접 다중 서명 명령을 처리하게 하자는 제안이 많다.
- 핵심 합의 규칙의 일부이며, 강력하고 안전한 것으로 입증된 비트코인의 다중 서명 시스템과 동일하다.
7. 스마트 컨트랙트와 솔리디티
- 디지털 형식으로 지정된 일련의 약속
스마트 컨트랙트
- 컴퓨터 프로그램(computer programs): 컨트랙트(contract)
- 불변의(immutable): 변경할 수 없다, 새로운 인스턴스를 배포
- 결정론적(deterministic)
- EVM 컨텍스트(EVM context)
- 탈중앙화된 월드 컴퓨터(decentralized world computer): 월드 컴퓨터로 작동
생명주기
- 저수준의 바이트코드로 컴파일
- 컨트랙트 생성(contract creation)
- 이더리움 주소로 식별
- 트랜잭션에 의해 호출된 경우에만 실행된다는 것이다.
- EOA로부터 트랜잭션에 의해 호출된다.
- 병력적으로 실행되지 않는다는 점도 주목할 만하다.
- 이런 의미에서 이더리움 월드 컴퓨터가 단일 스레드 컴퓨터라 할 수 있다.
- 원자성(automic):
- 트랜잭션은 모든 실행이 성공적으로 종료된 경우에만 글로벌 상태(컨트랙트, 계정 등)의 모든 변경사항이 기록되고 전체가 실행된다.
- 오류로 인해 실행이 실패하면 모든 영향(상태 변경)은 트랜잭션이 실행되지 않은 것처럼 롤백(rolled back)된다.
- 시도된 것으로 기록, 실행을 위해 가스로 소비된 이더는 원계정에서 차감되지만, 컨트랙트 또는 계좌 상태에는 영향을 미치지 않는다.
SELFDESTRUCT
- 음의 가스(negative gas)
- 삭제해도 컨트랙트의 트랜잭션 과거 내역이 제거되지 않는다.
- 컨트랙트 작성자가 해당 기능을 갖기 위해 스마트 컨트랙트를 프로그래밍한 경우에만 사용할 수 있다는 점도 중요하다.
- 컨트랙트 코드에 SELFDESTRUCT 연산코드가 없거나 접근할 수 없는 경우 스마트 컨트랙트는 삭제할 수 없다.
Solidity
- 일반적이어서 다른 여러 블록체인 플랫폼에서 스마트 컨트랙트를 코딩하는 데 사용된다.
- 시맨틱 버저닝(semantic versioning): major.minor.patch
brew install solidity
solc --optimize --bin Faucet.sol
- 애플리케이션 바이너리 인터페이스(Application Binary Interface, ABI)
- 기계 코드(machine code), 소스 코드(source code)
pragma solidity ^0.4.19;
데이터 타입
- 부울(bool)
- 정수(int, unit)
- 고정소수점(fixed, ufixed)
- 바이트 배열(고정 크기)
- 바이트 배열(가변 크기)
- 열거형
- 배열
- 구조체
- 매핑
- 시간 단위(time units): seconds
- 이더 단위(ether units): wei
- block
- blockhash
- coinbase
- difficulty
- gaslimit
- number
- timestamp
- msg
- sender
- value
- gas
- date
- sig
- tx
- gasprice
- origin
- address
- balance
- transfer
- send
- call
- callcode
- delegatecall
- function
- addmod, mulmod
- keccak256, sha256, sha3, ripemd160
- ecrecover
- selfdestrunct
- this
- interfact
- library
함수
function FunctionName([parameters]) {public|private|internal|external}
[pure|constant|view|payable] [modifiers] [returns (return types)]
pragma ^0.4.22
contract MEContract {
address owner;
constructor () {
owner = msg.sender;
}
function destroy() public {
require(msg.sender == owner);
selfdestruct(owner);
}
}
- 그 컨트랙트는 자기 파괴되고 남은 잔액을 owner 주소로 되돌려줄 것이다.
함수 변경자(function modifier)
- destroy 함수 내에 접근 제어 구문을 이미 갖고 있다.
modifier only Owner {
require(msg.sender == owner);
_; // 함수로 대체 (wrapping)
}
function destroy() public onlyOwner {
selfdestruct(owner);
}
컨트랙트 상속(inheritance)
contract owned {
address owner;
constructor() {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
}
contract mortal is owned {
function destroy() public onlyOwner {
selfdestruct(owner);
}
}
contrat Faucet is mortal {
function withdraw(uint amount) public {
require(amount <= 0.1 ether);
msg.sender.transfer(amount)
}
function () public payable {}
}
에러 처리(assert, require, revert)
- 게이트 조건(gate condition)
require(msg.sender == owner, "only owner");
이벤트
- 트랜잭션 연수증(transaction receipt)
- 로그(log)
- 이벤트(event)
- 댑(DApp)
- 감시(watch)
다른 컨트랙트 호출(send, call, callcode, delegatecall)
- 가장 안전한 방법은 직접 다른 컨트랙트를 만드는 것이다.
- 인터페이스와 동작이 확실할 수 있다.
가스 고려사항
- 가스 부족(out of gas)
- 상태가 복원된다.
- 트랜잭션 수수료로 간주디고 환불되지 않는다.
- 가스 비용이 높은 함수를 호출하지 않는 것이 좋다.
- 가스 비용을 최소화하도록 해야 한다.
- 프로그래머들로부터 받은 점검이 덜 된 라이브러리 사용상 위험이 더 높다.
- 네트워크로부터 가스 가격, 정확한 예상치 제공
var gasPrice = web3.eth.getGasPrice();
8. 스마트 컨트랙트와 바이퍼
- 개발자들이 이해하기 쉬운 코드
- 용이성(auditability)
- 개발자들이 오독하기 쉬운 코드(misleading code)
- 쉽게해서; 오독을 하기 쉽거나 취약점이 있는 코드를 작성하기 어렵게 한다.
취약점과 바이퍼
- 자기파괴 컨트랙트(suicidal contract): 아무 주소를 이용해서 삭제시킬 수 있는 스마트 컨트랙트
- 탐욕 컨트랙트(greedy contract): 이더를 빼올 수 없도록 막아버리는 상태에 도달할 수 있는 컨트랙트
- 방탕한 컨트랙트(prodigal contract): 이더를 아무런 주소로 보낼 수 있게 만든 스마트 컨트랙트
생략(omitting)
- 변경자
function changeOwner(address _newOwner) public onlyBy(owner) {
owner = _newOwner;
}
- 실수로 한줄을 놓칠 수 있다.
클래스 상속
- 상속은 강력한 기능이며 코드 재사용을 도와준다.
- 다중상속과 다형성(polymorphism)
- 다중 상속이 코드를 이해하기 어렵도록 너무 복잡하게 만든다는 견해를 갖고 있다.
인라인 어셈블리
- 가상 머신(EVM)에 대한 낮은 수준의 접근을 제공하므로 솔리디티 프로그램이 EVM 명령어에 직접 접근하여 작업을 수행할 수 있다.
- 바이퍼는.. 가독성 손실이 아주 큰 문제라고 생각하므로 인라인 어셈블리를 지원하지 않는다.
- 바이퍼는 함수 오버로딩을 지원하지 않는다.
변수 형변환
- 암시적 형변환(implicit typecasting): 컴파일 타임; 초기 바이퍼
- 명시적 형변환(explicit typecasting): 손실 가능
- 바이퍼는 convert 함수
전제 조건과 사후 조건
- 조건(condition)
- 효과(effect)
- 상호작용(interaction)
장식자(decorator)
@private: 외부에서 함수에 접근할 수 없게 함
@public: 공개적으로 볼 수 있고 실행 가능
@constant: 상태 변수를 변경할 수 없다.
@payable: 값 전송
함수와 변수 순서
- 바이퍼는 순서에 의존한다.
- 솔리디티는 순서에 의존하지 않는다.(호이스팅?)
컴파일
- 공개 경매
- 안전한 원격 구매
- ERC20 토큰
컴파일러 수준에서 오버플로 오류 방지
데이터 읽기 및 쓰기
- 글로벌 상태
- 로그: __log__
- 온체인(on-chain) 로그 이벤트를 읽을 수 없다.
결론
- 새로운 컨트랙트용 프로그래밍 언어
- 정확성에 중점
- 함정을 피함
- 보안 문제를 보면 바이퍼에 대해 이해 가능해질 것이다.
9. 스마트 컨트랙트 보안
- 보안 안티패턴
- 의도한 내용과 반드시 일치하지 않을 때가 있음
- 어떤 취약점이라도 악용될 수 있음
- 손실은 거의 항상 보구할 수 없음
- 모범 사례를 따르고 잘 테스트된 디자인 패턴을 사용하는 것이 중요
방어적 프로그래밍(defensive programming)
- 미니멀리즘/단순성(minimalism/simplicity)
- 복잡성은 보안의 적이다.
- 코드가 단순할수록, 코드가 적을 수록 버그나 예기치 못한 효과가 발생할 확률이 낮음
- 개발자는 종종 많은 코드를 작성하려고 시도
- 복잡성과 기능을 줄이는 노력을 해야함
- 간단할수록 안전하다.
- 코드 재사용(code reuse)
- 스마트 컨트랙트가 있으면 그것을 재사용
- DRY(Don't Repeat Yourself, 반복하지 마라)
- 두 번 이상 방복된 코드 문장이 있으면 함수 또는 라이브러리로 작성하여 재사용할 수 있는지 스스로에게 질문
- 광범위하게 사용되고 테스트된 코드는 새로 작성한 코드보다 안전
- NIH(Not Invented Here, 여기서 개발한 것이 아니다) 증후군을 조심
- 보안 위험은 종종 코드를 개선하는 것보다 더 중요하다.
- 코드 품질(code quality)
- 일단 코드가 배포(launch)되고 나면 문제를 해결할 수 있는 방법이 거의 없음
- 가독성/감사 용이성(readability/auditability)
- 코드는 명확하고 이해하기 쉬워야 함
- 집단적 지혜와 오픈 소스 개발의 가장 높은 공통 분모로부터의 혜택을 이용할 수 있기 때문이다.
- 이더리움 커뮤니티의 스타일과 명명 규칙에 따라 잘 문서화되고 읽기 쉬운 코드를 작성해야 한다.
- 테스트 범위(test coverage)
- 적절하게 경계가 지정되어 있거나,
- 호의적인 목적을 갖고 있다고 가정해서는 안됨
- 모든 인수를 테스트하여 코드 실행을 계속하기 전에 모든 인수가 예상 범위 내에 있는지와 올바르게 형식이 지정되었는지를 확인
보안 위험 및 안티패턴: 재진입성
- 악위적인 코드가 호출
- 재진입(reentrancy)
- 재진입한다(reenters)
function () payable {
if (etherStore.balance > 1 ether) {
etherStore.withdrawFunds(1 ether);
}
}
- 예방 기법
- 내장된 transfer 함수 사용
- 전송 전 상태 변경: 체크 효과 상호작용 패턴(checks-effects-interactions pattern)
- 뮤텍스(mutex): 컨트랙트를 잠그는 상태 변수를 추가하여 재진입 호출을 방지
보안 위험 및 안티패턴: 산술 오버플로/언더플로
- 데이터의 유형이 범위를 벗어나는 숫자가 될 수 있어 솔리디티 변수를 악용할 수 있음
- uint8 [0,255]
- overflow: 256 == 0
- underflow: 0 - 1 == 255
- int8 [-128,127]
- -128 - 1 == 127
- 예방 기법
- 수학 라이브러리 사용
- EVM은 0으로 나누게 되면 원 상태로 되돌림
- 오픈제플린(OpenZeppelin)
보안 위험 및 안티패턴: 예기치 않은 이더
- 폴백 함수나 컨트랙트에 정의된 또 다른 함수를 실행해야 함
- 불변 검사(invariant checking)
- 개발자가 솔리디티를 배울 때 컨트랙트가 payable 함수를 통해서만 이더를 받아들이거나 얻을 수 있다고 오해를 함
- 이러한 오해로 인해 내부의 이더 잔액에 대한 잘못도니 가정을 하는 컨트랙트가 생길 수 있음
- 다양한 취약점 발생
- 자기파괴(self-destruct/suicide)
- 이것은 아무 공격자나 selfdestruct 함수를 가진 컨트랙트를 만들고
- 이더를 보낸다음, selfdestruct(target)을 호출해서 target 컨트랙트에 강제로 이더를 보낼 수 있음을 의미함
- 미리 보내진 이더
- 자기파괴(self-destruct/suicide)
보안 위험 및 안티패턴: DELEGATECALL
- 이더리움 개발자가 코드를 모듈화할 수 있게 하는 데 유용함
- 예방 기법
- 라이브러리 컨트랙트가 스테이트리스(stateless)이며
- 비자기파괴적(non-self-destructable)임을 보장함
- 스토리지 컨텍스트의 복잡성을 완화
보안 위험 및 안티패턴: 디폴트 가시성
- 기본 가시성 public
- 실수로 private 생략하면 문제 발생
- 소유권을 공격자의 주소로 재설정할 수 있음
- 공격자는 소유자가 되어 지갑에서 모든 이더를 가져갈 수 있음
보안 위험 및 안티패턴: 엔트로피 환상
- 최초의 컨트랙트 중 일부는 도박을 기반
- 불확실성(베팅할 대상)이 필요하기 때문에 블록체인(결정론적 시스템)에 도박 시스템을 구축하는 것은 다소 어렵
- 커밋-공개 기법(commit reveal technique)
- 채굴자가 통제, 궁극적인 무작위 값이 될 수 없음
- 일반적인 함정은 미래의 블록 변수, 즉 해시, 타임스탬프, 블록 번호 또는 가스 한도 같은,
- 값이 아직 알려지지 않은 트랜잭션 블록에 대한 정보를 포함하는 변수를 사용
- 예방 기법
- 엔트로피(무작위성)의 원천은 블록체인 외부에 존재 필요
- 조작할 수 있으므로 엔트로피의 원천으로 사용하면 안됨
보안 위험 및 안티패턴: 외부 컨트랙트 참고
- 월드 컴퓨터, 상호작용하는 능력
- 예방 기법
- 참고된 컨트랙트의 인스턴스가 배포 시 생성
- 외부 컨트랙트 주소를 하드코딩하는 것
보안 위험 및 안티패턴: 짧은 주소/파라미터 공격
- 전송된 짧은 주소를 보완하기 위해 인코딩 끝부분에 00이 추가되었다.
- 토큰 값이 256배가 되었다.
- 예방 기법
- 유효성 검사
보안 위험 및 안티패턴: 확인되지 않은 CALL 반환 값
- 이더를 외부 계정으로 보내는 것은 transfer aptjem
- send 함수를 사용할 수 있음
- CALL 연산코드를 직접 사용할 수 있음
- call & send 함수는 호출성공 또는 실패 여부를 나타내는 true / false 반환
- 예방 기법
- transfer 함수 사용: 실패하면 롤백
- 항상 반환 값을 확인
- 출금 패턴(withdrawal pattern)을 채택
보안 위험 및 안티패턴: 레이스 컨디션 / 프런트 러닝
- 경쟁(race) 상태를 만드는 것
- 이더리움 노드는 트랜잭션을 풀링(pooling)
- 채굴자가 합의 메커니즘(PoW)을 해결하면 트랜잭션은 유효한 것으로 간주
- 더 높은 가스 값을 설정하여 공격 가능
- 프런트 러닝(front-running) 취약점의 경우,
- 채굴자는 공격 자체를 실행하기 위해 개별적인 인센티브를 받는 것
- (또는 엄청난 비용으로 이러한 공격을 실행하기 위해 매수할 수 있음)에 유의
- 예방 기법
- 가스 가격에 상한
- gasPrice를 높여서 트랜잭션 우선순위를 갖는 것을 막을 수 있음
- 가스 가격과 관계없이 원하는대로 트랜잭션의 순서를 변경할 수 있기 때문에 컨트랙트를 계속 공격할 수 있음
- 커밋-공개(commit-reveal) 방식을 사용하는 것
보안 위험 및 안티패턴: 서비스 거부(DoS)
- 이더를 컨트랙트 안에 영구히 잠기게 할 수 있음
- 공격자는 많은 사용자 게정을 만들어서 ..
- 블록 가스 한도를 초과하도록 수행할 수 있음 (for loop)
- 소유자 운영
- ICO(Initial Coin Offering)
- 소유자가 컨트랙트를 finalize하도록 요구
- 개인키를 잃거나 비활성 상태가 되면 전체 토큰 컨트랙트가 작동하지 않음
- 이 경우 소유자가 finalize를 호출할 수 없을 때는 토큰을 전송할 수 없게 되어 전체 토큰 생태계의 운영이 단 하나의 주소에 의해 결정되게 됨
보안 위험 및 안티패턴: 블록 타임스탬프 조작
- 블록 타임스탬프(block timestamp)
- 채굴자는 타임스탬프를 약간 조정할 수 있는데
- 채굴자는 필요한 경우 타임스탬프를 조정(block.timestamp)
- 예방 기법
- 블록 타임스탬프를 엔트로피 또는 랜덤 값을 생성하는 데 사용하면 안됨
보안 위험 및 안티패턴: 생성자 관리
- 생성자(constructor)
- constructor keyword
보안 위험 및 안티패턴: 초기화되지 않은 스토리지 포인터
- EVM은 데이터를 스토리지 혹은 메모리에 저장
- 슬롯(slot)에 순차적으로 저장
- 예방 기법
- memory or storage 지정자를 명시적으로 사용
보안 위험 및 안티패턴: 부동소수점 및 정밀도
- 고정소수점(fixed-point)
- 부동소수점(floating-point)
- 정수 유형, 오류 및 취약점
- 정밀도(precision)
- 근삿값(nearest)
- 예방 기법
- 비(atios)
- 비율(rates)
- uint256; 가스 사용에 최적임
- 숫자에 대해 임의의 정밀도를 정의할 때는 값을 더 높은 정밀도로 변환하고
- 모든 수학 연산을 수행한 다음
- 최종적으로 출력에 필요한 정밀도로 다시 변환하는 것이 좋음
보안 위험 및 안티패턴: Tx.Origin 인증
- 글로벌 변수: tx.origin
- 피싱(phishing) 같은 공격에 취약해진다.
- 취약한 컨트랙트에서 인증된 작업을 수행하도록 속일 수 있는 피싱 공겨겡 취약하다.
- 예방 기법
- 권한을 위해 사용되어서는 안 된다.
- 외부 컨트랙트가 현재 컨트랙트를 호출하는 것을 거부하려면 require(tx.origin == msg.sender) 형식의 요구사항을 구현
- 이 컨트랙트는 코드가 없는 일반 주소만이 호출할 수 있게 된다.
보안 위험 및 안티패턴: 컨트랙트 라이브러리
- 호출 가능한 라이브러리로 온체인(on-chain)에 배포되어 있거나
- 코드 샘플 라이브러리로 오프체인(off-chain)에 배포된 형태로서 재사용이 가능한 많은 코드
결론
- 스마트 컨트랙트 도메인에서 일하는 개발자는 누구나 알고 이해해야 하는 사항
- 설계 및 코드 작성의 모범 사례를 따라가면 심각한 함정에 빠지는 일을 피할 수 있음
- 신뢰할 수 있는 코드의 재사용을 극대화하는 것
- 매우 중요하며 널리 검증된 암호 알고리즘을 사용
- 스마트 컨트랙트의 경우, 커뮤니티에 의해 철저하게 검증도니 자유롭게 사용이 가능한 라이브러리를 가능한 한 많이 축적하는 것
10. 토큰(token)
- 사소한 내재가치를 지닌, 사적으로 발행한 특수 용도의 동전 같은 물건
- 물리적 토큰은 쉽게 교환할 수 없으며, 제한되는 경우가 많음
- 블록체인 토큰은 전 세계적으로 다양한 용도로 사용되며, 서로 교환되거나 전 세계 유동 시장에서 다른 화폐로 거래될 수 있음
- 대체성(fungibility)
- 내재성(intrinsicality)
토큰은 어떻게 사용되는가?
- 디지털 개인 화폐
- 화폐(currency)
- 앱(app)
- 자원(resource)
- 자산(asset): 소유권
- 접근(access): 접근 권한
- 지분(equity): 주주 지분
- 투표(voting): 투표권
- 수집(collectible): 수집물
- 신원(identify): ID
- 증명(attestation): 평판 시스템에 의한 사실 증명서 또는 인증서
- 유틸리티(utility): 사용료
- 익명 증명
토큰과 대체성
- 경제학에서 대체성이란, 개별 단위가 본질적으로 서로 호환성을 가지고 있는 재화나 상품의 속성
- 다른 토큰으로 대체할 수 있는 경우에 대체 가능(fungible: 직접 교환할 수 있는 돈)
- 대체 가능하지 않은 토큰(NFT)
- 예술 소유권 토큰
- 크립토키티(CryptoKitty)
- 디지털 수집물
- 시리얼 번호처럼 유일한 식별자와 같음
거래상대방 위험
- 거래상대방 위험(counterparty risk)은 트랜잭션에서 상대방이 자신의 의무를 이행하지 못하는 위험
- 트랜잭션
- 그 자산에 어떤 규칙이 적용되는가를 이해하는 것이 중요
토큰과 내재성
- 내재성(Intrinsicality)
- intrinsic
- intra
- from within
- 외재적인(extrinsic)
- 블록체인 내부(within)에 있지 않은 이런 아이템의 소유권은 토큰을 제어하는 합의 규칙과는 별도로 법률, 관습 및 정책에 의해 관리
- 토큰 발급자와 소유자는 실제 세계의 스마트하지 않은(non-smart) 컨트랙트에 여전히 의존해야만 한다.
- 지분(외재적)을 DAO 또는 유사한 (내재적) 조직의 지분똔느 투표 토큰으로 전환하는 것이다.
토큰 사용: 유틸리티 또는 지분
- 이더리움에 있는 거의 모든 프로젝트가 이종의 토큰으로 시작
- 토큰화(tokenize all the things)
- 유틸리티 토큰(utility token) 또는 지분 토큰(equity token)
- 지분 토큰
- 지분을 나타내는 토큰
- 탈중앙화된 자율 조직의 투표지분으로 확장될 수도 있는데,
- 여기서 플랫폼의 관리는 토큰 보유자들의 투표에 기반을 둔 상당히 복잡한 거버넌스 시스템을 통해 이루어짐
유틸리티 토큰: 누가 필요한가?
- 모든 것의 토큰화
- 현재 토큰을 이해하고 사용하고자 하는 사람들은 아직도 작은 암호화폐 시장의 일부분일 뿐임
- 초기 수용자(early adopters)
- 각각의 혁신은 그 스타트업의 실패 가능성을 증가시키는 리스크를 불러옴
- 플랫폼(이더리움)
- 광범위한 경제(거래소, 유동성)
- 모든 위험을 더하는 것이다.
- 그것은 스타트업에 많은 위험을 안겨줌
- 모든 것을 토큰화하라
- 위험과 불확실성을 능가하는지 여부
- 올바른 근거를 가지고 결정함
- 토큰을 사용하지 않으면 애플리케이션이 작동하지 않으므로 토큰을 사용
이더리움 토큰
- 이더리움에서 첫 번째 토큰 표준이 소개되고 나서 토큰이 폭발적으로 증가
- 비탈릭 부테린, 범용적이고 프로그래밍 가능한 블록체인의 가장 명확하고 유용한 애플리케이션의 하나로 토큰 제안
- 가장 일반적인 토큰 구현을 보여주었다.
ERC20 토큰 표준
- ERC(Ethereum Request for Comments)
- 깃허브 이슈번호 20이 자동으로 할당되어 ERC20 토큰이라는 이름이 되었다.
- EIP-20(Ethereum Improvement Proposal 20)
- ERC20은 대체 가능한 토큰(fungible token)
totalSupply
balanceOf
tansfer
transferFrom
approve
allowance
Transfer
Approval
name
symbol
decimals
- 데이터 매핑(data mapping)
mapping(address => uint256) balances;
mapping(address => mapping (address => uint256)) public allowed;
ERC20 토큰 문제
- ERC20 토큰 표준의 채택은 정말로 폭발적
- 크라우드 펀드(crowdfund) 경매 및 ICO에서 자금을 모으기 위해 수천 개의 토큰이 출시되었음
- 컨트랙트 주소로 토큰을 전송하는 문제에서 알 수 있듯이 몇 가지 잠재적인 함정이 있음
- 컨트랙트를 목적지로 함
- 많은 ERC20 토큰들은 유용한 토큰이라기보다는 전자 메일 스팸과 유사
- 쓰레기(junk) 토큰
- payable 함수 또는 외부 소유 주소에 의해 수신(accepted)
ERC721: 대체 불가능한 토큰(증서) 표준
- 대체 가능한(fungible)
- 대체할 수 없는(non-fungible)
- 법적 문서(legal documents)
- 소유권(ownership of property)
토큰 표준 사용
- 최소(minimum)
- 상호운용성(interoperability)
- 인터페이스(interface)
- 규범적(prescriptive)
- 기술적(descriptive)
- 딜레마(dilemma)
- NIH(Not Invented Here)
- 구현(implementation)
- 참조(reference)
토큰 인터페이스 표준 확장
- 소각(burning)
- 발행(minting)
- 크라우드펀딩(crowdfunding)
- 캡(caps)
- 복구 백도어(recovery backdoors)
- 화이트리스트(whitelisting)
- 블랙리스트(blacklisting)
11. 오라클(oracle)
- 외부의 데이터를 이더리움 스마트 컨트랙트로 제공
- 그리스 신화에서 신의 계시를 전달하고 미래의 모습을 보는 사람이라는 뜻
- 신뢰가 필요 없는(trustless) 시스템
- 탈중앙화 원칙을 바탕으로 작동하기 때문
오라클은 왜 필요한가?
- EVM 실행, 완전히 결정론적
- 데이터 페이로드(payload)로서만 유입
- 난수 함수(a true random function)의 사용을 금지하는 것을 이해하려면
- 임의성(randomness)
- 데이터는 확인할 수 없는 출처에서 비롯되어 전혀 신뢰할 수 없음
오라클 유스케이스와 사례
- 순수 난수와 같은 외부
- 신뢰가 필요없는(trustless, near-trustless)
- 스마트 컨트랙트를 통해 실세계 이벤트와 데이터를 기반으로 계약적인 관계를 강화하면 오라클의 사용 범위는 크게 확대됨
- 소유자가 사망하기 전에 오라클을 해킹하고 자산을 분배하려 할 것
- 당첨자를 공정하게 뽑는 것
- 정확한 교환 비율(pegging)
- 토큰화된 자산/증권의 가격 책정
- 예측 시장 결과 제공
- 상호운용성 함수
- 클럽의 통계
오라클 디자인 패턴
- 오프체인 소스에서 데이터를 수집
- 서명된 메시지로 온체인에 전송
- 스마트 컨트랙트의 스토리지에 저장하여 사용
- 요청-응답(request-response)
- 데이터 공급자 사업 영역에 적용 가능한 모델
- 게시-구독(publish-subscribe)
- 폴링(polling)
- 구독(subscribed)
- 즉시 읽기(immediate-read)
데이터 인증
- 진위성 증명(authenticity proof)
- 신뢰할 수 있는 실행 환경(Trusted Execution Environment, TEE)
- 데이터 운반자(data carrier)
- 데이터 입증자(data attestation)
결론
- 스마트 컨트랙트에 중요한 서비스 제공
- 컨트랙트 실행을 위해 외부 정보를 가져옴
- 오라클은 상당한 위험 초래
- 신뢰 모델(trust model)에 대해 매우 신중해야 함
- 오라클을 신뢰할 수 있다고 가정하면, 잠재적인 잘못된 입력에 노출되어 스마트 컨트랙트의 보안을 약화시킬 수 있음
728x90
'읽은책' 카테고리의 다른 글
운명을 바꾸는 부동산 투자 수업 - 정태익(부읽남) (0) | 2023.06.30 |
---|---|
MLOps 도입 가이드 기업에서 머신러닝 모델을 가장 효율적으로 운영하는 방법 (0) | 2023.01.14 |
Effective Java (0) | 2021.12.31 |
JUnit in Action (단위테스트의 모든 것) (0) | 2021.12.31 |
터틀 트레이딩 - 마이클 코벨 (0) | 2021.11.08 |
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- wlw
- 할인
- 유투브
- 레퍼럴
- 어떻게 능력을 보여줄 것인가?
- 모델y
- 테슬라 크레딧 사용
- 팔로워 수 세기
- 모델 Y 레퍼럴
- 테슬라 추천
- 김달
- Kluge
- 메디파크 내과 전문의 의학박사 김영수
- 테슬라 리퍼럴 코드 생성
- 테슬라 리퍼럴 코드 혜택
- 테슬라 리퍼럴 코드
- 테슬라
- 테슬라 레퍼럴 적용 확인
- 책그림
- 테슬라 레퍼럴 코드 확인
- follower
- 테슬라 레퍼럴
- 클루지
- 개리마커스
- COUNT
- 연애학개론
- Bot
- 인스타그램
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함