web3公測版本教程(三)-不用本身同步以太坊節點,直接發起簽名交易

一.前言

前文提到目前有一些公司提供公共的以太坊對外服務,就是以你能夠調用他的web3接口,以前一直被兩個問題困擾,一個是以爲別人的節點不安全,還有初步嘗試後發現Infura節點沒有開放帳戶相關的方法。無法使用web3.eth.sendTransaction方法,覺得只能進行一些查詢服務,用處就較爲雞肋。最後毅然決然的選擇本身同步節點的苦逼之路。看了大神文章,兩個問題迎刃而解,並踩過大神文章重的一些坑,實際的寫了一個羣發幣腳本。html

二.申請Infura

目前較爲主流的以太坊服務就是Infura,到Infura官網申請,只要輸入一點基本資料和Email就能夠獲得API-key(輸入本身經常使用郵箱,回覆的郵件不要刪除,由於Infura不存在登入系統,因此再次使用只能去郵箱找API-key,沒保留只能再次申請了)。web

三.用鏈接Infura發起智能合約交易

要發起交易首先要解決的就是問題一,web3.eth.sendTransaction不能夠用。爲何不能用呢,其實web3.eth.sendTransaction的原理是建立一個交易而後發給你鏈接的以太坊節點,以太坊節點能夠理解爲有兩個功能,一個是發出一筆簽了名的正確交易,另外一個是給本節點中處於解鎖狀態的帳戶中發來的交易簽名。本身同步節點就能夠先解鎖在簽名交易,而後發送交易給其餘節點。但Infura提供給你的服務只有各類查詢和轉發交易,並沒把錢包開放給你儲存私鑰(開放也不放心存過去)。是的但你能夠把簽名好的交易發給它他幫你轉發掉。因此第二個安全問題也就解決了,由於你沒有把私鑰發給它,只是把你承認你本身簽名的交易發給他了。 npm

下面是實現web3中用智能合約私鑰簽名的細節:安全

1.建立一個交易對象
var _web3 = new Web3(yourInfuraAddress);
const txData = {
    nonce: _web3.utils.toHex(nonce),
    gasLimit: _web3.utils.toHex(99000),   //
    gasPrice: _web3.utils.toHex(10e9),    // 10 Gwei
    to: contract_address,
    from: address1,
    value: '0x00',         
    data: '0x'+'a9059cbb'+'000000000000000000000000'+address2+hexNum
}

參數解釋:ui

  • nonce:整數類型,nonce從零開始計數每次加一,直接填寫較大的會等待它前面的數的交易完成才能交易,較小會失敗,使用與本身發送的處於pending狀態的交易相同的nonce,則會取消掉前一筆交易,因此通常錢包發給同一我的的前一筆交易被擁堵能夠發送一個0eth的交易取消前面交易。咱們使用下面方法獲取當前的nonce:
_web3.eth.getTransactionCount(sendAddress).then(function(res){
    nonce = res;
}
  • gasLimit和gasPrice: gasPrice通常能夠設置1G位到10G位之間,gasLimit話費gas數量eth交易通常是固定21000個,智能合約會根據合約方法複雜程度自動變化,gaslimit能夠設置消耗最大值,超過這個值將取消交易。(注意:須要轉換成16進制,可使用web3.utils.toHex方法。)
  • to:若是是智能合約交易則是智能合約地址
  • from:發起方的公鑰
  • value:轉帳的eth數,智能合約交易請填0x00
  • data:這個有門道了,0x開頭表示十六進制,前八位方法名通常基於erc20的tranlation方法爲a9059cbb,其餘的能夠將合約粘貼到remix上面看,以後64位依次第一個參數接受token方第二個參數token數量(要16進制不夠64位前面補0,補零方法在後邊,更加牛逼的用法官網參數解釋

補零方法:3d

function addPreZero(num){
  var t = (num+'').length,
  s = '';
  for(var i=0; i<64-t; i++){
    s += '0';
  }
  return s+num;
}
2.建立raw transaction

要引入另外一個套件 ethereumjs-tx。記得先用 npm 安裝。創建raw transaction、code

var Tx = require('ethereumjs-tx');
var tx = new Tx(rawTx);
3.使用私鑰簽名
const privateKey = new Buffer('<your-private-key>', 'hex'); tx.sign(privateKey);
4.交易序列化
const serializedTx = transaction.serialize().toString('hex')
5.發送交易及各類狀態初六
var tran = _web3.eth.sendSignedTransaction('0x' + serializedTx);
    tran.on('confirmation', (confirmationNumber, receipt) => {
      //console.log('confirmation: ' + confirmationNumber);
    });
    tran.on('transactionHash', hash => {
        console.log('hash');
        console.log(hash);
    });
    tran.on('receipt', receipt => {
        console.log('receipt:');
        console.log(receipt);
    });
    tran.on('error', (err)=>{
        alert('出現錯誤請查看控制檯');
        console.log(err);        
    });
相關文章
相關標籤/搜索