如何用私钥签名合约调用裸交易?【Web3.js】

戏子无情 提交于 2020-08-10 12:09:48

交易签名是你向区块链证明自己身份的唯一途径,这也是使用以太坊的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
  
});

再次提醒,上述操作中用到了私钥,因此一定要格外小心安全问题。


原文链接:以太坊合约调用裸交易签名教程 — 汇智网

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!