主页 > 怎么把imtoken转到平台 > js获取按钮的值_使用ethers.js开发以太坊网页钱包3

js获取按钮的值_使用ethers.js开发以太坊网页钱包3

怎么把imtoken转到平台 2023-02-16 07:36:09

使用 Provider 连接以太坊网络

我们之前两篇文章介绍了创建(或导入)钱包账户的过程是离线的,即可以不依赖以太坊网络创建钱包账户,但是如果要获取钱包账户的信息,比如余额和交易记录,要发起交易,钱包需要连接到以太坊网络。

无论是在 Web3 还是 Ethers.js 中,Provider 都是用于网络连接的。 Ethers.js 提供了集成多个 Provider 的方法:

1let defaultProvider = ethers.getDefaultProvider('ropsten');

连接Provider和wallet的方法如下:

// 连接本地的geth 节点,8545是geth 的端口var provider = new ethers.providers.JsonRpcProvider("http://127.0.0.1:8545");// wallet 为前两篇文章中生成的钱包对象, activeWallet就是后面可以用来请求余额发送交易的对象var activeWallet = wallet.connect(App.provider);

启动geth时,需要注意。 需要使用 --rpc --rpccorsdomain 开启RPC通信和跨域。

显示钱包详情:查询余额和Nonce

连接到以太坊网络后,您可以向网络请求余额并获取账户交易数量。 使用以下 API:

activeWallet.getBalance().then(function(balance) {});activeWallet.getTransactionCount().then(function(transactionCount) {});

activeWallet 是后面可以用来请求发送交易的对象

86546327681816cc10d1c4b586f23355.png

钱包详情: 地址:

平衡:

随机数:

刷新

js处理的逻辑是获取到信息后以太坊交易信息获取,填写相应的控件。 代码如下:

var inputBalance = $('#wallet-balance');var inputTransactionCount = $('#wallet-transaction-count');$("#wallet-submit-refresh").click(function() {// 获取余额时, 包含当前正在打包的区块 activeWallet.getBalance('pending').then(function(balance) { // 单位转换 wei -> ether inputBalance.val(ethers.utils.formatEther(balance, { commify: true })); }, function(error) { }); activeWallet.getTransactionCount('pending').then(function(transactionCount) { inputTransactionCount.val(transactionCount); }, function(error) { });});// 模拟一次点击获取数据$("#wallet-submit-refresh").click();

发送签名交易

我们之前有一篇文章:如何使用Web3.js API在页面上转账。 我们引入了交易发起,但是当时的签名是使用MetaMask完成的。 现在我们要完成一个钱包,必须发送一个签名交易。 签名交易也称为离线交易(因为这个过程可以离线进行:离线签署交易,然后广播签署的交易)。

尽管 Ethers.js 提供了一个非常简洁的 API 来发送签名交易,但探索简洁 API 背后的细节仍然很有帮助。 这个过程大致可以分为三个步骤:

构造交易 交易签名 发送(广播)交易

构建交易

让我们看一下交易是什么样子的:

const txParams = { nonce: '0x00', gasPrice: '0x09184e72a000', gasLimit: '0x2710', to: '0x0000000000000000000000000000000000000000', value: '0x00', data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057', // EIP 155 chainId - mainnet: 1, ropsten: 3 chainId: 3}

在发起交易时,需要填写各个字段来构建这样的交易结构。

to和value:很容易理解,就是用户想要转账的目标和金额。

数据:它是附加到交易的消息。 如果向合约地址发起交易,这将转化为合约功能的执行。 请参考:如何理解以太坊ABI

nonce:交易序号

chainId:链id,用于区分不同的链(分叉链)id可以在EIP-55中查询。

nonce和chainId的一个重要作用就是防止重放攻击。 如果没有随机数,收款人可以再次广播已签名的交易。 没有chainId,以太坊上的交易可以在Ethereum Classic Broadcast上重新获取。

gasPrice和gasLimit:gas是以太坊的工作计费机制,是交易发起方打包给矿工的费用。 以上参数的设置都比较固定,而Gas(尤其是gasPrice)的设置就灵活多了。

gasLimit 表示指令和存储空间的预估工作量。 如果工作量没有用完,则返回给事务发起者。 如果不够,就会出现 out-of-gas 错误。

对于普通转账交易,工作量固定,gasLimit为21000,合约执行gasLimit可变。 有些人可能会认为将它设置为更高的值无论如何都会返回它,但是如果合约执行出错,它会吃掉所有的gas。幸运的是,web3和ethers.js都提供了一种测量Gas Limit的方法,并且下次发送令牌

gasPrice 是交易发起者愿意为工作量支付的单位费用。 当矿工选择交易时,他们会根据 gasPrice 对交易进行排序,并首先为出价高的人提供服务。 因此,如果出价过低,交易将在很长一段时间内无法打包确认。 高反始作俑者多亏。

web3和ethers.js提供了一个方法getGasPrice()来获取最近几个历史区块的gas价格的中位数,还有一些第三方提供了预测gas价格的接口,比如:gasPriceOracle、ethgasAPI、etherscan gastracker,这些服务通常是它还会参考当前交易池中的交易数量和价格,更具参考性。

一个常规的做法是利用这些接口给用户一个参考值,然后用户可以根据参考值进行微调。

交易签名

交易构造完成后,用私钥进行签名,代码如下:

const tx = new EthereumTx(txParams)tx.sign(privateKey)const serializedTx = tx.serialize()

代码参考ethereumjs-tx

发送(广播)交易

然后就是发送(广播)交易,代码如下:

web3.eth.sendRawTransaction(serializedTx, function (err, transactionHash) { console.log(err); console.log(transactionHash);});

通过这三个步骤,就完成了发送签名交易的过程。 ethers.js中提供了一个简洁的界面来完成这三个步骤(在界面中强调已经为我们完成了签名)。 界面如下:

activeWallet.sendTransaction({ to: targetAddress, value: amountWei, gasPrice: activeWallet.provider.getGasPrice(), gasLimit: 21000, }).then(function(tx) { });

使用 ethers.js 发送交易

我们来看看发送交易的UI界面:

15445cebe23a56a396cead3527eab89f.png

以太币转账:发送至:

数量:

发送

上面主要定义了两个文本输入框和一个“发送”按钮以太坊交易信息获取,并运行点击发送时的(key)代码:

var inputTargetAddress = $('#wallet-send-target-address');var inputAmount = $('#wallet-send-amount');var submit = $('#wallet-submit-send');submit.click(function() {// 得到一个checksum 地址 var targetAddress = ethers.utils.getAddress(inputTargetAddress.val());// ether -> wei var amountWei = ethers.utils.parseEther(inputAmount.val()); activeWallet.sendTransaction({ to: targetAddress, value: amountWei, // gasPrice: activeWallet.provider.getGasPrice(), (可用默认值) // gasLimit: 21000, }).then(function(tx) { console.log(tx); });})