CryptoZombies - Lesson1

학미새🐥·2022년 7월 25일
0

CryptoZombies

목록 보기
1/1
post-custom-banner

Chapter 2 : 뼈대

Version Pragma

  • 해당 코드가 이용해야 하는 솔리디티 버전 선언
  • 컴파일 버전이 업데이트 되어도 코드가 깨지지 않도록
pragma solidity ^0.x.x;
contract Title {

}

<실습>

1.우측 박스에 우리 컨트랙트가 솔리디티 버전 0.4.19를 쓸 수 있도록 설정한다.
2.ZombieFactory라는 빈 컨트랙트를 생성한다.

pragma solidity ^0.4.19;

contract ZombieFactory {
    
}

Chapter 3 : 상태변수 & 정수

상태변수

  • 컨트랙트 저장소(이더리움 블록체인)에 영구적으로 저장됨
  • DB에 데이터 삽입하는 것과 동일
  • uint : unsigned integer. 부호없는 정수타입. (음수 X)
  • int : signed integer. 부호있는 정수타입.

dnaDigits라는 uint를 선언하고 16이라는 값을 배정해 보게.

pragma solidity ^0.4.19;

contract ZombieFactory {
    uint dnaDigits = 16;
}

Chapter 4 : 수학 연산

  • 덧셈 : +
  • 뺄셈 : -
  • 곱셈 : *
  • 나눗셈 : /
  • 모듈로 : %
  • 지수 : **

dnaModulus라는 uint형 변수를 생성하고 10의 dnaDigits승을 배정한다.

pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

}

Chapter 5 : 구조체

  • 복잡한 자료형 생성 가능

1.Zombie라는 struct를 생성한다.
2.우리의 Zombie 구조체는 name (string형)과 dna (uint형)이라는 2가지 특성을 가진다.

pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

}

Chapter 6 : 배열

  • 정적 배열 & 동적 배열
  • 정적 배열 : uint[n] Array;
    • 고정 길이의 배열
  • 동적 배열 : uint[] Array;
    • 고정된 길이가 없는 배열

public 배열

uint[] public Array;

  • public 배열을 위한 getter 메소드가 자동으로 생성됨
  • 다른 컨트랙트가 해당 배열을 읽을 수 있음 -> 공개 데이터 저장

Zombie 구조체의 public 배열을 생성하고 이름을 zombies로 한다.

pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

    Zombie[] public zombies;
}

Chapter 7 : 함수 선언

function 함수명(타입 인자명, 타입 인자명) {

}
  • 함수 인자명을 _로 시작하면 전역 변수와 구별한다는 의미
    ex) _name, _amount

createZombie라는 함수를 생성한다. 이 함수는 다음 2개의 인자를 전달받아야 한다. _name (string형)과_dna (uint형).

pragma solidity ^0.4.19;

contract ZombieFactory {

    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

    Zombie[] public zombies;

    function createZombie(string _name, uint _dna) {

    }
}

Chapter 8 : 구조체와 배열 활용

새로운 구조체 생성

  • 구조체 Person의 요소가 두개 일때

  • 구조체 Person을 가지는 배열 people

  • 구조체 생성하여 변수에 넣기 : Person 변수명 = Person(값, 값);

  • 생성한 구조체를 배열에 추가 : people.push(변수명);
    -> people.push(Person(값, 값));

  • push : 배열의 끝에 요소 삽입

1.함수에 코드를 넣어 새로운 Zombie를 생성하여 zombies 배열에 추가하도록 한다. 새로운 좀비를 위한 name과 dna는 createZombie함수의 인자값이어야 한다.
2.코드를 한 줄로 간결하게 작성해 보자.

function createZombie(string _name, uint _dna) {
        zombies.push(Zombie(_name, _dna));
}

Chapter 9 : Private/Public 함수

  • default 함수 : public (모든 컨트랙트가 해당 컨트랙트의 해당 함수 호출 가능)
  • private 함수 선언 방법 : function 함수명(타입 인자명) private { }
    • 함수 정의문 맨 뒤에 private 넣기
  • private 함수명언더바로 시작하는 관례

🔊 Solidity는 private한 변수, 함수 이름 앞에 _를 붙이는 관례가 있다!!

createZombie 함수를 변경하여 private 함수로 만든다. 함수명에 대한 관례를 잊지 말 것!

function _createZombie(string _name, uint _dna) private {
        zombies.push(Zombie(_name, _dna));
 }

Chapter 10 : 함수 더 알아보기

반환값

  • 반환값의 타입을 함수 정의문 맨 마지막 (private보다 더 뒤)에 returns (타입) 으로 추가
  • 함수 내부에서 return 반환할 변수명;

함수 제어자

  • view 함수
    • 어떤 값을 변경하지 않고 데이터에 접근만 하는 솔리디티 함수
    • function 함수명() public view returns (리턴타입) {}
  • pure 함수
    • 어떠한 데이터에도 접근조차 하지 않는 함수
    • 오로지 함수가 받은 인자값에 따라 반환값이 달라지는 함수
    • function 함수명(타입 인자명) private pure returns (타입) {}

1._generateRandomDna라는 private 함수를 만드시게. 이 함수는 _str (string형)을 인자로 전달받고, uint을 반환해야 하네.
2.이 함수는 컨트랙트 변수를 보지만 변경하지는 않을 것이므로 view로 선언하게.
3.이 함수의 내용은 현재로서는 비어 있는 상태로 냅두시게. 나중에 채울 것이네.

function _generateRandomDna(string _str) private view returns (uint) {

}

Chapter11 : Keccak256과 형변환

  • keccak256 : SHA3의 버전. 이더리움이 가지는 내장 해시 함수
    • 입력된 스트링을 랜덤 256비트 16진수로 매핑
    • 한글자만 달라져도 아예 다른 숫자가 나옴

형변환

  • 새타입(변환할변수명)
  1. 코드 첫 줄에서는 _str을 이용한 keccak256 해시값을 받아서 의사 난수 16진수를 생성하고 이를 uint로 형 변환한 다음, rand라는 uint에 결과값을 저장해야 한다.
  2. 우리는 좀비의 DNA가 16자리 숫자이기만을 원하므로(dnaModulus를 기억하나?) 코드의 두번째 줄에서는 위의 결과 값을 모듈로(%) dnaModulus로 연산한 값을 반환해야 한다. (형식: return 위의 결과 값 % dnaModulus).
function _generateRandomDna(string _str) private view returns (uint) {
        uint rand = uint(keccak256(_str));
        return rand % dnaModulus;
}

Chapter 12 : 종합

  1. createRandomZombie라는 public함수를 생성한다. 이 함수는 _name이라는 string형 인자를 하나 전달받는다. (참고: 함수를 private로 선언한 것과 마찬가지로 함수를 public로 생성할 것)
    2.이 함수의 첫 줄에서는 _name을 전달받은 _generateRandomDna 함수를 호출하고, 이 함수의 반환값을 randDna라는 uint형 변수에 저장해야 한다.
    3.두번째 줄에서는 _createZombie 함수를 호출하고 이 함수에 _name와 randDna를 전달해야 한다.
    4.함수의 내용을 닫는 }를 포함해서 코드가 4줄이어야 한다.
function createRandomZombie (string _name) public {
       uint randDna = _generateRandomDna(_name);
       _createZombie(_name, randDna);
   }

