查询以太币及代币余额与价格,进行以太币与代币的转账(两种方式)并获取交易记录
1 // 补齐64位,不够前面用0补齐 2 function addPreZero(num){ 3 var t = (num+'').length, 4 s = ''; 5 for(var i=0; i<64-t; i++){ 6 s += '0'; 7 } 8 return s+num; 9 }
一,使用web3.js
查询类方法在私链和主链上的方法都是一样的,说明以下几点:
-
主链地址。可以去
infura
申请 contractAbi
。合约的abi。可以去https://etherscan.io获取,如果代币合约提供了code
,就会有abi
1,链接web3.js
1 import Web3 from 'web3' 2 let getWeb3 = new Promise(function(resolve, reject) { 3 var web3 = window.web3 4 if (typeof web3 !== 'undefined') { 5 web3 = new Web3(web3.currentProvider) 6 results = {web3: web3} 7 console.log('Injected web3 detected.'); 8 resolve(results) 9 } else { 10 var provider = new Web3.providers.HttpProvider('https://mainnet.infura.io/v3/apikey') 11 web3 = new Web3(provider) 12 results = {web3: web3} 13 resolve(results) 14 } 15 })
2,查询以太币以及代币的价格与gasLimit
1 getWeb3.then(function (server) { 2 server.web3.eth.getGasPrice(function (error, result) {//获取当前价格 3 if (!error) { 4 alert(result.toNumber()) 5 server.web3.eth.getBlock("latest", function (error1, info) {//gasLimit 6 if (!error1) { 7 alert(JSON.stringify(info.gasLimit)) 8 9 } 10 11 }) 12 } 13 }); 14 });
3,查询以太币以及代币的余额
1 const BigNumber = require('bignumber.js'); 2 const Ether = new BigNumber(10e+17); 3 //查询以太币余额 4 balanceOfETH = (address) => { 5 let self = this; 6 getWeb3.then(function (server) { 7 let filter = server.web3.eth.filter('latest') 8 valueOfgetBalance(server, address, 0) 9 valueOfgetBalanceOther(server, address) 10 filter.watch(function (error, result) { 11 12 if (!error) { 13 valueOfgetBalance(server, address, 0) 14 valueOfgetBalanceOther(server, address) 15 } 16 }, function (err) { 17 console.log(err); 18 }); 19 }) 20 } 21 valueOfgetBalance = (server, address, num) => { 22 let self = this; 23 const balance = server.web3.eth.getBalance(address, (err2, bal) => { 24 if (!err2) { 25 let ret = new BigNumber(bal); 26 alert(ret.dividedBy(Ether)).toFixed(2))//以太币余额 27 } 28 29 }); 30 31 } 32 //查询代币余额 33 valueOfgetBalanceOther= (server, address) => { 34 let self = this; 35 const balance = server.web3.eth.getBalance(address, (err2, bal) => { 36 if (!err2) { 37 let contractother = 38 server.web3.eth.contract(contractabi).at(contractaddress); 39 contractother.balanceOf(address, (error2, bal) => { 40 if (!error2) { 41 let ret = new BigNumber(bal); 42 alert(ret.dividedBy(Ether)).toFixed(2))//代币币余额 43 } 44 45 }) 46 } 47 }); 48 }
4,在私链上转账以太币及代币
1 // 以太币转账 2 web3.eth.sendTransaction({ 3 from: currentAccount, 4 to: receiverAccount, 5 value: '1000000000000000' 6 }) 7 .then(function(receipt){ 8 console.log(receipt); 9 }); 10 11 // 代币转账 12 myContract.methods.transfer(to, amount).send({from: currentAccount}), function(error, transactionHash){ 13 if(!error) { 14 console.log('transactionHash is ' + transactionHash); 15 } else { 16 console.log(error); 17 } 18 });
5,在主链上转账以太币及代币
上面的方法只适用于私链。因为你在私链的账户在本地是有私钥的。而在主链上要进行写入数据的方法,是需要获取账户的私钥并对交易进行签名的,所以要用到web3.eth.sendSignedTransaction
方法。
文档http://web3js.readthedocs.io/en/1.0/web3-eth.html#sendsignedtransaction
需要npm
安裝'ethereumjs-tx'
1 npm install ethereumjs-tx
转账的方法(以太币以及代币)
1 // 引入ethereumjs-tx 2 var tx = require('ethereumjs-tx'); 3 transfer = (recipientAddress, balance, privateKey) => { 4 // ethGasLimit 5 let self = this; 6 getWeb3.then(function (server) { 7 let address =WalletaA;//转账人钱包地址 8 9 server.web3.eth.getTransactionCount(address, function (err, nonce) { 10 11 let balanceEth = parseFloat(balance) * Ether;//转换成ETH的最小单位数量 12 let rawTx = {} 13 if (self.state.token == 'ETH') {//以太币转账 14 //创建转账对象 15 rawTx = { 16 nonce: server.web3.toHex(nonce++),//nonce转出累计次数 17 gasPrice: server.web3.toHex(10e9), 18 from: address, //从keystore的address账户转出 19 gasLimit: server.web3.toHex(99000), //gasLimit限制 20 to: recipientAddress, //向recipientAddress转账 21 value: balanceEth//valueEth 22 } 23 } else {//代币转账 24 // data的组成,由:0x + 要调用的合约方法的function signature + 要传递的方法参数,每个参数都为64位(对transfer来说,第一个是接收人的地址去掉0x,第二个是代币数量的16进制表示,去掉前面0x,然后补齐为64位) 25 let data = '0x' + 'a9059cbb' + addPreZero(recipientAddress.substr(2)) + addPreZero(server.web3.toHex(balanceEth).substr(2)) 26 rawTx = { 27 nonce: server.web3.toHex(nonce++), 28 gasLimit: server.web3.toHex(9900), 29 gasPrice: server.web3.toHex(10e9), 30 // 注意这里是代币合约地址 31 to:address, 32 from: address, 33 // 调用合约转账value这里留空 34 value: '0x00', 35 // data的组成,由:0x + 要调用的合约方法的function signature + 要传递的方法参数,每个参数都为64位(对transfer来说,第一个是接收人的地址去掉0x,第二个是代币数量的16进制表示,去掉前面0x,然后补齐为64位) 36 data: data 37 } 38 } 39 let tx = new ethTX(rawTx); 40 let keyBuf = Buffer.from(privateKey, 'hex'); 41 //对交易进行签名 42 tx.sign(keyBuf); 43 if (tx.verifySignature()) { 44 console.log('Signature Checks out!') 45 } 46 let serializedTxHex = '0x' + tx.serialize().toString('hex'); 47 server.web3.eth.sendRawTransaction(serializedTxHex, function (err, transactionHash) { 48 //交易信息transctionHash可以通过web3.eth.getTransaction(transactionHash)详细交易信息 49 //alert(address + ' ' + nonce + ' ' + err + '; ' + transactionHash) 50 //alert('详细交易信息==' + transactionHash + '详细交易错误信息==' + JSON.stringify(err)); 51 52 }); 53 }); 54 }); 55 //}); 56 }
二,以太坊api
1,查询以太币以及代币的价格与gasLimit
1 fetch(`https://api.etherscan.io/api?module=proxy&action=eth_gasPrice&apikey=apikey`) 2 .then(result => result.json()) 3 .then(result => { 4 // alert(JSON.stringify(parseInt(result.result, 16))/ 1e9) 5 // if (result.status == 1) { 6 let parseIntresult = parseInt(result.result, 16) 7 8 //alert(result.result+'===0x'+parseIntresult.toString(16)) 9 10 fetch(`https://api.etherscan.io/api?module=proxy&action=eth_getBlockByNumber&tag=0x10d4f&boolean=true&apikey=apikey`) 11 .then(info => info.json()) 12 .then(info => { 13 // alert(JSON.stringify(info)) 14 let parseIntinfo = parseInt(info.result.gasLimit, 16) 15 16 }) 17 .catch(e => { 18 }) 19 }) 20 .catch(e => { 21 })
2,查询以太币以及代币的余额
1 //以太币余额 2 return fetch(`https://api.etherscan.io/api?module=account&action=balance&address=${address}&tag=latest&apikey=apikey`) 3 .then(result => result.json()) 4 .then(result => { 5 if (result.status == 1) { 6 let ret = new BigNumber(result.result); 7 alert(ret.dividedBy(Ether)).toFixed(2);//以太币余额 8 9 } 10 }) 11 .catch(e => { 12 13 }) 14 15 //代币余额 16 return fetch(`https://api.etherscan.io/api?module=account&action=tokenbalance&contractaddress=${contactaddress}&address=${address}&tag=latest&apikey=apikey`) 17 .then(result => result.json()) 18 .then(result => { 19 if (result.status == 1) { 20 let ret = new BigNumber(result.result); 21 alert(ret.dividedBy(Ether)).toFixed(2); 22 23 } 24 }) 25 .catch(e => { 26 27 })
3,在主链上转账以太币及代币
1 transfer = (recipientAddress, balance, privateKey) => { 2 // ethGasLimit 3 let self = this; 4 let address = WalletaA;//转账人钱包地址 5 fetch(`https://api.etherscan.io/api?module=proxy&action=eth_getTransactionCount&address=${address}&tag=latest&apikey=apikey`) 6 .then(result => result.json()) 7 .then(result => { 8 let nonce = parseInt(result.result, 16)+1 9 let gasPrice = 10e9;//gas价格 10 let gasLimit = 9900;//gas限制 11 let balanceEth = parseFloat(balance) * Ether;//转换成ETH的最小单位数量 12 let rawTx = {} 13 if (self.state.token == 'ETH') { 14 //创建转账对象 15 rawTx = { 16 nonce: '0x'+nonce.toString(16),//nonce转出累计次数 17 gasPrice: '0x'+gasPrice.toString(16), 18 from: address, //从keystore的address账户转出 19 gasLimit: '0x'+gasLimit.toString(16), //gasLimit限制 20 to: recipientAddress, //向recipientAddress转账 21 value: balanceEth//valueEth 22 } 23 } else { 24 // data的组成,由:0x + 要调用的合约方法的function signature + 要传递的方法参数,每个参数都为64位(对transfer来说,第一个是接收人的地址去掉0x,第二个是代币数量的16进制表示,去掉前面0x,然后补齐为64位) 25 let data = '0x' + 'a9059cbb' + addPreZero(recipientAddress.substr(2)) + addPreZero(balanceEth.toString(16)) 26 rawTx = { 27 nonce: '0x'+nonce.toString(16), 28 gasLimit: '0x'+gasLimit.toString(16), 29 gasPrice: '0x'+gasPrice.toString(16), 30 // 注意这里是代币合约地址 31 to: hrcjson.address, 32 from: address, 33 // 调用合约转账value这里留空 34 value: '0x00', 35 // data的组成,由:0x + 要调用的合约方法的function signature + 要传递的方法参数,每个参数都为64位(对transfer来说,第一个是接收人的地址去掉0x,第二个是代币数量的16进制表示,去掉前面0x,然后补齐为64位) 36 data: data 37 } 38 } 39 let tx = new ethTX(rawTx); 40 let keyBuf = Buffer.from(privateKey, 'hex'); 41 //对交易进行签名 42 tx.sign(keyBuf); 43 if (tx.verifySignature()) { 44 console.log('Signature Checks out!') 45 } 46 47 let serializedTxHex = '0x' + tx.serialize().toString('hex'); 48 fetch(`https://api.etherscan.io/api?module=proxy&action=eth_sendRawTransaction&hex=${serializedTxHex}&apikey=apikey`) 49 .then(info => info.json()) 50 .then(info => { 51 alert('转账信息=='+JSON.stringify(info)) 52 53 }) 54 .catch(e => { 55 56 }) 57 }
三,获取交易记录
1 fetch(`https://api.etherscan.io/api?module=account&action=tokentx&contractaddress=${contractaddress}&address=${address}&page=1&offset=20&sort=desc&apikey=apikey`) 2 .then(transactionList => transactionList.json()) 3 .then(transactionList => { 4 if (transactionList.status == 1) { 5 let value = transactionList.result[transactionList.result.length - 1].value 6 transactionList = transactionList.result; 7 8 // const txnIn = transactionList.filter(t => t.to === address); 9 // const txnOut = transactionList.filter(t => t.from === address); 10 //处理转账数据,转入转出 11 } 12 13 14 }).catch(err => {});