이더리움 EVM과 Solidity - 2

Lumi·2021년 11월 22일
0
post-thumbnail

글이 너무 길어지는 것 같기 떄문에 추가로 적겠다.

🔥 Hello World

앞선 글에서 기본적인 솔리디티 문법을 배웠다.

단순히 이런게 있구나 라는 느낌이였기 때문에 좀더 실습을 진행해 보고자 한다.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

contract helloWorld{
    
    function renderHelloWorld () public pure returns(string memory){
        return "Hello World!";
    }
}

많은 것을 담고 있지는 않지만 간다하게 알 수가 있다.

일단 기본적으로 함수를 사용하였고 public로 선언을 하였다

그리고 return문은 string이다.

  • 왜냐하면 return이 string값이기 떄문에

나는 따른 변수를 읽거나 쓰지 않기 떄문에 pure를 추가한 것이다.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

contract helloWorld{
    string answer = "HelloWorld";
    
    function renderHelloWorld () public returns(string memory){
        return answer;
    }
}

만약 변수를 읽고자 한다면 pure를 이처럼 제거 해야 한다.

// SPDX-License-Identifier: MIT
pragma solidity 0.8.7;

contract helloWorld{
    
    string answer;
    
    function set(string memory x) private {
        answer = x;
    }
    
    function renderHelloWorld () public returns(string memory){
        return answer;
    }
}

따로 변수를 읽고자 한다면 이렇게 작성을 하면 된다.

🔨 memory

memory를 사용하는 이유에 대해 의문이 들 것이다.

  • 나도 의문이 들었다;;

솔리디티 버전이 올라감에 따라 변수에 memory를 적어주어야 한다고 한다..

  • 구글링을 해서 알게 되었다.

🔥 가위바위보 게임 만들기

앞서 정말 간단한 솔리디티를 작성해 보았고 이번에는 좀더 복잡한 솔리디티를 작성해 보자.

두 명의 플레이어가 가위바위보 게임을 진행하고, 이긴 경우 두 참여자의 베팅금액을 모두 가져간다.

세가지 퍼블릭 함수를 가지고 있다.

  • createRoom : 가위바위보 게임을 하기 위한 방을 만든다.
  • joinRoom : 만들어진 방에 참가한다.
  • payout : 게임을 마친다. 결과에 따라 금액을 송금하다.

다음과 같은 플로우로 진행이 된다.

[1] 방장이 우선 createRoom 을 호출한다.

방장은 인자로 자신이 낼 가위/바위/보 와 베팅 금액을 넘겨준다.
- createRoom은 새로운 방을 만들고, 방의 번호를 return한다.

[2] 참가자는 joinRoom을 호출한다.

참가자는 인자로 참여할 방 번호, 자신이 낼 가위/바위/보 값과 베팅 금액을 넘겨준다.
- joinRoom은 참가자를 방에 참여시킨다.
- joinRoom은 방장과 참가자의 값을 확인하고 승자를 설정한다.

[3] 방장 또는 참가자가 payout함수를 호출한다.

인자로 게임을 끝낼 방 번호를 넘겨준다.
- 게임의 결과에 따라 베팅 금액을 송금하다.

🌪 기본 설정

기본적인 사용자 설정과 게임 구성도 이다.

  • enum은 다루지 않았지만 열거형을 말한다.

HAND는 낼수 있는 카드(주먹/가위/보)를 의미하며

PlaterStatus는 플레이어들의 현재 상태를 나타낸다.

GameStatus는 현재 게임의 진행도를 나타낸다.

각각의 플레이어들은 개인의 지갑 주소와 배팅금액 등등을 상태로 가지고 있고

Game은 Player중에서 방장과 상대방을 지정하며 총 배팅금액 및 게임의 진행 상태를 가지고 있다.

🌪 게임 생성하기

일단 mapping을 통해서 키-값 형태인 rooms를 만들어 준다.

이후 함수를 통해서 만들어 주면 된다.

  • 좀더 코드를 여러번 확인하면 알 수가 있다.

이렇게 되면 우리는 originator과 taker를 만들 었다.

하지만 이떄 originator즉 방장이 방을 생성하였을떄 가위/바위/보 같이 아닌 다른 값이 지정될 수도 있기 떄문에 우리는 modifier를 활용하여 값을 미리 확인해야 한다.

