web3交易
Web3简介
通过Web3我们在以太坊网络中创造自己的节点,并过JSON-RPC协议访问以太坊网络,创建智能合约,部署智能合约,处理交易,web3中提供eth对象,web3.eth来与区块链以太坊进行交互。
Web3交易分类
交易名 参数
|
发布合约 |
主币交易 |
代币交易 |
内部交易 |
发送方地址(from) |
必填 |
必填 |
必填 |
必填 |
接受方地址(to) |
不填 |
必填 |
必填(合约地址) |
必填(合约地址) |
随机数(nonce) |
必填 |
必填 |
必填 |
必填 |
金额(value) |
不填 |
必填 |
必填 |
必填 |
Gas用量(gas Limit) |
必填(相比其他交易需要更多) |
必填 |
必填 |
必填 |
Gas价格(gas Price) |
必填 |
必填 |
必填 |
必填 |
Data |
byteCode(合约源码编译的二进制) |
不填 |
必填 |
必填 |
说明 |
没有接受方的交易为发布合约 |
用主币发交易 |
合约交易是由合约地址和abi构建成合约对象,通过合约对象,调用合约源码中记录合约交易方法生成对应data
|
内部交易为合约交易中一种主币交易,用合约对象操作合约,用主币发送交易 |
准备工作
引入
var Web3 = require('web3');
使用
Var node_url = "http://192.168.0.1:8080";//区块链节点及端口
var web3 = new Web3(new Web3.providers.HttpProvider(node_url));
常用方法
获取nonce(交易随机数)
getTransactionCount(address[,function(error,nonce)]);
发送原始交易
sendSignedTransaction(tx[,function(error,hash)] ).then(function(data))
第一个function会在节点接收到交易后经过效验后触发
第二个function会在交易被确认之后触发
Data:交易回执(可在ethereumjs-tx库)中查看其数据结构
获取地址余额
getBalance(address[,function(error,balance)])
ethereumjs-tx库
引入
var Transaction = require('ethereumjs-tx');
交易对象
nonce:
记录发起交易的账户已执行交易总数。Nonce的值随着每个新交易的执行不断增加,这能让网络了解执行交易需要遵循的顺序,并且作为交易的重放保护。
gasPrice:
该交易每单位gas的价格,Gas价格目前以Gwei为单位(即10^9wei),其范围是大于0.1Gwei,可进行灵活设置。
gasLimit:
该交易支付的最高gas上限。该上限能确保在出现交易执行问题(比如陷入无限循环)之时,交易账户不会耗尽所有资金。一旦交易执行完毕,剩余所有gas会返还至交易账户。
to:
该交易被送往的地址(调用的合约地址或转账对方的账户地址)。
value:
交易发送的以太币总量。
实例化交易对象
Var tx = new Transaction({nonce,to,value,gasLimit,gasPrice,data});
签名交易
使用私钥对原始的交易信息进行签名,得到签名后的交易数据
let privateKey = Buffer.from(私钥, 'hex');
tx.sign(privateKey);
let serializedTx = tx.serialize();
交易回执
Data: {
"transactionHash":"0xd14db3c4091a8a5fe4bf0af8a8d57c9...",//交易hash
"transactionIndex": 1,//交易下标
"blockHash":"0x80d53ba712e47c509ae44f092ad9f...",//块hash
"blockNumber": 194619,//块号
"from": "0xbe77356f55a762cce...",//发送方地址
"to": "0x7385018a12ce8c5ea626241d87...",//接受方地址
"cumulativeGasUsed": 74956,//最多费用
"gasUsed": 51474,//实际费用
"contractAddress": null,//合约地址
"logs": [{
"logIndex": 0,//日志下标
"transactionIndex": 1,//交易下标
"transactionHash":"0xd14db3c4091a8a5fe4bf0a...",’
"blockHash":"0x80d53ba712e47c509ae44f092ad9f7a9da...",
"blockNumber": 194619,//块号
"address": "0x7385018A12cE8C5E",//合约地址
"data": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000...",//金额
"topics":["0xddf252ad1be2c89b69c2...", "0x00000000000000000000....", "0x000000000000000023e58c0..."],
id": "log_cf0320cf.."
],
logsBloom": "0x00000000000....",
"status": true
}
solc编译器
引入
var solc = require("solc");
编译合约
let cacl=solc.compile(合约源码,false);
获取ABI和byteCode
let abi= JSON.parse(cacl.contracts[':合约对象名].interface);
let bytecode=cacl.contracts[':合约对象名'].bytecode;
发送交易
发布合约交易
Nonce:根据发送方地址实时获取
From:发送方地址
privateKey:发送方私钥
data:’0x’+ bytecode//16进制源码
gasLimit:最大里程数(一般默认web3.utils.toHex(200000))
gasPrice:油价(一般默认web3.utils.toHex(web3.utils.toWei("15", "gwei")))
主币交易
From:发送方地址
privateKey:发送方私钥
Nonce:根据发送方地址实时获取
To:接收方地址
value:交易金额
gasLimit:最大里程数(一般默认web3.utils.toHex(60000))
gasPrice:油价(一般默认web3.utils.toHex(web3.utils.toWei("15", "gwei")))
代币交易
From:发送方地址
privateKey:发送方私钥
Nonce:根据发送方地址实时获取
To: 发布合约所产生的合约地址
value:交易金额,一般合约交易不需要交易金额,默认0x0
gasLimit:最大里程数(一般默认web3.utils.toHex(200000))
gasPrice:油价(一般默认web3.utils.toHex(web3.utils.toWei("15", "gwei")))
data: 由合约地址和abi构造成的合约对象,合约对象调用合约源码方法得到
(new web3.eth.Contract(abi,合约地址). methods.transfer(To,wei).encodeABI();)
内部交易
From:发送方地址
privateKey:发送方私钥
Nonce:根据发送方地址实时获取
To: 发布合约所产生的合约地址
value:交易金额,一般合约交易不需要交易金额,默认0x0
gasLimit:最大里程数(一般默认web3.utils.toHex(200000))
gasPrice:油价(一般默认web3.utils.toHex(web3.utils.toWei("15", "gwei")))
data: 由合约地址和abi构造成的合约对象,约对象调用合约源码方法得到
(new web3.eth.Contract(abi,合约地址). methods.transferETHS([To],[wei]).encodeABI();)
交易发送
根据不同交易类型参数,分别封装不同相对应的交易对象
Let tx = New Transaction({
nonce : web3.utils.toHex(nonce),
to:To,
value: web3.utils.toHex(web3.utils.toWei(value, "ether")),
gasLimit: web3.utils.toHex(gasLimit),
gasPrice: web3.utils.toHex(web3.utils.toWei(gasPrice, "gwei")),
data:data
})
获取签名
let privateKey = Buffer.from(privateKey, 'hex')
tx.sign(privateKey);
let serializedTx = tx.serialize();
发送原始交易
web3.eth.sendSignedTransaction('0x'+serializedTx.toString('hex'),function(err, hash){}).then(function(data) {});
操作如下:
1,首先,我们需要一套Node环境支持我们做开发操作,使用node –v 确认node环境已经撘好
其次,引入一些相关的依赖,如下图所示:
组件Web3,里面有发送交易的一些方法
组件solc,用来编译合约源码,得到对应的abi和byteCode
组件tx,用来封装交易参数,构建交易对象
2,发布合约,我们先编译合约源码,得到需要的byteCode和abi,发布合约的data中需要存放对应的byteCode
发布一份智能合约,示例如下:
3,主币交易
主币交易与发布合约相比,主币交易的交易对象中需要有接受方地址,而且要有对应金额的参数,示例如下:
3,合约交易
合约交易和主币交易的不同就是合约交易需要用到合约地址,合约交易的接收方地址必须是合约地址,用合约对象处理交易,如下图: