지난 번 트론토큰의 전송은 성공했으니 이제 스마트 컨트랙트를 만들어 보려고 합니다. 토큰을 받으면 어찌저찌 처리한 후에 다시 특정계정으로 보내거나, 스테이킹을 한다거나 하는 기능들을 만들어보려고요.
아주 천천히 잘 가르쳐 주는 크립토좀비 사이트를 이용해서 공부를 해보려고 합니다.
이번 포스팅에서는 Solidity 속성들에 대해서 정리를 해봅니다.
1. pragma
- 솔리디티 소스 코드 빌드 버전을 선언합니다.
pragma solidity ^0.4.19; // 버전은 상황에 맞도록 설정
2. contract
- 컨트랙트 함수를 선언합니다.
- 내부에 각종 소스를 듬뿍듬뿍 넣을 수 있습니다.
contract ZombieFactory {
}
3. 상태변수/정수
- 상태변수는 컨트랙트 저장소에 영구적으로 저장됩니다. 즉 이더리움 체인에 기록이 된다는 것입니다.
- 데이터베이스에 데이터를 쓰는 것과 동일하다고 보시면 됩니다.
- 솔리디티에서 uint는 실제로 uint256, 즉 256비트 부호 없는 정수의 다른 표현입니다.
- uint8, uint16, uint32 등과 같이 uint를 더 적은 비트로 선언할 수도 있습니다.
- 주요 자료형
uint : 부호가 없는 정수형
int : 정수형
bool : 논리 자료형
string : UTF-8 인코딩 문자열
bytes : 바이트
address : 이더리움 주소 값 (0xaDc7192A0…)
레퍼런스 자료형
배열 : 자료형이 같은 데이터를 묶은 자료 구조입니다.
구조체1 : 다양한 자료형의 데이터를 묶은 자료 구조입니다.
unit dnaDigits = 16;
4. 수학연산
- 덧셈/뺄셈/곱셈/나눗셈 같은 연산입니다.
- +, -, *, /, %(나머지 구하기), **(지수연산 ex:10 ** 2 = 10^2 = 100)
uint dnaModulus = 10 ** dnaDigits;
5. 구조체
- 조금 더 복잡한 자료형을 사용하기 위해서 사용되는 형태입니다.
struct Zombie {
string name;
uint dna;
}
6. 배열
- Array 형태의 변수 선언 방법
- 구조체의 배열도 가능합니다.
// 2개의 원소를 담을 수 있는 고정 길이의 배열:
uint[2] fixedArray;
// 또다른 고정 배열으로 5개의 스트링을 담을 수 있다:
string[5] stringArray;
// 동적 배열은 고정된 크기가 없으며 계속 크기가 커질 수 있다:
uint[] dynamicArray;
7. 가시성(visiability)
- 솔리디티에서 함수는 기본적으로 public으로 선언됩니다.
- external : 다른 컨트랙트나 트랜잭션을 통해서만 호출 될 수 있습니다. f()는 동작하지 않고, this.f()는 동작합니다.
- public : 누구나 접근 가능합니다. 단, setter는 생성되지 않기 때문에 지정된 값을 변경하는 것은 불가능합니다.
- internal : 내부적으로만 접근가능한 변수입니다. 접근을 위해서 this를 사용 할 수 없습니다.
- private : internal과 비슷하게 내부적으로만 사용가능하지만 상속된 컨트랙트에서는 접근 할 수 없습니다.
8. 함수선언
- function 명령어를 이용하여 함수를 선언합니다.
- 함수의 parameter은 _로 시작해서 다른 변수와 구분하는 관례를 따르는 것이 좋습니다.
- private 함수명은 언더바(_)로 시작하는 것이 관례입니다.
function _createZombie(string _name, uint _dna) private {
zombies.push(Zombie(_name, _dna));
}
9. 함수제어자(view, pure)
- view로 선언된 함수는 함수 내에 데이터가 변경되지 않는 다는 것을 명시하는 것입니다.
- pure로 선언된 함수는 함수 내부의 변수가 외부의 변수도 접근하지 않는다는 것을 명시하는 것입니다.(paramter 변수만으로 함수 내부가 모두 작동됨)
function sayHello() public view returns (string) {}
function _multiply(uint a, uint b) private pure returns (uint) {
return a * b;
}
10. keccak256
- keccak256함수는 입력 스트링 값을 랜덤 256비트 16진수로 변경하여 주는 함수입니다.
- keccak256함수를 이용하여 발생시킨 랜덤 값은 보안에 뛰어나다고 볼 수는 없습니다. 일단 랜덤 값이 필요한 경우에만 활용하는 것으로 하면 될 것 같습니다.
//6e91ec6b618bb462a4a6ee5aa2cb0e9cf30f7a052bb467b0ba58b8748c00d2e5
keccak256("aaaab");
//b1f078126895a1424524de5321b339ab00408010b7cf0e6ed451514981e58aa9
keccak256("aaaac");
11. 형 변환
uint8 a = 5;
uint b = 6;
// a * b가 uint8이 아닌 uint를 반환하기 때문에 에러 메시지가 난다:
uint8 c = a * b;
// b를 uint8으로 형 변환해서 코드가 제대로 작동하도록 해야 한다:
uint8 c = a * uint8(b);
// keccak256으로 나온 값을 uint로 형 변환
uint rand = uint(keccak256(_str));
12. 이벤트
- 사용자 단에서 무언가 액션이 발생했을 때 작동하는 기능
// 이벤트를 선언한다
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;
}