Web3 Javascript API及常用操作

现今有许多Dapp Librarys可以用来跟Ethereum网络沟通,像是由Java撰写web3J,python的Web3.py和.Net的nethereum。今天要介绍的Web3.js则是由Javascript撰写的Ethereum JavaScript API。Web3.js提供了一些基本操作,譬如getBalane()、sendTransaction()…等,也可以利用Web3.js来帮我们布署smart contract到Ethereum网络上。使用者可以利用Web3.js提供的界面来跟Metamask或Geth Node,甚至是Ganache Testrpc互动。

PS: Ganache Testrpc是专门用来模拟私人Ethereum网络环境的工具,只在本地端的电脑上运行,资料只存放在Memory中。重开后等同于建立另一个全新的私人Ethereum网络。适合前期拿来开发Dapp功能。

 
Web3.js可以跟后端的Ethereum网络(Metamask或Geth)沟通或模拟的Ethereum网络(Ganache Trestrpc)

Web3.js API Overview

Web3.js Asynchronous

Web3.js的API有分成同步(Synchronous)和非同步(Asynchronous)的呼叫,非同步呼叫采用的是Error-First Callback的方式。

web3.eth.getSyncing(function(error, result) { 
    if(error) { 
        // error handle 
    } else { 
        // do something 
    } 
});

可以看到在web3.eth.getSyncing()的参数中注册了一个callback function,而且callback function中的第一个参数是放回传的error,第二个参数才是放回传的result。可以在callback function中针对回传的结果进行处理。

Web3.js API Type

Web3.js的API大约分成几个种类:

  • eth: Etherum blockchain related methods
  • net: Node's network status
  • personal: Account functions and sending
  • db: Get/put for local LevelDB
  • shh: P2P messaging using Whisper

Web3.js Big Number

Javascript不能正确的处理big number value,所以Web3.js使用了BigNumber library来处理。但即便使用了BigNumber也无法处理超过20个floating points。建议在处理balance的时候使用Wei来取代Ether会比较好。

Web3.js常用的操作

接下来会提到Web3.js几个比较常见和重要的操作。每个操作的范例都可以从Web3APIScript下载,范例就放在scripts资料夹中。

Web3 Get Node

判断目前使用者所连接是那种型态的Ethereum节点,Testrpc、Geth或Metamsak…等。

web3.version.getNode(function(error, result){ 
    if(error){ 
        // error handle 
    } else { 
        // do something 
    }; 
});

Web3 Syncing

判断使用者所连接的Ethereum节点是否正在做同步的动作。正在同步为True,否则为False。

web3.eth.getSyncing(function(error, result) { 
    if(error) { 
        // error handle 
    } else { 
        // do something 
    } 
});

Web3 Coinbase

查看连接Ethereum节点的coinbase address。coinbase是专门存放挖矿所获得奖励的read only帐户。在Geth Node环境下可以使用Geth console下指令web3.miner.setEtherbase()去修改coinbase address。

web3.eth.getCoinbase(function(error, result) { 
    if(error) { 
        // error handle 
    } else { 
        // do something 
    } 
});

Web3 Default Account

查看目前连接Ethereum节点的deault account address。deault account是read/write only。当我们在进行某些操作例如sendTransaction时,若没有特别指定要从哪一个帐户发出,则默认就是使用deault account。因为每个Ethereum节点实作的方式不同,default account不一定有定义,使用前最好检查一下。

web3.eth.defaultAccount//为了避免default account undefined的话,可以改写成下面的Code 
var defaultAccount = web3.eth.defaultAccount; 
if(!defaultAccount) { 
        web3.eth.defaultAccount = web3.eth.accounts[0]; 
        defaultAccont = web3.eth .accounts[0]; 
}

Web3 Get Balance

取得帐户里的余额。分成同步和非同步两种。使用web3.eth.getBalance()所获得余额的单位是Wei。web3.fromWei()就是把Wei转成其他单位,下面范例则是转成Ether。toFixed()是我们只取到小数点后两位数。getBalance()的第二个参数可以指定要从那个Block读取资料。web3.eth.defaultBlock默认是latest,意思就是从最新的Block读取该帐户的余额。

/* Get Balance Sync */ 
var balance = web3.fromWei(web3.eth.getBalance(web3.eth.accounts[0]), 'ether').toFixed(2);/* Get Balance Async */ 
web3.eth.getBalance(web3.eth.accounts[0],web3.eth.defaultBlock, 
    function(error,result){ 
        if(error){ 
            // error handle 
        } esle { 
            var balance = web3.fromWei(result,'ether').toFixed(2); 
       } 
    } 
);

Web3 Lock/Unlock Account

上锁和解锁帐户。对于某些特定的操作必须先把帐户先unlock才能进行,例如sendTransaction()相关操作。web3.personal.unlockAccount()的第三个参数duration可以设定要解锁多久。若使用者连接的Etherum节点是Testrpc或Metamask,可以不须作lock/unlock动作。若是在Geth环境下,则在sentd transaction前必须先unlock帐户。

