크립토 좀비 - 4

Lumi·2021년 11월 25일
0

크립토 좀비

목록 보기
4/7
post-thumbnail

🔥 개념 정리

알고있지만 좀더 반복한다는 의미에서 다시 대략적인 내용을 정리해보자.

🔨 접근제어자

총 4가지로 구성이 된다.

[1] private

반드시 내부의 다른 함수들에서만 호출이 될수 있는 함수를 말한다.
- public함수에서 private함수를 호출해야지 바로 private함수는 호출할 수가 없다.
- 또한 같은 컨트랙트 안에서만 호출이 가능하다.
* 따로 상속받는 곳에서도 사용이 불가능한 함수이다. *

[2] internal

private와 거의 같으며 차이점은 단 한가지이다.
* 상속하는 함수에서도 호출이 가능하다. *

[3] external

오직 컨트랙트 외부에서만 호출이 가능하다.
- 외부의 인자를 받을떄 주로 사용이 된다.
* 외부의 인자를 받는 제어자는 public, external두 경우밖에 없다. *

[4] public

어디서든 사용이 가능한 함수를 말한다.

🔨 상태 제어자

블록체인과 상호작용하는 제어자를 말한다.

  • 대표적으로 view, pure두가지가 있다.
[1] view

함수를 실행해도 어떤 데이터도 변경하지 않는 것을 의미한다.
- 단순히 데이터의 값을 읽어온다.

[2] pure

컨트랙트 내의 어떠한 변수나 함수도 사용하지 않는 것을 말한다.
오로지 외부의 값을 받아서 Return할떄에 사용이 된다.
  • 이 두가지 제어자는 모두 읽어오는 행위만 하기 떄문에 수수료를 소비하지 않는다.

하지만 만약 다른 함수에 의해 내부적으로 호출될 떄에는 수수료가 발생한다.

또한 사용자 정의 제어자에 대해서도 학습을 하였다.

  • modifier을 말한다.

또한가지 매력적인 제어자가 있다.

[1] payable

이더를 받을수 있는 특별한 함수 유형을 말한다.

일반적인 함수는 이더를 받을수가 없다.(즉 금액을 받을수가 없다.)

하지만 payable제어자를 활용하면 이더를 받을수 있게 된다.
- 즉 이 제어자를 통해서 금액을 주고 받을수 있게 되는 것이다.

🔨 금액의 송출금

금액의 송출금을 하는 함수는 다양하게 있다.

일단 기본적으로 금액을 받게되면 그 금액은 모두 컨트랙트에 저장이 된다.

  • 따로 송출 과정이 없다면 금액이 컨트랙트 계좌에 갇히게 된다.

그러기 떄문에 송출하는 함수가 따로 필요하다.

[1] transfer

다른 주소로 금애글 보내는 함수이다.
- 특정 주소로 금액을 전달한다.

[2] this.balance

컨트랙트에 있는 모든 금액을 말한다.
- 즉 100명의 사용자가 1원씩 전송했다면 컨트랙트에는 100원이 존재한고
- this.balance는 100원을 의미하게 될 것이다.

[3] msg.sender

트랜잭션을 발생시킨 사용자를 말한다.
- 만약 함수의 기준치 금액보다 초과해서 금액이 들어오게 된다면 되돌려 주어야 하는데
- 이떄 msg.sender.transfer 을 통해서 되돌려 줄 수가 있다.
* 다른 방식으로 도 활용이 가능하다. *
- msg.sender은 트랜잭션을 발생시키는 사용자를 의미하기 떄문에

이러한 사용방법 및 함수들은 제약이 없다.

다방면에서 활용이 가능하고 다양한 방식으로도 활용이 가능하다.

🔥 코드

코드 수정사항이랑이 너무 많아서... 어떻게 정리를 해야 할지를 모르겠다..ㅠㅠ

일단 이번 시간을 통해 학습한 이론적인 내용은 위에있는 것과 같으며

이번 시간에서는 좀비가 다른 사용자의 좀비를 공격하는 코드를 수행했다.

그러기 위해서 좀비 구조체에 승리,패배 카운트 변수를 추가하였고
이를 활용하여 사용자마다 좀비 승리,패배 카운트를 가지게 만들었다.

코드를 수정한 부분보다는 새롭게 작성한 코드 쪽을 살펴보겠다.

  • 너무 방대하다.. 수정된 코드까지 보기에는

🔨 zombieattack.sol

import "./zombiehelper.sol";

contract ZombieBattle is ZombieHelper {
  uint randNonce = 0;
  uint attackVictoryProbability = 70;

  function randMod(uint _modulus) internal returns(uint) {
    randNonce++;
    return uint(keccak256(now, msg.sender, randNonce)) % _modulus;
  }

  function attack(uint _zombieId, uint _targetId) external ownerOf(_zombieId) {
    Zombie storage myZombie = zombies[_zombieId];
    Zombie storage enemyZombie = zombies[_targetId];
    uint rand = randMod(100);
    if (rand <= attackVictoryProbability) {
      myZombie.winCount++;
      myZombie.level++;
      enemyZombie.lossCount++;
      feedAndMultiply(_zombieId, enemyZombie.dna, "zombie");
    } else {
      myZombie.lossCount++;
      enemyZombie.winCount++;
    }
    _triggerCooldown(myZombie);
  }
}

- 다른 컨트랙트에 존재하는 제어자
modifier ownerOf(uint _zombieId) {
    require(msg.sender == zombieToOwner[_zombieId]);
    _;
 }

randMod

이 함수는 랜덤한 난수를 생성하는 함수이다.

attack

일단 임의의 ownerOf라는 제어자를 받게 된다.

  • 이 제어자는 이 컨트랙트에 없다.
  • 다른 컨트랙트에 있으며 이를 import하기 떄문에 사용가능한 것이다.

그후 나의 좀비와 상대방의 좀비를 찾아낸다

  • Zombie는 블록체인상에 저장이 되어 있기 떄문에 storage로 꺼내와야 한다.

그후 랜덤한 값을 받고

  • 이 랜덤한 값은 0~99까지의 값중 하나이다.

그 값이 변수값인 70보다 크면 공격에 성공한 것이다.

만약 그 난수값이 70보다 크게되면 공격에 실패한것이고, 작으면 공격에 성공한 것이다.

그러면 상태를 변경해주고 feedAndMultiply를 실행한다.

이러면 상대방 좀비의 dna값과 나의 dna값을 합쳐서 새로운 좀비가 탄생하게 된다.

이후 좀비의 공격쿨타임을 초기화 해주면 된다.

  • 졌을떄는 단순히 카운트만 증가하지 따로 레벨이 다운되는 과정은 없다.

🔥 후기

코드를 중간중간 수정해가고, 반복되는 작업을 따로 정의 제어자로 만들어서 수정하다보니

전체적으로 코드를 다시 리뷰하기가 힘들어진것 같다..

슬슬 연관관계도 복잡하게 엮이고 있다보니 모든것을 리뷰할수는 없고,, 이후에는 새로배운 개념이나 이론

또는 코드 작성한 부분에 대해서만 다룰듯 싶다

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

0개의 댓글