본문 바로가기

블록체인 관련 공부

Solidity - CryptoZombies (Beginner) [Lesson 1]

 

ch.1 좀비 DNA 만들기

내가 디자인한 좀비 (5 7 2 235 269 163)

 

ch.2 컨트랙트

pragma solidity ^0.4.19 //1. 여기에 솔리디티 버전 적기

contract ZombieFactory { //2. 여기에 컨트랙트 생성

}

- 컨트랙트는 이더리움 애플리케이션의 기본적인 구성 요소로, 솔리디티 코드는 컨트랙트 안에 싸여 있다. (= 모든 변수와 함수는 어느 한 컨트랙트에 속함.)

- 컨트랙트는 모든 프로젝트의 시작 지점

 

 

ch.3 상태 변수 & 정수

uint dnaDigits = 16;

- uint 자료형은 부호 없는 정수


* 솔리디티에서 uint는 실제로 uint256, 즉 256비트 부호 없는 정수의 다른 표현이지. uint8, uint16, uint32 등과 같이 uint를 더 적은 비트로 선언할 수도 있음

 

 

ch.4 수학 연산

uint dnaModulus = 10**dnaDigits;

덧셈: x + y
뺄셈: x - y,
곱셈: x * y
나눗셈: x / y
Modulus(나머지): x % y 

* 솔리디티는 지수 연산도 지원함

uint x = 5 ** 2; // 즉, 5^2 = 25

 

 

ch.5 구조체

 

struct Zombie {
    string name;
    uint dna;
}

 

 

ch.6 배열

Zombie[] public zombies;

* public 배열 : 다른 컨트랙트들이 이 배열을 읽을 수 있지만 쓸 수는 없음. 컨트랙트에 공개 데이터를 저장할 때 유용한 패턴 (getter 메소드를 자동으로 생성)

 

 

ch.7 함수 선언

function createZombie(string _name, uint _dna){
        
}

* 함수 인자명을 언더스코어(_)로 시작해서 전역 변수와 구별하는 것이 관례

 

 

ch.8 구조체와 배열 활용하기

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

 

 

ch.9 Private/Public 함수

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

- 솔리디티에서 함수는 기본적으로 public으로 선언. 즉, 누구나 (혹은 다른 어느 컨트랙트가) 자네 컨트랙트의 함수를 호출하고 코드를 실행할 수 있음.
  > 항상 바람직한 건 아닐 뿐더러, 컨트랙트를 공격에 취약하게 만들 수 있음.

  > 기본적으로 함수를 private으로 선언하고, 공개할 함수만 public으로 선언

- private : 컨트랙트 내의 다른 함수들만이 이 함수를 호출하여 numbers 배열로 무언가를 추가할 수 있다는 것을 의미


* private 키워드는 함수명 다음에 작성. 함수 인자명과 마찬가지로 private 함수명도 언더바(_)로 시작하는 것이 관례

 

 

ch.10 함수 제어자

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

* 솔리디티는 pure 함수도 가지고 있는데, 이는 함수가 앱에서 어떤 데이터도 접근하지 않는 것을 의미

 

ex)

function _multiply(uint a, uint b) private pure returns (uint) {
  return a * b;
}

 

 

ch.11 Keccak256과 형 변환

function _generateRandomDna(string _str) private view returns (uint) {
        uint rand = uint(keccak256(_str));
        return rand%dnaModulus;
}

* 이더리움은 SHA3의 한 버전인 keccak256를 내장 해시 함수로 가지고 있음. 해시 함수는 기본적으로 입력 스트링을 랜덤 256비트 16진수로 매핑. 스트링에 약간의 변화라도 있으면 해시 값은 크게 달라짐.

 

 

ch.12 종합하기

function createRandomZombie (string _name) public{
        uint randDna = _generateRandomDna(_name);
        _createZombie(_name, randDna);
}

 

 

ch.13 이벤트

pragma solidity ^0.4.19;

contract ZombieFactory {

    // 여기에 이벤트 선언
    event NewZombie(uint zombieId, string name, uint dna);
    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;

    struct Zombie {
        string name;
        uint dna;
    }

    Zombie[] public zombies;

    function _createZombie(string _name, uint _dna) private {
        uint id = zombies.push(Zombie(_name, _dna))-1;
        //이벤트 실행
        NewZombie(id, _name, _dna);
    }

    function _generateRandomDna(string _str) private view returns (uint) {
        uint rand = uint(keccak256(_str));
        return rand % dnaModulus;
    }

    function createRandomZombie(string _name) public {
        uint randDna = _generateRandomDna(_name);
        _createZombie(_name, randDna);
    }

}

- 이벤트는 컨트랙트가 블록체인 상에서 앱의 사용자 단에서 무언가 액션이 발생했을 때 의사소통하는 방법

- 컨트랙트는 특정 이벤트가 일어나는지 "귀를 기울이고" 그 이벤트가 발생하면 행동을 취함.

 

 

ch.14 - Web3.js

*이더리움은 Web3.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
}

 

 

ch.15 완료

dande_lion 좀비

 

 

 

https://share.cryptozombies.io/ko/lesson/1/share/dande_lion?id=Y3p8MTk3Njgz 

 

 

제 크립토좀비 OGURL을/를 확인해 보세요!

제가 방금 전에 크립토좀비 레슨 1을 마쳤어요. 이더리움 게임을 만드는 기본 내용을 배웠어요. 제가 처음 만든 좀비를 한번 보세요!

share.cryptozombies.io