作者:林冠宏 / 指尖下的幽灵

掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8

博客:http://www.cnblogs.com/linguanh/

GitHub : https://github.com/af913337456/

腾讯云专栏: https://cloud.tencent.com/developer/user/1148436/activities


目录

  • 前序
  • 数据签名
    • 整体流程
    • 非对称加密
    • RLP 序列化
  • 数据验证
  • 数据篡改

前序

最近的工作一直是基于 以太坊公链 做 DApp 开发,虽然对其各 API 的调用都已经很了解了,但是源码部分一直还没深入去看过。工欲善其事,必先利其器,故计划阅读完 以太坊go 版源码,后续会更新系列文章。本文主要简谈 sendRawTransaction 是如何保证我们交易安全的。

1.数据签名

方法:sendRawTransaction

整体流程:

  1. 传入各参数 ---->
  1. 使用from 对应的 privateKeysecp256k1 算法对 各入参 签名得出三个量:V,R,S ---->
  1. RLP (递归长度前缀) 方式序列比签名的数据 与 原入参数据 ---->
  1. 发送到 ETH 节点

sendRawTransaction 函数的各个入参:

  • from 发送者钱包地址
  • value 数值,为与 decimal 的乘积
  • gas 油费,非最终真实使用值,真实为 gasUsed
  • gasPrice 油费单价
  • data 附属的数据,可做智能合约函数入参
  • nonce 交易系列号,类似id

它们都将会被 from 所对应的密钥 进行签名而得出三个量:V,R,S。同时,各个入参依然以原来的可见的形式进入序列化步骤。

注意:

还有另外一个叫做 sendTransaction 的方法,通过分析源码,可以发现 sendTransaction 内部其实会帮助我们根据我们传参的 from 字段到节点的 accountManager 账号管理器中获取from 的密钥,来帮我们进行数据签名,所以,sendTransaction 一般不会用于远程调用,而用于本地调用,因为只有在本地启动节点的时候,才能配置我们解锁的钱包。

所用的签名加密方式是:非对称加密 中的 secp256k1 椭圆曲线算法

非对称加密:

它是一类加密方式的统称。具体到某种能实现它的算法有下面几种:

  • RSA
  • secp256k1 (椭圆曲线)
  • ElGamal
  • ...

sendRawTransaction 用到的就是 secp256k1

RLP 序列化

RLP (递归长度前缀)提供了一种适用于任意二进制数据数组的编码,RLP已经成为以太坊中对对象进行序列化的主要编码方式。RLP的唯一目标就是解决结构体的编码问题;对原子数据类型(比如,字符串,整数型,浮点型)的编码则交给更高层的协议;以太坊中要求数字必须是一个大端字节序的、没有零占位的存储的格式。

签名后,数据将会被发送到 ETH 节点。

2. 数据验证

对应到以太坊的 sendRawTransaction RPC 接口。

  1. 收到 RLP 序列化的数据后,先进行 RLP 的反序列化
func (s *PublicTransactionPoolAPI) SendRawTransaction(..., encodedTx hexutil.Bytes) (common.Hash, error) {
tx := new(types.Transaction)
if err := rlp.DecodeBytes(encodedTx, tx); err != nil { // 反序列化
return common.Hash{}, err
}
return submitTransaction(ctx, s.b, tx)
}
  1. 数据的基础校验,主要是一些范围限制以及格式限制校验

    • tx.Size() > 32*102
    • tx.Value().Sign() < 0
    • pool.currentMaxGas < tx.Gas()
    • ...
  2. 检查签名,所使用的是 secp256k1.RecoverPubkey 方法,secp256k1 本身支持根据签名信息反推公钥

用消息和签名推导出对方的公钥。再通过公钥,签名,消息的哈希值计算出一个叫 r 的值,这个 r 是签名的一部分,校验签名就是拿计算出来的 r 和签名中携带的 r 经行对比,如果一致就校验通过


if C.secp256k1_ext_ecdsa_recover(
context,
(*C.uchar)(unsafe.Pointer(&pubkey[0])),
sigdata, // 签名
msgdata) == 0 { // msgdata tx 的 hash 内容 return nil, ErrRecoverFailed
}

3. 数据篡改

因为签名生成的 V R S 是由私钥进行签名的,如果修改者只修改了外部的值,例如 value,本来是要转 10 个 ETH , 被改成转 100 个,等数据传到以太坊的时候,在检查签名的时候,就会发现不匹配,而抛出错误。

