1. 程式人生 > >查詢以太幣及代幣餘額與價格,進行以太幣與代幣的轉賬(兩種方式)並獲取交易記錄

查詢以太幣及代幣餘額與價格,進行以太幣與代幣的轉賬(兩種方式)並獲取交易記錄

查詢以太幣及代幣餘額與價格,進行以太幣與代幣的轉賬(兩種方式)並獲取交易記錄

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 => {});

&n