# 4. Write Smart Contract

1. Background
2. Define the variable
3. Define functions
4. Let's do something more\
   4.1. Add a variable \ 4.2. Update functions

## 1) 배경지식 <a href="#id-1-background" id="id-1-background"></a>

"Count"라는 매우 간단한 컨트랙트를 만들 거에요.

a. `count`라는 스토리지 변수가 하나만 있습니다.\
b. 사용자는 `count` 변수를 1씩 늘리거나 줄일 수 있습니다. 따라서 `count` 변수를 1만큼 증가시키는 `plus` 함수와 `count` 변수를 1만큼 감소시키는 `minus` 함수, 총 2개의 함수가 있습니다. 참 쉽죠?

## 2) 변수 정의 <a href="#id-2-define-the-variable" id="id-2-define-the-variable"></a>

변수를 설정하기 전에 솔리디티 버전을 지정해야 합니다. 0.5.6 stable 버전을 사용할게요.

```
 solidity 0.5.6; // 솔리디티 버전을 지정합니다.
```

그런 다음 컨트랙트의 이름을 "Count"로 지정합니다.

```
pragma solidity 0.5.6;

contract Count { // 컨트랙트의 이름을 "Count"로 합니다.

}
```

`count` 변수를 `uint`(unsigned integer) 자료형으로 선언하고 0으로 초기화하세요.

```
pragma solidity 0.5.6;

contract Count {
  uint public count = 0; // Declare count variable as uint type and initialize its value to 0.
}
```

## 3) 함수 정의 <a href="#id-3-define-functions" id="id-3-define-functions"></a>

`plus`와 `minus` 두 개의 함수가 필요해요. 각 함수의 역할은 다음과 같습니다:\
`plus` - `count` 변수를 1만큼 증가. (count = count + 1)\
`minus` - `count` 변수를 1만큼 감소. (count = count - 1)

```
pragma solidity 0.5.6;

contract Count {
  uint public count = 0;

  function plus() public { // 'plus'라는 이름의 public 함수를 작성합니다.
    count = count + 1; // 'plus' 함수는 count 변수를 1씩 증가시킵니다.
  }

  function minus() public { // 'minus'라는 이름의 public 함수를 작성합니다.
    count = count - 1; // 'minus' 함수는 count 변수를 1씩 감소시킵니다.
  }
}
```

*NOTE*\
컨트랙트 외부에서 함수를 호출하려면 `public`으로 선언해야 합니다.

```
function plus() public { … }
```

## 4) Let's do something more <a href="#id-4-let-s-do-something-more" id="id-4-let-s-do-something-more"></a>

기능 하나만 더 추가해볼까요? 마지막 참가자의 지갑 주소를 기억하는 기능은 어때요?

### 4-1) 변수 추가 <a href="#id-4-1-add-a-variable" id="id-4-1-add-a-variable"></a>

`lastParticipant` 변수를 `address` 자료형으로 선언해주세요:\
`address public lastParticipant;`

```
pragma solidity 0.5.6;

contract Count {
  uint public count = 0;
  address public lastParticipant;

  function plus() public { // 'plus'라는 이름의 public 함수를 작성합니다.
    count = count + 1; // 'plus' 함수는 count 변수를 1씩 증가시킵니다.
  }

  function minus() public { // Make a public function called 'plus'
    count = count - 1; // 'minus' function decreases count variable by 1.
  }
}
```

### 4-2) 업데이트 함수 <a href="#id-4-2-update-functions" id="id-4-2-update-functions"></a>

마지막 참가자의 주소를 추적하기 위해 `lastParticipant`에 다음과 같이 주소를 저장합니다.

```
pragma solidity 0.5.6;

contract Count {
  uint public count = 0;
  address public lastParticipant;

  function plus() public {
    count = count + 1;
    lastParticipant = msg.sender; // msg.sender의 값을 lastParticipant에 저장합니다.
  }

  function minus() public {
    count = count - 1;
    lastParticipant = msg.sender; // msg.sender의 값을 lastParticipant에 저장합니다.
  }
}
```

*참고*\
1\) `public` 변수 또는 함수를 `public`으로 선언했다면 블록체인 외부에서 접근할 수 있습니다. 즉 프론트엔드 어플리케이션에서 해당 변수 또는 함수에 접근할 수 있습니다. 나중에 [Count 컴포넌트](/content/dapp/tutorials/count-dapp/5.-frontend-code-overview/5-3.-count-component.md) 장에서 어떻게 프론트엔드 애플리케이션으로부터 컨트랙트의 public 메서드 및 변수와 상호작용할 수 있는지 볼게요.

2\) `msg.sender`\
`msg.sender`는 현재 트랜잭션을 시작한 주소입니다.\
`msg.sender` 변수를 통해 트랜잭션 발신자의 주소를 얻을 수 있습니다.

```
lastParticipant = msg.sender;
```

이 줄은 `lastParticipant` 변수가 `msg.sender`의 주소 값을 갖도록 합니다.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://archive-ko.docs.klaytn.foundation/content/dapp/tutorials/count-dapp/4.-write-smart-contract.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
