1. 개요
블록체인은 기존 중앙 시스템과 달리 분산 원장을 가진다는 장점을 가지고있다. 이 장점을 이용하면 데이터가 여러사람에 의해 무결성을 검증받을 수 있다는 점이다.
블록체인 기술로 만들어진 이더리움은 블록체인이 가진 장점에 더해 스마트 컨트랙트를 작성할 수 있게 되었다.
이번 튜토리얼은 로또 스마트컨트랙트를 만들어 보는 내용이다.
위 그림은 로또 dApp의 전체적인 구성도이다. 참여자들은 스마트 컨트랙트를 이용해 일정 금액을 모금하고 모금이 완료되면 컨트랙트 생성을 했던 사람은 당첨자 추첨을 진행합니다.
2. 로또 컨트랙트 작성
pragma solidity ^0.5.10;
contract Lottery {
}
기본적인 컨트랙트를 작성합니다. 필요한 변수는 2가지가 필요합니다.
- 스마트 컨트랙트 생성자
- 로또 참여자 배열
pragma solidity ^0.5.10;
contract Lottery {
address public owner; // 스마트 컨트랙트 생성한 사람
address payable[] public players; // 로또 참여자
// 생성자
constructor() public {
owner = msg.sender;
}
}
constructor() 부분에서는 해당 컨트랙트가 생성시 자동으로 owner 변수에 스마트 컨트랙트를 생성한 사람의 정보가 담깁니다.
이번에는 로또 컨트랙트에 입금하는 함수를 작성해보겠습니다.
function deposit() public payable {
require(msg.sender >= 1 ether, "Minimum value is 1ETH");
players.push(msg.sender);
}
해당 함수에는 ETH를 전송하는 기능을 포함해야하므로 payable을 붙여줍니다.
그리고 최소 입금 금액은 1ether이상만 가능하고 로또 응모자로 등록됩니다.
function generateRandomNumber() public view returns (uint) {
return uint(keccak256(abi.encodePacked(now, block.difficulty, players.length)));
}
해당 함수는 로또 당첨자를 추첨하기 위한 난수 생성함수입니다.
이 부분까지 테스트 하기 위해서 remix에 deploy를 합니다.
deploy를 하면 작성한 함수 2개 그리고 전역변수 2개를 볼 수 있습니다.
먼저 해당 로또 컨트랙트를 deploy한 계정주소를 보겠습니다.
deploy한 주소입니다. 이 후 tutorial에서 설명드리겠지만 해당 계정으로만 로또 당첨자 추첨을 진행할 수 있습니다.
generateRandomNumber함수를 통해 얻은 값입니다. 해당 값은 블록 생성시간, 블록 difficulty, 참여자 수를 이용해 난수를 생성한 값입니다. 추후 (로또 당첨자 추첨시 해당 값 % 로또 참여자 수)를 한 나머지 값이 당첨자가 됩니다.
이제 4개의 계정을 이용해 1ETH씩 deposit을 한 후 players 변수 값을 확인해보겠습니다.
총 4명의 참여자가 players 배열변수에 등록되있는 것을 확인해볼 수 있습니다.
마지막으로 로또 추첨을 하는 함수를 작성해보겠습니다.
그 전에 개요부분에서 로또 컨트랙트에서 로또 당첨자 추첨은 스마트컨트랙트 deploy한 계정만 동작시킬 수 있다고 정의하였습니다.
해당 부분을 구현하기 위해서는 solidity 문법에서 modifier을 사용해야합니다.
modifier OwnerOnly {
if (msg.sender == owner) {
_;
}
}
트랜잭션을 발생하는 계정이 스마트 컨트랙트가 deploy한 계정일 때만 함수가 호출되게 하는 modifier이다.
function pickWinner() OwnerOnly public {
uint randNum = generateRandomNumber(); // 난수 생성
uint idx = randNum % players.length; // 당첨자 index
address payable winner; // 당첨자 address
winner = players[idx];
winner.transfer(address(this).balance); // 당첨자 address로 모금액 전송
players = new address payable [](0); // players 배열 초기화
}
해당 함수를 구현 후 pickWinner을 호출하면 로또 당첨금액이 당첨자에게 입금되는 스마트컨트랙트를 만들 수 있다.
전체 코드 : https://gist.github.com/dongw00/ed5ef601b85381ec093042aa158d03a3#file-lottery-sol
'블록체인 > 이더리움' 카테고리의 다른 글
[이더리움 dApp] 이더리움으로 간단한 상품관리 dApp 만들기 (8) | 2019.05.09 |
---|---|
[이더리움]Geth를 이용해 multi node Private network 구성하기 (1) | 2018.12.09 |
[이더리움]Genesis json이 무엇인가 (0) | 2018.12.01 |
댓글