[이더리움] 스마트 컨트랙트 배포 및 실행

민수·2023년 5월 22일
0

이더리움 스마트 컨트랙트 배포

  1. Solidity 파일 생성 및 작성 : Solidity라는 언어로 코드를 작성
  2. Solidity 파일 컴파일 : EVM이 해석할 수 있도록 HEX값으로 코드를 컴파일
  3. Transaction 생성 : Transaction 객체를 생성 후 이더리움 노드에 전송

로컬 환경에서 이더리움 스마트 컨트랙트 배포

  1. 프로젝트 디렉터리에 패키지 설치
npm install ganache-cli web3 solc@0.8.18
# solc 최신 버전이 호환되지 않아 0.8.18버전을 사용
  1. solidity 파일 생성 및 작성

class.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Counter {
    uint256 value;

    constructor(){}

    // setter, send
    function setValue(uint256 _value) public {
        value = _value;
    }

    // getter, call
    function getValue() public view returns(uint256) {
        return value;
    }
}
  1. solidity 파일 컴파일
npx solc --bin --abi ./class.sol

컴파일 진행 후 bin 파일과 abi 파일이 생성됨

bin 파일은 스마트 컨트랙트 배포를 할 때 EVM에 등록할 코드를 byte code로 컴파일 한 내용을 담고 있음

608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063209652551461003b5780635524107714610059575b600080fd5b610043610075565b60405161005091906100a1565b60405180910390f35b610073600480360381019061006e91906100ed565b61007e565b005b60008054905090565b8060008190555050565b6000819050919050565b61009b81610088565b82525050565b60006020820190506100b66000830184610092565b92915050565b600080fd5b6100ca81610088565b81146100d557600080fd5b50565b6000813590506100e7816100c1565b92915050565b600060208284031215610103576101026100bc565b5b6000610111848285016100d8565b9150509291505056fea264697066735822122029da9ba8ae64ae66cf30162ed11840a712d312aacb68f399c38268fd324bda4764736f6c63430008120033

abi 파일은 스마트 컨트랙트 안에 존재하는 함수와 매개변수들을 json 형식으로 나타낸 리스트를 담고 있음

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"getValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setValue","outputs":[],"stateMutability":"nonpayable","type":"function"}]
  1. Transaction 생성

    1. ganache-cli로 가상의 이더리움 네트워크 실행
    npx gaanche-cli -h 0.0.0.0
    1. ganache-cli에서 트랜잭션에 사용할 EOA 가져오기
    2. 컴파일 된 결과 중 bin 파일의 내용 가져오기
    3. Transaction 생성
    const Web3 = require("web3")
    const web3 = new Web3("http://127.0.0.1:8545")
    const tx = web3.eth.sendTransaction({
      from: "0x697Cf8433AA77C66913c0eA4F6188d5Cf72e23aD", // EOA
      gas: "500000",
      data: "0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063209652551461003b5780635524107714610059575b600080fd5b610043610075565b60405161005091906100a1565b60405180910390f35b610073600480360381019061006e91906100ed565b61007e565b005b60008054905090565b8060008190555050565b6000819050919050565b61009b81610088565b82525050565b60006020820190506100b66000830184610092565b92915050565b600080fd5b6100ca81610088565b81146100d557600080fd5b50565b6000813590506100e7816100c1565b92915050565b600060208284031215610103576101026100bc565b5b6000610111848285016100d8565b9150509291505056fea264697066735822122029da9ba8ae64ae66cf30162ed11840a712d312aacb68f399c38268fd324bda4764736f6c63430008120033", // bin 파일 내용 앞에 0x를 붙여줘서 hex값이라는 걸 명시해줌
    })
    
    web3.eth.sendTransaction(tx).then(console.log) // 트랜잭션을 발생시켜 이더리움 네트워크에 코드를 등록한다.

    배포가 완료되면 리턴값에서 ContractAddress를 얻을 수 있다. (CA)

    ContractAddress를 이용해 스마트 컨트랙트 코드에 접근이 가능하다.

이더리움 스마트 컨트랙트 실행

로컬 환경에서 이더리움 스마트 컨트랙트 실행

  1. abi 파일 내용 가져오기
  2. Transaction 생성
const Web3 = require("web3")
const web3 = new Web3("http://127.0.0.1:8545")

const abi = [
  { inputs: [], stateMutability: "nonpayable", type: "constructor" },
  {
    inputs: [],
    name: "getValue",
    outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
    stateMutability: "view",
    type: "function",
  },
  {
    inputs: [{ internalType: "uint256", name: "_value", type: "uint256" }],
    name: "setValue",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  },
]

// 호출은 제3자가 가능하지면 실행하는 건 EVM이 실행하기 때문에 EVM이 알 수 있도록 HEX값으로 변환해줘야 한다.
const dataCodeCall = web3.eth.abi.encodeFunctionCall(
  {
    inputs: [],
    name: "getValue",
    outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
    stateMutability: "view",
    type: "function",
  },
  []
)
console.log(dataCodeCall) // 0x20965255

// Call은 Gas가 발생하지 않기 때문에 From을 명시하지 않아도 된다.
// 실행되도 블럭이 생성되지 않는다.
web3.eth
  .call({
    to: "0x6B1E5EA334e1fc5feA3cE97837C858e41C23C742", // 실행할 CA
    data: dataCodeCall,
  })
  .then(console.log)

const dataCodeSend = web3.eth.abi.encodeFunctionCall(
  {
    inputs: [{ internalType: "uint256", name: "_value", type: "uint256" }],
    name: "setValue",
    outputs: [],
    stateMutability: "nonpayable",
    type: "function",
  },
  [10]
)
// setValue 메서드에 매개변수가 들어가기 때문에 두 번째 인자에 내용을 넣어줘야 한다.

console.log(dataCodeSend)
// 0x55241077000000000000000000000000000000000000000000000000000000000000000a

// Send는 Gas가 발생하기 때문에 From을 명시해줘야 한다.
// 실행이 되면 Transaction Pool에 Pending되어 있다 Mining이 될때 블록에 들어가면서 값이 변경이된다.
const tx = {
  from: "0xb7253b719a20593D75d00abbf4ee1f8B1328EAAB", // Gas를 지불할 EOA
  to: "0x6B1E5EA334e1fc5feA3cE97837C858e41C23C742", // 실행할 CA
  data: dataCodeSend,
  gas: "50000",
  gasPrice: 20000000000,
}

web3.eth.sendTransaction(tx).then(console.log)

call

JavaScript에서 getter와 같이 자신의 상태 변수를 가져오는 메서드를 호출하는 것은 call이라고 부른다.

call은 단순히 자신의 상태 변수를 가져오기만 하기 때문에 블록을 생성하지 않고 블록을 생성하지 않기 때문에 Gas 비용이 들지 않는다.

Solidity 문법에서 getter를 표현할 수 있는 예약어로 view가 존재하는데 이 예약어가 적힌 메서드는 Gas 비용이 들지 않는다고 보면 된다.

send

JavaScript에서 setter와 같이 값을 변경하는 메서드를 호출하는 것은 send라고 한다.

send는 변경된 내용이 반영되려면 블록에 저장되야 하기 때문에 Mining이 필요하고 변경 과정에서 연산이 필요하기때문에 Gas 비용이 부과된다.

0개의 댓글