EOS 스마트 컨트랙트 Set up(Hello World!)
EOS 스마트 컨트랙트로 Hello world를 출력하는 예제를 작성해 보도록하겠다.
기본적인 개발 환경 세팅은 EOS 개발환경 설치 및 실행 포스트에서 진행해야하며, 이 글의 원본은 EOS 공식 Git 예제를 참조했다.
nodeos 실행
Hello world 로그 확인을 위해 — contracts-console 옵션을 추가하여 실행시킨다.
nodeos --contracts-console
컨트랙트 생성
nodeos를 띄운 터미널 외에 다른 터미널에서 아래와 같은 명령어를 입력하여 eos 디렉토리로 접근하여 hello 폴더를 생성하자
$ cd eos
$ cd mkdir hello
$ cd hello
그리고 hello.cpp 파일을 만들어 아래의 예제를 복사하여 붙여넣어준다. hello 컨트랙트는 EOS.IO가 제공하는 라이브러리중 contract를 상속 받으며, print 함수로유저 이름에 “Hello,”를 붙여 출력하는 hi 함수를 가지고 있다.
코드 컴파일
- 첫번째 명령어로 코드를 웹 어셈블리로 컴파일 하자, 컴파일 시 경고가 출력될수 있으나 무시해도 상관없다.
- 두번째 명령어로 abi를 생성한다.
# 웹 어셈블리 컴파일
eosiocpp -o hello.wast hello.cpp# abi 생성
eosiocpp -g hello.abi hello.cpp
계정 생성 및 컨트랙트 배포
- hello.code라는 account를 생성해준다. 우리는 이 계정으로 hello 컨트랙트를 배포할 것이다.
- ‘cleos set contract ${account} ${path} -p ${permmition}’ 명령으로 컨트랙트를 배포한다.
$ cleos create account eosio hello.code EOS8QMGRoRPZ4uf3w8WACcrg3wKzLtXpCk5Gpia6pdFzSuftLigWT EOS8QMGRoRPZ4uf3w8WACcrg3wKzLtXpCk5Gpia6pdFzSuftLigWTexecuted transaction: e6847fc85c7733dd70a9ff27c2cad98ea0b50fb6c80c2b0c7ea1bf64f9917916 200 bytes 225 us# eosio <= eosio::newaccount {"creator":"eosio","name":"hello.code","owner":{"threshold":1,"keys":[{"key":"EOS8QMGRoRPZ4uf3w8WACc...$ cleos set contract hello.code ../hello -p hello.codeReading WAST/WASM from ../hello/hello.wasm...Using already assembled WASM...Publishing contract...executed transaction: 7e1b070382188677e70cf4b87e8fbe02c072f10063983ffc1d8259b127d8fea7 1800 bytes 723 us# eosio <= eosio::setcode {"account":"hello.code","vmtype":0,"vmversion":0,"code":"0061736d01000000013b0c60027f7e006000017e600...# eosio <= eosio::setabi {"account":"hello.code","abi":"0e656f73696f3a3a6162692f312e30000102686900010475736572046e616d6501000...
함수 호출
그럼 hello 클래스의 hi 함수를 호출해 보도록하겠다. 다음의 명령어로 함수를 호출할 수 있다.
cleos push action ${contract_name} ${function} ${[argument]} -p ${permission}
아래 예제에서는 user 계정이 hello.code 컨트랙트의 hi 함수를 호출했다.
$ cleos push action hello.code hi '["user"]' -p userexecuted transaction: d7932d1ee61ab6b0fed1f9e20d4a2e2607b029763aeaf1daea4ed718d2885797 104 bytes 500 us# hello.code <= hello.code::hi {"user":"user"}
결과
nodeos 터미널에 트랜잭션이 실행된 블럭에서 다음과같은 출력이 추가된다. “Hello, ” 뒤에는 hi 함수를 호출한 사용자 명이 따라 온다.
2703777ms thread-0 apply_context.cpp:28 print_debug ][(hello.code,hi)->hello.code]: CONSOLE OUTPUT BEGIN =====================Hello, user[(hello.code,hi)->hello.code]: CONSOLE OUTPUT END =====================
extra) require로 실행 권한 부여
- hello.cpp에서 아래와 같이 require_auth가 추가된 hi 함수로 교체해준다.
결과
- 권한이 없는 계정으로 호출 시 첫번째와 같은 에러가 발생한다.
- 권한이 있는 계정은 정상적으로 출력된다.
# 권한 없음$ cleos push action hello.code hi '["tester"]' -p userError 3090004: missing required authority# 권한 있음$ cleos push action hello.code hi '["tester"]' -p testerexecuted transaction: 16a34c27c7d162dc3940358197306df619911fb930cbddd6d208125a770886f4 104 bytes 243 us# hello.code <= hello.code::hi {"user":"tester"}
- nodeos의 블럭에서 로그는 다음과 같이 출력된다.
2525788ms thread-0 http_plugin.cpp:405 handle_exception ] FC Exception encountered while processing chain.push_transaction2525788ms thread-0 http_plugin.cpp:406 handle_exception ] Exception Details: 3090004 missing_auth_exception: missing required authoritymissing authority of tester {"account":"tester"}thread-0 apply_context.cpp:132 require_authorization {"_pending_console_output.str()":""}thread-0 apply_context.cpp:62 exec_one