해당 글은 CrytoZombie를 공부하면서 정리한 내용입니다.
"좀비 공장"을 만듬
기본적인 기능을 가진 좀비 생성
좀비 DNA가 활용되는 방법
pragma solidity ^0.4.19;
contract HelloWorld {
}
contract Example {
// 이 변수는 블록체인에 영구적으로 저장된다
uint myUnsignedInteger = 100;
}
대부분의 프로그래밍 언어의 수학 연산과 동일
솔리디티는 지수 연산도 지원한다.
ex) "x의 y승"= x^y
uint x = 5 ** 2; // 즉, 5^2 = 25
struct Person {
uint age;
string name;
}
/* 정적 배열*/
// 2개의 원소를 담을 수 있는 고정 길이의 배열:
uint[2] fixedArray;
// 또다른 고정 배열으로 5개의 스트링을 담을 수 있다:
string[5] stringArray;
/*동적 배열*/
// 동적 배열은 고정된 크기가 없으며 계속 크기가 커질 수 있다:
uint[] dynamicArray;
// 구조체를 배열로
Person[] people; // 이는 동적 배열로, 원소를 계속 추가할 수 있다.
Person[] public people;
function eatHamburgers(string _name, uint _amount) {}
: 이 함수는 eatHamburgers라는 함수로, string과 uint 2개의 인자를 전달받는다._
)로 시작해서 전역 변수와 구별하는 것이 관례이지 의무는 아니다.struct Person {
uint age;
string name;
}
Person[] public people;
// 새로운 사람 생성
Person ella = Person(11,'ella')
// 이 사람을 배열에 추가
people.push(ella);
// 한줄로 표현
people.push(Person(100,'juily'))
uint[] numbers;
function _addToArray(uint _number) private {
numbers.push(_number);
}
_
)로 시작하는 것이 관례이다.// 반환값 string
string greeting = "What's up dog";
function sayHello() public returns (string) {
return greeting;
}
// view 함수
function sayHello() public view returns (string){}
// pure 함수 : 이 함수는 읽는 것도 하지 않고, 다만 반환값이 함수에 전달된 인자값에 따라서 달라진다.
function _multiply(uint a, uint b) private pure returns (uint) {
return a * b;
}
//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);
a * b
는 uint를 반환하는데 우리는 이 반환값을 uint8에 저장하려고 하니 잠재적으로 문제를 야기할 수 있다.b
의 반환값을 uint8으로 형 변환하면 코드가 제대로 작동하고 컴파일러도 에러 메시지를 주지 않는다.// 이벤트를 선언한다
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;
}
// js로 변환
YourContract.IntegersAdded(function(error, result) {
// 결과와 관련된 행동을 취한다
})
Smart Contract
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);
}
}
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
}