# Week4 - 7.25 #### Day1 - PoW 链中区块的确认 攻击者利用算力攻击网络时,可能使 Conflux 的 PoW 链中的 pivot 区块发生变更,进而导致已上链区块中交易的顺序与执行结果发生改变。我们可以通过RPC `cfx_getConfirmationRiskByHash` 获知持有全网 **15%** 算力的攻击者对指定区块发起攻击的成功概率。当该值小于 `1e-8`,即 `0.000001%` 时,该区块可被视作已确认。区块从上链到确认一般需要40-50秒。 > 广为人知的比特币的确认时间为6个区块(1个小时)。这意味着持有全网10%算力的攻击者对6个区块之前的区块发起攻击的成功概率为0.1%。 ```bash // Request curl -X POST --data '{"jsonrpc":"2.0","method":"cfx_getConfirmationRiskByHash","params":["0x3912275cf09f8982a69735a876c14584dae95078762090c5d32fdf0dbec0647c"],"id":1}' -H "Content-Type: application/json" localhost:12539 // fix64 格式的返回值,使用该值除以2**256-1可以得到概率为1e-8 { "jsonrpc": "2.0", "result": "0x2af31dc4611873bf3f70834acdae9f0f4f534f5d60585a5f1c1a3ced1b", "id": 1 } ``` #### Day2 - 进行重要交易时的区块确认方法 一般情况下,RPC `cfx_getConfirmationRiskByHash` 的返回值足以满足日常交易的安全性需求。但在特定情况下,例如在发送某些重要交易时,我们可能有更高级别的安全需求,这时可以借助 PoS 链为 PoW 链提供的 Finality(最终性)来确认交易。简单来说,PoS 链会指定 PoW 链中的 pivot 区块,在这之后,即使 **51%** 攻击者尝试逆转这个区块,也不会被 PoW 节点认可。 通过RPC `cfx_getStatus` 可以得到当前的节点状态,其中的 `latestFinalized` 字段就包括当前已被 PoS 链确认的最新 Epoch。通过比较该值与区块的 Epoch,就能知道区块是否已被最终确认。 > 这种确认方式要更加安全,但同时也会更加耗时。从区块上链到确认需要花费400秒左右。可以在Conflux Scan中查看[最新状态到 PoS 最终确认状态的间隔](https://www.confluxscan.io/pos-charts/finalized-interval)。 ```bash // Request curl -X POST --data '{"jsonrpc":"2.0","method":"cfx_getStatus","id":1}' -H "Content-Type: application/json" localhost:12539 // Result { "jsonrpc": "2.0", "result": { "bestHash": "0x7bbb518ec0b8671a60e9c98619137b0d52522a9ef9490c9b4c23c30f178312f8", "chainId": "0x405", "ethereumSpaceChainId": "0x406", "networkId": "0x405", "epochNumber": "0x2fa1a24", "blockNumber": "0x70a7fda", "pendingTxNumber": "0x83b", "latestCheckpoint": "0x2f91bc0", "latestConfirmed": "0x2fa19e1", "latestState": "0x2fa1a20", "latestFinalized": "0x2fa1854" // 已被 PoS 链确认的最新 Epoch }, "id": 1 } ``` #### Day3 - 使用内置合约在链上读取 EpochNumber 等信息 在链下我们可以借助SDK提供的接口或直接通过RPC `cfx_getStatus` 获取 `EpochNumber` 等信息。在链上的合约中,则可以借助内置合约`ConfluxContext`来获取相关信息。合约可以借助`ConfluxContext`提供的`epochNumber(), posHeight(), finalizedEpochNumber()` 函数获取当前的区块链状态。 > `ConfluxContext`的地址为`CFX:TYPE.BUILTIN:AAEJUAAAAAAAAAAAAAAAAAAAAAAAAAAAAU5XA6TK73 / CFXTEST:TYPE.BUILTIN:AAEJUAAAAAAAAAAAAAAAAAAAAAAAAAAAAUV2XPKD3X`。包含 abi 的 metadata 文件可以在[这里](https://raw.githubusercontent.com/Conflux-Chain/conflux-rust/master/internal_contract/metadata/ConfluxContext.json)获取。 ```solidity pragma solidity >=0.4.15; contract ConfluxContext { /*** Query Functions ***/ /** * @dev get the current epoch number * @return the current epoch number */ function epochNumber() public view returns (uint256) {} /** * @dev get the height of the referred PoS block in the last epoch ` * @return the current PoS block height */ function posHeight() public view returns (uint256) {} /** * @dev get the epoch number of the finalized pivot block. * @return the finalized epoch number */ function finalizedEpochNumber() public view returns (uint256) {} } ``` #### Day4 - 估算gas消耗时的 `gasUsed` 与 `gasLimit` 通过SDK或RPC `cfx_estimateGasAndCollateral` 估算交易gas消耗时,得到的返回值 `estimate` 中包括 `estimate.gasUsed` 与 `estimate.gasLimit` 字段。其中 `estimate.gasUsed` 字段代表交易将实际消耗的燃气数,但由于在EVM中[每次子函数调用只会传入63/64的gasLimit](https://eips.ethereum.org/EIPS/eip-150),直接将交易`tx`的`tx.gasLimit`字段直接设置为`estimate.gasUsed`常常会引发 gas 不足的问题。通常推荐使用 `estimate.gasLimit` 作为交易的燃气上限 `tx.gasLimit` ,该值为 `estimate.gasUsed` 的 `4/3` 倍。这样一般可以保证 gas 上限设置得足够, `gasUsed` 以外的燃气消耗也能够全额返还。 > 在以太坊中,超出`gasUsed`的燃气消耗将会全额返还,但Conflux中返还的燃气消耗至多为 `tx.gasLimit * 1/4`。换言之,设置的`tx.gasLimit`大于 `gasUsed * 4/3` 将会导致 `gasUsed` 以外的燃气消耗无法被全额返还。更详细的 gas 知识可以参考 [Gas 科普](https://wiki.conflux123.xyz/books/conflux101/page/gas)。 ``` bash // Request curl -X POST --data '{"method":"cfx_estimateGasAndCollateral","id":1,"jsonrpc":"2.0","params":[{"from":"cfx:type.user:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg","to":"cfx:type.contract:acc7uawf5ubtnmezvhu9dhc6sghea0403y2dgpyfjp","data":"0x","gasPrice":"0x2540be400","nonce":"0x0"}]}' -H "Content-Type: application/json" localhost:12539 // Result { "jsonrpc": "2.0", "result": { "gasLimit": "0x6d60", // 21000 * 4/3 "gasUsed": "0x5208", // 21000 "storageCollateralized": "0x80" }, "id": 1 } ``` #### Day5 - 交易中的 EpochHeight 参数 Conflux中的交易中需要指定`EpochHeight`参数。当 `-100000 < currentEpochNumber - tx.epochHeight < 100000` 时交易才会被执行。一般将交易的`EpochHeight`设置为当前的`EpochNumber`即可。如果交易对执行的时间点比较敏感,也可以通过设置更小的`EpochNumber`来避免交易被过晚执行。 > 产生 100000 个 Epoch 需要 100000 秒左右,约 28 个小时