Smart contract storage

Storage data

스마트 컨트랙트를 작성하면, storage, memory등의 데이터를 다루게 된다.

storage같은 경우에는 블록체인 상에 영구적으로 저장이 되는데, 정확하게 어디에 어떻게 저장이 되는 것일까?

다음과 같은 컨트랙트를 예시로 들어보자.

contract StorageContract {

	struct Data {
		address user;
		uint256 amount;
	}

	mapping (uint256=>Data) mapper;
}

mapper에 있는 data들은 어디에 저장될까?

당연히 블록에 저장된다. 블록체인의 각 블록에는 트랜잭션 목록이 포함되어 있다.

트랜잭션에는 암호화폐 전송이 포함될 수 있지만 스마트 컨트랙트와의 상호 작용도 포함될 수 있다.

트랜잭션이 스마트 컨트랙트와 상호 작용할 때 컨트랙트의 함수를 실행하고 해당 스토리지 데이터를 수정할 수 있다.

이 때 스마트 컨트랙트의 새로운 상태는 블록체인에 저장된다.

그런데 여기서 한 가지 의문이 더 생긴다.

스마트 컨트랙트의 코드는 바이트 코드로 컴파일 되는데, 내가 스토리지 데이터를 바꾸면 그것은 어떤 식으로 반영이 될까?

스마트 컨트랙트와 상호 작용할 때 실제로 수행하는 작업은 데이터의 특수 페이로드가 포함된 트랜잭션을 생성하는 것이다.

이 페이로드는 일반적으로 스마트 컨트랙트에 수행할 작업을 알려주는 매개 변수를 포함한 함수 호출이다.

트랜잭션이 블록에 포함되고 블록이 채굴되면 네트워크의 모든 노드는 트랜잭션에서 함수 호출을 실행한다.

여기에는 제공된 매개변수로 컨트랙트의 바이트코드를 실행하는 것이 포함된다.

제공된 페이로드를 이용해서, 바이트코드를 실행한다.

함수가 컨트랙트의 상태를 수정하면(즉, 컨트랙트에 저장된 데이터가 변경됨) 새 상태가 블록체인에 저장된다.

위에서 설명한 것과 동일

이는 컨트랙트 자체의 바이트 코드가 변경된다는 의미는 아니다.

바이트코드는 계약 소스 코드의 컴파일된 버전이며 계약이 배포된 후에도 변경되지 않는다.

대신 변경되는 것은 컨트랙트와 연결된 상태(status)이다.

컨트랙트의 바이트 코드를 프로그램으로, 컨트랙트의 상태를 프로그램이 사용하는 변수로 생각할 수 있다.

컨트랙트와 상호 작용할 때 프로그램 자체(바이트 코드)를 변경하는 것이 아니다.

대신 특정 입력으로 프로그램을 실행하고 이로 인해 변수(상태)가 변경될 수 있다.

컨트랙트의 상태에는 구조체 및 매핑과 같은 복잡한 데이터 유형을 포함하여 함수 본문 외부에서 선언된 모든 변수가 포함된다.

각 컨트랙트의 상태는 Key-value pair의 구조를 가지는 블록체인 상태 트리(머클 트리)의 특정 위치에 저장된다.

컨트랙트와 상호 작용할 때 변경되는 것은 바이트 코드가 아니라 상태 트리의 값이다.

이더리움 블록체인의 각 블록에는 Merkle Tree의 루트 해시가 블록 헤더의 일부로 포함된다.

따라서 상태 트리 자체는 블록체인 내에 직접 저장되지 않는다.

오히려 이더리움 네트워크에 참여하는 각 노드에 의해 별도로 유지 관리된다.

Last updated