본문 바로가기

Language/Solidity

CryptoZombies ; Lesson 1-2 - 핵심내용정리

챕터 8 ; 구조체와 배열의 활용


- 구조체를 통해 새로운 객체(?)를 생성하고 Public 배열에 추가하는 방법

- 예시

struct Person {
uint age;
string name;
}

Person[] public people;
//이제 새로운 Person를 생성하고 people 배열에 추가하는 방법을 살펴보도록 하지.

// 새로운 사람을 생성한다:
Person satoshi = Person(172, "Satoshi");

// 이 사람을 배열에 추가한다:
people.push(satoshi);

//이 두 코드를 조합하여 깔끔하게 한 줄로 표현할 수 있네:
people.push(Person(16, "Vitalik"));


- array.push() : 배열의 끝에 순서대로/차례대로 추가.


pragma solidity ^0.4.19;

contract ZombieFactory {
uint dnaDigits = 16; // 이 변수는 블록체인에 영구 저장됨.
uint dnaModulus = 10 ** dnaDigits; // 좀비 DNA가 16자리 숫자가 되기 위한 또 다른 변수. 나중에 %를 이용하여 16자리로 줄일 수 있음

struct Zombie { // 구조체 선언
string name;
uint dna;
}

Zombie[] public zombies; // Public 구조체 배열 선언

function createZombie(string _name, uint _dna){ //좀비를 만드는 함수 선언
zombies.push(Zombie(_name, _dna)); // 새로운 좀비를 만든 후 Public 배열에 추가
}
}





챕터 9 ; Private / Public 함수


- 솔리디티 함수


- 기본적으로 public 으로 선언 = 누구나 혹은 다른 컨트랙트가 내 컨트랙트의 함수를 호출하고 코드를 실행할 수 있음

- 습관들이기 : 우선 private로 선언 (공개할 함수만 public으로 선언)

- private 함수 : 해당 컨트랙트 내(동일한 파일)의 다른 함수들만이 이 함수를 호출 가능

- private 함수 선언 : 함수명 앞에 언더바 ( _ ) 관례

- 형태 

uint[] numbers;

function _addToArray(uint _number) private {
numbers.push(_number);
}


pragma solidity ^0.4.19;

