共计 3065 个字符,预计需要花费 8 分钟才能阅读完成。
Transaction stages
发送交易是区块链世界的最频繁操作,交易从开始结构到最终上链并确定,会经验多个阶段。充沛理解交易的各个阶段将有助于用户和开发者更好的查找交易发送的问题,并最终确保交易被胜利确认。
交易从结构到确认会经验如下几个阶段:
- 筹备交易发送方(
from
)的私钥和地址 - 筹备交易的
meta 信息
,组装后进行签名
和编码
->原始交易(RawTransaction)
- 将
RawTransaction
通过cfx_sendRawTransaction
RPC 办法发送给 fullnode -> 交易被放入交易池 - 交易被矿工打包进某个区块 -> Minded in Block
- Defer 5 个 epoch -> Executed
- 期待大概 50 个 epoch -> Confirmed
- 期待被 PoS 链所援用 -> Finalized
交易阶段介绍
筹备交易发送账户私钥和地址
所有发送的交易都须要应用私钥进行签名,能力被区块链网络所承受并胜利执行,因而发送交易前首先须要筹备好交易发送方的私钥,通过私钥能够推导出账户的地址。
另外交易的发送须要领取肯定的 CFX 手续费,因而交易的发送方账户须要保障有一部分 CFX 能力胜利发送交易,测试网
的 CFX 能够通过水龙头支付。
在 Conflux 网络有一种状况不须要发送方领取交易的手续费:
- 交易的接管方是合约
- 有人对合约的燃气和存储进行了资助
- 交易发送方地址在合约燃气应用白名单中(能够将白名单齐全关上,让所有人都可被资助)
- 交易执行破费的燃气费用低于合约赞助商所设置的燃气代付下限
如果想理解 Conflux 代付的具体细节,能够查看内置合约 SponsorWhitelistControl 介绍
筹备交易元信息,并进行签名和编码
筹备好发送账户的私钥之后,就须要构建交易了,构建交易第一步须要依据交易的发送目标确定交易的各个元信息,包含:
to
:交易接管方nonce
:交易的顺序号value
:交易金额,单位为 Dripdata
:交易数据chainId
:交易执行的链 IDepochHeight
:交易执行指标高度gas
:燃气下限gasPrice
:燃气价格storageLimit
:存储抵押下限
如果想理解交易各字段的含意及指定形式可参看 Conflux 交易详解
元信息筹备好之后,须要他们依照固定程序进行 RLP
编码,并生成 hash,而后应用私钥进行 secp256k1
签名操作,失去 交易签名
。
最终将 元信息
和签名
组合到一块进行 RLP 编码,并转换为 hex
格局,即失去可发送给 Conflux 节点的 原始交易(RawTransaction)
。
通常钱包和 SDK 会主动进行交易的组装,签名,编码等操作,不须要手动解决。
发送 RawTransaction 到节点交易池
将原始交易通过 fullnode 的 cfx_sendRawTransaction
RPC 办法,发送给节点,节点首先会对交易进行查看,如果结构的交易有问题, 发送将会失败,可能的失败状况有:
- nonce 设置谬误(
重复使用
或设置的 nonce 过大
) - gas 数值过大,超过 1500w
- 签名谬误
- chainId 应用谬误
- epochHeight 与以后值间隔超过 10w
- 其余:交易池满
须要留神的是:该办法不会查看发送方的余额是否足够领取交易金额和手续费,即便发送账户余额不够,交易也能发送胜利。
如果查看没有问题,交易将会被放入节点的交易池,并返回交易的 hash.
这时通过 RPC 办法 cfx_getTransactionByHash
能够获取到交易,但因为交易还没有被打包,所以交易的区块信息(blockHash), 及执行后果相干字段(contractCreated, status, transactionIndex) 都为空。
因为交易还未执行,所以交易的收据(receipt)还未产生。
矿工打包交易
交易池中的交易可能会有三种状态:
- nonce 跳跃
- 余额不够
- ready to pack
前两种状态的交易将会 pending 在交易池内,直到交易 nonce 之前所有的 nonce 被执行或者余额足够之后才会变为 ready to pack
.
达到打包条件的交易,将会大抵依照 gasPrice 从高到低的程序被矿工打包进区块
区块被提早执行
Conflux 网络有一个区块提早执行机制,即区块被打包后,不会立即被执行,而是须要提早 5 个 Epoch 才会执行。区块执行实质是区块中的所有交易被执行。
交易执行之后通过 cfx_getTransactionByHash
办法获取的交易信息里将会蕴含 blockHash, status 等字段。
此时也能够通过 cfx_getTransactionReceipt
办法获取交易的 收据 (receipt)
信息。
交易的执行并不一定会胜利,能够通过 transaction 的 status
字段或 receipt 的 outcomeStatus
字段判断交易的状态:
0
– 执行胜利1
– 执行失败2
或null
– 交易未执行,被跳过
经验肯定数量 Epoch,交易被确认
交易被执行之后并不意味着交易的状态不会再发生变化,因为区块链数据链式存储构造的起因,区块链可能会因为新区块的达到或产生而导致主链产生分叉或偏移,从而导致某笔交易被 revert。
通常须要期待打包交易区块之后,再产生肯定数量的新区块,交易能力达到最终确认状态。
在 Conflux 网络中能够应用交易 receipt
中的 epochNumber
与最新的 confirmed epochNumber 进行比拟,如果最新确认的 epochNumber 更大的话,意味着交易已被确认。
能够应用 cfx_epochNumber
办法,传递 latest_confirmed
参数,来获取最新 Confirmed 的 EpochNumber
区块被 PoS 链所援用,交易被 Finalize
Conflux 从 v1.2.0 开始,为了避免 51% 算力攻打,引入了 PoS finality 机制,用于在全网算力较低的状况下,保护区块不被 revert。
通过引入一条独自的 PoS 链,来对 PoW 的区块进行 finalize 投票,所有被投票 finalized 的区块的状态将会达到最终态。
从 v1.2.0 开始会引入一个新的 Tag latest_finalized
能够应用此 tag,申请 cfx_epochNumber
办法,获取最新被 finalized 的 epochNumber
FAQ
交易为什么发送失败
如果调用 cfx_sendRawTransaction
办法发送交易失败的话,大概率是交易结构有问题,须要调整交易的元字段。
如果返回的谬误音讯为 txpool is full, 能够等会,略微进步 gasPrice 从新发送交易试试。
为什么交易始终没有上链被执行
交易发送胜利之后,但迟迟没法在 scan 上查到交易被胜利执行,那交易大概率被 pending 在交易池中,可能的状况有以下三种:
- 交易没有应用间断的 nonce:须要正确的设置交易的 nonce
- 发送账户的余额不够:给发送账户转账,以获取足够余额
- 网络交易比拟拥挤:如果网络比拟拥挤,矿工大抵会依照 gasPrice 从高到低的程序,打包交易,因而能够通过进步交易 gasPrice 的形式来放慢交易执行
能够应用 cfx_getAccountPendingTransactions
办法获取用户以后的 Pending 交易及起因。
是否能够勾销或者替换某笔交易
如果交易还未被打包进区块处于交易池中,能够从新发送一笔 nonce 雷同,gasPrice 更高的交易来替换掉原来那笔交易。
交易无奈勾销,但能够通过将原交易替换为一笔 value 为 0 的交易,达到勾销的成果。
如何给交易减速
如果想给交易的执行减速,能够进步交易的 gasPrice 从新发送