💡 스마트 컨트랙트의 동작 방식
스마트 컨트랙트는 블록체인 위에 올라가서 거래 이외의 것들을 할 수 있게 만들어 줍니다. 이 스마트 컨트랙트는 어떻게 만들고 어떻게 사용될까요? 스마트 컨트랙트의 동작 방식과 전반적인 흐름에 대해 살펴보도록 하겠습니다.
💻 스마트 컨트랙트 코딩
블록체인에 올라갈 스마트 컨트랙트를 구현해보도록 하겠습니다. 스마트 컨트랙트는 스마트 컨프랙트를 구현할 수 있는 언어로 코드를 작성합니다. 다양한 IDE에서 작성할 수 있지만 테스트할 수 있는 IDE는 제한적입니다. IDE란 Integrated Development Environment 우리말로는 통합 개발 환경입니다. 이는 코딩, 디버그, 컴파일, 배포 등 프로그램 개발에 관련된 모든 작업을 하나의 프로그램 안에서 처리할 수 있는 환경을 제공하는 소프트웨어입니다. 대표적인 IDE로는 이클립스, 비주얼 스튜디오, 엑스 코드 등이 있습니다. 솔리디티의 경우 대표적으로 Remix라는 웹 IDE에서 작성, 테스트를 할 수 있습니다.
솔리디티 언어를 사용해 예시를 작성해보도록 하겠습니다. 아래 코드를 간략하게 설명하자면, 컨트랙트에 storedData라는 숫자 타입 공용 변수를 설정합니다. set 메서드는 storedData를 받아오고 get 메서드는 공용 변수 storedData를 조회하여 반환하는 코드입니다.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
contract SimpleStorage {
uint storedData;
function set(uint x) public{
storedData = x;
}
function get() public view returns (uint){
return storedData;
}
}
💻 스마트 컨트랙트 소스 코드 컴파일
작성한 스마트 컨트랙트 소스를 바로 사용할 수는 없기 때문에, 컴퓨터와 소통이 가능하도록 컴파일을 해줘야 합니다. 위에서 솔리디티로 작성한 코드를 컴파일하면 아래와 같이 ABI Code, Byte code가 생성됩니다.
ABI Code
[
{
"inputs": [],
"name": "get",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "x",
"type": "uint256"
}
],
"name": "set",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
Byte code
{
"functionDebugData": {},
"generatedSources": [],
"linkReferences": {},
"object": "608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b6100556004803603810190610050919061009d565b610075565b005b61005f61007f565b60405161006c91906100d9565b60405180910390f35b8060008190555050565b60008054905090565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea2646970667358221220514775e17906094599596bd4169d48d7375d0e13f02638fe1e358a1eae7be32e64736f6c63430008070033",
"opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x150 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x36 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x60FE47B1 EQ PUSH2 0x3B JUMPI DUP1 PUSH4 0x6D4CE63C EQ PUSH2 0x57 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x55 PUSH1 0x4 DUP1 CALLDATASIZE SUB DUP2 ADD SWAP1 PUSH2 0x50 SWAP2 SWAP1 PUSH2 0x9D JUMP JUMPDEST PUSH2 0x75 JUMP JUMPDEST STOP JUMPDEST PUSH2 0x5F PUSH2 0x7F JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH2 0x6C SWAP2 SWAP1 PUSH2 0xD9 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST DUP1 PUSH1 0x0 DUP2 SWAP1 SSTORE POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 SLOAD SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP2 CALLDATALOAD SWAP1 POP PUSH2 0x97 DUP2 PUSH2 0x103 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0xB3 JUMPI PUSH2 0xB2 PUSH2 0xFE JUMP JUMPDEST JUMPDEST PUSH1 0x0 PUSH2 0xC1 DUP5 DUP3 DUP6 ADD PUSH2 0x88 JUMP JUMPDEST SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH2 0xD3 DUP2 PUSH2 0xF4 JUMP JUMPDEST DUP3 MSTORE POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 ADD SWAP1 POP PUSH2 0xEE PUSH1 0x0 DUP4 ADD DUP5 PUSH2 0xCA JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x10C DUP2 PUSH2 0xF4 JUMP JUMPDEST DUP2 EQ PUSH2 0x117 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 MLOAD SELFBALANCE PUSH22 0xE17906094599596BD4169D48D7375D0E13F02638FE1E CALLDATALOAD DUP11 0x1E 0xAE PUSH28 0xE32E64736F6C63430008070033000000000000000000000000000000 ",
"sourceMap": "71:192:0:-:0;;;;;;;;;;;;;;;;;;;"
}
💻 배포
Step 1. bytecode와 abi 를 사용해 컨트랙트 객체를 생성합니다. 이 객체는 블록체인에 컨트랙트를 배포할 때 사용됩니다.
Step 2. 배포 트랜잭션을 생성합니다. 트랜잭션을 생성할 때는 계정, gas limit, 컨트랙트 객체 등의 정보가 포함되어야 합니다.
Step 3. 트랜잭션을 네트워크에 올립니다.
Step 4. 이후 채굴 노드가 이 배포 트랜잭션을 포함한 블록을 채굴하고 브로드캐스팅 하게 되면, 우리가 작성한 스마트 컨트랙트의 CA(컨트랙트 계정)가 생성됩니다.
배포는 하나의 방법이 아닌, 배경이나 언어에 따라 여러 방법으로 가능하기 때문에 더 자세한 사항은 보인의 환결 설정과 언어, 블록체인 네트워크를 확인해보아야 합니다. 만약 Remix를 사용한다면 컴파일 버튼을 누르고 배포 칸으로 들어와 설정 (Account, gas, value 등) 후 버튼 클릭만으로 배포는 자동으로 이우어져 컨트랙트 주소가 생성됩니다.
스마트 컨트랙트 주소 값: 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
이렇게 생성된 주소가 바로 스마트 컨트랙트 계정 주소 값이 되며, 이 주소 값으로 스마트 컨트랙트를 활용할 수 있게 됩니다.
트랜잭션 해시 값: 0xb811aa48465ff1b67ae77f269b0b63a6cf3a9b5505d0e3398c6642252d013abb
트랜잭션 해시 값과 스마트 컨트랙트 주소 값은 전혀 다른 정보이니 헷갈리시면 안됩니다.
트랜잭션 해시를 살펴보면 위와 같은 내용을 얻을 수 있습니다. 여기서 가장 긴 input 값은 스마트 컨트랙트 소스를 컴파일한 바이트 코드입니다. 일반 송금 거래에서는 스마트 컨트랙트 소스가 필요없기 때문에 0x 로 나타나지만 스마트 컨트랙트가 있는 경우엔 저렇게 길게 나타나게 됩니다. 또한 to 에도 null 이라는 것을 볼 수 있는데, 보내는 이만 있고 받는 이는 없다는 것이다. 스마트 컨트랙트는 특정 수신을 지정하지 않고 자신이 생성한 계약 코드를 블록 체인에 올리기 때문에 당연히 송신자의 계정만 기록됩니다.
💻 접근 및 사용
스마트 컨트랙트 주소를 이용하여 정보를 활용할 수도 있습니다. 트랜잭션을 생성할 때 스마트 컨트랙트 주소를 사용하게 되면, 스마트 컨트랙트가 가지고 있는 메서드를 사용할 수 있는데, 이를 이용해 이더리움 블록체인에 있는 상태를 변경하거나 조회할 수도 있게 됩니다.
송금이나 스마트 컨트랙트 등, 상태를 변경하는 경우엔 함수를 실행하겠다는 메시지를 담은 트랜잭션을 보내야 합니다. 이는 블록체인에 기록을 하는 것이기 때문입니다. 반면, 블록체인으로부터 스마트 컨트랙트의 변수값 등을 단순히 조회만 하는 경우, 블록체인에 기록하지 않기 때문에 별도로 비용이 들지는 않습니다. 따라서, 일반적인 트랜잭션과는 다르게 자신의 노드에 동기화된 블록 내에 데이터를 읽어 주는 트랜잭션 call을 합니다. 이는 데이터를 읽기만 하기 때문에 비용이 들지 않습니다.
메인 넷에서 이루어지는 모든 트랜잭션에는 가스비라고 하는 수수료가 부과되기 때문에 테스트넷에서 충분한 테스트를 거쳐야 합니다.
'블록체인 > WEB3 개발' 카테고리의 다른 글
로컬 컴퓨터에 Remix 코드 저장하기 - Remixd (0) | 2022.07.12 |
---|---|
Remixd 문제 해결 : Cannot connect to the remixd daemon. Please make sure you have the remixd running in the background. (0) | 2022.07.12 |
이더리움 개발 환경 구성하기 - Remix, 스마트 컨트랙트 코드 작성해서 컴파일해보고 배포까지 해보자! (0) | 2022.07.12 |
솔리디티 컴파일러(solc) 설치하고 컴파일해보기 (0) | 2022.07.12 |
솔리디티 기본 문법 - 반복문 (0) | 2022.07.11 |
댓글