이번 포스팅에서는 Truffle을 이용해 스마트 컨트랙트를 배포 및 실행하는 방법에 대해 알아보고자 한다.
Truffle은 스마트 컨트랙트를 쉽게 배포하고 실행시킬 수 있도록 해주는 스마트 컨트랙트 개발 프레임워크이다. Truffle 이외에도 Hardhat 이라는 프레임워크가 존재하는데 Truffle에서는 web3 라이브러리를 사용하고 Hardhat에서는 ethers 라이브러리를 사용한다. 본 포스팅에서는 Truffle을 이용해 스마트 컨트랙트를 배포하고 실행해보도록 하겠다.
👉 설치
$ npm install truffle
$ # 버전 확인
$ npx truffle version
truffle 설치를 완료했다면 터미널에 다음과 같이 입력하여 truffle 프레임워크를 생성해주도록 하자.
$ npx truffle init
npx truffle init 을 실행하면 위와 같은 디렉토리 구조가 생성되는데 각각의 디렉토리는 다음과 같은 역할을 한다.
- build/ : Solidity 코드를 컴파일한 내용이 json 파일 형태로 build 디렉토리 안에 저장된다.
- contracts/ : 스마트 컨트랙트 코드를 작성하는 디렉토리
- migrations/ : deploy(배포) 관련 코드를 컨트랙트 별로 모아놓은 디렉토리
- test/ : 스마트 컨트랙트 관련 테스트 코드를 작성하는 디렉토리
- truffle-config.js : truffle 환경 설정 파일
👉 Solidity 코드 작성
contracts/ 디렉토리 안에서 다음과 같은 스마트 컨트랙트 코드를 작성해주었다.
/* contracts/ 디렉토리 HelloWorld.sol 파일 */
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15; // 버전
// HelloWorld 라는 컨트랙트 생성
contract HelloWorld {
string public value; // 상태 변수
constructor() {
value = 'Hello World!';
}
// 인스턴스에 있는 상태변수를 바꾸는 함수
function setValue(string memory _v) public {
value = _v;
}
}
👉 컴파일
터미널 창에서 다음과 같은 명령어를 입력하여 컴파일을 진행해준다.
$ npx truffle compile
build/ 디렉토리 안에 contracts/ 디렉토리가 생성되며 HelloWorld.json 파일이 생성되는 것을 확인할 수 있다. 생성된 json 파일 안에는 abi, bytecode 등에 관한 내용들이 들어있게 된다.
👉 truffle-config.js 파일 설정
배포를 진행하기에 앞서 truffle-config.js 파일 안에서 어떤 네트워크에 배포할 것인지에 대한 설정을 해줘야만 한다. truffle-config.js 파일 안에 작성된 내용들 중 networks 부분에 다음과 같이 스마트 컨트랙트를 배포하고자 하는 네트워크에 대한 정보를 넣어준다. ( 현재 ws://127.0.0.1:9005 로 geth를 실행시켜 놓은 상태이다. )
/* truffle-config.js 파일 */
networks: {
development: {
host: '127.0.0.1', // Localhost (default: none)
port: 9005, // Standard Ethereum port (default: none)
network_id: '*', // Any network (default: none)
websockets: true,
},
}
👉 배포하기
배포를 진행하기 위해서는 migrations/ 디렉토리 안에서 다음과 같은 배포 관련 코드를 작성한 파일을 만들어줘야 한다. 배포 관련 코드는 npx truffle init 명령어로 인해 자동 생성되었던 1_initial_migration.js 파일 안에 작성된 코드 형식을 따라서 작성하면 된다.
/* migrations/ 디렉토리 2_deploy_HelloWorld.js 파일 */
const helloworld = artifacts.require('HelloWorld');
// build 디렉토리 안의 json 파일 가져오기
module.exports = function (deployer) {
deployer.deploy(helloworld);
};
작성된 코드의 대략적인 내용은 다음과 같다.
- artifacts.require('컴파일 후 생성된 json 파일명') : 계약 정보를 읽어오는 코드
- deployer : truffle이 제공해주는 배포를 위한 툴
- deployer.deploy('읽어온 계약 정보')
참고로 migration/ 디렉토리 안에 배포 관련 코드가 작성된 파일을 만들 때 파일명은 [번호]_[내용]_[컨트랙트 이름].js 와 같은 형식으로 만들어주도록 하자.
이제 터미널에서 다음과 같은 명령어를 입력해 배포를 진행해주면 된다.
$ npx truffle migration
위와 같이 migration/ 디렉토리 안에 있는 파일명의 번호 순서대로 배포가 진행되는 것을 확인할 수 있다. 이제 블록을 마이닝 해주기만 하면 다음과 같은 내용이 출력되면서 우리가 작성한 HelloWorld 스마트 컨트랙트가 이더리움 네트워크 상에 배포된다.
truffle의 경우 migration이 한번 진행되어 배포가 완료되었다면 자체적으로 재배포를 방지해준다. 이럴 경우 migration을 진행할 때 아래와 같은 옵션을 추가하면 재배포를 진행할 수 있다.
$ npx truffle migration --reset
👉 truffle console : 배포 확인 및 스마트 컨트랙트 실행
우리가 작성한 스마트 컨트랙트가 제대로 배포되었는지 truffle 콘솔창을 통해 확인해보고자 한다. 터미널에서 다음의 명령어를 입력하면 truffle 콘솔창을 사용할 수 있다.
$ npx truffle console
truffle(development) > 와 같은 창이 터미널에 나타났다면 위에서 배포했던 스마트 컨트랙트인 HelloWorld를 입력해보자. HelloWorld 컨트랙트와 관련된 내용들이 출력되는 것을 확인할 수 있을 것이다. 다음으로 HelloWorld.address를 입력하면 스마트 컨트랙트 배포시 반환받게 되는 CA를 조회할 수 있다.
이제 배포된 스마트 컨트랙트를 콘솔창에서 실행시켜 보도록 하자.
HelloWorld.deployed().then(instance => hello = instance)
deployed( ) 는 truffle에서 제공해주는 메소드로 Promise 객체를 반환한다. 따라서 HelloWorld.deployed( ) 를 통해 배포된 HelloWorld 컨트랙트를 가져온 다음 .then( ) 메소드를 사용해 전역변수 hello에 HelloWorld 컨트랙트에 의해 생성된 instance를 할당해주었다. 이제 truffle 콘솔창에서 아래와 같이 hello를 사용해 스마트 컨트랙트 관련 내용을 조회하거나 컨트랙트를 실행시킬 수 있다.
스마트 컨트랙트 안에 존재하는 상태변수의 값을 가져오기 위해 getter 함수인 value를 호출하면 다음과 같이 상태변수 값이 콘솔창에 나타나는 것을 확인할 수 있다.
hello.value.call()
상태변수 값을 바꿔주는 setValue( ) 함수를 호출할 경우 트랜잭션이 발생되며 txpool에 트랜잭션이 담기게 된다.
hello.setValue('Hello Truffle!')
이후 geth 콘솔창에서 miner.start( ) 메소드를 사용해 마이닝을 진행해주면 트랜잭션이 블록 안에 담기면서 스마트 컨트랙트가 실행된다. 그리고 truffle 콘솔창에는 다음과 같은 정보가 출력된다.
다시 getter 함수를 호출해 상태변수의 값을 조회해 보면 setValue( ) 함수의 인자값으로 전달했던 'Hello Truffle!' 로 그 값이 변경된 것을 확인할 수 있다.
👉 테스트 코드 작성
마지막으로 test/ 디렉토리 안에서 HelloWorld.test.js 파일을 만들어 테스트 코드를 작성해보고자 한다.
/* test/ 디렉토리 HelloWorld.test.js 파일 */
const HelloWorld = artifacts.require('HelloWorld');
// contract 안에서 작성할 시 배포 진행
contract('HelloWorld', (account) => {
console.log(account); // eth.getAccounts()
let hello;
describe('Hello Contract', () => {
it('Hello World Contract', async () => {
hello = await HelloWorld.deployed();
});
it('get value', async () => {
console.log(await hello.value.call());
});
it('set value', async () => {
await hello.setValue('Hello Truffle!');
console.log(await hello.value.call());
});
});
});
작성된 테스트 코드를 실행시키기 위해서는 터미널에서 다음과 같은 명령어를 입력하면 된다.
$ npx truffle test
contract( ) 안에서 테스트 코드를 작성할 시 truffle에서 자동으로 배포를 진행하게 되며 it( 'set value', ( )=>{ } ) 코드 안에서 hello.setValue( ) 메소드를 사용해 트랜잭션을 발생시켰으므로 마이닝을 해줘야만 테스트 결과를 확인할 수 있다. 마이닝이 완료되면 다음과 같이 터미널 창에 테스트 결과가 나타나며 이를 통해 스마트 컨트랙트가 제대로 배포되었는지 스마트 컨트랙트 코드가 제대로 실행되는지를 확인할 수 있다.
'Ethereum' 카테고리의 다른 글
Ethereum/이더리움 - 스마트 컨트랙트 이벤트 등록 및 백엔드에서 트랜잭션 생성하기 (0) | 2022.07.14 |
---|---|
Ethereum/이더리움 - 메타마스크를 통한 스마트 컨트랙트 실행 (0) | 2022.07.13 |
Ethereum/이더리움 - JavaScript로 스마트 컨트랙트 배포 및 실행 (0) | 2022.07.12 |
Ethereum/이더리움 - 스마트 컨트랙트 배포 및 실행 (3) | 2022.07.11 |
Ethereum/이더리움 - private 네트워크 RPC 설정하기 (1) | 2022.07.01 |