从记录跟踪交易探索以太坊交易
V刘晨曦
post on 2022-12-5 10:43:17
23
0
0
然后创建文件 tx.js ,请求依赖关系。var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider('https://ropsten.infura.io/'));
var util = require('ethereumjs-util');
var tx = require('ethereumjs-tx');
首先我们从理解一个私钥开始。以太坊通过
公钥加密
进行授权。具体来说,用
椭圆曲线数字加密算法
,通过
secp256k1
标准生成公钥。除了有一些
限制
外,私钥只是一个随机的 256 位的数。例如:var privateKey = '0xc0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0de';
通过私钥导出相应的公钥:var publicKey = util.bufferToHex(util.privateToPublic(privateKey));
如果你输出公钥,可以看到下面的 16 进制数:0x4643bb6b393ac20a6175c713175734a72517c63d6f73a3ca90a15356f2e967da03d16431441c61ac69aeabb7937d333829d9da50431ff6af38536aa262497b27
与私钥相关联的以太坊地址是用相应公钥进行
SHA3-256 (Keccak)
哈希运算后得到的后 160 位。var address = '0x' + util.bufferToHex(util.sha3(publicKey)).slice(26);
//0x53ae893e4b22d707943299a8d0c844df0e3d5557
正如你看到的,多个私钥可以有相同的地址。一个以太坊账户与一个地址相关联,而且每个地址都有以下属性:
nonce:输出交易的次数,从 0 开始
balance:账户中的以太币数
storageRoot:与账户存储相关联的哈希值
codehash:控制账户的代码的哈希,如果它是空的,那么就是一个正常账户,能够通过私钥访问的,否则,它就是一个智能合约,其交互受到代码的控制
接下来我们看一下交易,交易有 6 个输入域:
nonce:输出交易的次数,从 0 开始
gasPrice:交易中花费的单位 Gas 的价格
gasLimit:处理交易允许花费的最大 Gas 量
to:交易发送到的账户,如果是空,交易就会创建合约
value:发送的以太币的量
data:可以是任意的消息或合约函数调用或创建合约的代码
一个发送 1000wei 以太并且留下消息 0Xc0de 的交易可以被构造如下:var rawTx = {
nonce: web3.toHex(0),
gasPrice: web3.toHex(20000000000),
gasLimit: web3.toHex(100000),
to: '0x687422eEA2cB73B5d3e242bA5456b782919AFc85',
value: web3.toHex(1000),
data: '0xc0de'
};
注意, from 地址并没有指定,在私钥签署后,它会从签名中提取。签署交易:var p = new Buffer('c0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0dec0de', 'hex');
var transaction = new tx(rawTx);
transaction.sign(p);
然后交易就可以发送到网络上,而且能通过一个 256 位的交易 ID 进行追踪。这个交易可以在
Etherscan
中查看。交易 ID 是交易的哈希值console.log(util.bufferToHex(transaction.hash(true)));
//0x8b69a0ca303305a92d8d028704d65e4942b7ccc9a99917c8c9e940c9d57a9662
接下来,我们看一下指什么构成了函数调用的数据。以此次合约交易数据为例:console.log(web3.eth.getTransaction('0xaf4a217f6cc6f8c79530203372f3fbec160da83d1abe048625a390ba1705dd57').input);
//0xa9059cbb0000000000000000000000007adee867ea91533879d083dd47ea81f0eee3a37e000000000000000000000000000000000000000000000000d02ab486cedbffff
为了知道调用的是哪个函数,必须提前知道合约的所有的函数,才能创建哈希表。前 32 位 a9059cbb 是函数哈希的前 32 位。在当前情况下,函数为 transfer(address _to, uint256 _value) ,它的哈希为:console.log(web3.sha3('transfer(address,uint256)'));
//0xa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b
接下来是参数,每个 256 位,所以当前情况下 address 是:0x0000000000000000000000007adee867ea91533879d083dd47ea81f0eee3a37e
uint256 是:0x000000000000000000000000000000000000000000000000d02ab486cedbffff
接下来,如上所述,通过省略 to 域,可以建立一个合约。但是如何确定合约地址呢?以此交易为例:console.log(web3.eth.getTransactionReceipt('0x77a4f46ff7bf8c084c34293fd654c60e107df42c5bcd2666f75c0b47a9352be5').contractAddress);
//0x950041c1599529a9f64cf2be59ffb86072f00111
合约地址是发送者地址哈希值的后 160 位,而且 nonce 可以提前确定。对于这个交易来说,发送者和 nonce 可以在下列代码中发现:var contractTx = web3.eth.getTransaction('0x77a4f46ff7bf8c084c34293fd654c60e107df42c5bcd2666f75c0b47a9352be5');
console.log(contractTx.from);
//0x84f9d8b0e74a7060e20b025c1ea63c2b171bae6f
console.log(contractTx.nonce);
//0
所以合约地址是:console.log('0x' + util.bufferToHex(util.rlphash(['0x84f9d8b0e74a7060e20b025c1ea63c2b171bae6f', 0])).slice(26));
//0x950041c1599529a9f64cf2be59ffb86072f00111
现在我们算是搞清楚了这些十六进制数的含义!以太坊和智能合约具有打破许多行业的巨大潜力。线上有许多资源,你可以在下面找到几个更多关于以太坊的教程!以太坊主站
https://www.ethereum.org/
以太坊的其中一个客户端 Mist 的 GitHub Repo
https://github.com/ethereum/mist/releases
Solidity
http://solidity.readthedocs.io/en/latest/
Web3 api
https://github.com/ethereum/wiki/wiki/JavaScript-API
社区讨论
https://www.reddit.com/r/ethereum/
如果你有任何关于此文的问题,你可以在我们
GitHub nightlyHacks repo
中提出。
BitMere.com is Information release platform,just provides information storage space services.
The opinions expressed are solely those of the author,Does not constitute advice, please treat with caution.
The opinions expressed are solely those of the author,Does not constitute advice, please treat with caution.
Write the first review