이더리움 Dapp만들기 [6. web3.js를 이용해서 geth와 통신하기]

in #kr6 years ago (edited)

geth콘솔을 이용해서 배포한 스마트 컨트랙트를 web3.js를 이용하면 웹에서 사용할 수 있습니다. web3.js는 이더리움에서 제공하는 javascrript API입니다.

web3.js 다운로드와 geth 연결

해당 링크로 가서 web3.min.js를 다운받습니다. 이 번에 사용할 web3.js 버전은 0.20.6 입니다. https://github.com/ethereum/web3.js/tree/v0.20.6/dist

해당 파일 다운로드가 완료되었으면 test.html로 에디터로 문서를 만들겠습니다.
가장 먼저 해야할 건 web3.min.js를 html문서에 포함시키는 겁니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset=”UTF-8”>
    <title>web3 test</title>
    <script type=”text/javascript” src=”web3.min.js”></script>
</head>
<body>
</body>
</html>

여기까지 완료하고 test.html문서를 열어서 에러 문구가 나타나지 않으면 web3.min.js 가 성공적으로 로딩이 완료된겁니다. 그럼 web3를 이용해서 geth와 연결하는 방법을 알아보겠습니다. (geth가 실행중이여야 합니다!!!!!!!!!!!!!!!!)

web3.min.js를 불러오는 태그 밑에 script태그를 만들고 그 안에 자바스크립트 코드를 작성하겠습니다.

<head>
    <meta charset=”UTF-8”>
    <title>web3 test</title>
    <script type=”text/javascript” src=”web3.min.js”></script>
    <script type=”text/javascript”>
        var Web3 = require(‘web3’);
        var web3 = new Web3( new Web3.providers.HttpProvider(“http://localhost:8545”));
        var network_version = web3.version.network;
        console.log(network_version);
    </script>
</head>

var Web3 = require(‘web3’) 는 web3모듈을 로딩해서 변수 Web3에 할당하는 구문입니다.
var web3 = new Web3()는 web3 객체를 생성해서 변수 web3에 할당하는 구문이며 new Web3()안에 삽입된 구문은 web3객체와 geth콘솔과 연결하는 구문입니다.

new Web3.providers.HttpProvider(“http://localhost:8545”)

HttpProvider함수를 사용해서 geth와 연결하며 파라미터로 연결하고 싶은 geth의 도메인과 rpc port넘버를 사용하면 됩니다. geth를 실행할 때 rpc port를 명시하지 않았으면 8545가 설정됩니다.

geth와 잘 연결이 됐는지 web3를 이용해서 연결된 geth의 network 정보를 출력해보겠습니다.

var network_version = web3.version.network;
console.log(network_version);

아래와 같이 geth 옵션에서 사용한 네트워크 아이디가 출력되는 걸 확인할 수 있습니다.

01.png

web3.js로 이더 전송하기

web3와 geth 연결을 확인했으니 web3를 이용해서 이더를 전송해보겠습니다. web3.eth.accounts 를 사용하면 연결된 geth의 모든 계좌의 주소를 가져올 수 있습니다.
web3.eth.sendTransaction()함수를 사용하면 트랜잭션을 실행시킬 수있습니다.
sendTransaction함수는 Transacton Object와 callback함수를 파라미터로 받습니다.
Transaction Object는 이더를 전송할 from, 이더를 받은 to, 전송할 이더의 양 value 을 명시해주면 됩니다. (그 외에 gas, gasPrice, nonce, data 를 옵션으로 지정할 수 있습니다.)

첫 번째 계좌에서 두 번째 계좌로 1000 wei를 보내겠습니다.

<script type=”text/javascript”>
    var Web3 = require(‘web3’);
    var web3 = new Web3( new Web3.providers.HttpProvider(“http://localhost:8545”));
    var network_version = web3.version.network;
    console.log(network_version);


    var accounts = web3.eth.accounts;  //account 정보 가져오기
    var from_account = accounts[0];
    var to_account = accounts[1];

    var transactionObj = { //transaction object 설정
        from: from_account,
        to:to_account,
        value: 1000
};

web3.eth.sendTransaction(transactionObj)
</script>

이렇게 작성을 하고 실행을 시키기 전에 geth에서 첫 번째 계좌의 락을 풀어줘야 합니다. geth 콘솔창에서

personal.unlockAccount(eth.accounts[0])

를 입력해서 락을 풀어준 후에 html문서를 실행시킵니다.
아! 마이닝도 실행시켜줘야 합니다!!!!! geth 콘솔창에서 miner.start()를 입력합니다.

마이닝이 됐으면 geth콘솔창에서 eth.getBalance(eth.accounts[1])을 실행해서 제대로 수행됐는지 확인해보면 됩니다!

02.png

web3.js를 이용해서 컨트랙트 사용하기

web3를 이용해서 private network에 배포된 스마트 컨트랙트를 사용하는 법을 알아보겠습니다. solc 컴파일러를 사용해서 geth에서 스마트 컨트랙트를 사용할 때 알아야할 정보가 두 가지 였습니다. 첫 번째는 컨트랙트의 abi, 두 번째는 배포된 컨트랙트의 주소!

web3에서도 이 두 개의 정보를 사용해서 컨트랙트와 연결합니다. 5번째 글(https://busy.org/@pangol/dapp-5-solc) 에서 배포한 컨트랙트를 사용하도록 하겠습니다.

<script type=”text/javascript”>
    var Web3 = require(‘web3’);
    var web3 = new Web3( new Web3.providers.HttpProvider(“http://localhost:8545”));
    var from_account = accounts[0];
    
//contract abi 설정
    var contractAbi = [{"constant":false,"inputs":[{"name":"_data","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}];

    //배포된 컨트랙트 주소 설정
                var contractAddress = "0x2a2d085b683c995e5155260d044db06d117fb666";
                
var contract = web3.eth.contract(contractAbi);
                var contractInstance = contract.at(contractAddress);

                var result = contractInstance.get()
                console.log(result.toString());
</script>

abi와 주소를 설정한 후 web3.eth.contract()안에 abi를 인자로 넘기고 컨트랙트를 인터페이스를 설정하고 contract.at()함수를 사용해서 컨트랙트의 인스턴스를 할당 받습니다. 그럼 배포된 컨트랙트를 사용할 수 있습니다. get()을 이용해서 data에 저장된 숫자를 출력합니다.

web3.js에서는 bignumber 라이브러리를 사용해서 숫자를 처리하기 때문에 result.toString() 또는 result.toNumber()를 붙이지 않고 result만 출력하게 되면 숫자가 아닌 객체가 출력되니 유의하시기 바랍니다.

03.png

마지막으로 컨트랙트의 set함수를 사용해서 컨트랙트 변수의 값을 변경해보겠습니다. set함수는 get함수와 다르게 변수의 값을 변화시키기 때문에 transaction object를 인자로 같이 넘겨줘야 합니다.

contractInstance.set(1000, {from:eth.accounts[0]})

transaction을 전송하기 때문 eth.accounts[0]의 락이 풀린 상태여야 합니다. 마이닝을 한 후, 값을 확인해보면 변경된 걸 볼 수 있습니다.

web3에 대해서 자세히 알고 싶은 분은 https://github.com/ethereum/wiki/wiki/JavaScript-API 에서 확인해보시면 됩니다.

Sort:  

(jjangjjangman 태그 사용시 댓글을 남깁니다.)
호출에 감사드립니다! 즐거운 스티밋하세요!

감사합니다 :)