(TIL24) 스마트컨트랙트 생성해보기

져니·2021년 10월 13일
0

블록체인

목록 보기
7/7
post-thumbnail

1. 스마트 컨트랙트 개념 📃

현재 블록체인에서 사용되고 있는 스마트 컨트랙트는, 서면으로 이루어지던 계약을 코드로 구현하고 특정 조건이 충족되었을 때 해당 계약이 이행되도록 하는 script에 가깝습니다.

[출처: 블록체인 애플리케이션 개발 실전 입문]

EVM은 이더리움 가상머신을 의미한다. 우리가 쓴 솔리디티 언어를 EVM에서 해석할 수 있게끔 컴파일하여서 실행!

스마트 컨트랙트 생성 순서

1) 스마트 컨트랙트 코드를 작성
솔리디티 혹은 다른언어를 사용 대표적인 언어는 솔리디티 언어. 솔리디티를 재밌게 배우고싶다면 크립토좀비사이트 추천

2) 스마트 컨트랙트 코드를 컴파일

  • 컴파일 명령어
solcjs --abi --bin [파일명]

결과물로 abi, bin파일 생성됨

  • abi: Application binary Interface 런타임시 바이너리 코드와 데이터 실행시키기 위한 JSON파일
  • bin : 바이너리 파일

3. 컴파일 결과를 배포(블럭에 내용이 추가됨)
스마트 컨트랙트를 배포한다는 것은 컴파일 후 코드들이 EVM이 해석할 수 있는 코드로 변환되었고, EVM에서 코드를 입력받아 트랜잭션을 생성시키고 블럭에 정보를 담는 것!!

마이너가 해당 블럭을 채굴하게 되면 블록체인에 포함됨

2. 🔨 환경세팅

node.js 환경에서 셋팅 가능합니다.
Truffle,Ganashe 설치해줘야함

1. npm install -g truffle
2. npm install -g ganache-cli
3. npm init
4. npm install web3

⭐web3 설치는 npm init 후에 해주기! 그래야 오류나지 않음

web3란 무엇인가❓❓❓

  • RPC통신을 쉽게 구현할 수 있게 도와주는 라이브러리
  • web3를 통해서 abi파일로 EVM과 통신할 수 있음

버전확인

truffle version

저는 Truffle v5.4.14이라고 나옴

ganache는 서버를 키면 확인 가능

ganache-cli --host 0.0.0.0

저는 Ganache CLI v6.12.2 (ganache-core: 2.13.2)이라고 나옴

3. 터미널에서 ganache-cli --host 0.0.0.0

터미널을 두개 켜서 하나는 위 명령어를 쳐서 Ganache를 돌리고 있기!!!
Ganache는 로컬에서 블록체인을 실험해보기 위한 도구, 위 명령어를 치면 가나쉬 버전 확인도 가능하고, 테스트를 위한 정보들을 쭉 알려줌

Ganache CLI v6.12.2 (ganache-core: 2.13.2)
Available Accounts
==================
(0) 0x744Fb501915e200dBf69732F8781F23dC51E8F4B (100 ETH)
(1) 0x5b4ef082638d58423bfc92602264C3a1F0eC01c5 (100 ETH)
(2) 0x4b4f863031686Bd81730b8ee5eFba43b10d8D9A9 (100 ETH)
(3) 0xc0676a7fcD255Ca54217Ed48c71D8E953C3122e5 (100 ETH)
(4) 0x6f0d1C9920f8918E5Ce480929Cb1E23F80511464 (100 ETH)
(5) 0x7FF0909b4EFba9c89Cc319d32BbbE0A0380edFD3 (100 ETH)
(6) 0x5e81A4BE62B59594E70DdD7e9892FDe856deB270 (100 ETH)
(7) 0xF2Df561Cd38b144C2148C4990F2f97436C2279A5 (100 ETH)
(8) 0x3b802c3Fb3610a14bdAD8ABC1862063Bd0dDc8F4 (100 ETH)
(9) 0xBf2e8C562Cd509Efc5507387683a3EEe60Fd5c46 (100 ETH)
Private Keys
==================
(0) 0xde4e77dff3039494f17c0a9a871dd00a17a88ee457e13fdc25a336fcabd30495
(1) 0x18bc71785954cb948a9688bc814c7b06c92005bd8901e11d00683ec3a85f8777
(2) 0x5eddc187357abae49a5f8dc8fbfc17f551b801d93f8608cdd8673dabb4602675
(3) 0xcd01f607aa5fbe705ffa0c377b357eec1091cb05410a62377381be75d1e20ef6
(4) 0x3a62ef3b7eacbc130e40aaebc01fb636a9d3f1689ae6ec06dd96cf4031411f5e
(5) 0x880deda152bda657dac57bb23dac0902b9aae1bca4251bb5b7fe21cd1bc0707a
(6) 0xba95ddc01db7ecf342c40f28bbfe2dc354294b0a1d05aa1974ff03e7da829dab
(7) 0xed298cf0ab3edc0232d51d48137e95b7459896bba1a408c132abea5621bce889
(8) 0x798026cd62d8c1757d4c8797e237f2b1f672102878f3c0735a1a1b796fe680e1
(9) 0x5a012937c092536a9e62315b208af228a1a01e4c7e646807e37a4c614f810814
HD Wallet
==================
Mnemonic:      glass naive rib suggest ostrich all razor pistol regret core ranch goat
Base HD Path:  m/44'/60'/0'/0/{account_index}
Gas Price
==================
20000000000
Gas Limit
==================
6721975
Call Gas Limit
==================
9007199254740991
Listening on 0.0.0.0:8545

