Monday, October 29, 2018

Ethereum web3 filter로 transaction watch하기

이더리움에서 일반 이더를 송금할 때는 완료 이벤트를 받을 수가 없다.

따라서 다음과 같이 filter를 걸어서 block 안의 transactions에 우리가 원하는 transaction Hash가transactionHash가 포함되었는지를 확인함으로써 송금이 완료되었는지를 확인할 수 있다.

아래의 소스코드는 node.js로 작성하였다.

// 이더리움 web3에 접속
var EthConn = require('../contracts/ethconn.js');
var host = 'http://localhost:8545'
var ethconn = new EthConn(host);
console.log(ethconn.web3.eth.accounts);

var web3 = ethconn.web3;
var eth = web3.eth;
var personal = web3.personal;
var accounts = eth.accounts;

// 0번을 unlock
personal.unlockAccount(accounts[0], '1');
var txhash = eth.sendTransaction({
    from: accounts[0],
    to: accounts[1],
    value: web3.toWei(1, 'ether')
});
console.log(`txhash=${txhash}`);

var filterString = 'latest';
var filter = eth.filter('latest');

filter.watch((err, res) => {
    if (!err) {
        console.log(`res ${res}`);
        var block = eth.getBlock(res);
        console.log(`block ${JSON.stringify(block)}`);
        if (block.transactions.includes(txhash)) {
            filter.stopWatching();
            console.log(`${txhash} completed`);
            var receipt = eth.getTransactionReceipt(txhash);
            console.log(receipt);
        }
    } else {
        console.log(`err ${err}`);
    }
});
console.log('filter watch');

Ethereum web3.js에서 localhost 접속하기

이더리움에서 web3.js를 통해서 network에 접속하는 API를 제공받게 되는데 현재 버그가 존재한다.

web3.setProvider('http://localhost:8545')
not connected to provider

다음과 같은 곳에서 자료를 찾을수 있다. https://github.com/ethereum/web3.js/issues/1051

해결 방법 다음과 같이 package.json을 만들어서 local module로 관리한다.

npm install web3@0.20.0 --save
{
    "dependencies": {
        "request": "^2.83.0",
        "web3": "0.19.0"
    }
}
문제의 원인 npm으로 web3를 버전 없이 설치하였을 경우 web3@1.0.0-beta.x가 설치되는데 이 베타버전에서 localhost로 setProvider를 수행하는 과정에서 버그가 있었기 때문이다.

web3@1.0.0-beta.29

Android 외장 SD카드 메모리 경로 획득

public static String getExternalSdCardPath() {
    File root = Environment.getExternalStorageDirectory();
    if (root == null)
        return null;

    File parent = root.getParentFile();
    if (parent == null)
        return null;

    File storage = parent.getParentFile();
    if (storage == null)
        return null;

    File[] files = storage.listFiles();
    for (File file : files) {
        String path = file.getName();
        if (path.equals("emulated"))
            continue;
        if (path.equals("self"))
            continue;
        return file.getAbsolutePath();
    }
    return null;
}


Saturday, October 27, 2018

Node.js sequelize async로 sync하기

sequelize를 프로그램 시작시에 sync하기 위해서는 sequelize.sync()를 호출해줘야 하는데 이것은 Promise<any>를 리턴하여 바로 다음줄에 DB작업을 하기 위해서는 에러가 날 위험이 있다.

따라서 다음과 같이 async/await으로 변경하면 위험을 막을 수 있다.
async function sync() {
  console.log('sync begin')
  await sequelize.sync();
  console.log('sync end')
  // all tables created
}

sync();