/* Lock Account */ 
web3.personal.lockAccount(account, passwd, 
    function(error, result){ 
        if(error) { 
            // error handle 
        } else { 
            // do something 
        } 
    } 
);/* Unlock Account */ 
web3.personal.unlockAccount(account, passwd, duration 
    function(error, result){ 
        if(error) { 
            // error handle 
        } else { 
            // do something 
        } 
    } 
);

Web3 Send Transaction

传送交易。web3.eth.sendTransaction()的第一个参数txnObject是一个JSON format的物件。txnObject可以指定这次transaction的资讯。from是指从哪个帐户送出,若无指定默认是default account。to是送到那个帐户。value则是要传送的金额。其他还有像是gas、gasPrice、data、nonce …等参数可以指定。传送完后可以得到transaction hash,使用web3.eth.getTransactionReceipt( hash )去查询transaction的状态。

var txnObject = { 
    "from": fromAccount, 
    "to": toAccount, 
    "value": web3.toWei(1, 'ether'), 
    // "gas": 21000, // (optional) 
    // "gasPrice": 4500000, // (optional) 
    // "data": 'For testing', // (optional) 
    // "nonce": 10 // (optional) 
};web3.eth.sendTransaction(txnObject, function(error, result){ 
    if(error) { 
        // error handle 
    } else { 
        var txn_hash = result; //Get transaction hash 
    } 
});

Web3 Deploy Contract

Deploy contract有两种方式,一种是使用Web3.js contract的new(),另一种是使用sendTransaction()的方式。这里只列出contract new()的方式,sendTransaction()方式可以从Web3ApIScript的范例中看到。在deploy contract之前我们需要先complie contract的sol档来获得abi和bytecode。利用abiDefinition建立contractInstance并将bytecode放入data栏位中。constructor_param则是contract 初始化所使用的参数。使用contract new()来进行布署。执行完new()之后,callback function一共会被呼叫两次。第一次回传transaction hash,第二次则是contract address。

var contractInstance = web3.eth.contract(abi); 
var params = { 
    from: fromAccount, 
    data: bytecode, 
    gas: gas 
}; 
var constructor_param = 10; //contract init paramcontractInstance.new(constructor_param, params, 
    function(error, result){ 
        if(error) { 
            // error handle 
        } else { 
            if(result.address){ 
                var contractAddress = result.address; 
            } else { 
                var txhash = result.transactionHash ; 
            } 
        } 
});

Web3 Interact Contract

与smart contract互动的方式主要分成,取得contract资料的call和改变contract资料的send。使用call只是单纯取得contarct资料,并不会改变contract的状态,所以不会花费任何费用。呼叫call()时要有contract abi和contract address。contract. METHOD .call()的METHOD是放contract中所定义的function名称,以下面的例子就是getNum。

var contract = web3.eth.contract(abi); 
var contractInstance = contract.at(address);/* contractInstance.METHOD.call, 
   METHOD=getNum is the function of contract 
*/contractInstance.getNum.call(function(error, result) { 
    if (error) { 
        // error handle 
    } else { 
        // result is string 
        // do something 
    } 
});

若想要改变contract中的资料就必须使用send。这里的send指的是send transaction。因为会改变contract中的资料,需要缴交手续费给矿工帮忙把资料纪录在block中。改变的资料一样会存放在block中,等同于发起了一笔transaction。使用contract. METHOD.sendTransaction()来改变contract资料。回传该transaction的hash。METHOD一样是指contract所定义的function名称,下面例子就是setNum。parameterValue则是要赋予contract的新值。

var contract = web3.eth.contract(abi); 
var contractInstance = contract.at(address); 
var txnObject = { 
    from: fromAccount, 
    gas: estimatedGas 
};// contractInstance.METHOD.sendTransaction, METHOD=setNum is the function of contract 
var parameterValue = 5 ; 
contractInstance.setNum.sendTransaction(parameterValue, txnObject,              
    function(error, result){ 
        if(error){ 
            // error handle 
        } else { 
            // do something 
        } 
});

结尾

Web3.js是Dapp Library,专门拿来与Ethereum网络沟通。在学习的过程算是比较有趣的部份,对Ethereum网络会有更深一层的理解。这里只是介绍了Web3.js一些常用的操作,但完全没有介绍到Event的部份。因为Event的部份东西比较多,我打算另外写一篇。不然写完一篇落落长,连我自己看了都眼花。上面的操作都可以在Web3APIScript这里找到相对应的范例,有兴趣的可以去看看。

Web3.js算是目前最多人使用的Dapp Library,所以才特别拿来说明。对于我自己来说,Javascript算一个比较陌生的语言。本身所使用较多的语言是python,希望改天能有时间可以玩一下Web3.py,到时再来写一篇关于Web3.py的文章,但目前还是先乖乖学习Web3.js吧!以上是我对于Web3.js的一些理解。若观念或理解有误,也拜托各位大大不吝啬给于纠正。

本文链接地址:https://www.wwsww.cn/btbjiaoxue/6247.html
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。