728x90
Contract Truffle 배포
counter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Counter{
uint256 value;
constructor(){}
function increment() public {
value += 1;
}
function decrement() public {
// 조건식. value가 0이 아니면 실행
// 조건문 통과가 안되면 가스비 지불하지 않고 에러구문이 뜬다.
require(value != 0, "vlaue 0 error");
value -= 1;
}
function getValue() public view returns(uint256){
return value;
}
}
1_deploy_Counter.js
// build 폴더 안에 컴파일된 Counter.json을 가져온다.
const Counter = artifacts.require("Counter");
module.exports = (deployer)=>{
// deployer.deploy 메서드를 통해, 가져온 json파일 내용으로 배포를 진행한다.
deployer.deploy(Counter);
}
숫자 야구 게임
Baseball.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Baseball{
// 컨트랙트를 배포한 사람
// 컨트랙트 소유자를 지정. CA에 있는 balance를 가져오거나 게임을 리셋시킬 수 있는 사람.
// 게임 규칙
//// 1. 컴퓨터가 숫자 3개를 랜덤하게 뽑는다.
//// 2. 이 숫자 3개를 플레이어들이 맞추는 게임
//// 3. 숫자를 입력해서 값을 비교하고 틀리면 그 사람은 이더를 CA에 보낸다.
//// 4. CA 플레이어들이 게임을 하면서 모인 이더를 최종적으로 맞춘 사람에게 보상으로 준다.
//// 5. 게임 플레이 횟수가 있는데 라운드가 모두 종료되었을 때까지 아무도 맞추지 못하면 보상은 플레이어가 아닌 컨트랙트 소유자가 보상으로 받는다.
// 컨트랙트 배포자
address private owner;
// 게임의 횟수
// constant : 상태를 변경하지 않는 상태 변수이다. (JS의 const 같은)
uint256 private constant GAME_COUNT = 5;
// 게임에 참가하기 위해 지불해야 하는 이더
uint256 private ticket = 5 ether;
// 정답의 값(랜덤 값)을 담아놓을 변수
// 컴퓨터가 정할 랜덤 값. 3자리 수의 숫자
uint256 private random;
// 게임의 진행도
uint256 private progress;
// 플레이어가 지불한 총 상금
uint256 private reward;
// 게임의 현재 상태
enum GameStatus {
Playing, // 0
GameOver // 1
}
GameStatus gameStatus; // 최초의 상태 값은 0이다. 따라서 게임 플레이(playing) 중이다.
// 컨트랙트 생성자
// 컨트랙트가 배포되면 딱 한 번 실행된다.
// 따라서, 컨트랙트 생성자를 실행시킨 사람이 배포자일 것이다.
constructor(){
// 최초에 딱 한 번 배포자가 상태변수에 담긴다.
owner = msg.sender;
// keccak256 : 솔리디티에서 랜덤 값을 뽑을 때 사용한다. 매개변수를 해시 값으로 변경해준다.
// SHA-3을 사용한다.
// block
// abi.encodePacked : 매개변수로 전달 된 내용들을 가지고 바이트 배열로 만들어준다.
random = uint256(keccak256(abi.encodePacked(block.timestamp, block.coinbase, block.number)));
// 큰 숫자가 나오는데, 이 숫자를 가지고 나머지 연산을 통해 원하는 자릿수의 숫자를 구하자
// 100 ~ 999 까지의 범위를 지정할 예정이다.
random = (random % 900) + 100;
// 100 ~ 999 까지의 랜덤 값
}
// 유저의 값을 받아서 비교를 통해 값이 맞는지 게임의 정답을 맞췄는지 구할 함수
function gameStart(uint256 _value) public payable {
require(progress < GAME_COUNT, "GameOver"); // 게임의 진행도가 정해진 라운드를 지났는지
require(msg.value == ticket, "ticket amount error (5 ether)" ); // 지불한 금액이 티켓 금액과 동일한지 확인
require((_value >= 100) && (_value < 1000), "_value error (99 < _value < 1000)"); // 입력한 값이 100~999의 값인지 확인
progress += 1;
if(_value == random){ // 정답을 맞췄으면
// 게임 끝
// this.balance : 게임 CA에 잔액을 가리킨다.
require(reward <= address(this).balance); // CA의 잔액이 보상만큼 있는지 검사
payable(msg.sender).transfer(address(this).balance);
reward = 0;
// gameStatus 상태가 상수값 1로 들어감
// 1은 게임이 끝났다는 얘기이다.
gameStatus = GameStatus.GameOver;
}
else if(progress == GAME_COUNT){
// 게임 끝
// this.balance : 게임 CA에 잔액을 가리킨다.
require(reward <= address(this).balance); // CA의 잔액이 보상만큼 있는지 검사
payable(owner).transfer(address(this).balance);
reward = 0;
// gameStatus 상태가 상수값 1로 들어감
// 1은 게임이 끝났다는 얘기이다.
gameStatus = GameStatus.GameOver;
}
else{
reward += msg.value;
}
}
// 지금 현재 쌓인 보상을 보여줄 함수
function getReward()public view returns(uint256){
return reward;
}
// 게임이 얼마나 진행됐는지 보여줄 함수
function getProgress() public view returns(uint256){
return progress;
}
// 티켓의 금액을 보여줄 함수
function getTicketPrice() public view returns(uint256){
return ticket;
}
// 어드민 모드로 정답을 확인하는 함수
function getRandom() public view returns(uint256){
require(msg.sender == owner, "only admin");
return random;
// return msg.sender;
}
// 게임 중인지 확인할 함수
function getPlaying() public view returns(uint256){
// 메모리 영역 변수. 지역변수로 생각하면 된다.
// 게임이 진행되고 있는 상수값이 0
uint256 Playing = 0;
if((gameStatus != GameStatus.Playing) || (progress == GAME_COUNT)){
// 게임이 끝났다.
Playing = 1;
}
return Playing;
}
// 게임을 재시작하는 함수
function setRestart() public {
gameStatus = GameStatus.Playing;
reward = 0;
progress = 0;
}
}
728x90