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中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

k8s中实现mysql主备过程详解

《k8s中实现mysql主备过程详解》文章讲解了在K8s中使用StatefulSet部署MySQL主备架构,包含NFS安装、storageClass配置、MySQL部署及同步检查步骤,确保主备数据一致... 目录一、k8s中实现mysql主备1.1 环境信息1.2 部署nfs-provisioner1.2.

5 种使用Python自动化处理PDF的实用方法介绍

《5种使用Python自动化处理PDF的实用方法介绍》自动化处理PDF文件已成为减少重复工作、提升工作效率的重要手段,本文将介绍五种实用方法,从内置工具到专业库,帮助你在Python中实现PDF任务... 目录使用内置库(os、subprocess)调用外部工具使用 PyPDF2 进行基本 PDF 操作使用

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

在Node.js中使用.env文件管理环境变量的全过程

《在Node.js中使用.env文件管理环境变量的全过程》Node.js应用程序通常依赖于环境变量来管理敏感信息或配置设置,.env文件已经成为一种流行的本地管理这些变量的方法,本文将探讨.env文件... 目录引言为什么使php用 .env 文件 ?如何在 Node.js 中使用 .env 文件最佳实践引

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

使用Node.js和PostgreSQL构建数据库应用

《使用Node.js和PostgreSQL构建数据库应用》PostgreSQL是一个功能强大的开源关系型数据库,而Node.js是构建高效网络应用的理想平台,结合这两个技术,我们可以创建出色的数据驱动... 目录初始化项目与安装依赖建立数据库连接执行CRUD操作查询数据插入数据更新数据删除数据完整示例与最佳

linux部署NFS和autofs自动挂载实现过程

《linux部署NFS和autofs自动挂载实现过程》文章介绍了NFS(网络文件系统)和Autofs的原理与配置,NFS通过RPC实现跨系统文件共享,需配置/etc/exports和nfs.conf,... 目录(一)NFS1. 什么是NFS2.NFS守护进程3.RPC服务4. 原理5. 部署5.1安装NF