Lottery DApp 개발 Lottery React웹 프론트[3]
web3js - filter
Bet함수 사용 후 큐에 저장된 베팅 정보를 해결하는 Distribute함수를 설계 해보자
function distribute() public {
// head 부터 tail 까지 도는 loop
uint256 cur;
BetInfo memory b;
for(cur = _head; cur < _tail; cur++){
b = _bets[cur];
//현재 블록과 결과확인 블록의 hash가 같을 경우 = win
//현재 블록과 결과확인 블록의 hash가 한 글자만 같을 경우 = draw
//현재 블록과 결과확인 블록의 hash가 다를 경우 = fail
}
이 때, 베팅한 hash와 +3 블럭의 hash가 같은지 비교해주는 함수를 따로 작성해준다.
isMatch함수를 구현해 보면
/**
* @dev 베팅글자와 정답을 확인
* @param challenges 베팅 글자
* @param answer 블럭해쉬
* @return 정답결과
*/
function isMatch(byte challenges, bytes32 answer) public pure returns(BettingResult){
//challenges 0xab, answer 0xab....... 32bytes
byte c1 = challenges;
byte c2 = challenges;
byte a1 = answer[0];
byte a2 = answer[0];
c1 = c1 >> 4;
c1 = c1 << 4;
a1 = a1 >> 4;
a1 = a1 << 4;
c2 = c2 << 4;
c2 = c2 >> 4;
a2 = a2 << 4;
a2 = a2 >> 4;
if(a1 == c1 && a2 == c2)
return BettingResult.win;
if(a1 == c1 || a2 == c2)
return BettingResult.draw;
return BettingResult.fail;
}
shift를 이용해서 값을 한 비트씩 비교해준다.
0xab » 4 = 0x0a / 0x0a « 4 = 0xa0
isMatch 함수의 리턴 값은 BettingResult 로 해주었으니 변수를 선언해 준다.
enum BettingResult {fail, win, draw}
fail부터 0, win은 1, draw는 2로 인식하게 된다.
잘 기억해 두자 test할 때 비교값으로 넣어준다
또 필요한 함수가 뭐가 있을까 생각해보자
현재 블록의 상태를 구해서 에러가 나는 상황인지 체크해주는 함수가 필요하다.
function getBlockStatus(uint256 answerBlockNumber) internal view returns(BlockStatus) {
if(block.number > answerBlockNumber && block.number < BLOCK_LIMIT + answerBlockNumber){
return BlockStatus.Checkable;
}
if(block.number <= answerBlockNumber){
return BlockStatus.NotRevealed;
}
if(block.number >= answerBlockNumber + BLOCK_LIMIT){
return BlockStatus.BlockLimitPassed;
}
return BlockStatus.BlockLimitPassed;
}
여기서 return값이 BlockStatus이므로 변수로 선언해준다.
enum BlockStatus {Checkable, NotRevealed, BlockLimitPassed}
checkable은 매핑이 완료 되 답 비교가 가능한 것을 나타내고 notrevealed는 현재 블럭이 베팅을 건 블럭보다 앞에 있으면 매핑이 안되 답을 확인할 수 없는 것을 나타내고, BlockLimitPassed는 limit를 넘겼을 때 답을 구할 수 없는 것을 나타내는 것이다.
지금까지 작성한 함수를 이용해 distribute함수를 작성해보자!
function distribute() public {
// head 부터 tail 까지 도는 loop
uint256 cur;
BetInfo memory b;
BlockStatus currentBlockStatus;
for(cur = _head; cur < _tail; cur++){
b = _bets[cur];
currentBlockStatus = getBlockStatus(b.answerBlockNumber);
if(currentBlockStatus == BlockStatus.Checkable){
//win bettor gets pot
//fail bettor's momey goes pot
//하나만 맞췄을 경우 refund bettor's money
}
if(currentBlockStatus == BlockStatus.NotRevealed){
break;
}
if(currentBlockStatus == BlockStatus.BlockLimitPassed){
}
popBet(cur);
}
}
lotery.test.js 파일에
describe.only('isMatch', function (){
let blockHash ='0xab66ec4675534645e7f83e0c9d369356db51a012a0746e2f0e82df38a345b38b'
it('should be BettingResult.win when two characters match', async () =>{
let matchingResult = await lotery.isMatch('0xab', blockHash);
assert.equal(matchingResult, 1);
})
it('should be BettingResult.draw when two characters match', async () =>{
let matchingResult = await lotery.isMatch('0xac', blockHash);
assert.equal(matchingResult, 2);
})
it('should be BettingResult.fail when two characters match', async () =>{
let matchingResult = await lotery.isMatch('0xcd', blockHash);
assert.equal(matchingResult, 0);
})
});
이 때 Blockhash값은 web3.eth.getBlock(0) 해서 아무값이나 넣어주었다.
처음에 이곳에서 오류가 낫었다
이유는 BettingResult를 선언해 줄 때 win, fail, draw 순으로 선언 해 주고는 강의 그대로 따라해서 넣었더니
당연이 일치하지 않으므로 에러가 났었다. 그래서 고쳐 준 후 isMatch 함수 return 부분을 다시 입력해주고
truffle test test/lotery.test.js를 실행하니
web3js - filter
web3js - send & call
React js 환경 설정
Distribute 함수설계 & 테스트
Distribute 함수설계 & isMath함수 구현 및 테스트
Bet 함수 구현&테스트
Bet 함수 구현&테스트
Lotery domain과 queue설계
Lotery 를 테스트할 테스트 파일을 test폴더 안에 만들어준다.
왜 제목이 안보이지; 너무어렵다 블로긍 ㅠㅡㅜ 다들 맥으로 설명해오앵애ㅐㅐㅐㅐㅐㅐㅐㅐㅐㅐ