概述
一、 交易大致流程
以太坊的交易大致分以下几步:
1、 发起交易:指定目标地址和交易金额以及相关的gas/gaslimit发起相关交易,如果目标地址为空,则表示其为一个智能合约的交易。
2、 交易签名:使用私钥对交易进行签名。这涉及到上一篇中帐户的私钥和公钥的产生机制。
3、 提交交易:把交易添加到交易池中,类似于比特币。签名验证后,通过一定的规则对池内的交易进行排序(如交易的gas)。
4、 广播交易:EVM执行交易,然后广播到其他节点。
5、 交易打包:POW工作量证明,然后形成新的区块打包交易。
6、 广播区块事件:即提交最终的区块。
通过以上六个步骤,把一个完整的交易过程展现出来,严格意义上来说,5和6要归到区块链的模块中去,但是一个完整的交易是需要有这个过程才能证明是完成的。所以在说明时,重点说明前四条。
二、交易的步骤
1、 发起交易
交易的发起一般通过调用RPC接口实现,ETH源码本身提供了相关api,位于源码的ethereum/go-ethereum的internal包中
(1) 交易入口源码位于ethereum/go-ethereum/internal/ethapi/api.go
// SendTransaction creates a transaction for the given argument, sign it and submit it to the
// transaction pool.
func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) {
// Look up the wallet containing the requested signer
account := accounts.Account{Address: args.From}
//a.根据发送者地址找出对应钱包用于签名
wallet, err := s.b.AccountManager().Find(account)
if err != nil {
return common.Hash{}, err
}
if args.Nonce == nil {
// Hold the addresse's mutex around signing to prevent concurrent assignment of
// the same nonce to multiple accounts.
// 前面提出的问题,防止双花
s.nonceLock.LockAddr(args.From)
defer s.nonceLock.UnlockAddr(args.From)
}
// Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, s.b); err != nil {
return common.Hash{}, err
}
// Assemble the transaction and sign with the wallet
//b.处理原生交易数据
tx := args.toTransaction()
var chainID *big.Int
if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) {
chainID = config.ChainID
}
//c.对交易进行签名
signed, err := wallet.SignTx(account, tx, chainID)
if err != nil {
return common.Hash{}, err
}
//d.提交交易
return submitTransaction(ctx, s.b, signed)
}
(2) 分析b处理原生交易数据 源码如下
func (args *SendTxArgs) toTransaction() *types.Transaction {
var input []byte
if args.Data != nil {
input = *args.Data
} else if args.Input != nil {
input = *args.Input
}
// 接收者地址为空时,即为创建合约交易
if args.To == nil {
return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input)
}
// 此处为普通交易
return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input)
}
(3)分析c对交易进行签名,源码:ethereum/go-ethereum/accounts/keystore/keystore.go
// SignTx signs the given transaction with the requested account.
func (ks *KeyStore) SignTx(a accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
// Look up the key to sign with and abort if it cannot be found
ks.mu.RLock()
defer ks.mu.RUnlock()
unlockedKey, found := ks.unlocked[a.Address]
if !found {
return nil, ErrLocked
}
// Depending on the presence of the chain ID, sign with EIP155 or homestead
if chainID != nil {
return types.SignTx(tx, types.NewEIP155Signer(chainID), unlockedKey.PrivateKey)
}
return types.SignTx(tx, types.HomesteadSigner{}, unlockedKey.PrivateKey)
}
(4) 分析d提交交易
…待续
最后
以上就是高大音响为你收集整理的以太坊ETH源码分析(2):交易执行过程一、 交易大致流程二、交易的步骤的全部内容,希望文章能够帮你解决以太坊ETH源码分析(2):交易执行过程一、 交易大致流程二、交易的步骤所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复