반응형

솔리디티 소스 코드의 기본 뼈대는 아래와 같다.


1
2
3
4
5
pragma solidity ^0.4.19;
 
contract HelloWorld{
 
}
cs


모든 솔리디티 소스 코드의 시작은 "version pragma"로 시작한다.


버전을 선언하는 이유는 새로운 컴파일러 버전이 나와도 기존 코드가 깨지지 않도록 예방하기 위해서이다.

contract는 다른 언어에서 class가 바뀐 이름이라고 생각할 수 있다.

부호없는 정수로는 uint, uint8, uint16, uint32, uint256 등등 이 있는데 uint256은 uint로 쓸 수 있다.


솔리디티에서 함수는 기본적으로 public으로 선언된다.

이때 public으로 선언하여 모든이에게 공개되어도 괜찮은 것이라면 상관없지만

컨트랙트가 공격에 취약해질 위험이 있기에 공개하지 않을 함수는 private로 선언한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pragma solidity ^0.4.19;
contract HelloWorld{
    
    struct People {
        string name;
        uint age;
    }
    People[] public peoples;
    function birth(string _name, uint _age) private {
        people.push(People(_name, _age));
    }
}
cs
 




event

1
2
3
4
5
6
7
8
9
// 이벤트를 선언한다
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;
}
cs


위의 코드는 이벤트를 의미하는데


이벤트는 컨트랙트가 블록체인 상에서 사용자 단의 앱에서 액션이 발생할 경우 귀를 기울이고 있는 상황을 의미한다.


이렇게 이벤트를 설정하면 특정 이벤트가 발생하면 블록체인 상에서 행동을 취하게 된다.






msg.sender


1
2
3
4
5
6
7
8
9
10
mapping(string => address) house;
function setHouse(string _name) public {
    // 'msg.sender'에 대해 '_name'이 저장되도록 map에 mapping한다.
    house[msg.sender= _name;
}
function getHouse() public view returns(string) {
    // map에서 msg.sender에 저장된 값을 불러온다.
    // sender가 'setHouse'를 아직 호출하지 않았다면 반환값은 '0'이 된다.
    return favoriteNumber[msg.sender];
}
cs

 

솔리디티에는 모든 함수에서 이용 가능한 특정 전역 변수들이 있다.


그 중의 하나가 현재 함수를 호출한 사람 (혹은 스마트 컨트랙트)의 주소를 가리키는 msg.sender이다.


msg.sender를 활용하면 이더리움 블록체인의 보안성을 높일 수 있다.

msg.sender는 개인키 역할을 하기에 누군가 다른 사람의 데이터를 변경하려면 해당 이더리움 주소와 관련된 개인키를 훔치지 않는 이상 해킹을 당하지 않게된다.




require


require는 특정 조건이 참이 아닐 때 함수가 에러 메시지를 발생하고 실행을 멈추게 된다.


따라서 require는 함수를 실행하기 전에 참이어야 하는 특정 조건을 확인하는 데 있어서 꽤 유용하다.


(참고: 솔리디티는 고유의 스트링 비교 기능을 가지고 있지 않기 때문에 스트링의 keccak256 해시값을 비교하여 스트링 값이 같은지 판단한다)


1
2
3
4
5
6
7
function compareHouse(string _name) public returns(string) {
    // 현재 sender의 msg.sender를 매핑한 결과와 현재 이름이 같지 않은 경우
    // 에러 메시지를 발생하고 함수를 벗어난다.
    require(keccak256(house[msg.sender]) == keccak256(_name));
    // 참이면 함수 실행을 진행한다:
    return "This is True";
}
cs




상속


이전 다른 언어들에서 클래스 상속과 똑같은 의미이다.


상속을 하기 위해서는 child is parent 로 is라는 개념을 이용한다.


kau 컨트랙트는 university 컨트랙트를 상속하게 되고. 

여기서는 kau는 이제 university의 catchphrase() 함수와 anotherCatchphrase() 함수에 모두 접근할 수 있게 된다.


1
2
3
4
5
6
7
8
9
10
11
contract university{
    function catchphrase() public returns(string) {
        return "University";
    }
}
 
contract kau is university{
    function anotherCatchphrase() public returns(string) {
        return "KAU is University";
    }
}
cs




internal / external


internal은 internal로 정의된 함수가 있는 컨트랙트를 상속하는 컨트랙트에서도 접근이 가능하다.

-> private + 상속한 컨트랙트가 접근 가능


external은 함수가 컨트랙트 바깥에서만 호출될 수 있고 컨트랙트 내의 다른 함수에 의해 호출될 수 없다

-> public + 현재 컨트랙트에서는 접근 불가



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
contract sandwich{
    uint private sandwichCnt= 0;
 
    function eat1() internal {
        sandwichCnt++;
    }
 
    function eat2() external {
        sandwichCnt++;
    }
 
    function eat3() {
        // eat2가 external이기에 eat3가 호출 할 수 없다.
        eat2();
    }
}
 
contract BLT is Sandwich{
    uint private BLTcnt = 0;
 
    function eatBLT1() public returns(string) {
        BLTcnt++;
        // eat1이 internal이기에 여기서 호출이 가능하다. 
        eat1();
    }
 
    function eatBLT2() public returns(string) {
        BLTcnt++;
        // eat2가 external이기에 여기서 호출이 가능하다 
        eat2();
    }
}
cs





Storage / Memory 


솔리디티에는 storagememory라는 변수를 저장할 수 있는 두가지 공간이 있다.


Storage는 블록체인 상에 영구적으로 저장되는 변수를 의미하고, 

Memory는 임시적으로 저장되는 변수이며 컨트랙트 함수에 대한 외부 호출들이 일어나는 사이에 지워진다.


솔리디티는 컨트랙트 내의 상태 변수(함수 외부에 선언된 변수)는 storage로 초기화 해주고

함수 내에 선언된 변수memory로 자동적으로 초기화해준다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
contract SandwichFactory{
    struct Sandwich {
    string name;
    string status;
}
Sandwich[] sandwiches;
    function eatSandwich(uint _index) public {
        // 'mySandwich'는 저장된 'sandwiches[_index]'를 가리키는 포인터가 된다.
        // 이 코드는 블록체인 상에서 'sandwiches[_index]'을 영구적으로 변경한다. 
        Sandwich storage mySandwich = sandwiches[_index];
 
        mySandwich.status = "Eaten!";
 
        // 'anotherSandwich'는 단순히 메모리에 데이터를 복사하는 것이 된다.     
        Sandwich memory anotherSandwich = sandwiches[_index + 1];
    }
}
cs



반응형

'Applied > Blockchain' 카테고리의 다른 글

Solidity 프로그래밍 기초 - 2  (0) 2018.05.02
이더리움 가스(Ethereum Gas)  (2) 2018.05.01
블록체인 멤풀(Blockchain Mempool)  (0) 2018.04.28
블록체인 노드(Blockchain Node)  (0) 2018.04.28
머클트리(Merkle Tree)  (0) 2018.04.23