5.1 EOSJS 설치 및 웹에서 사용하기

앞서 개발한 EOS 프로젝트들은 cleos를 이용한 명령어를 통해서만 접근했습니다. EOSJS API를 이용하면 웹과 스마트 컨트랙트를 연동하여 DApp을 쉽게 사용할 수 있습니다. EOSJS는 EOSIO RPC API를 사용하여 EOSIO 기반의 블록체인과 통합하기 위한 Javascript API 입니다. 쉽게 말하면, EOS 블록체인을 Javascript로 쉽게 컨트롤 할 수 있게 만들어 놓은 라이브러리 입니다.

EOSJS 설치

EOSJS를 사용하기 위해서는 Contract와 연동할 웹 사이트, 혹은 웹 서버가 필요합니다. 웹 사이트의 경우 다음과 같이 CDN을 이용해서 EOSJS를 사용할 수 있습니다.

<script src="https://cdn.jsdelivr.net/npm/eosjs@15.0.6/lib/eos.min.js" integrity="sha512-QX0dPq5pyX33coEuy5x1UqKHFDeveQYMp7Sz+qOUwRL9mol4QDvViU+QAjd+k6P7QjPjrDCoyhK1kz2GDxCP9A=="crossorigin="anonymous"></script>

웹 서버의 경우에는 NodeJS를 이용해서 설치합니다. 설치 명령어는 다음과 같습니다.

$ npm install eosjs@beta

HTML을 활용한 야구 게임 연동하기

EOSJS를 이용하여 우리가 개발했던 야구 게임과 HTML 웹 사이트를 연동하겠습니다. 웹사이트에서 버튼을 클릭하는 간단한 액션으로 트랜잭션이 생성될 수 있도록 구현하겠습니다.

다음의 코드로 HTML파일을 생성합니다.

<HTML> <head> <meta charset="utf-8"> <script src="https://cdn.jsdelivr.net/npm/eosjs@15.0.6/lib/eos.min.js" integrity="sha512-IDRAIcOGQTZN3jE/TvTiG3czpjzmWPiYi0+mwWbJVdYwPfbhD2YtzlpD4+rKE+MIuysseAenToyLNoO1whNFUg==" crossorigin="anonymous"></script> <script> config ={ chainId:'cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f', keyProvider: ['5J65pj2idRRtebqDHnA2DWHTiermZkwAxxPRCNT1JjiwrQRFr3p','5JqznY4X9JueqvNunT61PhRAHDZE2CG3iywbCpFevDyZSmopTZt'], // WIF string or array of keys.. } eos = Eos(config) function start(){ eos.contract('devtooth').then( function(contract){ return contract.start('devtooth',{authorization:['devtooth@active']})}).then( function(result){}).catch(e=>{console.error("catch : " + e)}); } function throwball(){ var guessnum = document.getElementById('num').value; eos.contract('devtooth').then( function(contract){ return contract.throwball('devtooth',guessnum,{authorization:['devtooth@active']})}).then( function(result){}).catch(e=>{console.error("catch : " + e)}); } </script> </head> <body> <ul> See console object: Eos <button onclick="start()">start</button> </ul> <ul> Guess the goal num <li><input id="num" type="text"></li> <button onclick="throwball()">throwball</button> </ul> </body> </HTML> <script src="https://cdn.jsdelivr.net/npm/eosjs@15.0.6/lib/eos.min.js" integrity="sha512-IDRAIcOGQTZN3jE/TvTiG3czpjzmWPiYi0+mwWbJVdYwPfbhD2YtzlpD4+rKE+MIuysseAenToyLNoO1whNFUg=="crossorigin="anonymous"></script>
config ={
      chainId:'cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f',
           keyProvider: ['5J65pj2idRRtebqDHnA2DWHTiermZkwAxxPRCNT1JjiwrQRFr3p','5JqznY4X9JueqvNunT61PhRAHDZE2CG3iywbCpFevDyZSmopTZt'], // WIF string or array of keys..
   }
eos = Eos(config)
EOSJS의 EOS객체를 선언하고, 위에서 설정한 config 값으로 옵션을 설정합니다.

function start(){
     eos.contract('devtooth').then(
      function(contract){
        return contract.start('devtooth',{authorization:['devtooth@active']})}).then(
      function(result){}).catch(e=>{console.error("catch : " + e)});
   } 
야구 게임의 start action을 실행하는 트랜잭션을 생성하는 함수를 정의합니다. eos Contract 객체에 contract명을 인자값으로 입력하여 스마트 컨트랙트를 연결합니다. 
연결된 contract의 action은 contract.action_name(args1, args2, ...argsN, {authorization:[권한]} 명령어로 실행합니다. 

function throwball(){
     var guessnum = document.getElementById('num').value;
     eos.contract('devtooth').then(
      function(contract){
        return contract.throwball('devtooth',guessnum,{authorization:['devtooth@active']})}).then(
      function(result){}).catch(e=>{console.error("catch : " + e)});
   } 

<button onclick="start()">start</button> <li><input id="num" type="text"></li> <button onclick="throwball()">throwball</button>

EOSJS.HTML 실행

방금 작성한 HTML 코드를 실행을 해보겠습니다. HTML 파일로 저장하고 로컬 노드를 실행한 뒤, 테스트를 진행합니다. EOSJS.HTML 파일을 실행하면 다음과 같은 웹 페이지가 출력됩니다.

 < html.page > 

로컬테스트넷 체인에 트랜잭션을 실행시키기 위해 Start 버튼을 클릭합니다.

 < 생성 중인 Block 화면 > 

..#39377 @ 2018-11-23TO8:38:36.500 signed by eosio [trxs: 0, lib: 39376, confirmed: 0]
2018-11-23TO8:38:37.001 thread-0 producer_plugin.cpp:1419   produce_block    ] Produced block .....
#39378 @ 2018-11-23TO8:38:37.000 signed by eosio [trxs: 0, lib: 39377, confirmed: 0]
2018-11-23TO8:38:37.501 thread-0 producer_plugin.cpp:1419   produce_block    ] Produced block .....
#39379 @ 2018-11-23TO8:38:37.501 signed by eosio [trxs: 0, lib: 39378, confirmed: 0]
2018-11-23TO8:38:38.000 thread-0 producer_plugin.cpp:1419   produce_block    ] Produced block .....
#39380 @ 2018-11-23TO8:38:38.000 signed by eosio [trxs: 0, lib: 39379, confirmed: 0]
2018-11-23TO8:38:38.501 thread-0 producer_plugin.cpp:1419   produce_block    ] Produced block .....
#39381 @ 2018-11-23TO8:38:38.500 signed by eosio [trxs: 0, lib: 39380, confirmed: 0]
2018-11-23TO8:38:39.000 thread-0 producer_plugin.cpp:1419   produce_block    ] Produced block …

