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문서에 포함시키는 겁니다.
web3 test
여기까지 완료하고 test.html문서를 열어서 에러 문구가 나타나지 않으면 web3.min.js 가 성공적으로 로딩이 완료된겁니다. 그럼 web3를 이용해서 geth와 연결하는 방법을 알아보겠습니다. (geth가 실행중이여야 합니다!!!!!!!!!!!!!!!!)
web3.min.js를 불러오는 태그 밑에 script태그를 만들고 그 안에 자바스크립트 코드를 작성하겠습니다.
web3 test
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 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 옵션에서 사용한 네트워크 아이디가 출력되는 걸 확인할 수 있습니다.
[IMAGE: https://ipfs.busy.org/ipfs/QmadCwFu8tEgVcRg2LZxMvWtVnh2VfPcV8K9SzwjTHban8]
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를 보내겠습니다.
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)
이렇게 작성을 하고 실행을 시키기 전에 geth에서 첫 번째 계좌의 락을 풀어줘야 합니다. geth 콘솔창에서
personal.unlockAccount(eth.accounts[0])
를 입력해서 락을 풀어준 후에 html문서를 실행시킵니다.
아! 마이닝도 실행시켜줘야 합니다!!!!! geth 콘솔창에서 miner.start()를 입력합니다.
마이닝이 됐으면 geth콘솔창에서 eth.getBalance(eth.accounts[1])을 실행해서 제대로 수행됐는지 확인해보면 됩니다!
[IMAGE: https://ipfs.busy.org/ipfs/QmRyCPccTJ2xKpdom5WrnRek3djwDor8wWjhcyGGJgMPbQ]
web3.js를 이용해서 컨트랙트 사용하기
web3를 이용해서 private network에 배포된 스마트 컨트랙트를 사용하는 법을 알아보겠습니다. solc 컴파일러를 사용해서 geth에서 스마트 컨트랙트를 사용할 때 알아야할 정보가 두 가지 였습니다. 첫 번째는 컨트랙트의 abi, 두 번째는 배포된 컨트랙트의 주소!
web3에서도 이 두 개의 정보를 사용해서 컨트랙트와 연결합니다. 5번째 글(https://busy.org/@pangol/dapp-5-solc) 에서 배포한 컨트랙트를 사용하도록 하겠습니다.
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());
abi와 주소를 설정한 후 web3.eth.contract()안에 abi를 인자로 넘기고 컨트랙트를 인터페이스를 설정하고 contract.at()함수를 사용해서 컨트랙트의 인스턴스를 할당 받습니다. 그럼 배포된 컨트랙트를 사용할 수 있습니다. get()을 이용해서 data에 저장된 숫자를 출력합니다.
web3.js에서는 bignumber 라이브러리를 사용해서 숫자를 처리하기 때문에 result.toString() 또는 result.toNumber()를 붙이지 않고 result만 출력하게 되면 숫자가 아닌 객체가 출력되니 유의하시기 바랍니다.
[IMAGE: https://ipfs.busy.org/ipfs/Qma5uxGhuEivLommLBNs8AZfPWRkpmMp1VcRExnFpXN7c9]
마지막으로 컨트랙트의 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 에서 확인해보시면 됩니다.