以太坊设计与实现:数据结构与对象-交易与签名

在以太坊中最重要的数字签名属交易签名,这也是以太坊账户私钥最核心用途。私钥用于对内容(交易、文本)签名,以证明该内容来自签名者签发。这里,我只讨论以太坊最新的交易签名与交易解析签名者流程。

交易签名流程

以太坊加密算法是采用比特币的椭圆曲线 secp256k1加密算法。签名交易对应代码如下:

//core/types/transaction_signing.go:56
func SignTx(tx *Transaction, s Signer, prv *ecdsa.PrivateKey) (*Transaction, error) {//❶
   h := s.Hash(tx)//❷
   sig, err := crypto.Sign(h[:], prv)//❸
   if err != nil {
      return nil, err
   }
   return tx.WithSignature(s, sig)//❹
}
  • ❶ 交易签名时,需要提供一个签名器(Signer)和私钥(PrivateKey)。需要Singer是因为在EIP155修复简单重复攻击漏洞后,需要保持旧区块链的签名方式不变,但又需要提供新版本的签名方式。因此通过接口实现新旧签名方式,根据区块高度创建不同的签名器。

    //core/types/transaction_signing.go:42
    func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
       var signer Signer
       switch {
       case config.IsEIP155(blockNumber):
          signer = NewEIP155Signer(config.ChainID)
       case config.IsHomestead(blockNumber):
          signer = HomesteadSigner{}
       default:
          signer = FrontierSigner{}
       }
       return signer
    }
    
  • ❷ 重点介绍EIP155改进提案中所实现的新哈希算法,主要目的是获取交易用于签名的哈希值 TxSignHash。和旧方式相比,哈希计算中混入了链ID和两个空值。注意这个哈希值 TxSignHash 在EIP155中并不等同于交易哈希值。

    以太坊设计与实现:数据结构与对象-交易与签名_第1张图片

    这样,一笔已签名的交易就只可能属于某一确定的唯一一条区块链。

  • ❸ 内部利用私钥使用secp256k1加密算法对TxSignHash签名,获得签名结果sig

  • ❹ 执行交易WithSignature方法,将签名结果解析成三段R、S、V,拷贝交易对象并赋值签名结果。最终返回一笔新的已签名交易。

    func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, error) {
       r, s, v, err := signer.SignatureValues(tx, sig)
       if err != nil {
          return nil, err
       }
       cpy := &Transaction{data: tx.data}
       cpy.data.R, cpy.data.S, cpy.data.V = r, s, v
       return cpy, nil
    }
    

根据上面代码逻辑,提炼出如下交易签名流程,整个过程利用了 RLP编码、Keccak256哈希算法和椭圆曲线 secp256k1加密算法。从这里可以看出,密码学技术是区块链成功的最大基石。

以太坊设计与实现:数据结构与对象-交易与签名_第2张图片

交易签名解析流程

签名交易后,如何才能获得交易签名者呢?未完,待写…...

你可能感兴趣的:(区块链,以太坊)