以太坊原理分析4 交易

关于交易的思考

狭义的交易是从A到B的一笔转账。广义的交易,是区块链系统中的一个指令,一条有效的指令,会改变区块链中的账户状态。在设计交易指令的时候,需要考虑几个问题:
* 交易类型
* 发起者身份确认
* 接受者身份确认(也可不一定马上确认,比如比特币)
* 发起内容
* 交易代价(交易代价在普通交易中也就是交易费,交易代价的引入,完全是因为区块链系统的去中心化特性:要想有人收录你的交易,你就得给予利益)

以下描述的是以太坊中的交易,包括普通交易和对智能合约账户的指令。

转账交易流程

  • 用户输入转账的地址和转入的地址和转出的金额
  • 系统通过转出的地址的私钥对转账信息进行签名(用于证明这 笔交易确实有本人进行)
  • 系统对交易信息进行验证
  • 把这笔交易入到本地的txpool中(就是缓存交易池)
  • 把交易信息广播给其它节点

以太坊交易内容

  • to:接收者的地址。在合约创建交易中,合约账户的地址还没有存在,所以值先空着。
  • nonce:发送者发送交易数的计数。
  • gasPrice:发送者愿意支付执行交易所需的每个gas的Wei数量。(理论上gas的单位可以不是wei, 但实际上就是wei)
  • gasLimit:发送者愿意为执行交易支付gas数量的最大值。这个数量被设置之后在任何计算完成之前就会被提前扣掉。
  • value:从发送者转移到接收者的Wei数量。在合约创建交易中,value作为新建合约账户的开始余额。
  • v,r,s:用于产生标识交易发生着的签名。
  • init(只有在合约创建交易中存在):用来初始化新合约账户的EVM代码片段。init值会执行一次,然后就会被丢弃。当init第一次执行的时候,它返回一个账户代码体,也就是永久与合约账户关联的一段代码。
  • input(可选域,只有在消息通信中存在):消息通话中的输入数据(也就是智能合约调用时得参数)。例如,如果智能合约就是一个域名注册服务,那么调用合约可能就会期待输入域例如域名和IP地址。
    > 以太坊的结构里面没有from字段,但from信息其实保存在v,r,s里面

交易数据结构

core/types/transaction.go

type Transaction struct {
    data txdata
    // caches
    hash atomic.Value
    size atomic.Value
    from atomic.Value
}

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:"-"`
}

交易和消息

  • 交易是外部世界和以太坊内部状态的桥梁
  • 消息或内部交易类似于交易,不过与交易有着最大的不同点—它们不是由外部拥有账户产生的。相反,他们是被合约产生的。
  • 消息是虚拟对象,与交易不同,没有在链上,而且只存在与以太坊执行环境。
  • 内部交易或者消息不包含gasLimit

发表评论

电子邮件地址不会被公开。 必填项已用*标注