以太坊: ETH 发送交易 sendRawTransaction 方法数据的签名 和 验证过程的更多相关文章

  1. 以太坊ETH中智能合约消耗的Gas、Gas Limit是什么?

    以太坊ETH中智能合约消耗的Gas.Gas Limit是什么? 数字货币交易一般是有交易费的,比特币(BTC)的交易费很容易理解,就是直接支付一定额度的BTC作为手续费.而以太坊(ETH)的交易费表面 ...

  2. 以太坊 EVM内交易执行分析(一)

    以太坊上交易最终都会由EVM进行解析存入数据库,今天就来探讨一下,一笔交易是如何别EVM执行的.我们可以把交易分为三种.(注意,和交易相关的模块很多,交易的生命周期存在于整个以太坊中,我们这次只是分析 ...

  3. 以太坊 EVM内交易执行分析(二)

    接着上次的分析,分析一下run方法是如何执行智能合约的.至于以太币的交易,在上一篇中,已经由分析的那两个函数完成了: 合约的运行是从run开始的,go-ethereum/core/vm/evm.go  ...

  4. 以太坊中的账户、交易、Gas和区块Gas Limit等概念

    什么是账户 以太坊账户与我们所知的账户概念有一定相似之处,却又有很大的区别,更不同于比特币中UTXO. 账户分两类: - 外部拥有账户(EOA),也就是普通账户 - 合约账户 普通账户 所谓的普通账户 ...

  5. 以太坊和IPFS如何存储数据

    如何将JSON文件存储在IPFS上,并使用Oraclize访问智能合约中的数据呢? 以太坊是一个成熟的区块链,使开发人员能够创建智能合约,在区块链上执行的程序可以由交易触发.人们经常将区块链称为数据库 ...

  6. 数字货币比特币以太坊买卖五档行情数据API接口

    数字货币比特币以太坊买卖五档行情数据API接口       数字货币一般包含比特币BTC.以太坊ETH.瑞波币XRP.泰达币USDT.比特币现金BCH.比特币SV.莱特币LTC.柚子币EOS.OKB. ...

  7. 理解以太坊的Layer 2扩容解决方案:状态通道(State Channels)、Plasma 和 Truebit

    -宾夕法尼亚州的尼科尔森大桥建设照片(图源).罗马人的工程原理扩展至新的应用 对于以太坊来说,2018年是专注底层架构之年.今年很多早期参与者会测试网络极限,并且重新关注以太坊的扩容技术. 以太坊仍然 ...

  8. 死磕以太坊源码分析之Ethash共识算法

    死磕以太坊源码分析之Ethash共识算法 代码分支:https://github.com/ethereum/go-ethereum/tree/v1.9.9 引言 目前以太坊中有两个共识算法的实现:cl ...

  9. 死磕以太坊源码分析之txpool

    死磕以太坊源码分析之txpool 请结合以下代码阅读:https://github.com/blockchainGuide/ 写文章不易,也希望大家多多指出问题,交个朋友,混个圈子哦 交易池概念原理 ...

随机推荐

  1. Mac下多个jdk自由切换

    1.缘由,某些场合下需特别配置jdk,如最近学习遇到 annotation注解支持jdk1.5以上版本,而我用的jdk1.8,导致tomcat启动失败,提示降低jdk版本到1.7,1.6 2.搜索ma ...

  2. 使用Regsvr32.exe程序注册/注销ActiveX控件

    使用ActiveX控件之前需要注册该控件. 使用Regsvr32.exe程序可以注册.注销ActiveX控件. Regsvr32.exe程序位于Windows目录的system子目录下. 可以在cmd ...

  3. JSON序列——保存修改数据2

    JSON序列——保存修改数据2 procedure TForm1.Button7Click(Sender: TObject); begin var delta: TynJsonDelta := Tyn ...

  4. linux i2c 的通信函数i2c_transfer在什么情况下出现错误

    问题: linux i2c 的通信函数i2c_transfer在什么情况下出现错误描述: linux i2c设备驱动 本人在写i2c设备驱动的时候使用i2c transfer函数进行通信的时候无法进行 ...

  5. Centos yum国内源及配置含义

    Centos yum源的位置: /etc/yum.repos.d,可以通过配置文件/etc/yum.conf指定其他位置 主要的yum源种类:前两个是必须的,不然yum安装很多软件时会失败.yum本来 ...

  6. spring boot swagger-ui.html 404

    很奇怪的问题,找了好久. 因为spring boot+swagger实现起来很简单.看下面三部曲: 1.pom添加两个swagger依赖. <!-- Swagger依赖包 --> < ...

  7. 通过Tag标签回退版本修复bug

    tag是对历史一个提交id的引用,如果理解这句话就明白了使用git checkout tag即可切换到指定tag,例如:git checkout v0.1.0 切换到tag历史记录会处在分离头指针状态 ...

  8. 每天一个linux命令:free

    1.命令简介 free (free) 命令可以显示Linux系统中空闲的.已用的物理内存及swap内存,及被内核使用的buffer. 2.用法 free [-b | -k | -m | -g | -h ...

  9. make[1]: *** [storage/perfschema/unittest/CMakeFiles/pfs_connect_attr-t.dir/all] 错误 2 解决方法

    make[2]: *** [storage/perfschema/unittest/pfs_connect_attr-t] 错误 1 make[1]: *** [storage/perfschema/ ...

  10. Effective Java 第三版——83. 明智谨慎地使用延迟初始化

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...