가스(Gas)

이더리움 스마트 컨트랙트를 배포하고 실행할 때 사용되는 수수료

4. 스마트컨트랙트 코딩 👩‍💻

환경설정을 완료했다면 vs코드에서 hello.sol이라는 파일 생성

hello.sol

pragma solidity ^0.8.0; // (1) 버전 프라그마 반드시 첫줄에 써줘야함
// (2) 계약 선언
contract hello {
  // (3) 상태 변수 선언
    string value; 
  // (4) 생성자
    constructor(){
        value = "hello world!";
    }
  // (5) 메서드 선언
    function get() public view returns(string memory){ 
    //returns와 return은 다른것
        return value;
    }
}

string 뒤의 memory는 정보를 어디서 가져올것인지에 대한 것
storage,momory 두가지 타입이 있음

storage -> 파일시스템 파일에 저장된 내용을 가져옴
memory -> 메모리에 저장된 내용을 가져옴

5. ⛓ 컴파일 작업

컴파일 명령어

solcjs --bin --abi .\hello.sol

터미널에서 명령어를 치면 abi파일과 bin파일이 생성됩니다.

이 두 파일에 있는 정보들을 활용하여 배포를 진행할 것임
hello_sol_hello.abi

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"get","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

hello_sol_hello.bin

608060405234801561001057600080fd5b506040518060400160405280600c81526020017f68656c6c6f20776f726c642100000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610166565b82805461006e90610134565b90600052602060002090601f01602090048101928261009057600085556100d7565b82601f106100a957805160ff19168380011785556100d7565b828001600101855582156100d7579182015b828111156100d65782518255916020019190600101906100bb565b5b5090506100e491906100e8565b5090565b5b808211156101015760008160009055506001016100e9565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061014c57607f821691505b602082108114156101605761015f610105565b5b50919050565b610232806101756000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636d4ce63c14610030575b600080fd5b61003861004e565b6040516100459190610179565b60405180910390f35b60606000805461005d906101ca565b80601f0160208091040260200160405190810160405280929190818152602001828054610089906101ca565b80156100d65780601f106100ab576101008083540402835291602001916100d6565b820191906000526020600020905b8154815290600101906020018083116100b957829003601f168201915b5050505050905090565b600081519050919050565b600082825260208201905092915050565b60005b8381101561011a5780820151818401526020810190506100ff565b83811115610129576000848401525b50505050565b6000601f19601f8301169050919050565b600061014b826100e0565b61015581856100eb565b93506101658185602086016100fc565b61016e8161012f565b840191505092915050565b600060208201905081810360008301526101938184610140565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806101e257607f821691505b602082108114156101f6576101f561019b565b5b5091905056fea26469706673582212206e4c50589141371266b6884e2c02dcce54010b7bddbc7c39916ea9dd1d08dae164736f6c63430008090033

6. 배포하기 💻

이제 배포를 위한 자바스크립트 파일을 작성해줄 것입니다.
이 파일에서 web3를 가져와 쓸 것, example.js파일 생성

example.js

1) 거래 생성 코드

const Web3 = require('web3')
let connection = new Web3('http://127.0.0.1:8545')

// abi파일에 있는 정보들을 JSON형식으로 변형해서 ABI_CODE변수에 담아줌
const ABI_CODE = JSON.parse('[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"get","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]');

