Web3.js介绍 · Ethereum Blockchain Developer Crash Course(三)了解交易transaction运作过程

本文主要是介绍Web3.js介绍 · Ethereum Blockchain Developer Crash Course(三)了解交易transaction运作过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本节教你如何创建交易transaction,会告诉你当交易创建时发生了什么,如何手动的把交易通过web3.js广播到网络上。

本节旨在帮助你理解以太坊区块链的交易时如何运作的,当你创建交易时,你在写数据到区块链并且更新区块链的状态,比如账户间发送以太币,调用合约中会写数据的方法,部署合约到区块链等都是交易。

为了把交易广播到网络上,我们要先对交易进行签名,我们使用 ethereumjs-tx 这个JavaScript库,你可以这样安装它:

$ npm install ethereumjs-tx

用这个库的原因是我们想在本地对所有交易进行签名,如果我们的以太坊节点在本地运行,我们可以解锁存储在本地的账户并且对本地的所有交易进行签名,我们使用的是Infura管理的远程节点,即使 Infura 是个可靠的服务, 我们仍想在本地对交易进行签名,而不是让远程节点拥有我们的私钥。

下面让我们创建一个原始交易,对它签名,然后发送交易,广播到网络上。首先创建一个app.js 文件,不再用命令行写代码。

app.js中首先引入一个签名库,然后建立一个web3连接

var Tx = require('ethereumjs-tx')
const Web3 = require('web3')
const web3 = new Web3('https://ropsten.infura.io/YOUR_INFURA_API_KEY')

现在我们用的是Ropsten测试网络,不是之前的以太坊主链网络,用测试网络是因为不用真实的花费以太币,你可以获取假的以太币。 You can obtain fake Ether from a faucet on the Ropsten test network with a faucet. Here are two faucets you can use:

http://faucet.ropsten.be:3001/

https://faucet.metamask.io/

现在我们创建一个交易,发送假的以太币。首先要有两个账户和私钥,可以通过如下方式利用Web3.js建立新账户:

web3.eth.accounts.create()
// > {
//    address: "0xb8CE9ab6943e0eCED004cDe8e3bBed6568B2Fa01",
//    privateKey: "0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709",
//    signTransaction: function(tx){...},
//    sign: function(data){...},
//    encrypt: function(password){...}
// }

建好账户后,记得要给这两个账户申请假的以太币,然后我们保存这两个账户地址和私钥,不同机器地址和私钥不同。

const account1 = '0xb8CE9ab6943e0eCED004cDe8e3bBed6568B2Fa01'
const account2 = '0xb8CE9ab6943e0eCED004cDe8e3bBed6568B2Fa02'
export PRIVATE_KEY_1='your private key 1 here'
export PRIVATE_KEY_1='your private key 2 here'

像上面这样保存私钥不安全,我们可以从web3.js环境中读取私钥再保存,可以使用NodeJS中的 process 全局对象:

const privateKey1 = process.env.PRIVATE_KEY_1
const privateKey2 = process.env.PRIVATE_KEY_2

为了用私钥对交易进行签名,我们要用Buffer把私钥转换成字符串,Buffer是NodeJS的一个模块:

const privateKey1 = Buffer.from(process.env.PRIVATE_KEY_1)
const privateKey1 = Buffer.from(process.env.PRIVATE_KEY_2)

现在所有变量都准备好了,我们要:

  1. Build a transaction object 建立一个交易对象
  2. Sign the transaction 对交易签名
  3. Broadcast the transaction to the network 把交易广播到网络上

可以像下面建立交易:

const txObject = {nonce:    web3.utils.toHex(txCount),to:       account2,value:    web3.utils.toHex(web3.utils.toWei('0.1', 'ether')),gasLimit: web3.utils.toHex(21000),gasPrice: web3.utils.toHex(web3.utils.toWei('10', 'gwei'))}
  • nonce - 这是之前的交易总数  this is the previous transaction count for the given account. We'll assign the value of this variable momentarily. We also must convert this value to hexidecimal. We can do this with the Web3.js utilitly web3.utils.toHex()
  • to - 接收以太币的账户 the account we're sending Ether to.
  • value - 以太币数量,单位是Wei,且是16进制。 the amount of Ether we want to send. This value must be expressed in Wei and converted to hexidecimal. We can convert the value to we with the Web3.js utility web3.utils.toWei().
  • gasLimit - this is the maximum amount of gas consumed by the transaction. A basic transaction like this always costs 21000 units of gas, so we'll use that for the value here.
  • gasPrice - this is the amount we want to pay for each unit of gas. I'll use 10 Gwei here.

在交易对象中没有 from 字段,当我们用 account1的私钥对交易签名时它会自动引用。

我们可以通过  web3.eth.getTransactionCount()方法获取nonce值,通过回调函数包装后:

web3.eth.getTransactionCount(account1, (err, txCount) => {const txObject = {nonce:    web3.utils.toHex(txCount),to:       account2,value:    web3.utils.toHex(web3.utils.toWei('0.1', 'ether')),gasLimit: web3.utils.toHex(21000),gasPrice: web3.utils.toHex(web3.utils.toWei('10', 'gwei'))}
})

现在我们有了交易对象,需要对它签名:

const tx = new Tx(txObject)
tx.sign(privateKey1)const serializedTx = tx.serialize()
const raw = '0x' + serializedTx.toString('hex')

使用 etheremjs-tx 库来创建一个新的 Tx 对象,利用 privateKey1对交易进行签名,然后把交易序列化,转化为十六进制的字符串,能传到Web3中。

最后,我们使用web3.eth.sendSignedTransaction()方法发送签名后序列化的交易到测试网络上:

web3.eth.sendSignedTransaction(raw, (err, txHash) => {console.log('txHash:', txHash)
})

完整的 app.js 文件如下:

var Tx     = require('ethereumjs-tx')
const Web3 = require('web3')
const web3 = new Web3('https://ropsten.infura.io/YOUR_INFURA_API_KEY')const account1 = '' // Your account address 1
const account2 = '' // Your account address 2const privateKey1 = Buffer.from('YOUR_PRIVATE_KEY_1', 'hex')
const privateKey2 = Buffer.from('YOUR_PRIVATE_KEY_2', 'hex')web3.eth.getTransactionCount(account1, (err, txCount) => {// Build the transactionconst txObject = {nonce:    web3.utils.toHex(txCount),to:       account2,value:    web3.utils.toHex(web3.utils.toWei('0.1', 'ether')),gasLimit: web3.utils.toHex(21000),gasPrice: web3.utils.toHex(web3.utils.toWei('10', 'gwei'))}// Sign the transactionconst tx = new Tx(txObject)tx.sign(privateKey1)const serializedTx = tx.serialize()const raw = '0x' + serializedTx.toString('hex')// Broadcast the transactionweb3.eth.sendSignedTransaction(raw, (err, txHash) => {console.log('txHash:', txHash)// Now go check etherscan to see the transaction!})
})

在 NodeJS 控制台中可以运行 app.js 文件:

$ node app.js

或者这样运行也可以:

$ node app

本节完整的代码在: github.

这篇关于Web3.js介绍 · Ethereum Blockchain Developer Crash Course(三)了解交易transaction运作过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1062955

相关文章

redis过期key的删除策略介绍

《redis过期key的删除策略介绍》:本文主要介绍redis过期key的删除策略,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录第一种策略:被动删除第二种策略:定期删除第三种策略:强制删除关于big key的清理UNLINK命令FLUSHALL/FLUSHDB命

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

Pytest多环境切换的常见方法介绍

《Pytest多环境切换的常见方法介绍》Pytest作为自动化测试的主力框架,如何实现本地、测试、预发、生产环境的灵活切换,本文总结了通过pytest框架实现自由环境切换的几种方法,大家可以根据需要进... 目录1.pytest-base-url2.hooks函数3.yml和fixture结论你是否也遇到过

PyInstaller打包selenium-wire过程中常见问题和解决指南

《PyInstaller打包selenium-wire过程中常见问题和解决指南》常用的打包工具PyInstaller能将Python项目打包成单个可执行文件,但也会因为兼容性问题和路径管理而出现各种运... 目录前言1. 背景2. 可能遇到的问题概述3. PyInstaller 打包步骤及参数配置4. 依赖

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

将Mybatis升级为Mybatis-Plus的详细过程

《将Mybatis升级为Mybatis-Plus的详细过程》本文详细介绍了在若依管理系统(v3.8.8)中将MyBatis升级为MyBatis-Plus的过程,旨在提升开发效率,通过本文,开发者可实现... 目录说明流程增加依赖修改配置文件注释掉MyBATisConfig里面的Bean代码生成使用IDEA生

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处