基础概念

在计算机里,一个字节(Byte)是8个比特(Bit),即8位二进制数,即1Byte=8bit。8位二进制数也就是2位十六进制数。

举个例子:
全是0的1个字节就是 00000000,转换为十六进制字符串就是"0x00"
全是1的1个字节就是 11111111,转换为十六进制字符串就是"0xFF"
最低位是1的1个字节就是 00000001,转换为十六进制字符串就是"0x01"

前缀0x表示十六进制。

我们每进行一笔以太坊的交易,就会得到该笔交易的交易id,它是一个64位的十六进制字符串,例如:
“0x22a1264249302682475703933c819e32b4c1524938f93ff35b87c19f4e8beeb2”

在使用计算机编程语言go语言实现的以太坊里,它实际上是用32个字节的字节数组来表示的。所以这32个字节转换为十六进制字符串,也就是64位的十六进制字符串。

那么,这32个字节又是如何来的呢?是对整个交易结构的所有数据进行哈希的结果。该哈希值(即交易id)会被写入区块链里。我们平时在区块链浏览器里通过交易哈希查询一笔交易时使用的就是这个哈希值来进行查询的。

这里解释一下哈希是什么?哈希,英文Hash,从百度的解释结果就是:
Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数

简单一点,你可以把哈希看作一种单向的算法或函数(散列函数),对于任意长度的输入,经过哈希函数的处理后,都能得到一个固定长度的输出结果(哈希值)。一般来说,不同的输入,经过哈希函数的处理后得到相同的哈希值(也就是冲突)概率是很低很低的(差不多和中彩票特等奖的概率差不多,哈哈)。对于同一个输入内容,在使用同一种哈希函数处理后得到的哈希值是唯一的,即对于同一个输入内容,在使用同一种哈希函数处理,无论运行多少遍,其得到的哈希值是唯一的。因此,对于2笔不同的以太坊的交易,哪怕交易内容只有1个字节,甚至是1比特(bit)的不同,它们的交易id都不会一样。

基本流程

下面我们在以太坊的命令行终端通过交易哈希来查询一笔交易,可以看到交易的内容大概有哪些字段

eth.getTransaction(“0x22a1264249302682475703933c819e32b4c1524938f94ff35b87c19f4e8beeb2”)
{
blockHash: “0x3be26d1481eeb783742f2792d0c6fa1c6398ce15bf1ec3c1c5a863fd46014035”,
blockNumber: 22027,
from: “0x06fe0338213124b2d8f198eafb1914956824e218”,
gas: 21000,
gasPrice: 1000000000,
hash: “0x22a1264249302682475703933c819e32b4c1524938f94ff35b87c19f4e8beeb2”,
input: “0x”,
nonce: 3,
r: “0x325ead2013e351133a98876e83e2cb39954c3f370bdba397b091a06c3026f30d”,
s: “0x2ba924507b42faa0f709fd7c7a5b785d5f26eff391c804598920cfaf850f8239”,
to: “0x815261DC4186502eC0D8CCFEf163785e1617b1A8”,
transactionIndex: 0,
v: “0x1df”,
value: 20000000000000000000
}

以太坊一笔交易的交易id就是对上面主要的字段,通过哈希函数计算出来的,进行哈希的字段包括:
from:交易发送者
gas:该笔交易可以使用的手续费gas的最大值,该笔交易实际使用多少gas由系统来计算
gasPrice:gas的价格,单位是 Wei。即1gas等于多少 Wei。以太坊的最小单位是 Wei。1 个以太币 = 10 的 18 次方 Wei。gas的价格越高,该笔交易越容易被矿工打包进区块里
input:扩展字段,发起智能合约交易时使用
nonce:交易发送者的交易计数器
r:签名值的r字段
s:签名值的s字段
v:签名值的v字段
to:交易接收者
value:交易转账数量,单位是 Wei

但不包括这些字段:blockNumber(区块号)、blockHash(区块id)、hash(交易id)这些字段。

上面的交易是一笔普通的转账交易,转账金额是value字段里的值,即20个eth。当使用以太坊的客户端钱包发送一笔转账时,客户端钱包先使用钱包私钥对转账内容进行签名,计算出r、s、v这3个字段,生成签名值。然后再对转账交易的相关字段进行哈希运算,此时该笔转账的交易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// cacheshash atomic.Valuesize atomic.Valuefrom 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 creationAmount       *big.Int        `json:"value"    gencodec:"required"`Payload      []byte          `json:"input"    gencodec:"required"`// Signature valuesV *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:https://blog.csdn.net/powervip
我的知乎: https://www.zhihu.com/people/powervip
我的腾讯微云网盘:https://share.weiyun.com/5qT0TvG

如果你觉得这篇文章写得还可以,请帮忙点个赞,谢谢!

你的鼓励,我的动力!

以太坊的交易id是如何来的相关推荐

  1. 【前沿解读】斯坦福研究员论文-以太坊可逆交易标准ERC20/721R的机制、创新与局限

    区块链交易的不可逆特性,一度被形容为是唯一的人类对上帝'时间'的低劣仿制品,然而也正是因为不可逆,导致大量黑客攻击资金被盗无处解决,也被趣称为web2向web3最成功的转型:黑客. 而斯坦福大学研究员 ...

  2. 一、以太坊单笔交易字段含义

    消费者可以通过Metamask.mist浏览器实现与以太坊的交互,而开发者可以通过web3js工具库实现以太坊的交互. 单笔交易需要的字段: nonce :   定义 官方文档对于nonce的说明: ...

  3. 【以太坊】交易的重点学习

    一.交易信息获取 1.1 合约事件例子定义 举例,比如合约中事件如下:(以下内容均使用该事件例子) event Transfer(address indexed from, address index ...

  4. 一文讲明白以太坊上交易类型含义、作用、发展过程

    目录 以太坊链上上主要有3中交易类型 Txn Type: 0 (Legacy transactions, 遗留事务) EIP-2718议案 EIP-155复杂性看旧交易格式的现有问题 EIP-2718 ...

  5. 以太坊的交易树和收据树

    交易树和收据树 每次发布一个区块时,区块中的交易会形成一颗交易树.此外,以太坊还添加了一个收据树,每个交易执行完之后形成一个收据,记录交易相关信息.也就是说,交易树和收据树上的节点是一一对应的. 为什 ...

  6. Clickhouse 以太坊分析:交易日志分析

    概述 读者可前往我的博客获得更好的阅读体验. 在上一篇中,我们介绍了如何使用 Clickhouse 进行基础的信息提取,这些信息往往依赖于以太坊底层机制,我们只能获得如 ETH 转账. gas 等信息 ...

  7. Grayscale获得FINRA许可,在OTC市场进行受监管的以太坊信托交易

    点击上方 "蓝色字" 可关注我们! 暴走时评: 据报道,美国数字资产管理公司Grayscale Investments证实,其以太坊信托(ETHE)已获得金融业监管局(FINRA) ...

  8. 以太坊ETH交易数据解析

    ETH 有账户概念,大致数据含义如下: f8 //数据长度,f7+len (大于56) , 80+len (小于56) 6d // 大于56 时,数据长度 82 // 80+len  nonce 长度 ...

  9. 以太坊区块和交易存储

    区块存储 区块(Block)是以太坊的核心数据结构之一,Block包含Header和Body两部分.区块的存储是由leveldb完成的,leveldb的数据是以键值对存储的. // BlockChai ...

最新文章

  1. 《Python程序设计》教学大纲
  2. Codeforces Round #703 (Div. 2) B.Eastern Exhibition 中位数结论
  3. 小爱同学与小冰将实现联合进步
  4. python找思路_python 爬取贝壳的一些思路和方法设计(用地址找到小区名字)
  5. 能搜python题的软件_中国大学MOOC的APP用Python玩转数据期末考试搜题公众号答案...
  6. php重点,php – 课程。重点是什么?
  7. MATLAB遇到问题:MATLAB2020以上版本代码拷到其他低版本电脑出现中文乱码的解决方案
  8. android imagebutton 设置边框,【Android技巧】ImageButton 去边框 添加按下效果
  9. 极大似然函数求解_快速理解极大似然法
  10. 有用的一些链接Powerstore VxRail
  11. qq linux for android,腾讯QQ for android 糊弄还是敷衍?
  12. JavaScript如何判定一个给定的时间区间在哪些时间段范围内?
  13. Python的re库和正则表达式
  14. linux cnc 树莓派,谈谈LinuxCNC
  15. Shell基础之自定义变量
  16. 电力电子转战数字IC20220629day35——路科实验2b
  17. 阿里云服务器部署(新手福利)
  18. 学习心得,书读百遍其义自见!
  19. MySQL基础全套全网最详细讲解
  20. 动态创建excel文件,动态合并单元格并提供下载

热门文章

  1. A Tale from the Dark Side of The Moon
  2. 机器学习入门资料推荐
  3. android cda格式播放,安卓手机如何打开.cda文件
  4. php打水印与去水印,php打水印函数
  5. C# 引用Indesign
  6. MySQL的7种JOIN表连接结果集,你了解几个?搞懂仅需1张图
  7. python产品经理_数据产品经理该懂的python技术
  8. CobaltStrike 插件编写入门教程
  9. WDS+MDT部署Windows7操作系统3—ADK安装和MDT
  10. 电脑网络栏只剩下飞行模式