// bin 파일에 있는 정보들을 ''으로 감싸서 BYTECODE 변수에 담아줌
const BYTECODE = '608060405234801561001057600080fd5b506040518060400160405280600c81526020017f68656c6c6f20776f726c642100000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610166565b82805461006e90610134565b90600052602060002090601f01602090048101928261009057600085556100d7565b82601f106100a957805160ff19168380011785556100d7565b828001600101855582156100d7579182015b828111156100d65782518255916020019190600101906100bb565b5b5090506100e491906100e8565b5090565b5b808211156101015760008160009055506001016100e9565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061014c57607f821691505b602082108114156101605761015f610105565b5b50919050565b610232806101756000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636d4ce63c14610030575b600080fd5b61003861004e565b6040516100459190610179565b60405180910390f35b60606000805461005d906101ca565b80601f0160208091040260200160405190810160405280929190818152602001828054610089906101ca565b80156100d65780601f106100ab576101008083540402835291602001916100d6565b820191906000526020600020905b8154815290600101906020018083116100b957829003601f168201915b5050505050905090565b600081519050919050565b600082825260208201905092915050565b60005b8381101561011a5780820151818401526020810190506100ff565b83811115610129576000848401525b50505050565b6000601f19601f8301169050919050565b600061014b826100e0565b61015581856100eb565b93506101658185602086016100fc565b61016e8161012f565b840191505092915050565b600060208201905081810360008301526101938184610140565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806101e257607f821691505b602082108114156101f6576101f561019b565b5b5091905056fea26469706673582212206e4c50589141371266b6884e2c02dcce54010b7bddbc7c39916ea9dd1d08dae164736f6c63430008090033'

const contract = new connection.eth.Contract(ABI_CODE)

contract.deploy({
    data:BYTECODE
})

// from 안에 Ganache를 돌려서 얻었던 Available Accounts중 하나를 ''로 감싸서 입력
// Gas(수수료)는 Gas Limit에 입력되어있던 6721975로 설정
.send({
    from:'0x11eeC4232900708324D58ebca115566a02F59Ddd',
    gas:'6721975'
},(error,result)=>{
    console.log(error)
})
.then( data =>{
    console.log(data.options.address)
})

여기서 나온 data.options.address의 값은 하나의 영수증이다!
해당거래가 있었음을 증명해주는 영수증!!!!
이제 이 영수증코드를 이용해서 해당 거래 정보를 불러오기도 가능

2) data.options.address를 통해 얻은 주소를 입력하여 거래정보 가져와서 보는 코드

const ABI_CODE = JSON.parse('[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"get","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]');
const BYTECODE = '608060405234801561001057600080fd5b506040518060400160405280600c81526020017f68656c6c6f20776f726c642100000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610166565b82805461006e90610134565b90600052602060002090601f01602090048101928261009057600085556100d7565b82601f106100a957805160ff19168380011785556100d7565b828001600101855582156100d7579182015b828111156100d65782518255916020019190600101906100bb565b5b5090506100e491906100e8565b5090565b5b808211156101015760008160009055506001016100e9565b5090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061014c57607f821691505b602082108114156101605761015f610105565b5b50919050565b610232806101756000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636d4ce63c14610030575b600080fd5b61003861004e565b6040516100459190610179565b60405180910390f35b60606000805461005d906101ca565b80601f0160208091040260200160405190810160405280929190818152602001828054610089906101ca565b80156100d65780601f106100ab576101008083540402835291602001916100d6565b820191906000526020600020905b8154815290600101906020018083116100b957829003601f168201915b5050505050905090565b600081519050919050565b600082825260208201905092915050565b60005b8381101561011a5780820151818401526020810190506100ff565b83811115610129576000848401525b50505050565b6000601f19601f8301169050919050565b600061014b826100e0565b61015581856100eb565b93506101658185602086016100fc565b61016e8161012f565b840191505092915050565b600060208201905081810360008301526101938184610140565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806101e257607f821691505b602082108114156101f6576101f561019b565b5b5091905056fea26469706673582212206e4c50589141371266b6884e2c02dcce54010b7bddbc7c39916ea9dd1d08dae164736f6c63430008090033'

const contract = new connection.eth.Contract(ABI_CODE)

const helloContract = new connection.eth.Contract(ABI_CODE,'0x3A00Cf40E3C6f26Cf31A1A64e2C4BB4FE53cf2A5')

helloContract.methods.get().call().then( data => {
    console.log(data)
})

Ganache를 돌리고 있는 터미널 외의 다른 터미널을 하나 더켜서 아래 명령어 치기

node example.js

⭐1번 코드를 통해 영수증 코드를 알아내고 1번 코드를 주석처리 한 뒤 2번 코드를 입력하면 거래했던 내용들을 불러와서 볼 수 있다.

참고 블로그 : [스마트컨트랙트(Smart Contract), 글 한 편으로 제대로 이해하기], [이더리움 스마트 컨트랙트 동작방식의 이해]

안녕하세요!😊 국비지원으로 개발쪽 공부를 시작한 학생입니다!
혹시나 제가 잘못된 정보를 제공하고 있다면 댓글 부탁드립니다! 💚
글 읽어주셔서 정말 감사합니다🙇‍♀️

profile
성실함은 최고의 무기

0개의 댓글