以太坊合约交易签名web3.js
环境:window
工具或客户端:ganache 1.2.1 ,
browser-solidity(
在线地址①:
https://ethereum.github.io/browser-solidity/#optimize=false&version=soljson-v0.4.21+commit.dfe3193c.js
在线地址②:
http://remix.ethereum.org/#optimize=false&version=soljson-v0.4.24+commit.e67f0147.js
)
开发语言:javacript
依赖的javacript文件:
web3.min.js;
ethereumjs-tx.js;
bignumber.js
(下载地址链接:
https://pan.baidu.com/s/1KRbH7G0yw5gnXl6iu3k83w 密码: jjqb )
下载后把这三个文件放在同一目录,并新建一个html页面含基础标签元素并引入以上三 个文件
例:
写在前面
预读此文档你将学习到以下内容
1.使用web3js与现有合约交互
2.使用在线solidity编译器创建编译合约
3. 使用web3js和ethereumjs-tx发布一个新的智能合约
4. 以太坊手机客户端轻钱包在安卓,ios中实现
5. 使用web3js实现合约交易签名
6. 发送合约交易前如何获取最佳gaslimit(要点)及算法实现
7. 发送合约交易前如何获取最佳gasprice
8. 发送合约交易前如何获取nonce
9.判断广播交易之后的状态和是否成功
10.网页钱包开发在html中实现
参考文档:
Web3.js中文文档(常用api):
http://web3.tryblockchain.org/ethereum-web3.js-%E5%85%A5%E9%97%A8%E8%AF%B4%E6%98%8E.html
Web3.js英文文档(比中文文档更全):
http://web3js.readthedocs.io/en/1.0/index.html
案例:
1)实例化web3
var web3 = new Web3();
// 连接到以太坊节点
web3.setProvider(new Web3.providers.HttpProvider("http://localhost:7545"));
2) ABI
//ABI可以从browser-solidity直接获取复制粘贴(ABI)
var ABI = [ { "constant": false, "inputs": [ { "name": "receiver", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "sendCoin", "outputs": [ { "name": "sufficient", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "addr", "type": "address" } ], "name": "getBalance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "_from", "type": "address" }, { "indexed": true, "name": "_to", "type": "address" }, { "indexed": false, "name": "_value", "type": "uint256" } ], "name": "Transfer", "type": "event" } ]
var MyContract = web3.eth.contract(ABI).at("contract address"); //获得已部署合约对象
//创建发布合约
3) WEB3DEPLOY直接从browser-solidity直接获取复制粘贴(WEB3DEPLOY)即下面蓝色字体部分
var metacoinContract = web3.eth.contract(
[{"constant":false,"inputs":[{"name":"receiver","type":"address"},{"name":"amount","type":"uint256"}],"name":"sendCoin","outputs":[{"name":"sufficient","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"addr","type":"address"}],"name":"getBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"}]);
var metacoin = metacoinContract.new(
{
from: web3.eth.accounts[1], //自定义(创建合约的地址)
data: '0x6060604052341561000f57600080fd5b6127106000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506102c5806100636000396000f30060606040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806390b98a1114610051578063f8b2cb4f146100ab575b600080fd5b341561005c57600080fd5b610091600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506100f8565b604051808215151515815260200191505060405180910390f35b34156100b657600080fd5b6100e2600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610251565b6040518082815260200191505060405180910390f35b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610149576000905061024b565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190505b92915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509190505600a165627a7a72305820e2d46191a8715f82d9e47514eff86596520cf4a8cd19717c8579c92ac0c86b1b0029',
gas: '4700000'
}, function (e, contract){
console.log(e, contract);
if (typeof contract.address !== 'undefined') {
console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
}
})
//查询合约地址余额
var balance_account_one = metacoin.getBalance.call(web3.eth.accounts[1]);
balance_account_one.toString(10);
< "10000"
//获取bufferl类型私钥
var privatekey=New EthJS.Buffer.Buffer.from(
'f0a6e4f7f3a51033d50057c0debc5d2f1306e97bf0ae6c8723bd1f15a46e0a54','hex');
//获取调用智能的data
//方法abi+参数(参数1,接收地址;参数2 发送代币金额)也可以自己拼接data
var data = metacoin.sendCoin.getData("0xE7E0afc3D0A1876e1DdA5FD001D127d5dC8FAb29",500);
Console.log(data);
//"0x90b98a11000000000000000000000000e7e0afc3d0a1876e1dda5fd001d127d5dc8fab2900000000000000000000000000000000000000000000000000000000000001f4"
//获取gasprice
var gasPrice = web3.eth.gasPrice;
console.log(gasPrice.toString(10)); //20000000000
var gasPrice_hex = web3.toHex(20000000000)
//签名交易
var nonce = web3.eth.getTransactionCount(web3.eth.accounts[1]);
Consle.log(nonce); //1
var nonce_hex = web3.toHex(0)
var rawTx_example = {
nonce: 0x01, //nonce_hex
gasPrice: '0x4a817c800', //gasPrice_hex
to: '0x90A679A0a247b9218c88d473B2Ce556460993ec3', //tokenaddress:调用合约时使用合约地址;非合约交易时接收地址
value: '0x00',
data:'0x90b98a11000000000000000000000000e7e0afc3d0a1876e1dda5fd001d127d5dc8fab2900000000000000000000000000000000000000000000000000000000000001f4' //data
}
var gaslimit = web3.eth.estimateGas(rawTx_example)
Console.log(gaslimit ) //36002
<36002
var gaslimit_hex = web3.toHex(36002);
Console.log(gaslimit_hex) //0x8ca2
<"0x8ca2"
var rawTx = {
nonce: 0x01, //nonce_hex
gasPrice: '0x4a817c800', //gasPrice_hex
Gaslimit:’0x8ca2’ , // gaslimit_hex
to: '0x90A679A0a247b9218c88d473B2Ce556460993ec3', //tokenaddress:调用合约时使用合约地址;非合约交易时接收地址
value: '0x00',
data:'0x90b98a11000000000000000000000000e7e0afc3d0a1876e1dda5fd001d127d5dc8fab2900000000000000000000000000000000000000000000000000000000000001f4' //data
}
var tx =new EthJS.Tx(rawTx);
tx.sign(privateKey);
var serializedTx = tx1.serialize();
web3.eth.sendRawTransaction(‘0x’+serializedTx , function(err, hash) {
console.log(err)
console.log(hash); //"0x39225d367c12f9eab59b6ff95cfe8e90e3c24142647ef73fa63e268e24d63506"
});
var balance_account_one= metacoin.getBalance.call(web3.eth.accounts[1]);
balance_account_one.toString(10);
<"9500"
拿到交易回执:
web3.eth.getTransactionReceipt("0x39225d367c12f9eab59b6ff95cfe8e90e3c24142647ef73fa63e268e24d63506");
根据返回的结果status判断,如果是0X1就代表交易被确认打包.转账成功是否成功以交易记录为准
成功!