# 4. Soạn hợp đồng thông minh

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) Hình nền <a href="#id-1-background" id="id-1-background"></a>

Chúng ta sẽ tạo ra hợp đồng siêu đơn giản tên là "Count".

a. Chỉ có một biến lưu trữ gọi là `count`.\
b. Người dùng có thể tăng hoặc giảm biến `count` thêm 1. Vì thế, sẽ có 2 hàm, hàm `plus` tăng biến `count` thêm 1 và hàm `minus` giảm biến `count` đi 1. Thế là xong!

## 2) Định nghĩa biến <a href="#id-2-define-the-variable" id="id-2-define-the-variable"></a>

Trước khi đặt biến, chúng ta nên xác định phiên bản Solidity. Hãy sử dụng phiên bản ổn định 0.5.6.

```
 solidity 0.5.6; // Xác định phiên bản solidity
```

Sau đó, chúng ta sẽ đặt tên hợp đồng là "Count".

```
pragma solidity 0.5.6;

contract Count { // đặt tên hợp đồng là "Count"

}
```

Chúng ta cần khai báo biến `count` là `uint` kiểu (số nguyên không dấu) và khởi tạo giá trị là 0.

```
pragma solidity 0.5.6;

contract Count {
  uint public count = 0; // Khai báo biến count kiểu uint và khởi tạo giá trị là 0.
}
```

## 3) Định nghĩa hàm <a href="#id-3-define-functions" id="id-3-define-functions"></a>

Chúng tôi cần hai hàm, `plus` và `minus`. Vai trò của mỗi hàm là:\
`plus` - tăng `count` thêm 1. (count = count + 1)\
`minus` - giảm `count` đi 1. (count = count - 1)

```
pragma solidity 0.5.6;

contract Count {
  uint public count = 0;

  function plus() public { // Tạo hàm công khai 'plus'
    count = count + 1; // hàm 'plus' tăng biến count thêm 1.
  }

  function minus() public { // Tạo hàm công khai 'plus'
    count = count - 1; // hàm 'minus' giảm biến count đi 1.
  }
}
```

*LƯU Ý*\
Để cho phép hàm được gọi bên ngoài, hàm phải được khai báo `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>

Chúng tôi muốn thêm một tính năng nữa. Việc nhớ địa chỉ ví của người tham gia gần đây nhất thì thế nào?

### 4-1) Thêm biến <a href="#id-4-1-add-a-variable" id="id-4-1-add-a-variable"></a>

Vì vậy, chúng ta sẽ có một biến, `lastParticipant` có kiểu `address`:\
`address public lastParticipant;`›

```
pragma solidity 0.5.6;

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

  function plus() public { // Tạo hàm public có tên là 'plus'
    count = count + 1; // hàm 'plus' tăng giá trị biến count thêm 1.
  }

  function minus() public { // Tạo hàm public có tên là 'plus'
    count = count - 1; // Hàm 'minus' giảm giá trị biến count đi 1.
  }
}
```

### 4-2) Cập nhật hàm <a href="#id-4-2-update-functions" id="id-4-2-update-functions"></a>

Để theo dõi địa chỉ của người tham gia mới nhất, chúng tôi lưu địa chỉ vào `lastParticipant` như dưới đây:

```
pragma solidity 0.5.6;

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

  function plus() public {
    count = count + 1;
    lastParticipant = msg.sender; // lưu msg.sender vào lastParticipant
  }

  function minus() public {
    count = count - 1;
    lastParticipant = msg.sender; // lưu msg.sender vào lastParticipant
  }
}
```

*LƯU Ý*\
1\) `public` Nếu bạn khai báo biến hoặc hàm là `public`, bạn có thể truy cập từ bên ngoài blockchain, ví dụ: bạn có thể truy cập biến hoặc hàm này từ ứng dụng frontend của mình. Bạn có thể xem cách tương tác với phương pháp và biến public của hợp đồng từ ứng dụng frontend trong chương [Count componenent](https://archive-vn.docs.klaytn.foundation/content/dapp/tutorials/count-dapp/5.-frontend-code-overview/5-3.-count-component).

2\) `msg.sender`\
`msg.sender` là địa chỉ khởi tạo giao dịch hiện tại.\
Để lấy được địa chỉ của người gửi giao dịch, chúng ta có thể sử dụng biến `msg.sender`.

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

Dòng này sẽ làm cho `lastParticipant` có giá trị `msg.sender`.
