[네뷸러스 DApp 개발 튜토리얼] 1. 스마트 컨트랙트 개발환경 구축
서문(Intro)
네뷸러스(Nebulas)는 NEO의 공동 창립자 2명과 Ant Financial의 블록체인 플랫폼 설계 팀장 출신이 모여 시작한 프로젝트입니다. 2018년 1분기에 메인넷이 런칭되었고 블록체인 플랫폼으로써 네뷸러스를 활용한 DApp을 개발할 수 있습니다. 또한 2018년 5월 7일부터 7월 2일까지 네뷸러스의 세 가지 핵심 기술 요소 중 하나인 Developer Incentive Protocol(DIP)에 기초한 인센티브 프로그램을 진행하여 현재 6800여개의 네뷸러스를 활용한 DApp이 개발되었습니다.
네뷸러스 플랫폼에서 스마트 컨트랙트 개발을 위해서 개발환경을 구축해보고 간단한 스마트 컨트랙트 예제를 작성하겠습니다.
네뷸러스는 맥과 리눅스를 지원하고 윈도우는 아직 지원하지 않습니다. 맥 OSX 기준으로 설명하겠습니다.
go-nebulas 설치
- 로컬에서 프라이빗 체인을 돌리기 위해 go-nebulas를 설치해야 합니다.
Golang 설치
- go-nebulas는 GO 언어로 개발되었기 때문에 GO를 설치해야 합니다:
brew install go
export GOPATH=/path/to/workspace
go-nebulas 소스코드 클론
mkdir -p $GOPATH/src/github.com/nebulasio
cd $GOPATH/src/github.com/nebulasio
git clone https://github.com/nebulasio/go-nebulas.git
cd go-nebulas
git checkout master
RocksDB 설치
- Homebrew를 통해 rocksdb를 설치합니다:
brew install rocksdb
Go 의존성 모듈 설치하기
Go-Nebulas의 Go 의존성 모듈은 Dep에 의해 관리됩니다.
Dep 설치하기
- Homebrew를 통해 Dep 설치하기:
brew install dep
brew upgrade dep
의존성 모듈 설치
프로젝트의 루트로 들어가서 Go-Nebulas의 의존성 모듈을 설치합니다:
cd $GOPATH/src/github.com/nebulasio/go-nebulas
make dep # 의존성 패키지를 설치합니다
네뷸러스의 NVM(네뷸러스 가상 머신)은 V8 자바스크립트 엔진에 의존합니다.
네뷸러스는 맥/리눅스용 v8 의존성 모듈을 개발했고 다음 명령어로 v8 의존성 패키지를 설치합니다.
make deploy-v8
Neb 빌드하기
Golang 의존성 모듈과 V8 의존성 패키지를 설치한 후에 go-nebulas 실행 파일을 빌드할 수 있습니다.
make build
빌드가 끝나고 나면 루트 디렉토리 내에 neb
실행파일이 있을 것입니다.
노드 실행하기
시드노드(Seed Node) 실행
conf/default/genesis.conf
에 genesis 블록에 대한 설정이 들어있고, conf/default/config.conf
에 시드노드에 대한 설정이 들어있습니다.
다음 명령어로 시드노드를 실행할 수 있습니다.
./neb -c conf/default/config.conf
마이너노드(Miner Node) 실행
conf/example/miner.conf
에 마이너노드에 대한 설정이 들어있습니다.
다음 명령어로 마이너노드를 실행할 수 있습니다.
./neb -c conf/example/miner.conf
로컬에서 블록 생성시간 단축하기
네뷸러스의 한 블록의 생성시간은 15초입니다. 그러나 위와 같은 로컬에서는 작동하고 있는 conf/default/genesis.conf
에서 정의된 21명의 마이너 중 오직 한 명의 마이너만 존재하기 때문에 새 블록을 얻기까지 315(=15*21)초를 기다려야 합니다. 따라서 로컬에서의 생산성 높은 개발을 위해서 몇몇의 설정파일들을 수정한 후 다시 neb
파일을 새로 빌드해야 합니다.
1.conf/default/genesis.conf
에서 dynasty
를 하나만 놔두고 다 제거합니다.
// for example:
dynasty: [
"n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE"
]
2.consensus/dpos/dpos_state.go
에서 DynastySize
를 21에서 1로 수정합니다.
3.conf/default/config.conf
에서 시드노드가 마이닝할 수 있도록 수정합니다.
chain {
datadir: "data.db"
keydir: "keydir"
genesis: "conf/default/genesis.conf"
- start_mine: false
+ start_mine: true
+ miner: "n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE"
+ coinbase: "n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE"
+ passphrase: "passphrase"
signature_ciphers: ["ECC_SECP256K1"]
}
4.노드를 새로 돌리기 위해 예전에 저장되었던 블록들을 제거합니다.
rm -rf *.db/
5.make build
커맨드를 실행하여 neb
파일을 새로 빌드합니다.
make build
이제 다음 명령어로 시드노드이자 마이너노드인 노드를 실행시킬 수 있습니다.
./neb -c conf/default/config.conf
노드를 실행하면 아래 터미널과 같이 보일 것입니다.
스마트 컨트랙트(Smart Contract)
스마트 컨트랙트 작성(Write Smart Contract)
이더리움은 스마트 컨트랙트 작성하기 위해서 솔리디티라는 언어를 사용하지만 네뷸러스는 자바스크립트와 타입스크립트를 지원합니다. 그럼 블록체인에 영구히 저장되는 숫자를 읽고 쓰는 간단한 스마트 컨트랙트 코드를 작성해보겠습니다.
class ExampleContract {
constructor() {
// `num`이라는 이름을 가진 프로퍼티를 스토리지에 정의합니다.
LocalContractStorage.defineProperty(this, "num");
}
init() {
// 컨트랙트를 배포할 때 실행되는 함수로 단 한 번만 실행됩니다.
// 생성자에서 정의한 프로퍼티는 다음과 같이 접근할 수 있습니다. 최초의 `num` 값을 0으로 설정했습니다.
this.num = 0;
}
// `num` 프로퍼티에 숫자를 저장합니다.
save(num) {
this.num = num;
return `${num} is saved`;
}
// `num` 프로퍼티에 저장되어 있는 숫자를 읽습니다.
read() {
return this.num;
}
}
module.exports = ExampleContract;
스마트 컨트랙트 배포(Deploy Smart Contract)
커맨드라인이나 웹 지갑을 이용하여 스마트 컨트랙트를 블록체인에 배포할 수 있습니다. 여기서는, UI가 편하게 되어있는 웹 지갑을 사용해서 스마트 컨트랙트를 배포하겠습니다. 웹 지갑은 web-wallet에서 클론해서 설치할 수 있습니다.
웹 지갑을 이용하여 스마트 컨트랙트 배포
1.Contract
탭에서 Deploy
메뉴로 들어간 뒤, code
필드에 위 코드를 붙여넣기합니다.
2.월렛 파일에는 keydir
폴더에 있는 n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE
를 업로드 후, 비밀번호를 passphrase
필드에 입력 후 언락합니다. 기본 비밀번호는 'passphrase'
입니다.
3.그러면 From Address
와 To Address
에 n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE
이 입력될 것이고 Balance
에 잔액이 나올 것입니다.
4.Test
버튼을 누른 후, 이상이 없으면 Submit
버튼을 눌러서 컨트랙트를 배포합니다. 다음 블록이 생성되는 시간인 15초를 기다리면 컨트랙트 배포가 성공했다는 것을 확인할 수 있고 스마트 컨트랙트 주소를 확인할 수 있습니다.
5.위 그림에서 이미지 오른쪽 아래 부분에 txhash
가 있는데 저 부분을 클릭하면 트랜잭션 전송 진행상황을 확인할 수 있고 스마트 컨트랙트 주소를 확인할 수 있습니다.
스마트 컨트랙트 호출(Call Smart Contract)
save
함수 호출
1.Contract
탭에서 Call
메뉴로 들어간 뒤 function
필드에 함수 이름 save
를 입력하고, arguments
필드에 [777]
를 입력합니다. (컨트랙트를 호출할 때 인자는 배열 타입으로 들어갑니다.)
2.지갑 파일을 업로드하고 언락한 다음 To Address
필드에 위에서 배포했던 스마트 컨트랙트 주소를 채워넣습니다.
3.Test
버튼을 누르면 아래 이미지와 같이 result
값에 777 is saved
로 결과값이 나온 것을 확인할 수 있습니다.
4.Submit
버튼을 누르면 스마트 컨트랙트의 save
함수가 실행되고, 다음과 같이 txhash가 생성되는데, txhash를 통해 트랜잭션의 상태를 확인할 수 있습니다.
read
함수 호출
위에서 컨트랙트의 save
함수를 통해 스마트 컨트랙트의 num
프로퍼티에 숫자 777
을 저장했습니다. 저장이 잘되었는지 read
함수를 호출해서 확인해보겠습니다.
1.function
필드에 read를
채우고 arguments
필드에는 아무것도 채워넣지 않습니다.
2.위와 마찬가지로 지갑 파일을 업로드하고 언락한 후, To Address
필드에 스마트 컨트랙트 주소를 채워넣습니다.
3.Test
버튼을 클릭하면 result에
777
이 나오는 것을 확인할 수 있습니다. read
는 단지 데이터를 읽는 함수이기 때문에 Submit
할 필요가 없습니다.
마치며(Conclusion)
go-nebulas
를 설치해서 네뷸러스 노드를 로컬에서 실행해보고 간단한 스마트 컨트랙트를 작성하고 배포하고 호출해보았습니다.
이더리움의 솔리디티와는 다르게 자바스크립트 혹은 타입스크립트로 스마트 컨트랙트를 작성할 수 있어서 접근하기가 매우 편했습니다. 네뷸러스가 아직 이더리움보다 개발 생태계가 크진 않지만 네뷸러스가 Developer Incentive Protocol, Bounties와 같은 개발 생태계를 위한 여러가지 프로그램을 진행하고 있기 때문에 개발 생태계가 곧 커질 것이라 믿습니다.
다음에는 스마트 컨트랙트에서 네뷸러스가 제공하는 내장된 라이브러리를 사용하는 법과 neb.js를 사용하여 웹 클라이언트에서 어떻게 스마트 컨트랙트와 상호작용하는지에 대해서 알아보겠습니다.
참고
크으~ 역시 과외 스승님~! 멋져요! 많이 공부하겠습니다.
코신트 수장님께서 이런 누추한곳까지... 서로 많이 배웠으면 좋겠습니다 ㅎㅎ