Chapter 13 : 이벤트

  • App에서 사용자가 액션을 취했을 때 반응하는 법
  • 이벤트 선언 : `event 이벤트명(인자, 인자, 인자);
  • 이벤트 실행 : 함수 내부에서 이벤트를 실행하여 앱에게 해당 함수가 실행되었음을 알림

1.NewZombie라는 event를 선언한다. zombieId (uint형), name (string형), dna (uint형)을 인자로 전달받아야 한다.
2._createZombie 함수를 변경하여 새로운 좀비가 zombies 배열에 추가된 후에 NewZombie 이벤트를 실행하도록 한다.
3.이벤트를 위해 좀비의 id가 필요할 것이다. array.push()는 배열의 새로운 길이를 uint형으로 반환한다. 배열의 첫 원소가 0이라는 인덱스를 갖기 때문에, array.push() - 1은 막 추가된 좀비의 인덱스가 될 것이다. zombies.push() - 1의 결과값을 uint형인 id로 저장하고 이를 다음 줄에서 NewZombie 이벤트를 위해 활용한다.

    event NewZombie(uint zombieId, string name, uint dna);

    function _createZombie(string _name, uint _dna) private {
         uint id = zombies.push(Zombie(_name, _dna)) - 1; 
		//array.push()는 배열의 새 길이를 uint형으로 반환함
        NewZombie(id, _name, _dna);
    }

Chapter14 : Web3.js

  • 완성된 컨트랙트와 상호작용하는 App의 js 코드 작성하기
  • Web3.js : 이더리움의 자바스크립트 라이브러리
    // 여기에 우리가 만든 컨트랙트에 접근하는 방법을 제시한다:
    var abi = /* abi generated by the compiler */
    var ZombieFactoryContract = web3.eth.contract(abi)
    var contractAddress = /* our contract address on Ethereum after deploying */
    var ZombieFactory = ZombieFactoryContract.at(contractAddress)
    // `ZombieFactory`는 우리 컨트랙트의 public 함수와 이벤트에 접근할 수 있다.
    // 일종의 이벤트 리스너가 텍스트 입력값을 취한다:
    $("#ourButton").click(function(e) {
      var name = $("#nameInput").val()
      // 우리 컨트랙트의 `createRandomZombie`함수를 호출한다:
      ZombieFactory.createRandomZombie(name)
    })
    // `NewZombie` 이벤트가 발생하면 사용자 인터페이스를 업데이트한다
    var event = ZombieFactory.NewZombie(function(error, result) {
      if (error) return
      generateZombie(result.zombieId, result.name, result.dna)
    })
    // 좀비 DNA 값을 받아서 이미지를 업데이트한다
    function generateZombie(id, name, dna) {
      let dnaStr = String(dna)
      // DNA 값이 16자리 수보다 작은 경우 앞 자리를 0으로 채운다
      while (dnaStr.length < 16)
        dnaStr = "0" + dnaStr
      let zombieDetails = {
        // 첫 2자리는 머리의 타입을 결정한다. 머리 타입에는 7가지가 있다. 그래서 모듈로(%) 7 연산을 하여
        // 0에서 6 중 하나의 값을 얻고 여기에 1을 더해서 1에서 7까지의 숫자를 만든다. 
        // 이를 기초로 "head1.png"에서 "head7.png" 중 하나의 이미지를 불러온다:
        headChoice: dnaStr.substring(0, 2) % 7 + 1,
        // 두번째 2자리는 눈 모양을 결정한다. 눈 모양에는 11가지가 있다:
        eyeChoice: dnaStr.substring(2, 4) % 11 + 1,
        // 셔츠 타입에는 6가지가 있다:
        shirtChoice: dnaStr.substring(4, 6) % 6 + 1,
        // 마지막 6자리는 색깔을 결정하며, 360도(degree)까지 지원하는 CSS의 "filter: hue-rotate"를 이용하여 아래와 같이 업데이트된다:
        skinColorChoice: parseInt(dnaStr.substring(6, 8) / 100 * 360),
        eyeColorChoice: parseInt(dnaStr.substring(8, 10) / 100 * 360),
        clothesColorChoice: parseInt(dnaStr.substring(10, 12) / 100 * 360),
        zombieName: name,
        zombieDescription: "A Level 1 CryptoZombie",
      }
      return zombieDetails
    }

😱내 좀비 증명서😱

profile
뭐든 다해보려는 공대생입니다
post-custom-banner

0개의 댓글