블록정보를 살펴보면 아무것도 실행되지 않았습니다. 원인을 살펴보기 위해 EOSJS.HTML 화면에서 F12 키를 눌러줍니다.

 < html.page 오류확인 (개발자도구) > 

http://127.0.0.1:8888/v1/chain/get_info 에 엑세스할 수 없다며 에러가 출력됩니다. 이를 해결하기 위해서 구글 크롬 확장프로그램인 CORS를 설치해야 합니다.

CORS는 Cross Origin Resource Sharing의 약자로, 현재 도메인과 다른 도메인으로 리소스가 요청될 경우를 말합니다. 이런 경우에 해당 리소스는 cross-origin HTTP 요청에 의해 요청되는데, 보안상의 이유로 브라우저가 CORS를 제한합니다. 때문에 Contract와 연결되지 않는 것입니다.
이를 해결하기 위해선 서버의 응답헤더를 변경해야 합니다. 서버의 헤더중에 Acccess-Control-Allow-Origin 속성이 있는데, CORS를 허용해줄 도메인을 입력하는 곳입니다. 이곳을 변경해주면 문제가 해결되는데 이를 편하게 해주는 구글 크롬 확장 프로그램이 존재합니다.

 < Allow-Control-Allow-Origin 확장프로그램(in chrome 웹스토어) > 

구글 크롬 확장프로그램 스토어에서 Allow-Control-Allow-Origin:* 를 설치합니다.
설치가 완료되면 다음과 같이 확장프로그램 탭에 CORS 아이콘이 추가됩니다.

 < CORS아이콘 확인 이미지 > 

해당 아이콘을 누르고 다음과 같이 활성화 해줍니다.

 < CORS Setting 버튼 이미지 > 

이제 EOSJS.HTML을 새로고침 해줍니다. 그럼 다음과 같이 에러가 해결됩니다.

 < html.page 에러없는 화면 > 

EOSJS.HTML 파일에서 start 버튼을 클릭하여 Start action 트랜잭션을 발생시킵니다.

 < html.page start 버튼 이미지 > 

블록 생성 화면을 확인하면 다음과 같이 action이 실행됩니다.

 < action 실행 후 출력 화면 > 

3077743ms thread-0    apply_context.cpp:28	print_debug	]
[(devtooth,start)->devtooth]: CONSOLE OUTPUT BEGIN ===================
Baseball game start!!!
 create goal number
[(devtooth,start)->devtooth]: CONSOLE OUTPUT END =========================

이번엔 입력폼에 123을 입력하고 throwball 버튼을 눌러 throwball action을 실행 하겠습니다.

 < html.page 액션 실행 버튼(123 입력) > 

다음과 같이 결과가 출력 됩니다.

 < action 실행 후 출력 화면 (123입력) > 

3077743ms thread-0    apply_context.cpp:28	print_debug	]
3153545ms thread-0    apply_context.cpp:28	print_debug	]
[(devtooth,throwball)->devtooth]: CONSOLE OUTPUT BEGIN ===================
  Strike : 0    Ball  : 1
[(devtooth,start)->devtooth]: CONSOLE OUTPUT END =========================

하나의 숫자가 다른 위치에 있음을 알려주는 1ball이 출력되었습니다. 입력폼에 다시 456을 입력하고 다시 action을 실행하겠습니다.

 < html.page 액션 실행 버튼(456 입력) > 

다음의 결과가 출력되었습니다.

 < action 실행 후 출력 화면 (456입력) > 

3247960ms thread-0    apply_context.cpp:28	print_debug	]
[(devtooth,throwball)->devtooth]: CONSOLE OUTPUT BEGIN ===================
  Strike : 0    Ball  : 2
[(devtooth,throwball)->devtooth]: CONSOLE OUTPUT END =====================

2개의 숫자가 다른 자리에 위치해 있음을 알 수 있습니다.
이번엔 입력폼에 541을 입력하고 action을 실행해 보겠습니다.

다음의 결과가 출력됩니다.

3352727ms thread-0    apply_context.cpp:28	print_debug	]
[(devtooth,throwball)->devtooth]: CONSOLE OUTPUT BEGIN ===================
Homerun!! You Win.

[(devtooth,throwball)->devtooth]: CONSOLE OUTPUT END =====================

모든 숫자가 제자리에 들어가 게임에서 승리합니다.
이처럼 EOSJS를 이용하면, 웹과 Contract를 연동하여 사용자가 좀 더 쉽게 Contract를 사용 할 수 있게 됩니다. 이를 좀 더 응용하면 상용화 할 수 있는 dApp도 개발할 수 있습니다.


Prev | Next