이와같이 수정을 하면 함수가 실행하기 전에 들어오는 매개변수값을 _hand를 통해 검사를 하게 될 것이다.

🌪 방에 참가하기

기존에 만들어진 방에 참가를 해야한다.

참가자들은 가위/바위/보 값을 인자로 보내고 금액을 msg.value로 설정한다.

마찬가지로 isValidHand를 사용한다.

앞선 코드에서는 taker은 지정하지 않았다.

  • 방만들기 코드를 보면 originator만 배팅을 하였다.

방을 만들떄마다 방 번호가 부여될 것이고 거기에는 반장이 미리 내놓은 선택지가 잇을것이다.

  • 주먹/ 가위/ 보

우리는 이 부분을 전제로 깔고 있어야 한다.

  • 반장이 한번 낸 선택지는 바뀌지 않는다.

왜냐하면 따로 바꾸는 함수가 없기 때문이다.

그럼 이제 taker입장에서는 방번호를 선택해 들어가면 되고 들어갈떄 인자로 선택지, 방번호를 입력해 주어야 한다.

그후 그 방의 taker를 갱신하고 전체 배팅금액을 늘린다.

  • 왜냐하면 반장 + taker의 금액을 합쳐야 하기 떄문에

그후 반장과 taker의 선택지를 비교하는 함수 compareHands를 호출하면 된다.

  • 이떄 인자로 roomNum을 보내준다.

그럼 compareHands에서는 일단 타입을 바꾸어 준다.

  • 왜냐하면 hand는 열거형이기 떄문에 해당 값을 계산하기 위해서 uint값으로 바꿔 주는 것이다.
한가지 알아 두어야 할 것이다 있다.

enum즉 열거형은 앞에 인자부터 0,1,2,3,4,... 이렇게 인덱스를 가지게 된다.

즉 rock = 1, paper = 2, scissors = 3

이런식이다.

자 이제 게임 방의 상태를 STATUS_STARTED 로 갱신을 한 뒤에

  • 왜냐하면 결과가 도출 되었기 떄문에

if문을 통해 누가 이겼는지를 파악한다.

  • 조건에 들어가는 판결 코드는 단순한 계산이다.
  • 별다른 것이 아니다.

🌪 배팅 금액 송금하기

우리가 if문을 통해서 승자의 상태를 바꾸었다는 것을 전 코드를 보면 알 수가 있다.

그럼 그 값을 통해서 누가 승자인지를 판별하고 그후 배팅한 금액을 돌려 주어야 한다.

우리는 컨트랙트에 있는 금액을 송금하기 위해서는 내장되어 있는 transfer 함수를 사용하면 된다.

사용법

ADDRESS.transfer(value)
// ADDRESS로 value만큼 송금한다.

단순하게 노가다 식으로 작성을 하면된다.

해당 상태의 값이 내가 원하는 값이면 원하는 방식에 맞게 처리를 해주면 된다.

  • 일단 먼저 비겼을떄를 비교를 하였다.

내가 한가지 간과한 것이 있다면 payout를 실행시키는 주체는 반장 또는 해당 방의 taker이어야 한다는 점이다.

  • 왜냐하면 다른 taker가 마음대로 작동시키면 안되기 떄문에

그러기 떄문에 modifier를 추가하여 적용시켜 주었다.

수정한 코드는 이와 같다.

msg.sender 즉 트랜잭션을 발생시키는 주체가 같은 방 사람일 경우에만 작동이 되게 하였다.

  • 추가적인 사항을 한다면 게임 방의 상태가 결정이 나있는 상태라는 조건을 추가 할 수도 있다.

🔨 긴 여정이 끝났다...ㅠㅠ

🔥 솔리디티 버전에 따른 변경점과 클레이튼에서의 솔리디티

현 시점에서 솔리디티의 최신 버전은 0.8.10이다.

계속해서 업데이트가 되어가고 있고 생태계마다 사용하는 솔리디티 버전은 조금씩 다르다.

솔리디티 버전이 업데이트 됨에 따라 문법적으로 약간씩 달라지기 떄문에 주의 하여야 한다.

  • 다른 버전에서 솔리디티가 작동하지 않는 이유가 이러한 이유이다.

클레이튼에서는 현재 0.5.6을 사용하고 있다.

🔨 차이점

profile
[기술 블로그가 아닌 하루하루 기록용 블로그]

0개의 댓글

관련 채용 정보