> For the complete documentation index, see [llms.txt](https://whs3-doge5k.gitbook.io/smartcontract-security-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://whs3-doge5k.gitbook.io/smartcontract-security-docs/basics/4./nonce.md).

# 논스(Nonce)

### 논스(Nonce)

nonce는 특정 EOA가 성공적으로 발생시킨 트랜잭션의 개수를 의미한다. 초기의 nonce 값은 0을 할당하며, 트랜잭션이 성공적으로 처리가 되었을 때 EOA의 nonce는 1 증가한다. 이후에는 EOA의 변경된 nonce 값을 기준으로 트랜잭션에 nonce 값을 할당한다.

EOA와 트랜잭션의 nonce 값 변화를 그림을 통해 알아보자.

<figure><img src="https://2462457462-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLf9vwRuaws92ULgGvzTi%2Fuploads%2FL0ktmxH7CHoGsU0JzENE%2Fimage.png?alt=media&amp;token=c3cbfdfd-27dc-4e0d-82b1-5570ead5a8bf" alt=""><figcaption></figcaption></figure>

<table><thead><tr><th width="350">상황</th><th>Nonce</th></tr></thead><tbody><tr><td><ol><li>EOA가 처음 만들어졌을 때</li></ol></td><td><ul><li>nonce 값: 0</li></ul></td></tr><tr><td><ol start="2"><li>트랜잭션을 하나 보냈을 때</li></ol></td><td><ul><li>트랜잭션의 nonce 값: 0</li><li>EOA의 nonce 값: 0</li></ul></td></tr><tr><td><ol start="3"><li>트랜잭션이 처리되었을 때</li></ol></td><td><ul><li>트랜잭션의 nonce 값: 0</li><li>EOA의 nonce 값: 1</li></ul></td></tr><tr><td><ol start="4"><li>새로운 트랜잭션을 보내고 처리되었을 때</li></ol></td><td><ul><li>트랜잭션의 nonce 값: 1</li><li>EOA의 nonce 값: 2</li></ul></td></tr></tbody></table>

***

### **특징**

#### **1. 중복 실행 방지**

Nonce는 고유한 값을 가지기 때문에 트랜잭션의 **중복 실행을 방지**할 수 있다. 특정 계정이 보낸 트랜잭션의 nonce 값이 해당 계정의 현재 nonce와 정확히 일치할 경우에만, 트랜잭션은 유효하다고 판단된다. 만약 트랜잭션이 유효성 검증을 통과하고 블록에 포함되면, 해당 계정의 nonce는 1 증가한다. 이후 동일한 트랜잭션을 다시 실행하려고 시도하면, 계정의 현재 nonce와 일치하지 않기 때문에 EVM은 트랜잭션을 revert 시킨다.&#x20;

#### **2. 처리 순서 보장**

또한 nonce는 트랜잭션 **처리 순서를 보장**한다. 만약에 A라는 EOA가 nonce 값이 5일 때, 트랜잭션 3개를 동시에 보냈다고 가정하자. 각 트랜잭션에는 순서대로 5,6,7 이라는 pending nonce 값이 할당된다.

* **account nonce**: EOA가 성공적으로 블록체인에 포함시킨 트랜잭션 수
* **pending nonce**: EOA가 account nonce를 기준으로, 다음 트랜잭션에 지정한 nonce 값

<figure><img src="https://2462457462-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FLf9vwRuaws92ULgGvzTi%2Fuploads%2FFLTQs2XlzVQDxdy30RiO%2Fimage.png?alt=media&amp;token=bd907389-6eae-49aa-86c8-0ed262da166f" alt=""><figcaption></figcaption></figure>

nonce 값이 7인 트랜잭션이 먼저 네트워크에 도달하면, 해당 트랜잭션은 현재 account nonce보다 크기 때문에 메모리풀에 **queued** 상태로 저장된다. 이후 nonce 값이 5와 6인 트랜잭션이 도착하면, 노드는 계정의 현재 nonce 값(5)을 기준으로 순차적으로 유효성 검사를 진행한다. nonce 값이 5인 트랜잭션은 즉시 실행 가능한 상태로 pending으로 등록되며, 이어서 nonce 값이 6과 7인 트랜잭션도 선행 트랜잭션의 존재로 인해 차례대로 pending 상태로 전환된다.

* **Pending**: EOA의 현재 nonce와 일치하며, 즉시 실행 가능해 다음 블록에 포함될 수 있는 트랜잭션 상태
* **Queued**: EOA의 현재 nonce 값보다 큰 값을 갖고 있어, 이전 트랜잭션이 처리되기 전까지 대기해야 하는 트랜잭션 상태

#### **3. 컨트랙트 주소 생성 기여**

Nonce는 컨트랙트 **주소 생성에 기여**한다.\
컨트랙트를 배포하는 EOA는 해당 계정의 현재 nonce 값을 RLP 방식으로 인코딩하고, 이를 [Keccak-256](/smartcontract-security-docs/basics/undefined/keccak-256.md)으로 해시한 결과의 마지막 20바이트가 컨트랙트의 주소가 된다. 이 방식은 **누가(주소)**, **언제(nonce)** 컨트랙트를 생성했는지를 반영하여, 컨트랙트 주소의 고유성을 보장한다.

```javascript
keccak(rlp.encode([sender, nonce]))[12:]
```

keccak은 이더리움 데이터 무결성을 보장하기 위해 사용되는 해시함수이다. 더 자세한 정보는 아래의 링크를 통해 확인할 수 있다.

\[link]: <https://keccak.team/files/Keccak-reference-3.0.pdf>
