PBL Ⅲ/BlockChain

Hotel Reservation Smart Contract with SOLIDITY

myejinni 2022. 6. 9. 15:47

<암호화폐를 지불하고 호텔 예약을 할 수 있는 스마트 컨트랙트>

 

1. payable 키워드

: 계약 계정에 이더를 사용(송금, 수신)할 수 있도록 해 줌

 

book() 함수 안의 transfer() 함수는 이더의 수량만큼 전송할 수 있게 해 줌

 

2. enum (열거형)

: enum을 사용해 호텔 예약 여부에 대한 상태 변수를 추가 

: 미리 정의된 상수들의 목록

: 함수 내에서 선언 불가, 계약의 전역 이름 공간에 선언 가능

 

-> Vacant에는 정수값 0, Occupied에는 정수값 1이 세팅 됨 (자동으로 0,1,2..순서로 할당)

 

3. require () 함수

예약을 위해 체크해야 할 2가지 정보

-가격

-방이 비었는지에 대한 여부

-> 이를 확인하기 위해 require () 함수 사용

 

-> require 함수 첫 번째 값이 true면 실행; msg.value가 2ether보다 크거나 같음)

false면 오른쪽 메세지 출력 ; Not enough provided

 

-> require 함수 첫 번째 값이 true면 실행; 현재 상태= 방이 비어있는 상태

false면 오른쪽 메세지 출력 ; Currently occupied.

 

-> true일 때 해당 코드 실행됨

 

4. modifier(수정자)

- 수정자를 사용해 함수 세분화

-솔리디티에서는 수정자가 항상 함수와 연관성을 가짐

; 수정자를 사용하면 연관된 함수의 행위 변경 가능

 

-수정자를 사용하여 현재의 계약 상태, 상태변수, 이더값 등 실행이 가능한지 여부를 사전에 체크

& 실제 필요한 함수 수행하는데 사용

 

-> 실행순서

1. modifier onlyWhileVacant

2. modifier costs

3. book() 함수

 

 

5. Event(이벤트)

- 특정 이벤트가 발생할 경우 해당 이벤트를 처리하는 코드 실행

-솔리디티의 이벤트

=EVM의 로깅환경을 이용해 앱의 현재 계약상태에 대한 정보를 알려주는데  주로 사용

; 계약의 변화가 발생할 경우 이벤트가 사용됨

 

-> 이벤트 선언

 

-> 이벤트 사용

 

 

6. receive() 함수

- book() 함수를 receive() external로 변경해줌

- receive() 함수는 메타마스크 등과 같이 연결된 지갑을 통해서 결제할 수 있도록 해 줌

 

 

7. compile, deploy

 

-> compile

*작성한 버전과 실제 컴파일러 버전을 동일하게 설정

 

-> deploy

 

 

8. 실행

-> owner 주소 확인

 

 

1. 다른 계정 선택 후, 1 ether 송금해보자

-> transact 클릭 시, not enough Ether provided 안내문 뜸

 

 

2. 2 Ether 송금 시, 

-> 정상적으로 송금이 되며 스마트컨트랙이 보내진 것을 확인 가능

 

 

3. 다른 계정 선택 후 2 Ether 송금 시, 

-> Currently occupied 안내문이 뜨며 더 이상 예약 불가함을 알려줌

 

 


 

 

-코드 전문-

// in SOLIDITY
pragma solidity ^0.6.0;

contract HotelRoom{
    // 호텔 예약이 되었는지 상태변수(0,1)
    enum Statuses { Vacant, Occupied }
    Statuses currentStatus;

    event Occupy(address _occupant, uint _value);

    //payable 키워드=계약 계정에 이더를 사용(송금, 수신)할 수 있도록 해줌
    // ether로 호텔 예약할 것이니 식별자 설정
    address payable public owner ;

    constructor() public{
        owner=msg.sender;
        currentStatus = Statuses.Vacant; // 예약 안 되었으니 vacant
    }

        modifier onlyWhileVacant {
        //Check status - 예약 전 방이 비어있는지 확인
        require(currentStatus == Statuses.Vacant, "Currently occupied.");
        _;
        }

        modifier costs (uint _amount) {
        //Check price - 예약 전 가격 확인
        require(msg.value >= _amount, "Not enough Ether provided");
        _;
        }

        receive() external payable onlyWhileVacant costs(2 ether){
        
        // 예약되었으니 occupied
        currentStatus=Statuses.Occupied;
       
        //book함수의 transfer 함수는 이더의 수량만큼 전송하게 해줌
        // ether 수량만큼 전송
        owner.transfer(msg.value); 

        emit Occupy(msg.sender, msg.value);
        }
}

 

 

-참고-

https://kimsfamily.kr/338