스마트 컨트랙트 개발언어는 솔리디티만 있는 게 아닙니다.
바이러라는 최근 급성장하는 언어가 있습니다. 이것의 문법은 파이썬과 매우 유사합니다. 이름이 왜 바이퍼인가 했더니 파이썬과 문법이 유사해서 그렇습니다. 파이썬도 뱀을 의미하고, 바이퍼도 뱀을 의미하거든요. 좀 더 찾아보니 바이퍼는 파이썬3를 기반으로 만들었고, 바이퍼의 문법은 파이썬3과 호환된다고 합니다.
솔리디티와 바이퍼의 깃헙 통계를 비교해 보겠습니다.
2019년 8월 20일 기준
솔리디티
통계로 보면, 아직도 솔리디티가 대세인 것으로 보입니다.
솔리디티와 바이퍼는 문법은 다르지만 컴파일 결과 얻어지는 결과물은 ABI와 바이트코드로 동일합니다.물론 코드에 따라 바이트코드가 생성되는 것이기 때문에, 바이트코드 자체가 동일하지는 않습니다. 그러나 EVM에서는 바이트코드가 솔리디티 코드로 컴파일된건지, 바이버 코드로 컴파일된건지 따지지 않습니다.
솔리디티 코드와 바이퍼 코드 비교
바이퍼 코드 샘플입니다. 정말로 파이썬 코드를 보는 것 같습니다. 조금 다른 점이라면 변수를 선언하는 점이 좀 다르네요.
# Open Auction
# Auction params
# Beneficiary receives money from the highest bidder
beneficiary: public(address)
auctionStart: public(timestamp)
auctionEnd: public(timestamp)
# Current state of auction
highestBidder: public(address)
highestBid: public(wei_value)
# Set to true at the end, disallows any change
ended: public(bool)
# Keep track of refunded bids so we can follow the withdraw pattern
pendingReturns: public(map(address, wei_value))
# Create a simple auction with `_bidding_time`
# seconds bidding time on behalf of the
# beneficiary address `_beneficiary`.
@public
def __init__(_beneficiary: address, _bidding_time: timedelta):
self.beneficiary = _beneficiary
self.auctionStart = block.timestamp
self.auctionEnd = self.auctionStart + _bidding_time
# Bid on the auction with the value sent
# together with this transaction.
# The value will only be refunded if the
# auction is not won.
@public
@payable
def bid():
# Check if bidding period is over.
assert block.timestamp < self.auctionEnd
# Check if bid is high enough
assert msg.value > self.highestBid
# Track the refund for the previous high bidder
self.pendingReturns[self.highestBidder] += self.highestBid
# Track new high bid
self.highestBidder = msg.sender
self.highestBid = msg.value
# Withdraw a previously refunded bid. The withdraw pattern is
# used here to avoid a security issue. If refunds were directly
# sent as part of bid(), a malicious bidding contract could block
# those refunds and thus block new higher bids from coming in.
@public
def withdraw():
pending_amount: wei_value = self.pendingReturns[msg.sender]
self.pendingReturns[msg.sender] = 0
send(msg.sender, pending_amount)
# End the auction and send the highest bid
# to the beneficiary.
@public
def endAuction():
# It is a good guideline to structure functions that interact
# with other contracts (i.e. they call functions or send Ether)
# into three phases:
# 1. checking conditions
# 2. performing actions (potentially changing conditions)
# 3. interacting with other contracts
# If these phases are mixed up, the other contract could call
# back into the current contract and modify the state or cause
# effects (Ether payout) to be performed multiple times.
# If functions called internally include interaction with external
# contracts, they also have to be considered interaction with
# external contracts.
# 1. Conditions
# Check if auction endtime has been reached
assert block.timestamp >= self.auctionEnd
# Check if this function has already been called
assert not self.ended
# 2. Effects
self.ended = True
# 3. Interaction
send(self.beneficiary, self.highestBid)
솔리디티를 아직 접하지 못한 개발자라면, 솔리디티보다 바이퍼로 시작하는 것도 나쁘지 않겠습니다. 사실 솔리디티가 유명하지만, 보안 문제가 좀 있거든요
솔리디티 및 기타 언어로 배포된 스마트 컨트랙트의 주요 보안 문제는 다음과 같습니다.
이외에더 여러 경우가 있습니다. 그 이유는 솔리디티가 코더에게 거의 무한한 자유를 주기 때문입니다. 막말로, 컨트랙트의 selfdestruct함수에서 발행한 사람을 체크하는 코드가 없다면 누구나 컨트랙트를 삭제할 수도 있는 것입니다.
바이퍼는 솔리디티의 자유도는 낮춤으로써 보안성을 확보했습니다.
바이퍼의 컨트랙트는 다음과 같은 구조를 가집니다.
파이썬 문법을 따르다보니 파이썬에서 많이 보는 @public과 같은 @기호를 이용한 데코레이터를 지원합니다. 또한 파이썬과 같이 함수에서 self라는 키워드를 사용하여 컨트랙트 인스턴스에 접근할 수 있습니다. 즉 컨트랙트에 속한 어떤 함수에서라도 인스턴스 변수에 접근이 가능합니다.
또한 바이퍼는 솔리티티에는 없는 몇가지 데이터 타입을 제공합니다.
컨트랙트에서 변수 오버플로우 문제는 치명적입니다. 비트코인의 경우 2010년에 데이터 타입이 signed인 점을 이용해서 오버플로우를 의도적으로 이용해서 엄청난 수의 비트코인을 발행한 사건이 있었습니다. 이더리움의 경우도 2018년 4월에 이와 유사한 사례가 발생했습니다. 바이퍼는 오버플로우 검출기능을 내장하고 있습니다.
솔리디티 컴파일러는 C++로 작성되어 있는데, 바이퍼는 파이썬으로 작성되어 있습니다.
바이퍼도 온라인에서 컴파일할 수 있습니다.
https://vyper.online
배포는 아직 안되나 봅니다. 하지만 바이퍼 코드를 컴파일해서 얻어진 바이트코드와 ABI를 이용하여 리믹스에서 배포도 가능합니다. 아 새로운 리믹스는 바이퍼를 정식 지원하고 있습니다!
Truffle이라는 스마트 컨트랙트 개발 플랫폼이 있습니다. 바이퍼도 지원됩니다.
https://truffleframework.com/blog/truffle-v5-has-arrived
Truffle을 사용하면 테스트넷 셋업등이 매우 편합니다.
결론적으로 스마트 컨트랙트 개발을 솔리디티가 아니라 바이퍼로 해도 큰 이슈는 없는 걸로 보입니다. 그러나 많은 사람들이 바이퍼가 솔리디티를 대체하는 것은 아니라고 합니다. 그런데 바이퍼가 더 보안이 강하고, 솔리디티와 유사한 성능을 낸다면 많은 사람들이 바이퍼를 사용할 거 같습니다.