使用web3.js收发ETH或ERC20Token |
您所在的位置:网站首页 › 初音未来全员人物介绍骇音 › 使用web3.js收发ETH或ERC20Token |
以太坊的转账分主要分为为ETH转账、ERC20转账这2种,其转账流程,如图(1)所示: ![]() ETH和ERC20这2种类型的代币,主要区别,发生在第3步"初始化原始的交易单rawTx{}"时,设置to字段和value字段有差别,如下表所示: rawTxETHERC20说明fromfromAddressfromAddressToken发送人nonceweb3.utils.toHex(nonceNum)web3.utils.toHex(nonceNum)交易的nonce值gasLimitweb3.utils.toHex(8000000)web3.utils.toHex(8000000)区块的gas个数上限gasPriceweb3.utils.toHex(10e9)web3.utils.toHex(10e9)单步计算所需的gastotoAddresscontractAddress当币种为ETH时,填Token接收人;当币种为ERC20时,填合约地址valueweb3.utils.toHex(sendNum)“0x0”当币种为ETH时,填ETH的个数; 当币种为ERC20时,置空datacontractObj.methods.transfer(toAddress, sendNum).encodeABI()contractObj.methods.transfer(toAddress, sendNum).encodeABI()发送Token,并编码chainId0x040x04网段为Rinkeby 初始化rawTx{}的代码对比如下:![]() 对比如下: ![]() 3.1.1 创建一个文件夹名称为sendToken mkdir sendToken3.1.2 用npm和truffle初始化该该工程 cd sendToken npm init -y truffle init3.1.3 修改sendToken\package.json文件,改成如下: //package.json { "name": "sendToken", "version": "1.0.0", "description": "", "main": "truffle-config.js", "directories": { "test": "test" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "@openzeppelin/contracts": "^2.5.0", "@truffle/hdwallet-provider": "^1.1.1", "bignumber": "^1.1.0", "bignumber.js": "^8.1.1", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "eslint": "^5.15.0", "ethereumjs-tx": "^1.3.7", "request": "^2.88.2", "web3": "^1.3.0" }, "devDependencies": { "@babel/core": "^7.12.3", "@babel/preset-env": "^7.12.1" } }3.1.4 安装依赖包 npm install3.1.5 新建一个文件夹名称为myabi,然后在sendToken\myabi\目录下,新建一个ZTA_abi.json文件,该文件存放ZTA合约的abi 3.1.6 新建一个文件夹名称为projectConfig,然后在sendToken\projectConfig\目下,如下几个文件: net.infuraKey 存放Infura节点的Key值 net.mnemonic 存放账户的助记词 net.prikey 存放账户的私钥 3.1.7 整个工程的目录结构如下: ![]() 将如下代码保存到sendToken\test\1.sendEth.js里,该代码是发送0.02ETH //1.sendEth.js var Tx = require('ethereumjs-tx'); var Web3 = require('web3') var fs = require('fs'); const infuraKey = fs.readFileSync("./projectConfig/net.infuraKey").toString().trim(); var web3 = new Web3(new Web3.providers.HttpProvider(`https://rinkeby.infura.io/v3/` + infuraKey)) // web3 version console.log(`web3 version: ${web3.version}`) function getEthBalance(fromAddress, bookmark) { web3.eth.getBalance(fromAddress).then( function (wei) { balance = web3.utils.fromWei(wei, 'ether') console.log(bookmark + balance); } ) } function getPriKey(prikeyPath) { const privKeyFile = fs.readFileSync(prikeyPath).toString().trim(); const privKey = new Buffer.from(privKeyFile, 'hex'); return privKey } function getEthRawTx(fromAddress,toAddress,contractObj,sendNum,nonceNum, privKey) { //raw Tx var rawTransaction = { "from": fromAddress, "nonce": web3.utils.toHex(nonceNum), "gasLimit": web3.utils.toHex(8000000), "gasPrice": web3.utils.toHex(10e9), "to": toAddress, "value": web3.utils.toHex(sendNum), "data": contractObj.methods.transfer(toAddress, sendNum).encodeABI(), "chainId": 0x04 //4:Rinkeby, 3:Ropsten, 1:mainnet }; var tx = new Tx(rawTransaction); tx.sign(privKey); var serializedTx = tx.serialize(); return serializedTx; } async function signTransaction(fromAddress,toAddress,contractObj,sendNum,nonceNum, privKey) { var serializedTx = getEthRawTx(fromAddress,toAddress,contractObj,sendNum,nonceNum, privKey) // Comment out these three lines if you don't really want to send the TX right now console.log(`Attempting to send signed tx: ${serializedTx.toString('hex')}`); var receipt = await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')); console.log(`Receipt info: ${JSON.stringify(receipt, null, '\t')}`); } function sleep(delay) { return new Promise(reslove => { setTimeout(reslove, delay) }) } //an async function const sendEth = async () => { //the number of sended token //20 milli = 0.02 ether var transferAmount = web3.utils.toWei('20', 'milli'); var myAddress = "0x1d75...a5f"; var destAddress = "0x8a40....23fb"; // get the nonce var nonceCnt = await web3.eth.getTransactionCount(myAddress); console.log(`num transactions so far: ${nonceCnt}`); var abiArray = JSON.parse(fs.readFileSync("./myabi/ZTA_abi.json")); var contractAddress = "0xAc194f047E43Ee0Ee10026C0B7AAA66489a0Ec45"; var contract = new web3.eth.Contract(abiArray, contractAddress, { from: myAddress }); // begin eth numbers of myAddress await getEthBalance(myAddress, "Balance before send: "); const privkey = getPriKey("./projectConfig/net.prikey") await signTransaction(myAddress,destAddress,contract,transferAmount,nonceCnt, privkey) sleep(100) //100ms // end eth numbers of myAddress await getEthBalance(myAddress, "Balance After send: "); } sendEth();执行该nodejs脚本 node test\1.sendETH.js效果如下: ![]() 也可以直接调用web3来发送ETH,即不调用合约来发送ETH,代码如下: //3.sendETHv2.js var Tx = require('ethereumjs-tx'); var Web3 = require('web3') var fs = require('fs'); const infuraKey = fs.readFileSync("./projectConfig/net.infuraKey").toString().trim(); var web3 = new Web3(new Web3.providers.HttpProvider(`https://rinkeby.infura.io/v3/` + infuraKey)) // web3 version console.log(`web3 version: ${web3.version}`) function getEthBalance(fromAddress, bookmark) { web3.eth.getBalance(fromAddress).then( function (wei) { balance = web3.utils.fromWei(wei, 'ether') console.log(bookmark + balance); }); } function getPriKey(prikeyPath) { const privKeyFile = fs.readFileSync(prikeyPath).toString().trim(); const privKey = new Buffer.from(privKeyFile, 'hex'); return privKey } function getEthRawTx(fromAddress,toAddress,sendNum,nonceNum, privKey) { //raw Tx var rawTransaction = { "from": fromAddress, "nonce": web3.utils.toHex(nonceNum), "gasLimit": web3.utils.toHex(8000000), "gasPrice": web3.utils.toHex(10e9), "to": toAddress, "value": web3.utils.toHex(sendNum), "data": '', "chainId": 0x04 //4:Rinkeby, 3:Ropsten, 1:mainnet }; var tx = new Tx(rawTransaction); tx.sign(privKey); var serializedTx = tx.serialize(); return serializedTx; } async function signTransaction(fromAddress,toAddress,sendNum,nonceNum, privKey) { var serializedTx = getEthRawTx(fromAddress,toAddress,sendNum,nonceNum, privKey) // Comment out these three lines if you don't really want to send the TX right now console.log(`Attempting to send signed tx: ${serializedTx.toString('hex')}`); var receipt = await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')); console.log(`Receipt info: ${JSON.stringify(receipt, null, '\t')}`); } function sleep(delay) { return new Promise(reslove => { setTimeout(reslove, delay) }) } //an async function const sendEth = async () => { //the number of sended token //20 milli = 0.02 ether var transferAmount = web3.utils.toWei('20', 'milli'); var myAddress = "0x1d75...a5f"; var destAddress = "0x8a40....23fb"; // get the nonce var nonceCnt = await web3.eth.getTransactionCount(myAddress); console.log(`num transactions so far: ${nonceCnt}`); // begin eth numbers of myAddress await getEthBalance(myAddress, "Balance before send: "); const privkey = getPriKey("./projectConfig/net.prikey") await signTransaction(myAddress,destAddress,transferAmount,nonceCnt, privkey) sleep(100) //100ms // end eth numbers of myAddress await getEthBalance(myAddress, "Balance After send: "); } sendEth(); 3.3 发送ERC20将如下代码保存到sendToken\test\2.sendERC20.js里,该代码是发送0.02 ZTA //2.sendERC20.js var Tx = require('ethereumjs-tx'); var Web3 = require('web3') var fs = require('fs'); const infuraKey = fs.readFileSync("./projectConfig/net.infuraKey").toString().trim(); var web3 = new Web3(new Web3.providers.HttpProvider(`https://rinkeby.infura.io/v3/` + infuraKey)) // web3 version console.log(`web3 version: ${web3.version}`) function getERC20Balance(fromAddress,contractObj,bookmark) { contractObj.methods.balanceOf(fromAddress).call().then( function (wei) { balance = web3.utils.fromWei(wei, 'ether'); console.log(bookmark + balance); }); } function getPriKey(prikeyPath) { const privKeyFile = fs.readFileSync(prikeyPath).toString().trim(); const privKey = new Buffer.from(privKeyFile, 'hex'); return privKey } function getERC20RawTx(fromAddress,toAddress,contractAddress,contractObj,sendNum,nonceNum, privKey) { //raw Tx var rawTransaction = { "from": fromAddress, "nonce": web3.utils.toHex(nonceNum), "gasLimit": web3.utils.toHex(8000000), "gasPrice": web3.utils.toHex(10e9), "to": contractAddress, "value": "0x0", "data": contractObj.methods.transfer(toAddress, sendNum).encodeABI(), "chainId": 0x04 //4:Rinkeby, 3:Ropsten, 1:mainnet }; var tx = new Tx(rawTransaction); tx.sign(privKey); var serializedTx = tx.serialize(); return serializedTx; } async function signERC20Transaction(fromAddress,toAddress,contractAddress,contractObj,sendNum,nonceNum, privKey) { var serializedTx = getERC20RawTx(fromAddress,toAddress,contractAddress,contractObj,sendNum,nonceNum, privKey) // Comment out these three lines if you don't really want to send the TX right now console.log(`Attempting to send signed tx: ${serializedTx.toString('hex')}`); var receipt = await web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')); console.log(`Receipt info: ${JSON.stringify(receipt, null, '\t')}`); } function sleep(delay) { return new Promise(reslove => { setTimeout(reslove, delay) }) } //an async function const sendERC20 = async () => { //the number of sended token //20 milli = 0.02 ether var transferAmount = web3.utils.toWei('20', 'milli'); var myAddress = "0x1d75...a5f"; var destAddress = "0x8a40....23fb"; // get the nonce var nonceCnt = await web3.eth.getTransactionCount(myAddress); console.log(`num transactions so far: ${nonceCnt}`); var abiArray = JSON.parse(fs.readFileSync("./myabi/ZTA_abi.json")); var contractAddress = "0xAc194f047E43Ee0Ee10026C0B7AAA66489a0Ec45"; var contract = new web3.eth.Contract(abiArray, contractAddress, { from: myAddress }); // begin token numbers await getERC20Balance(myAddress,contract,"Balance before send: "); const privkey = getPriKey("./projectConfig/net.prikey") await signERC20Transaction(myAddress,destAddress,contractAddress,contract,transferAmount,nonceCnt, privkey) sleep(100) //100ms // end token numbers await getERC20Balance(myAddress,contract,"Balance before send: "); } sendERC20();执行该nodejs脚本 node test\2.sendERC20.js效果如下: ![]() |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |