LoginSignup
46
45

More than 5 years have passed since last update.

Web3.jsを使ってJavaScriptからEthereumのスマートコントラクトを制御する

Last updated at Posted at 2017-08-14

はじめに

以前CounterPartyを使って、独自コインを発行してみましたが、今回はEthereumを使った方法で独自コインを発行して、JavaScriptから制御する方法の覚書です。

先ずはプライベートネットの構築

http://qiita.com/oggata/items/eea4d5e37f38785f6079
を参考にGethで環境を作成して起動しておく。

geth --mine --unlock 0,1 --ipcpath="/tmp/geth.ipc" --minerthreads 2 --identity "sampleNode" --rpc --rpcport 8545 --rpcapi "web3,eth,net,personal" --rpccorsdomain "*" --rpcaddr "0.0.0.0" --datadir "/Users/hoge/eth_private" --nodiscover --networkid 10 console 2>> /Users/hoge/eth_private/geth.log

スマートコントラクトの用意

https://www.ethereum.org/token
を参考にするとトークンの作成方法が紹介されています。
今回は説明のために、もっとも基本的なexampleである
「MINIMUM VIABLE TOKEN」
を使ってみます。

スクリーンショット 2017-08-14 13.20.16.png

上記のようにコードを貼り付けて1000コインをcreateしてみます。
その後、transferを押下して作成したアドレスを見ると残高1000になっています。

node環境の構築とセットアップ

npm install web3@^0.20.0

サンプルスクリプトを用意する

create_account.js
var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));
var _account = web3.personal.newAccount("test");
console.log(_account)
balance.js
#!/usr/bin/env node

var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));
web3.eth.defaultAccount=web3.eth.accounts[0]

//Contract details (bytecode, interface etc.)のInterfaceをabiとして貼り付ける
var abi = [{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"}],"payable":false,"type":"constructor"}];

var _balance = web3.eth.contract(abi).at("コントラクトのaddress").balanceOf("残高をみるアドレス");
console.log(_balance);
transfer.js
#!/usr/bin/env node
var Web3 = require('web3');
var web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));
web3.eth.defaultAccount=web3.eth.accounts[0]

var abi = [{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"}],"payable":false,"type":"constructor"}];

var _transfer = web3.eth.contract(abi).at("コントラクトのaddress").transfer.sendTransaction("送信先のアドレス",10);
console.log(_transfer);

コインを送ってみる

1.残高

node balance.js
{ [String: '1000'] s: 1, e: 3, c: [ 1000 ] }

2.送る

node transfer.js

3.pendingTransactionsをみて処理されるのを待つ

> eth.pendingTransactions
[{
    blockHash: null,
    blockNumber: null,
    from: "0xe176db0944a2119eed8a74f667e4298e1325987f",
    gas: 90000,
    gasPrice: 20000000000,
    hash: "0xd38936a7927a811a0c2c51d538da8af498f57af36d95077914c6b07587dda289",
    input: "0xa9059cbb0000000000000000000000009c7e20e44bec6085165c27183605245f22c00f23000000000000000000000000000000000000000000000000000000000000000a",
    nonce: 64,
    r: "0x881600ba0fac1885c081f0311f45b0e0abcbc16d377bbe9eefa6a138f8b1f0ab",
    s: "0x541c7d8ce387d8c23e2145d7eb22f3e98d76435e3f4c371bd1a5ad5bb3e797c9",
    to: "0x231cc3c04af5c5b64fb34ecb322e264981ec6af7",
    transactionIndex: null,
    v: "0x1b",
    value: 0

4.完了後

コインが移動している

node balance.js
{ [String: '990'] s: 1, e: 2, c: [ 990 ] }

コインの売買など、機能を足したい場合はこちらを参考

https://www.ethereum.org/token
(AUTOMATIC SELLING AND BUYINGなど)

Promise.allで非同期な値をまとめて取得

const abi = require('./abi.json');
const config = require('./config.json');
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider(config.httpProvider));

const tokenInfo = (contractAddress)=>{
    const contract = new web3.eth.Contract(abi,contractAddress);

    let workers = [
        contract.methods.name().call(),
        contract.methods.symbol().call(),
        contract.methods.totalSupply().call(),
        contract.methods.decimals().call()
    ];
    return Promise.all(workers).then(res=>{
        let decimals = res[3];
        let divisor = Math.pow(10,decimals);
        let totalSupply = res[2];
        totalSupply = Number(totalSupply)/divisor;
        return Promise.resolve({
            'name':res[0],
            'symbol':res[1],
            'totalSupply':totalSupply,
            'decimals':decimals,
        })
    }).catch(err=>{
        return Promise.reject(err);
    });
}

参考

web3js
https://github.com/ethereum/wiki/wiki/JavaScript-API
https://github.com/ethereum/web3.js/

web3-ethの使い方
http://web3js.readthedocs.io/en/1.0/web3-eth.html

46
45
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
45