contract ZombieFactory {
uint dnaDigits = 16; // 이 변수는 블록체인에 영구 저장됨.
uint dnaModulus = 10 ** dnaDigits; // 좀비 DNA가 16자리 숫자가 되기 위한 또 다른 변수. 나중에 %를 이용하여 16자리로 줄일 수 있음

struct Zombie { // 구조체 선언
string name;
uint dna;
}

Zombie[] public zombies; // Public 구조체 배열 선언

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




챕터 10 ; 함수 더 알아보기


- 반환값

- 형태 : 솔리디티에서 함수 선언은 반환값 종류를 포함함. (아래 함수는 string을 반환하는 함수)

string greeting = "What's up dog";

function sayHello() public returns (string) {
return greeting;
}


- 함수 제어자

- view 함수 : 상태를 변화시키지 않는 함수 = 어떤 값을 변경하거나 무언가를 쓰지 않는 함수

   : 함수를 보기만 하고 변경하지 않는다는 뜻 (읽기전용함수)

   : 수수료(가스)를 소모하지 않기 때문에 데이터를 저장하는 함수에는 무조건 view 키워드 사용

   : 보통 발행된 전체 토큰의 개수를 알고 싶을 때 사용

function sayHello() public view returns (string) {


- pure 함수 : 앱에서 어떤 데이터도 접근하지 않는다는 뜻 = 앱에서 쓰지도 읽지도 않음

   : 블록체인 데이터와 무관한 함수임을 명시하는 키워드

   : 반환값이 함수에 전달된 인자값에 따라 달라질 뿐


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


- 어느 것을 써야 할지 모르겠다구? 컴파일러가 경고메세지를 통해 알려주니 걱정하지 말자.

pragma solidity ^0.4.19;

contract ZombieFactory {
uint dnaDigits = 16; // 이 변수는 블록체인에 영구 저장됨.
uint dnaModulus = 10 ** dnaDigits; // 좀비 DNA가 16자리 숫자가 되기 위한 또 다른 변수. 나중에 %를 이용하여 16자리로 줄일 수 있음

struct Zombie { // 구조체 선언
string name;
uint dna;
}

Zombie[] public zombies; // Public 구조체 배열 선언

function _createZombie(string _name, uint _dna) private { //좀비를 만드는 함수 선언
zombies.push(Zombie(_name, _dna)); // 새로운 좀비를 만든 후 Public 배열에 추가
}

function _generateRandomDna(string _str) private view returns (uint) {
//스트링으로부터 랜덤 DNA 숫자를 생성하는 도우미 함수
}
}




챕터 11 ; Keccak256과 형변환


- Keccak256

- SHA3의 한 버전

- 이더리움 내장 해시 함수

- 해시함수 : 기본적으로 입력 스트링을 랜덤 256비트 16진수로 매핑. (스트링의 작은 변화에도 해시 값이 크게 달라짐)

//6e91ec6b618bb462a4a6ee5aa2cb0e9cf30f7a052bb467b0ba58b8748c00d2e5
keccak256("aaaab");
//b1f078126895a1424524de5321b339ab00408010b7cf0e6ed451514981e58aa9
keccak256("aaaac");

- 용도 : 의사 난수 발생기 등

- 블록체인에서 안전한 의사 난수 발생기는 매우 어려운 문제이니. 심혈을 기울여야 함.


- 형변환

uint8 a = 5;
uint b = 6;
// a * b가 uint8이 아닌 uint를 반환하기 때문에 에러 메시지가 난다:
uint8 c = a * b;
// b를 uint8으로 형 변환해서 코드가 제대로 작동하도록 해야 한다:
uint8 c = a * uint8(b);


pragma solidity ^0.4.19;

contract ZombieFactory {
uint dnaDigits = 16; // 이 변수는 블록체인에 영구 저장됨.
uint dnaModulus = 10 ** dnaDigits; // 좀비 DNA가 16자리 숫자가 되기 위한 또 다른 변수. 나중에 %를 이용하여 16자리로 줄일 수 있음

struct Zombie { // 구조체 선언
string name;
uint dna;
}

Zombie[] public zombies; // Public 구조체 배열 선언

function _createZombie(string _name, uint _dna) private { //좀비를 만드는 함수 선언
zombies.push(Zombie(_name, _dna)); // 새로운 좀비를 만든 후 Public 배열에 추가
}

function _generateRandomDna(string _str) private view returns (uint) {
//스트링으로부터 랜덤 DNA 숫자를 생성하는 "도우미" 함수
uint rand = uint(keccak256(_str));
return rand % dnaModulus; // DNA가 16자리 숫자이기만을 원한 연산값 반환
}
}





챕터 12 ; Lesson 1 종합


- 랜덤 좀비 생성기 만들기


pragma solidity ^0.4.19;

contract ZombieFactory {
uint dnaDigits = 16; // 이 변수는 블록체인에 영구 저장됨.
uint dnaModulus = 10 ** dnaDigits; // 좀비 DNA가 16자리 숫자가 되기 위한 또 다른 변수. 나중에 %를 이용하여 16자리로 줄일 수 있음

struct Zombie { // 구조체 선언
string name;
uint dna;
}

Zombie[] public zombies; // Public 구조체 배열 선언

function _createZombie(string _name, uint _dna) private {//좀비를 만드는 함수 선언
zombies.push(Zombie(_name, _dna)); // 새로운 좀비를 만든 후 Public 배열에 추가
}

function _generateRandomDna(string _str) private view returns (uint) {
//스트링으로부터 랜덤 DNA 숫자를 생성하는 "도우미" 함수
uint rand = uint(keccak256(_str));
return rand % dnaModulus; // DNA가 16자리 숫자이기만을 원한 연산값 반환
}

function createRandomZombie(string _name) public {
uint randDna = _generateRandomDna(_name); // DNA 랜덤 생성
_createZombie(_name, randDna); // 생성한 DNA와 이름으로 좀비 생성하여 Public 배열에 추가
}
}




챕터 13 ; 이벤트


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

- 이벤트 선언과 실행 예시

// 이벤트를 선언한다
event IntegersAdded(uint x, uint y, uint result);

function add(uint _x, uint _y) public {
uint result = _x + _y;
// 이벤트를 실행하여 앱에게 add 함수가 실행되었음을 알린다:
IntegersAdded(_x, _y, result);
return result;
}

- 이를 사용자 단에서 해당 이벤트가 일어났는지 확인 ( 예시, 자바스크립트 )

YourContract.IntegersAdded(function(error, result) {
// 결과와 관련된 행동을 취한다
}


pragma solidity ^0.4.19;

contract ZombieFactory {

//좀비가 생성될 때마다 앱의 사용자 단에서 인지하고 이를 표시하는 이벤트 선언
event NewZombie(uint zombieId, string name, uint dna);

uint dnaDigits = 16; // 이 변수는 블록체인에 영구 저장됨.
uint dnaModulus = 10 ** dnaDigits; // 좀비 DNA가 16자리 숫자가 되기 위한 또 다른 변수. 나중에 %를 이용하여 16자리로 줄일 수 있음

struct Zombie { // 구조체 선언
string name;
uint dna;
}

Zombie[] public zombies; // Public 구조체 배열 선언

function _createZombie(string _name, uint _dna) private {//좀비를 만드는 함수 선언
//zombies.push(Zombie(_name, _dna)); // 새로운 좀비를 만든 후 Public 배열에 추가
uint id = zombies.push(Zombie(_name, _dna)) - 1; // 새로운 좀비를 만든 후 배열에 추가하면서 id 값 계산
NewZombie(id, _name, _dna);//좀비가 생성됐을 때 이벤트를 실행하여 앱의 사용자단에 알림
}

function _generateRandomDna(string _str) private view returns (uint) {
//스트링으로부터 랜덤 DNA 숫자를 생성하는 "도우미" 함수
uint rand = uint(keccak256(_str));
return rand % dnaModulus; // DNA가 16자리 숫자이기만을 원한 연산값 반환
}

function createRandomZombie(string _name) public {
uint randDna = _generateRandomDna(_name); // DNA 랜덤 생성
_createZombie(_name, randDna); // 생성한 DNA와 이름으로 좀비 생성하여 Public 배열에 추가
}
}




챕터 14 : 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
}



'Language > Solidity' 카테고리의 다른 글

CryptoZombies ; Lesson 1-1 - 핵심내용정리  (0) 2018.06.20