Advertisement

예제로 배우는 이더리움 결제구현 (거래소 지갑 구현 예시)

Software Engineer
Jul. 28, 2017
Advertisement

More Related Content

Slideshows for you(20)

Similar to 예제로 배우는 이더리움 결제구현 (거래소 지갑 구현 예시)(20)

Advertisement

예제로 배우는 이더리움 결제구현 (거래소 지갑 구현 예시)

  1. 예제로 배우는 이더리움 결제 Hyocheol Chae
  2. 목차 • 결제 시스템 구조 • 이더리움 주소 생성 • 입금 처리 • 송금 / 환불
  3. 대상 • 이더리움이 어떻게 돌아가는지 알고 싶은 분들 • 이더리움 입출금 개발을 시작하시려는 분들 • Go-ethereum 소스코드 공부하시는 분들
  4. 한계 • 본 발표자료에 사용된 코드는 데모용으로 만든 것이기 때문에 실제 개발에는 더 많은 주의가 필요 합니다
  5. Case Study: alfacoins.com
  6. Case Study: alfacoins.com
  7. Payment Solutions • https://smartex.io/ (BTC, ETH) • https://www.coinpayments.net/ (65 coins+) • https://alfacoins.com (BTC, ETH)
  8. Why Ethereum is great for payments • Simpler (No UTXO - easy to make wallet) • Cheap transaction fee (<$0.01) • Scalable & Off-chain payment (http://raiden.network) • Smart contract • Not good for privacy (UTXO is better)
  9. Raiden Network • Scalable: it scales linearly with the number of participants (1,000,000+ transfers per second possible) • Fast: Transfers are confirmed and final within the fraction of a second • Confidential: Single transfers don’t show up in the global shared ledger • Interoperable: Works with any token that follows Ethereum’s standardized token API • Low Fees: Transaction fees can be 7 orders of magnitude lower than on the blockchain • Micro-payments: Low transaction fees allow to efficiently transfer tiny values
  10. Raiden : Complementary to Ethereum • Vitalik Buterin: “State channels are an important technology that has the potential to greatly improve the scalability and privacy of many categories of blockchain applications; in conjunction with sharding and other privacy- preserving cryptographic technologies, they are an important ingredient in helping decentralized systems to achieve the properties that mainstream individual and institutional users expect and deserve.” • https://github.com/raiden-network/raiden
  11. 개발스택 • 이더리움 노드 • 로컬에 설치하면 속도가 매우 빠르지만 • 설치/운영 수고가 없는 infura.io 사용 • 개발 언어 + 라이브러리 • Go + Geth (as a RPC library)
  12. 이더리움 결제 고려사항 • 기능 • 특정 사용자용 이더리움 주소 생성 하여 입금 여부 실시간 확인 기능 • 입금 취소를 하는 경우 돈을 돌려줘야 하는데, 1ETH를 받으면 수 수료를 제외하고 송금하는 기능 • 장애처리 • 결제 누락 • 이중 지불
  13. 이더리움 노드 접속하기 • Geth에서 제공하는 EthereumClient 클래스 사용하여 Infura 접속
  14. 입금 주소 생성하기 • Go-ethereum 에서 제공하는 함수 이용하면 개인키와 주소를 쉽게 생 성 가능 • 개인키 = resPriv • 공개키 = address
  15. 입금 확인 • 입금 확인에는 2가지 방법이 있다 • Polling : 정기적으로 최근 블럭-트랜잭션 목록을 전수 조사하여 입금 여부 확인 • Subscribe : 새로운 블럭이 들어올 때 마다 검사하는 기능 • SubscribeNewHead : 그냥 새로운 블럭이 들어오면 콜백 호출 • SubscribeFilterLogs : 필터 조건 (시작/종료 블럭, 관심 주소) 에 맞 는 블럭이 들어오면 콜백 호출 - (infura.io 에서는 사용 불가) • 결제 주소마다 스마트컨트랙 생성후 결제시 로그를 남기는 방식으로 구현 가능. 그러나 스마트컨트랙 생성에 Gas가 소요되므로 좋은 방법은 아닌것 같음
  16. 입금 확인 : Polling Example
  17. 입금확인 : 인덱싱 서버와 입금확인 분리 패턴 • 인덱싱 서버 : 이더리움 트랜잭션 목록을 매번 읽어서 DB에 기록하는 서버 • 입금확인 서버 : DB에서 원하는 조건이 만족하면 입금으 로 처리
  18. 입금 확인 : 트랜잭션 목록 서명 검증 • Go-Ethereum 에서 트랜잭션 목록을 읽기 위해서는, 무 결성을 위해 전자서명이 검증된 값만 해석되도록 만들어 보안사고 방지 • 서명 클래스는 HomesteadSigner, FrontierSigner, EIP155Signer 중에 하나를 고를 수 있는데 가장 최신 버전인 EIP155Signer 를 선택하면 잘 작동 • EIP155 Signer 란? Replay Attack 막기 위해 이더리움 블럭체인 코드가 바뀌면서 포크 발생 • ChainID 는 메인넷은 1로 고정됨, 테스트넷(ropsten) 은 3
  19. 이더리움 송금 • 준비
  20. 이더리움 송금 • 송금
  21. 이더리움 송금시 주의사항 • GasLimit 과 GasPrice 가 충분치 않으면 송금이 안됨 • 트랜잭션시 Nonce 값이 틀리면 아무 메시지도 없이 무 효처리되는데, 이 값은 누적 트랜잭션 횟수를 입력해줘 야 함 (NonceAt 함수 사용 추천) • 송금을 하면 트랜잭션 해시 값이 만들어지는데 이 값을 이용해서 결과를 추적 가능
  22. 이더리움 송금 결과 체크 • 트랜잭션이 잘 수행되었는지 어떻게 아는가? • 이더리움에는 영수증(Receipt) 이라는 개념이 있다
  23. 이더리움 송금 결과 체크 (Before Geth 1.7) • TransactionReceipt 함수를 이용해 트랜잭션이 성공적 인지 확인 가능. 다만, Gas가 부족한 경우와 아닌 경우를 알기 어려운데 이는 gasUsed 와 gasLimit 을 비교해서 판별 가능 (어디까지나 확률적)
  24. 이더리움 송금 결과 체크 (Metropolis) • 최신 Geth 1.7 에서는 TransactionReceipt 함수를 호출 하면 트랜잭션이 성공했는지 알려준다. •
  25. 이더리움 송금 결과 체크 (Metropolis)
  26. Receipt 구조체 type Receipt struct { // Consensus fields PostState []byte // Failed bool // 송금의 성공여부 CumulativeGasUsed *big.Int // EVM 실행에 사용된 가스 사용량 Bloom Bloom // 로그 인덱스을 빠르게 할 Bloom 필터 Logs []*Log // 로그 목록 (컨트랙에서 남길 수 있음) // Implementation fields (don't reorder!) TxHash common.Hash ContractAddress common.Address GasUsed *big.Int }
  27. Receipt 는 언제 만들어지나? • 송금 (정확히는 ApplyTransaction) 이 발생할 때 receipt := types.NewReceipt(root, failed, usedGas) // 영수증 생성 receipt.TxHash = tx.Hash() // 트랜잭션 해쉬값을 영수증에 쓴다 receipt.GasUsed = new(big.Int).Set(gas) // 사용된 가스값 저장 // 트랜잭션이 Contract 생성하는 경우는 대상주소가 Nil if msg.To() == nil { receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce()) } // 영수증에 로그 정보와 블룸필터 정보를 쓴다 receipt.Logs = statedb.GetLogs(tx.Hash()) receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
Advertisement