主页 > 怎么在华为下imtoken > 以太坊的transaction id是怎么来的?
以太坊的transaction id是怎么来的?
基本概念
在计算机中,一个字节(Byte)就是8位(Bit),即一个8位的二进制数,即1Byte=8bit。 一个 8 位二进制数也是一个 2 位十六进制数。
例如:
1字节满0就是00000000,转换成十六进制字符串就是“0x00”
一个字节全为1是11111111,转换成十六进制字符串是“0xFF”
最低位为1的1个字节为00000001,转换为十六进制字符串为“0x01”
前缀 0x 表示十六进制。
我们每进行一次以太坊交易,都会得到该笔交易的交易ID,它是一个64位的十六进制字符串,例如:
“0x22a1264249302682475703933c819e32b4c1524938f93ff35b87c19f4e8beeb2”
在使用计算机编程语言go语言实现的以太坊中,它实际上是用一个32字节的字节数组来表示的。 所以这32个字节转换成一个十六进制字符串,就是一个64位的十六进制字符串。
那么,这32个字节是怎么来的呢? 是对整个交易结构的所有数据进行哈希处理的结果。 这个哈希值(即交易 id)将被写入区块链。 我们通常使用这个哈希值通过区块链浏览器中的交易哈希来查询交易。
在这里解释什么是哈希? Hash,英文Hash,百度的解释结果是:
Hash,一般译为散列、散列,或音译为散列,是将任意长度的输入(也称为预映射原像)通过哈希算法转化为固定长度的输出,输出即为哈希值. 这种转换是一个压缩映射,即哈希值的空间通常远小于输入的空间,不同的输入可能会哈希到同一个输出,因此无法从哈希中确定唯一的输入值value. 简单的说就是将任意长度的消息压缩成固定长度的消息摘要的函数
简单来说,你可以把散列看成是一种单向算法或函数(hash function)。 对于任意长度的输入,经过哈希函数处理后,可以得到固定长度的输出结果(哈希函数)。 价值)。 一般来说,对于不同的输入,经过哈希函数处理后得到相同哈希值(即碰撞)的概率是很低的(和彩票中奖的概率差不多,哈哈)。 对于相同的输入内容,使用相同的哈希函数后得到的哈希值是唯一的,即对于相同的输入内容,使用相同的哈希函数后,无论运行多少次,得到的哈希值都是 Values是独一无二的。 因此,对于两个不同的以太坊交易,即使交易内容只有1个字节,甚至1个比特(bit)不同,它们的交易ID也不会相同。
基本流程
接下来我们在以太坊的命令行终端通过交易哈希查询一笔交易,可以看到交易内容的大概字段
eth.getTransaction("0x22a1264249302682475703933c819e32b4c1524938f94ff35b87c19f4e8beeb2")
{
块哈希:“0x3be26d1481eeb783742f2792d0c6fa1c6398ce15bf1ec3c1c5a863fd46014035”,
区块编号:22027,
来自:“0x06fe0338213124b2d8f198eafb1914956824e218”,
煤气:21000,
gasPrice: 1000000000,
散列:“0x22a1264249302682475703933c819e32b4c1524938f94ff35b87c19f4e8beeb2”,
输入:“0x”,
随机数:3,
r: "0x325ead2013e351133a98876e83e2cb39954c3f370bdba397b091a06c3026f30d",
s: "0x2ba924507b42faa0f709fd7c7a5b785d5f26eff391c804598920cfaf850f8239",
至:“0x815261DC4186502eC0D8CCFEf163785e1617b1A8”,
交易指数:0,
五:“0x1df”,
值:200000000000000000000
}
以太坊中一笔交易的交易id是通过哈希函数从上述主要字段中计算出来的。 哈希字段包括:
来自:交易发送者
gas:本次交易可以使用的最大gas,本次交易实际使用多少gas由系统计算
gasPrice:gas 的价格,以 Wei 为单位。 即多少Wei等于1个gas。 以太坊的最小单位是 Wei。 1 以太 = 10 的 18 次方。 gas price 越高,交易越容易被矿工收录到区块中
input:扩展字段,发起智能合约交易时使用
nonce:交易发送方的交易计数器
r:签名值的r域
s:签名值的s字段
v:签名值的v字段
to: 交易接收者
value:交易转账金额,单位为Wei
但是这些字段不包括:blockNumber(区块编号)、blockHash(区块id)、hash(交易id)这些字段。
上述交易为普通转账交易,转账金额为value字段中的值,为20eth。 使用以太坊客户端钱包发送转账时,客户端钱包首先使用钱包私钥对转账内容进行签名以太坊怎么交易,计算出r、s、v三个字段,并生成签名值。 然后对转账交易的相关字段进行哈希运算。 这个时候转账的交易id已经确定了,不需要等转账写入区块再确定交易id。
看到这里,你应该对以太坊的交易id的基本处理流程有了一个大概的了解。 如果想详细了解交易id的计算过程,可以从以太坊的源码中了解更多。 如果您对以太坊的源代码不感兴趣,可以忽略以下内容。
源码分析
以太坊计算交易id的源码在文件中
go-ethereum/core/types/transaction.go
在 Hash() 函数中
func (tx *Transaction) Hash() common.Hash {
if hash := tx.hash.Load(); hash != nil {
return hash.(common.Hash)
}
v := rlpHash(tx)
tx.hash.Store(v)
return v
}
结构Transaction定义如下:
type Transaction struct {
data txdata
// caches
hash atomic.Value
size atomic.Value
from atomic.Value
}
结构体txdata定义如下:
type txdata struct {
AccountNonce uint64 `json:"nonce" gencodec:"required"`
Price *big.Int `json:"gasPrice" gencodec:"required"`
GasLimit uint64 `json:"gas" gencodec:"required"`
Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation
Amount *big.Int `json:"value" gencodec:"required"`
Payload []byte `json:"input" gencodec:"required"`
// Signature values
V *big.Int `json:"v" gencodec:"required"`
R *big.Int `json:"r" gencodec:"required"`
S *big.Int `json:"s" gencodec:"required"`
// This is only used when marshaling to JSON.
Hash *common.Hash `json:"hash" rlp:"-"`
}
以太坊使用的哈希函数是rlpHash()以太坊怎么交易,具体定义见core/types/block.go
func rlpHash(x interface{}) (h common.Hash) {
hw := sha3.NewLegacyKeccak256()
rlp.Encode(hw, x)
hw.Sum(h[:0])
return h
}
该函数首先对接口数据进行RLP编码,然后使用Keccak256哈希算法得到交易哈希。
网上关于RLP编码规则的文章很多,这里就不详细介绍了。 RLP编码的重点是在原始数据上加上几个字节的前缀,而这个前缀与数据的长度有关。 RLP编码后得到的是一个字节数组。
我的csdn:
我的知乎:
我的腾讯微云网盘:
如果觉得这篇文章写得不错,请点个赞,谢谢!
您的鼓励,我的动力!