天天看點

如何用私鑰離線簽名以太坊合約調用裸交易?【Web3.js】

交易簽名是你向區塊鍊證明自己身份的唯一途徑,這也是使用以太坊的Web3開發庫時需要理清的一個基本概念。在這個教程中,我們講學習如何使用Web3.js來完成以太坊智能合約調用交易的簽名與送出,适用于包括ERC20代币合約在内的所有以太坊合約的調用。

用自己熟悉的語言學習以太坊DApp開發: Java | Php Python .Net / C# Golang Node.JS Flutter / Dart

1、以太坊交易簽名概述

有兩種方法可以對交易進行簽名:使用解鎖賬号或使用私鑰。

如果你在用testRPC或Ganache開發,那麼應該已經了解其建立的測試賬号。這些賬号預設都是解鎖的,是以你可以直接用它們來簽名交易。你也可以使用特殊的Web3提供器例如truffle-hdwallet-provider來生成解鎖賬号。

更常見的則是以用發起交易的位址對應的私鑰來簽名交易。考慮到安全性,當你用到私鑰時需要格外小心。

2、建立以太坊智能合約調用交易

首先你需要建構一個調用合約方法的交易對象:

// 12 word mnemonic for HD Wallet Provider
// You can use any provider such as the HttpProvider if you are
// signing with private key
const mnemonic = "opinion destroy betray …";
const provider = new HDWalletProvider(mnemonic,"http://localhost:8545");
const web3 = new Web3(provider);
const myContract = new web3.eth.Contract(contractAbi,contractAddress);

const tx = {
  // this could be provider.addresses[0] if it exists
  from: fromAddress, 
  // target address, this could be a smart contract address
  to: toAddress, 
  // optional if you want to specify the gas limit 
  gas: gasLimit, 
  // optional if you are invoking say a payable function 
  value: value,
  // this encodes the ABI of the method and the arguements
  data: myContract.methods.myMethod(arg, arg2).encodeABI() 
};           

接下來如何簽名就取決于你使用解鎖賬号還是私鑰了。

3、使用解鎖賬号簽名以太坊交易

如果使用已經解鎖賬号,那麼使用如下的代碼進行簽名:

const signPromise = web3.eth.signTransaction(tx, tx.from);           

注意,如果你使用解鎖賬号,那麼直接調用

myContract.methods.myMethod(arg, arg2)

就可以自動完成簽名,上面的代碼隻是為了示範這一簽名過程。

4、使用私鑰簽名以太坊交易

不過如果這是一個鎖定的賬号,或者根本就不是節點管理的賬号,那麼你可以使用私鑰簽名交易:

const signPromise = web3.eth.accounts.signTransaction(tx, privateKey);           

在上述兩種情況下,傳回的都是一個Promise對象,其解析結果為簽名後的裸交易字元串。

5、廣播簽名後的裸交易字元串

由于簽名後的裸交易字元串中已經編碼了有關合約調用的全部資訊,包括方法名、調用參數、gas價格等等,是以可以直接送出給以太坊節點廣播:

signPromise.then((signedTx) => {  

  // raw transaction string may be available in .raw or 
  // .rawTransaction depending on which signTransaction
  // function was called
  const sentTx = web3.eth.sendSignedTransaction(signedTx.raw || signedTx.rawTransaction);  
  
  sentTx.on("receipt", receipt => {
    // do something when receipt comes back
  });
  
  sentTx.on("error", err => {
    // do something on transaction error
  });
  
}).catch((err) => {
  
  // do something when promise fails
  
});           
再次提醒,上述操作中用到了私鑰,是以一定要格外小心安全問題。

原文連結:

以太坊合約調用裸交易簽名教程 — 彙智網