티스토리 뷰

읽은책

Mastering Ethereum

승가비 2022. 1. 4. 18:07
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에서 정의한 표준화된 절차에 따라 지갑에서 자동으로 생성된다.
  • 지갑은 엔트로피의 원천에서 시작해서 체크섬을 추가하고 단어 목록에 엔트로피를 매핑한다.

니모닉 단어 생성

  1. 128~256 비트의 무작위 암호화 시퀀스 S를 생성한다.
  2. S를 SHA-256으로 해싱한 값을 32비트로 나눈 처음 길이를 체크섬으로 생성한다. (처음 4비트)
  3. 무작위 시퀀스 S의 끝에 체크섬을 추가한다. (132비트)
  4. 시퀀스와 체크섬을 연결한 것을 11비트 단위로 나눈다. (11 * 12)
  5. 각각의 11비트 값을 사전에 정의된 2,048단어 사전과 매핑한다. (11비트 == 2048)
  6. 단어의 시퀀스로부터 순서를 유지하면서 니모닉 코드를 생성한다.

니모닉에서 시드까지

  • 엔트로피는 키 스트레칭 (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 컨트랙트에 강제로 이더를 보낼 수 있음을 의미함
    • 미리 보내진 이더

보안 위험 및 안티패턴: 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
댓글