[Ethereum] Solidity 문법 이해(3)

기본 유형 간의 변환

배열, 문자열, 구조체, 열거형, 맵 이외의 모든 것을 기본 유형이라고 부른다. 일반적으로 값의 유실이 없는 경우 유형 간의 묵시적 변환이 가능하다.[1]

솔리디티는 명시적 변환도 지원한다. 그러나 예상하지 못한 결과가 나올 수도 있기 때문에 명시적 변환은 지양하는 것이 좋다.


var 사용

var를 사용하는 경우, 변수 유형은 첫 번째로 할당된 값에 따라 동적으로 결정된다. 값 지정 이후의 유형은 고정되므로, 다른 값을 할당하면 형 변환이 발생한다.[2]


제어 구조

솔리디티 또한 대부분의 언어에서 지원하는 if, else, while, for, break, continue, return,?를 지원한다.


new 연산자를 사용하여 컨트랙트 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
contract sample1 {
int a;

function assign(int b) {
a = b;
}
}

contract sample2 {
function sample2() {
sample1 s = new sample1();
s.assign(12);
}
}

예외

수동으로 예외를 발생시키기 위해서는 throw 키워드를 사용한다. 예외는 현재 호출 중인 모든 호출을 중지하고 상태를 원복시킨다. 단, 예외 처리(catch)는 불가능하다.

1
2
3
4
5
contract sample {
function myFunction() {
throw;
}
}

함수 호출

솔리디티에는 내부 함수 호출[3]과 외부 함수 호출[4]이 있다.

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
33
34
35
36
37
38
39
contract sample1 {
int a;

function sample1(int b) payable {
a = b;
}
function assign(int c) {
a = c;
}
function makePayment(int d) payable {
a = d;
}
}

contract sample2 {
function hello() { }
function sample2(address addressOfContract) {
// 컨트랙트 인스턴스 생성하며 12 wei 전송
sample1 s = (new sample1).value(12)(23);
s.makePayment(22);

// 다시 이더 전송
s.makePayment.value(45)(12);

// 사용할 가스의 양 지정
s.makePayment.gas(895)(12);

// 이더를 전송하고 가스를 다시 지정
s.makePayment.value(4).gas(900)(12);

// hello()는 내부 호출이며, this.hello()는 외부 호출
this.hello();

// 이미 배포된 컨트랙트를 지정
sample1 s2 = sample1(addressOfContract);

s2.makePayment(112);
}
}

가시성

가시성(visiability)은 누가 볼 수 있는지 정의한다.

  • external
    다른 컨트랙트나 트랜잭션을 통해서만 호출될 수 있다. f()는 동작하지 않지만 this.f()는 동작한다.
  • public
    모든 방법으로 접근할 수 있다. 단, setters는 생성하지 않기 때문에 이미 지정된 값을 변경할 수는 없다.
  • internal
    내부적으로만 접근할 수 있다. 접근을 위해 this를 사용할 수 없다.
  • private
    internal과 비슷하지만 상속된 컨트랙트에서 접근할 수 없다.
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
contract sample1 {
int public b = 78;
int internal c = 90;

function sample1() {
// 외부(external) 접근
this.a();

// 컴파일 오류
a();

// 내부(internal) 접근
b = 21;

// 외부(external) 접근
this.b;

// 외부(external) 접근
this.b();

// 컴파일 오류. setters가 지정되어 있지 않아 값을 변경할 수 없다.
this.b(8);

// 컴파일 오류. internal은 this로 접근할 수 없다.
this.c();

// 내부(internal) 접근
c = 9;
}
function a() external { }
}
}

contract sample2 {
int internal d = 9;
int private e = 90;
}

// sample3은 sample2를 상속
contract sample3 is sample2 {
sample1 s;

function sample3() {
s = new sample1();

// 외부(external) 접근
s.a();

// 외부(external) 접근
var f = s.b;

// 컴파일 오류. 접근자를 통해 값을 할당할 수 없다.
s.b = 18;

// 컴파일 오류. c는 internal.
s.c();

// 내부(internal) 접근
d = 9;

// 컴파일 오류. e는 private.
e = 7;
}
}


이 포스트의 모든 내용은 이더리움을 활용한 블록체인 프로젝트 구축(에이콘) 책을 참고하여 작성되었습니다.




  1. uint8은 uint16으로 변환 가능하지만, 역은 불가능. ↩︎

  2. 배열, 맵, 매개변수, 상태 변수를 정의할 때에는 var를 사용할 수 없다. ↩︎

  3. 같은 컨트랙트의 함수를 호출하는 것. ↩︎

  4. 다른 컨트랙트의 함수를 호출하는 것. ↩︎

Share