Skip to content

Instantly share code, notes, and snippets.

@HAOYUatHZ
Last active October 12, 2022 12:01
Show Gist options
  • Save HAOYUatHZ/f4dc96cedeb91de4375508dd340d467f to your computer and use it in GitHub Desktop.
Save HAOYUatHZ/f4dc96cedeb91de4375508dd340d467f to your computer and use it in GitHub Desktop.
DA & proof & bridge
  1. DA

查看 contract call calldata

function commitBlock(BlockHeader memory _header, Layer2Transaction[] memory _txn)

struct BlockHeader {
  bytes32 blockHash;
  bytes32 parentHash;
  uint256 baseFee;
  bytes32 stateRoot;
  uint64 blockHeight;
  uint64 gasUsed;
  uint64 timestamp;
  bytes extraData;
}

struct Layer2Transaction {
  address caller;
  uint64 nonce;
  address target;
  uint64 gas;
  uint256 gasPrice;
  uint256 value;
  bytes data;
}

  1. proof

监听 event

emit FinalizeBlock(_blockHash, uint64(_height));

1 和 2 的 ABI 都是

&bind.MetaData{
    ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"_blockHeight\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_parentHash\",\"type\":\"bytes32\"}],\"name\":\"CommitBlock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"_blockHeight\",\"type\":\"uint64\"}],\"name\":\"FinalizeBlock\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"RevertBlock\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_fee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_deadline\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_message\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_gasLimit\",\"type\":\"uint256\"}],\"name\":\"appendMessage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"baseFee\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"blockHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"gasUsed\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"internalType\":\"struct IZKRollup.BlockHeader\",\"name\":\"_header\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"gas\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct IZKRollup.Layer2Transaction[]\",\"name\":\"_txns\",\"type\":\"tuple[]\"}],\"name\":\"commitBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[]\",\"name\":\"_proof\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_instances\",\"type\":\"uint256[]\"}],\"name\":\"finalizeBlockWithProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"getMessageHashByIndex\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNextQueueIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_blockNumber\",\"type\":\"uint256\"}],\"name\":\"layer2GasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"revertBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_blockNumber\",\"type\":\"uint256\"}],\"name\":\"verifyMessageStateProof\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
}

用户从 L1 发起 deposit 会有

event DepositERC20(
  address indexed _l1Token,
  address indexed _l2Token,
  address indexed _from,
  address _to,
  uint256 _amount,
  bytes _data
);

event DepositETH(address indexed _from, address indexed _to, uint256 _amount, bytes _data);

到账之后会有

event FinalizeDepositERC20(
  address indexed _l1Token,
  address indexed _l2Token,
  address indexed _from,
  address _to,
  uint256 _amount,
  bytes _data
);

event FinalizeDepositETH(address indexed _from, address indexed _to, uint256 _amount, bytes _data);

log 里面有 tx_hash。 可以通过这个方式找到两笔交易。 麻烦的地方就是要自己找一下对应关系。 单纯从 event 里面的内容找不出对应关系。 但如果 event 都监听到的话,按顺序是能对应上的。至少相同内容 (_l1Token, _l2Token, _from, _to, _amount, _data) 的,两边是按顺序对应的。

同理,用户从 L2 发起 withdraw 会有

event WithdrawERC20(
  address indexed _l1Token,
  address indexed _l2Token,
  address indexed _from,
  address _to,
  uint256 _amount,
  bytes _data
);

event WithdrawETH(address indexed _from, address indexed _to, uint256 _amount, bytes _data);

到账之后会有

event FinalizeWithdrawERC20(
  address indexed _l1Token,
  address indexed _l2Token,
  address indexed _from,
  address _to,
  uint256 _amount,
  bytes _data
);

event FinalizeWithdrawETH(address indexed _from, address indexed _to, uint256 _amount, bytes _data);
@HAOYUatHZ
Copy link
Author

HAOYUatHZ commented Oct 12, 2022

L1 & L2 充提交易对应方法

倾向于不升级合约(在合约中加 ID)来用于跟踪。

目前能拿到的数据,有办法对应上。

之前提到有 几个 events

DepositETH
DepositERC20
FinalizeDepositETH
FinalizeDepositERC20
WithdrawETH
WithdrawERC20
FinalizeWithdrawETH
FinalizeWithdrawERC20

同一笔交易中其实还会有

event SentMessage(
    address indexed target,
    address sender,
    uint256 value,
    uint256 fee,
    uint256 deadline,
    bytes message,
    uint256 messageNonce,
    uint256 gasLimit
);

根据这些参数可以算出一个 msgHash

bytes32 _msghash = keccak256(abi.encodePacked(_from, _to, _value, _fee, _deadline, _nonce, _message));

对面 layer 到账之后会有个 event

event RelayedMessage(bytes32 indexed msgHash);

这个 event 里面的 msgHash 就是上面的 _msghash,这样就能对应起来。

注意 这里面的 _from, _to 并不意味着 Deposit/Withdraw 里面的 from/to,不是同一个东西,不一样

总结一下:

如果一个交易中有 Deposit/Withdraw event,那么同时也会有 SentMessage event
拿着 SentMessage event 可以算出 msgHash
在对面 layer 上看到 RelayedMessage event 的时候,说明这个 msgHash 对应的原来那笔交易中的那个 Deposit/Withdraw 到账,同时这笔交易也会有一个 FinalizeXXX event
通过 这个 msgHash 把 2 个 layer 上的充提&到账对应起来

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment