본문으로 건너뛰기

1 Nonce

  • 발신 EOA에 의해 발행되어 메시지 재사용을 방지하는 데 사용되는 일련번호
    • 블록의 논스와 트랜잭션 논스는 다른 것
  • 해당 주소에서 보낸 트랜잭션 건수와 동일한 스칼라 값
    • 컨트랙트 생성 트랜잭션도 포함
  • EOA가 트랜잭션을 보내는 경우 트랜잭션의 nonce는 현재 EOA의 nonce값이 된다.

2 논스 추적

  • 논스는 각 계정에서 발생한 확인된 트랜잭션 건수에 대한 최신 통계
  • 논스는 0부터 시작한다.
  • 논스는 블록체인 계정 상태로 저장되지 않기 때문에 논스를 구하려면 해당 주소로 전송되어 확정된 트랜잭션 개수를 세어서 구해야 한다.
  • 트랜잭션 개수는 web3.eth.getTransactionCount과 같이 web3를 사용해서 구할 수 있다

web3.eth.getTransactionCount 사용시 주의 사항

  • web3.eth.getTransactionCount 은 확정된 트랜잭션 개수만 세고 보류 중인 트랜잭션을 세지 않는다
  • 사용자가 빠르게 트랜잭션을 생성한다면 중복된 논스가 발생할 수 있다.

3 논스의 간격, 중복 논스 및 확인

  • 이더리움 네트워크는 논스에 따라 트랜잭션을 순차적으로 처리한다.
  • 여러 트랜잭션을 순서대로 생성하고 그중 하나가 공식적으로 모든 블록에 포함되지 않으면 이후의 모든 트랜잭션이 ‘멈추고’ 누락된 논스를 기다린다.
    • 논스가 0인 트랜잭션을 전송한 다음 논스가 2인 트랜잭션을 전송하면 두 번째 트랜잭션은 어떤 블록에도 포함되지 않는다.
    • 논스 1인 트랜잭션이 나타날 때 까지 논스 2인 트랜잭션은 멤풀에 저장된다.
  • 논스가 같지만 수신자나 값이 다른 2개의 트랜잭션이 발생하면 하나는 확정되고 하나는 거부된다.
    • 어떤 트랜잭션이 확정되는지는 첫 유효 노드에 도달하는 순서에 따라 결정된다.
  • 유효하지 않거나 가스가 모자란 트랜잭션은 논스 시퀀스에 의도치 않게 ‘갭’을 만들 수 있다.
  • 다시 트랜잭션이 계속되게 하려면 누락된 논스가 있는 유효한 트랜잭션을 전송해야 한다.
  • ‘누락’된 논스가 있는 트랜잭션이 네트워크에 의해 유효성이 검증되면, 이후의 논스가 있는 모든 브로드캐스트된 트랜잭션이 차례대로 유효해진다는 점도 똑같이 염두에 두어야 한다.
  • 트랜잭션을 회수(recall)하는 것은 불가능하다!

4 동시 실행, 트랜잭션 생성 및 논스

  • 동일한 주소에서 트랜잭션을 생성하는 여러 개의 독립적인 지갑 애플리케이션이 있을 때 동시에 출금을 수행하면 동시 실행 문제가 발생할 수 있다.

해결책

  • 단일 컴퓨터를 사용하여 트랜잭션에 서명하는 컴퓨터에 선착순으로 논스를 할당하는 방법
    • 이 단일 컴퓨터가 단일 실패 지점이 된다.
    • 즉 이 컴퓨터가 장애가 나면 해당 주소에서 출금을 할 수 없다.
  • 트랜잭션을 생성하고 논스를 할당하지 않는 방법
    • 서명되지 않은 이 트랜잭션들을 한 노드의 대기열에 올려서 이 노드가 트랜잭션을 서명하고 논스를 관리할 수 있게 하는 것
    • 이 노드가 단일 실패 지점이 된다.
    • 서명되지 않은 트랜잭션 생성 작업을 병렬 처리할 수 있다.

구현 솔루션

  • 대부분의 구현 솔루션들이 동시 실행을 피하고 거래소에서 출금 트랜잭션을 처리하는 단일 프로세스를 만드는 것처럼 병목 지점을 어쩔 수 없이 받아드린다.
  • 또는 독립적으로 작동하는 다수의 출금 담당 핫 월렛을 설치하고 중간중간에 각 지갑의 밸런스를 다시 채워주는 형식으로 해결하게끔 만든다.