使用web3.js 1.0纯前端操作以太坊

版权声明:学习中。。。 https://blog.csdn.net/fangdengfu123/article/details/82018313
如果不想自己搭建节点,可以使用https://infura.io/ 该网站提供的免费节点进行操作。
如果是自己搭建节点时,请预防偷渡攻击(慎用unLockAccount操作)。

在使用web3js操作以太坊时,主要包含3个步骤:
1、构造交易参数
2、将交易信息使用私钥签名
3、发送签名交易

rpc链接:

var web3;
if (typeof web3 !== 'undefined') {
    web3 = new Web3(web3.currentProvider);
} else {
    web3 = new Web3(new Web3.providers.HttpProvider(RPC_URL));
}

交易参数主要包含:

{
    from:                 // 交易发起方地址
    to:                   // 交易目标地址
    value:                // 交易eth数量(当调用合约时,此处可以为0)
    data:                 // 扩展字段(当调用合约时,此处为合约的方法以及参数)
    gasPrice:             // 手续费单价
    gasLimit:             // 手续费上限
}

签名方法:

web3.eth.accounts.signTransaction('你的交易参数对象', 'yourPrivateKey').then(tx => {
    console.log('Result: ', tx);
    var raw = tx.rawTransaction;
}

发送签名交易:

web3.eth.sendSignedTransaction('上面的raw').on('receipt', res => {
    console.log('操作成功');
}).on('error', err => {
    console.log('操作异常');
});

整体写法:

var txData = {
    from:                 // 交易发起方地址
    to:                   // 交易目标地址
    value:                // 交易eth数量(当调用合约时,此处可以为0)
    data:                 // 扩展字段(当调用合约时,此处为合约的方法以及参数)
    gasPrice:             // 手续费单价
    gasLimit:             // 手续费上限
}
web3.eth.accounts.signTransaction(txData , 'yourPrivateKey').then(tx => {
    console.log('Result: ', tx);
    var raw = tx.rawTransaction;
    web3.eth.sendSignedTransaction(raw).on('receipt', res => {
        console.log('操作成功');
    }).on('error', err => {
        console.log('操作异常');
    });
}
下面针对交易参数进行单独说明:
交易参数 转账ETH 调用合约
from 这个毫无疑问,交易发起方即操作人的钱包地址 -
to 目标账户 合约地址
value ETH数量 0x00
data 视为扩展字段,可有可无 方法名称+参数列表
gasPrice 手续费单价 -
gasLimit 手续费上限 -
如何动态设置交易手续费,使其最低(这里只是构造交易参数,使其在节点上模拟执行一次,获取此次执行的花费):
// 操作eth
web3.eth.estimateGas({
    from:yourAccountAddr,
    to: toAddress,
    data: '0x00'
}).then(res => {
    console.log(res);
}
// 操作合约
web3.eth.estimateGas({
    from: yourAccountAddr,
    to: token.options.address,
    data: funcAbi (该参数后面说明)
}).then(res => {
    console.log(res);
}
构建合约对象
// abi可以使用remix编译源码后获得
var abi = [];
var token = new web3.eth.Contract(abi, 'yourContractAddress');
账户操作:
// 可以直接获得地址和私钥
var account = web3.eth.accounts.create();
// 如果需要使用钱包的方式操作,加密获得的是一个json格式的钱包
var store = web3.eth.accounts.encrypt(account.privateKey, 'yourPassword');
// 通过钱包和密码生成私钥
account = web3.eth.accounts.decrypt(store, 'yourPassword');
var key = account.privateKey;

// 通过私钥生成账户信息,如果发生错误,说明私钥不正确
account = web3.eth.accounts.privateKeyToAccount(key);
  • 使用token对象获取funcAbi
var funcAbi = token.methods.transfer(toAddress, web3.utils.toWei(num, 'ether')).encodeABI();
  • 另外一种方式获取funcAbi
// 用上面的transfer进行举例
var tokenNum = web3.utils.toWei(num, 'ether');
// '0x70a08231' : 合约方法名称的hex编码
// substring(2) : 将hex编码的前缀(0x)拿掉
// addPreZero   : 参数前补0,已达到参数长度一致
var funcAbi = '0x70a08231' + addPreZero(toAddress).substring(2) + addPreZero(tokenNum).substring(2);
var addPreZero = (num) => {
  var t = (num+'').length,
  s = '';
  for(var i=0; i<64-t; i++){
    s += '0';
  }
  return s+num;
}
使用ethereumjs-tx.js进行离线签名:
// 引入js
// 创建对象
var tx = new ethereumjs.Tx(null, 'networkId');
tx.nonce = '';              // 账户的 transactionCount
tx.gasPrice = web3.utils.hexToNumber(web3.utils.toWei('price', 'gwei'));
tx.gasLimit = 100000;       // 此处因为是离线签名,所以无法动态获取gasLimit

// 获取私钥buffer对象
var keyBuffer = ethereumjs.Buffer.Buffer.from('yourKey', 'hex');

// 如果是ETH
    tx.value = (new web3.utils.BN(web3.utils.toWei(num, 'ether'))).toString('hex');
    tx.to = targetAddress;
// 如果是合约
    tx.data = funcAbi;
    tx.value = '0x00';
    tx.to = token.options.address;

tx.sign(keyBuffer);
var raw = '0x' + tx.serialize().toString('hex');
// 然后发送签名交易即可
BN大数字相关操作:
// res 为估算的gasLimit
var pay = new web3.utils.BN(res);
var balance = new web3.utils.BN(web3.utils.toWei(ethBalance, 'ether'));
// 比较大小    <     =    >
//            -1    0   1
if (balance.cmp(pay) === -1) {      
    console.log('手续费不足,请核实');
    return;
}
// 减;add 为 加
var subRes = balance.sub(pay);
// 乘
var mulRes = balance.mul(pay);
其它相关操作:
// 获取账户ETH余额
web3.eth.getBalance(defaultAccount).then(res => {
    var ethBalance = web3.utils.fromWei(res, 'ether');
});
// 获取账户代币余额
token.methods.balanceOf(address).call().then(res => {
    var vccBalance = web3.utils.fromWei(res, 'ether');
});
部署合约:
// 合约字节码和ABI均可以使用remix编译源码获得,args为构造函数参数列表
var contract = new api.web3.eth.Contract(JSON.parse(abi));
var transactionData = contract.deploy({
    data: '合约字节码',
    arguments: eval("(" + args + ")")
}).encodeABI();

var options = {
    from: address,
    data: transactionData,
    gasPrice: web3.utils.toWei(gasPrice, 'gwei'),
    gasLimit: '程序估算的值'
}
// 签名,发送交易
web3.eth.accounts.signTransaction(options, 'yourPrivateKey')....
其它内容后续用到再进行整理。。。

猜你喜欢

转载自blog.csdn.net/fangdengfu123/article/details/82018313