촉촉한초코칩
[Crypto Zombies] Beginner 본문
Ch1
좀비 공장 만들기
- 모든 좀비의 데이터베이스 유지
- 새로운 좀비 생성하는 함수
- 각 좀비는 랜덤하고 독특한 외모를 가진다.
좀비 DNA
- 16자리 정수 형태
- 각 숫자는 좀비가 가진 개별 특성과 매핑된다.
ex) 처음 2자리 : 좀비 머리 타입, 다음 2자리 : 좀비 눈 모양
ex) 8356281040284737
첫 2자리 숫자 : 83 > 머리 타입으로 매핑
* 튜토리얼에는 좀비의 머리 타입이 7개만 존재함
83 % 7 + 1 = 7 > 이 DNA를 가진 좀비는 7번째 좀비 머리 타입을 갖게 됨
Ch2 컨트랙트
* 솔리디티 코드는 컨트랙트 안에 싸여 있다.
* 솔리디티 코드는 version pragma로 시작한다.
컨트랙트
- 이더리움 애플리케이션의 기본적인 구성요소
- 모든 변수와 함수는 어느 한 컨트랙트에 속한다.
contract HelloWorld {
}
Version Pragma
- 해당 코드가 이용해야 하는 솔리디티 버전을 선언하여 이후 새로운 컴파일러 버전이 나와도 기존 코드가 깨지지 않도록 한다.
pragma solidity ^0.4.19;
contract HelloWorld {
}
실습) ZombieFactory라는 기본 컨트랙트 생성하기
pragma solidity ^0.4.19;
contract ZombieFactory {
}
Ch3 상태변수 & 정수
상태변수
- 컨트랙트 저장소(이더리움 블록체인)에 영구적으로 저장된다.
contract Example {
//myUnsignedInteger라는 uint를 생성하여 100이라는 값을 배정한다.
uint myUnsignedInteger = 100;
}
정수
- 부호 없는 정수 : uint 자료형
- 부호 있는 정수 : int 자료형
* 솔리디티에서 uint는 실제로 uint256 (256비트 부호 없는 정수)이다.
* uint256은 uint8, uint16, uint32와 같이 더 적은 비트로 선언 가능하다.
실습) 좀비 DNA는 16자리 숫자로 결정되므로 dnaDigits라는 uint를 선언하여 16이라는 값을 배정한다.
pragma solidity ^0.4.19;
contract ZombieFactory {
uint dnaDigits = 16;
}
Ch4 수학 연산
수학 연산
- 덧셈, 뺼셈, 곱셈, 나눗셈, 모듈로(나머지)
- 지수연산 : **
실습) DNA 16자리 숫자가 되도록 하기 위해 또다른 uint형 변수를 생성하고 10^16 값을 배정한다.
이후 모듈로 연산자 %와 함께 이용하여 16자리보다 큰 수를 16자리 숫자로 줄일 수 있다.
pragma solidity ^0.4.19;
contract ZombieFactory {
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
}
Ch5. 구조체
* String : 임의의 길이를 가진 UTF-8 데이터를 위해 사용한다.
예시
struct Person {
uint age;
string name;
}
실습) 좀비를 생성을 위해 다양한 특성을 가진 구조체를 생성한다.
a. Zombie라는 struct를 생성한다.
b. 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;
}
}
Ch6. 배열
배열
- 종류 : 정적 / 동적
- 상태변수 > 블록체인에 영구적으로 저장
구조체의 동적 배열 생성 > 컨트랙트에 구조화된 데이터 저장하는 데 유용 영구적 저장??인건가?
public 배열
- 솔리디티는 public 배열을 위해 getter 메소드를 자동으로 생성한다.
- public으로 생성하면 다른 컨트랙트들이 배열을 읽을 수 있다. (쓰기는 불가능)
- 컨트랙트에 공개 데이터를 저장할 때 유용하다.
//정적 배열
uint[2] fixedArray;
string[5] stringArray;
//동적 배열 > 크키 변경 가능
uint[] dynamicArray;
//구조체 배열 생성 가능
//동적 배열 > 원소 계속 추가 가능
Person[] people;
//public 배열
Person[] public people;
실습) 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;
}
Ch7. 함수 선언
함수 선언 형식
- 함수 인자명은 _로 시작하여 전역 변수와 구별한다.
function 함수명 (데이터타입 _변수명, uint _amout) {
}
함수 호출
함수병("",100);
실습) 좀비를 생성할 함수를 만든다.
함수명 : createZombie, 2개의 인자를 전달받는다. (string형의 _name, uint형의 _dna)
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) {
}
}
Ch8. 구조체와 배열 활용하기
새로운 구조체 생성하기 (이전에 만든 구조체 Person과 배열 people 사용)
//새로운 Person을 생성하여 people 배열에 추가한다.
Person satoshi = Person(172, "Satoshi");
//배열에 추가한다.
people.push(satoshi);
//한줄로 만들기
people.push(Person(16, "Vitalik"));
배열 추가 : array.push()
- 배열 끝에 추가하여 원소가 순서를 유지하도록 한다.
실습) creatZombie 함수에 새로운 Zombie를 생성하여 zombies 배열에 추가한다.
새로운 좀비를 위한 name과 dna는 createZombie 함수의 인자값이다.
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) {
zombies.push(Zombie(_name, _dna));
}
}
Ch9. Private / Public 함수
* 함수는 기본적으로 public으로 생성된다.
private 함수 생성하는 방법 : 함수인자명과 동일하기 _로 시작한다.
uint[] numbers;
//private는 컨트랙트 내의 다른 함수들만이 이 함수를 호출하여
//numbers 배열로 무언가를 추가할 수 있다는 것을 의미한다.
function _addToArray(uint _number) private {
numbers.push(_number);
}
실습) createZombie를 private으로 변경한다.
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) private {
zombies.push(Zombie(_name, _dna));
}
}
Ch10. 함수 더 알아보기 (반환값, 제어자)
* 솔리디티에서 함수 선언은 반환값 종류를 포함한다.
함수 반환값
string greeting = "What's up dog";
function sayHello() public returns (string) {
return greeting;
}
함수 제어자
- 함수 sayHello()의 경우, 솔리디티 내에서 상태를 변화(값 변경, 무언가 쓰지 않음)시키지 않는다.
- 이 경우 함수를 view 함수로 선언 > 함수가 데이터를 읽기만 하고 변경하지 않음
function sayHello() public view returns (string) {
}
* pure 함수 : 함수가 앱에서 어떤 데이터도 접근하지 않는 것을 의미한다.
//어떤 값도 읽지 않음
function _multiply(uint a, uint b) private pure returns (uint) {
return a * b;
}
실습) 스트링으로부터 랜덤 DNA를 생성할 함수 생성하기
a. _generateRandomDNA라는 private 함수를 생성한다. string형의 _str을 인자로 전달받고 uint을 반환한다.
b. 컨트랙트 변수를 보지만 변경하지는 않으므로 view로 선언한다.
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) private {
zombies.push(Zombie(_name, _dna));
}
function _generateRandomDna(string _str) private view returns(uint) {
}
}
Ch11. Keccak256, 형 변환
_generateRandomDna 함수의 반환값이 (반)랜덤인 uint가 되도록 수정한다.
* 이더리움은 SHA3의 한 버전인 Keccack256을 내장 해시 함수로 가지고 있다.
* 해시 함수는 기본적으로 입력스트링을 랜덤 256비트 16진수로 매핑한다.
(스트링 값 수정되면 해시값도 달라짐)
* 해시 함수는 이더리움에서 여러 용도로 활용되며, 이 문제에서는 의사난수 발생기(pseudo-random number generator)로 이용한다.
예시)
//6e91ec6b618bb462a4a6ee5aa2cb0e9cf30f7a052bb467b0ba58b8748c00d2e5 keccak256("aaaab"); //b1f078126895a1424524de5321b339ab00408010b7cf0e6ed451514981e58aa9 keccak256("aaaac");
형 변환
//a * b가 uint8이 아닌 uint를 반환하기 때문에 에러 메시지가 난다.
uint8 a = 5;
uint b = 6;
uint8 c = a * b;
//b를 uint8으로 형 변환한다.
uint8 c = a * uint8(b);
실습) _generatorRandomDna 함수 수정
a. _str을 이용한 keccak256 해시값을 받아서 의사난수 16진수를 생성하고 이를 uint형으로 변환한다. 변환한 값은 uint형의 rand 결과값에 저장한다.
b. 좀비의 DNA가 16자리 숫자이기를 원하므로 위의 결과 값을 모듈로(%) dnaModulus로 연산한 값을 반환한다.
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) private {
zombies.push(Zombie(_name, _dna));
}
function _generateRandomDna(string _str) private view returns(uint) {
uint rand = uint(keccak256(_str));
return rand % dnaModulus;
}
}
Ch12. 종합하기
실습) 좀비 이름을 입력받아 랜덤 DNA를 가진 좀비를 생성하는 public 함수 생성
a. createRandomZombie라는 public 함수 생성한다. 함수는 string형의 _name을 인자로 전달받는다.
b. _name을 전달받은 _generateRandomDna 함수를 호출하고, 이 함수의 반환값을 uint형의 randDna에 저장한다.
c. _createZombie 함수를 호출하고이 함수에 _name과 randDna를 전달한다.
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) private {
zombies.push(Zombie(_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);
}
}
Ch13. 이벤트
이벤트
- 컨트랙트가 블록체인 상에서 앱의 사용자 단에서 액션이 발생했을 때 의사소통하는 방법이다.
- 컨트랙트는 특정 이벤트가 발생하면 행동을 취해야 한다. > 앱의 사용자 단에서 자바스크립트로 구현
//이벤트 생성
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) {
})
실습) 좀비가 생성될 때마다 앱의 사용자 단에서 이에 대해 알고, 이를 표시하는 이벤트를 생성한다.
a. NewZombie라는 event 생성
ZombieId(uint형), name(string형), dna(uint형)을 인자로 받는다.
b. _createZombie 함수를 변경하여 새로운 좀비가 zombies 배열에 추가된 후에 NewZombie 이벤트를 실행하도록 한다.
c. 이벤트를 위해 좀비의 id가 필요하다.
array.push()는 배열의 새로운 길이를 uint형으로 반환한다.
배열 첫 원소의 인덱스는 0이므로 array.push() - 1은 막 추가된 좀비의 인덱스가 된다.
zombies.push() - 1 의 결과값을 uint형인 id로 저장하고 결과값을 NewZombie 이벤트에 활용한다.
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);
}
}
Ch14. 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
}
자바스크립트 코드가 zombieDetails에서 생성된 값을 받아 웹 브라우저 기반 자바스크립트와 같은 기능(실습에서는 Vue.js 사용)을 활용하여 이미지를 변경하고 CSS 필터를 적용한다.
실습) 이름을 입력하고 어떤 종류의 좀비가 나오는지 확인한다.

Ch15.
https://share.cryptozombies.io/ko/lesson/1/share/%ED%97%AC%EB%A1%9C?id=Y3p8NjE0NjAy
'Study > PBL' 카테고리의 다른 글
Machine Learning 3 (0) | 2024.05.28 |
---|---|
Machine Learning 2 (0) | 2024.05.27 |
Machine Learning 1 (~학습 및 테스트 세트) (0) | 2024.05.21 |
MFCC, STFT (0) | 2024.05.20 |
Tensorflow 강의 정리 (0) | 2024.05.15 |