pragma solidity ^0.x.x;
contract Title {
}
<실습>
1.우측 박스에 우리 컨트랙트가 솔리디티 버전 0.4.19를 쓸 수 있도록 설정한다.
2.ZombieFactory라는 빈 컨트랙트를 생성한다.
pragma solidity ^0.4.19;
contract ZombieFactory {
}
dnaDigits라는 uint를 선언하고 16이라는 값을 배정해 보게.
pragma solidity ^0.4.19;
contract ZombieFactory {
uint dnaDigits = 16;
}
dnaModulus라는 uint형 변수를 생성하고 10의 dnaDigits승을 배정한다.
pragma solidity ^0.4.19;
contract ZombieFactory {
uint dnaDigits = 16;
uint dnaModulus = 10 ** dnaDigits;
}
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;
}
}
uint[n] Array;
uint[] Array;
uint[] public Array;
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;
}
function 함수명(타입 인자명, 타입 인자명) {
}
_
로 시작하면 전역 변수와 구별한다는 의미_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) {
}
}
구조체 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));
}
function 함수명(타입 인자명) private { }
createZombie 함수를 변경하여 private 함수로 만든다. 함수명에 대한 관례를 잊지 말 것!
function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
}
returns (타입)
으로 추가return 반환할 변수명;
function 함수명() public view returns (리턴타입) {}
function 함수명(타입 인자명) private pure returns (타입) {}
1._generateRandomDna라는 private 함수를 만드시게. 이 함수는 _str (string형)을 인자로 전달받고, uint을 반환해야 하네.
2.이 함수는 컨트랙트 변수를 보지만 변경하지는 않을 것이므로 view로 선언하게.
3.이 함수의 내용은 현재로서는 비어 있는 상태로 냅두시게. 나중에 채울 것이네.
function _generateRandomDna(string _str) private view returns (uint) {
}
새타입(변환할변수명)
- 코드 첫 줄에서는 _str을 이용한 keccak256 해시값을 받아서 의사 난수 16진수를 생성하고 이를 uint로 형 변환한 다음, rand라는 uint에 결과값을 저장해야 한다.
- 우리는 좀비의 DNA가 16자리 숫자이기만을 원하므로(dnaModulus를 기억하나?) 코드의 두번째 줄에서는 위의 결과 값을 모듈로(%) dnaModulus로 연산한 값을 반환해야 한다. (형식: return 위의 결과 값 % dnaModulus).
function _generateRandomDna(string _str) private view returns (uint) {
uint rand = uint(keccak256(_str));
return rand % dnaModulus;
}
- 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);
}
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);
}
// 여기에 우리가 만든 컨트랙트에 접근하는 방법을 제시한다: 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 }