arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/eth/rollup.go
eth/rollup.goRaw
  1package eth
  2
  3import (
  4	"context"
  5	"math/big"
  6	"strings"
  7
  8	Hermez "github.com/hermeznetwork/hermez-node/eth/contracts/hermez"
  9
 10	"github.com/ethereum/go-ethereum"
 11	"github.com/ethereum/go-ethereum/accounts/abi"
 12	"github.com/ethereum/go-ethereum/crypto"
 13	"github.com/ethereum/go-ethereum/ethclient"
 14
 15	ethCommon "github.com/ethereum/go-ethereum/common"
 16	"github.com/ethereum/go-ethereum/core/types"
 17	"github.com/hermeznetwork/hermez-node/common"
 18	"github.com/hermeznetwork/hermez-node/log"
 19	"github.com/iden3/go-iden3-crypto/babyjub"
 20)
 21
 22const (
 23	// RollupConstFeeIdxCoordinatorLen is the number of tokens the coordinator can use
 24	// to collect fees (determines the number of tokens that the
 25	// coordinator can collect fees from).  This value is determined by the
 26	// circuit.
 27	RollupConstFeeIdxCoordinatorLen = 64
 28	// RollupConstReservedIDx First 256 indexes reserved, first user index will be the 256
 29	RollupConstReservedIDx = 255
 30	// RollupConstExitIDx IDX 1 is reserved for exits
 31	RollupConstExitIDx = 1
 32	// RollupConstLimitLoadAmount Max load amount allowed (loadAmount: L1 --> L2)
 33	RollupConstLimitLoadAmount = (1 << 128)
 34	// RollupConstLimitL2TransferAmount Max amount allowed (amount L2 --> L2)
 35	RollupConstLimitL2TransferAmount = (1 << 192)
 36	// RollupConstLimitTokens Max number of tokens allowed to be registered inside the rollup
 37	RollupConstLimitTokens = (1 << 32)
 38	// RollupConstL1CoordinatorTotalBytes [4 bytes] token + [32 bytes] babyjub + [65 bytes] compressedSignature
 39	RollupConstL1CoordinatorTotalBytes = 101
 40	// RollupConstL1UserTotalBytes [20 bytes] fromEthAddr + [32 bytes] fromBjj-compressed + [6 bytes] fromIdx +
 41	// [2 bytes] loadAmountFloat16 + [2 bytes] amountFloat16 + [4 bytes] tokenId + [6 bytes] toIdx
 42	RollupConstL1UserTotalBytes = 72
 43	// RollupConstMaxL1UserTX Maximum L1-user transactions allowed to be queued in a batch
 44	RollupConstMaxL1UserTX = 128
 45	// RollupConstMaxL1TX Maximum L1 transactions allowed to be queued in a batch
 46	RollupConstMaxL1TX = 256
 47	// RollupConstRfield Modulus zkSNARK
 48	RollupConstRfield = 21888242871839275222246405745257275088548364400416034343698204186575808495617
 49	// RollupConstInputSHAConstantBytes [6 bytes] lastIdx + [6 bytes] newLastIdx  + [32 bytes] stateRoot  + [32 bytes] newStRoot  + [32 bytes] newExitRoot +
 50	// [_MAX_L1_TX * _L1_USER_TOTALBYTES bytes] l1TxsData + totalL2TxsDataLength + feeIdxCoordinatorLength + [2 bytes] chainID =
 51	// 18542 bytes +  totalL2TxsDataLength + feeIdxCoordinatorLength
 52	RollupConstInputSHAConstantBytes = 18542
 53	// RollupConstNumBuckets Number of buckets
 54	RollupConstNumBuckets = 5
 55	// RollupConstMaxWithdrawalDelay max withdrawal delay in seconds
 56	RollupConstMaxWithdrawalDelay = 2 * 7 * 24 * 60 * 60
 57	// RollupConstExchangeMultiplier exchange multiplier
 58	RollupConstExchangeMultiplier = 1e14
 59	// LenVerifiers number of Rollup Smart Contract Verifiers
 60	LenVerifiers = 1
 61)
 62
 63var (
 64	// RollupConstEthAddressInternalOnly This ethereum address is used internally for rollup accounts that don't have ethereum address, only Babyjubjub
 65	// This non-ethereum accounts can be created by the coordinator and allow users to have a rollup
 66	// account without needing an ethereum address
 67	RollupConstEthAddressInternalOnly = ethCommon.HexToAddress("0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF")
 68
 69	// RollupConstERC1820 ERC1820Registry address
 70	RollupConstERC1820 = ethCommon.HexToAddress("0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24")
 71
 72	// ERC777 tokens signatures
 73
 74	// RollupConstRecipientInterfaceHash ERC777 recipient interface hash
 75	RollupConstRecipientInterfaceHash = crypto.Keccak256([]byte("ERC777TokensRecipient"))
 76	// RollupConstPerformL1UserTXSignature the signature of the function that can be called thru an ERC777 `send`
 77	RollupConstPerformL1UserTXSignature = crypto.Keccak256([]byte("addL1Transaction(uint256,uint48,uint16,uint16,uint32,uint48)"))
 78	// RollupConstAddTokenSignature the signature of the function that can be called thru an ERC777 `send`
 79	RollupConstAddTokenSignature = crypto.Keccak256([]byte("addToken(address)"))
 80	// RollupConstSendSignature ERC777 Signature
 81	RollupConstSendSignature = crypto.Keccak256([]byte("send(address,uint256,bytes)"))
 82	// RollupConstERC777Granularity ERC777 Signature
 83	RollupConstERC777Granularity = crypto.Keccak256([]byte("granularity()"))
 84	// RollupConstWithdrawalDelayerDeposit  This constant are used to deposit tokens from ERC77 tokens into withdrawal delayer
 85	RollupConstWithdrawalDelayerDeposit = crypto.Keccak256([]byte("deposit(address,address,uint192)"))
 86
 87	// ERC20 signature
 88
 89	// RollupConstTransferSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
 90	RollupConstTransferSignature = crypto.Keccak256([]byte("transfer(address,uint256)"))
 91	// RollupConstTransferFromSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
 92	RollupConstTransferFromSignature = crypto.Keccak256([]byte("transferFrom(address,address,uint256)"))
 93	// RollupConstApproveSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
 94	RollupConstApproveSignature = crypto.Keccak256([]byte("approve(address,uint256)"))
 95	// RollupConstERC20Signature ERC20 decimals signature
 96	RollupConstERC20Signature = crypto.Keccak256([]byte("decimals()"))
 97)
 98
 99// RollupConstants are the constants of the Rollup Smart Contract
100/* type RollupConstants struct {
101	// Maxim Deposit allowed
102	MaxAmountDeposit *big.Int
103	MaxAmountL2      *big.Int
104	MaxTokens        int64
105	// maximum L1 transactions allowed to be queued for a batch
106	MaxL1Tx int
107	// maximum L1 user transactions allowed to be queued for a batch
108	MaxL1UserTx        int
109	Rfield             *big.Int
110	L1CoordinatorBytes int
111	L1UserBytes        int
112	L2Bytes            int
113	MaxTxVerifiers     []int
114	TokenHEZ           ethCommon.Address
115	// Only test
116	GovernanceAddress ethCommon.Address
117	// Only test
118	SafetyBot ethCommon.Address
119	// Only test
120	ConsensusContract ethCommon.Address
121	// Only test
122	WithdrawalContract ethCommon.Address
123	ReservedIDx        uint32
124	LastIDx            uint32
125	ExitIDx            uint32
126	NoLimitToken       int
127	NumBuckets         int
128	MaxWDelay          int64
129}*/
130
131// RollupPublicConstants are the constants of the Rollup Smart Contract
132type RollupPublicConstants struct {
133	AbsoluteMaxL1L2BatchTimeout uint8
134	TokenHEZ                    ethCommon.Address
135	Verifiers                   []RollupVerifierStruct
136	HermezAuctionContract       ethCommon.Address
137	HermezGovernanceDAOAddress  ethCommon.Address
138	SafetyAddress               ethCommon.Address
139	WithdrawDelayerContract     ethCommon.Address
140}
141
142// RollupVariables are the variables of the Rollup Smart Contract
143type RollupVariables struct {
144	FeeAddToken           *big.Int
145	ForgeL1L2BatchTimeout int64
146	WithdrawalDelay       uint64
147}
148
149// QueueStruct is the queue of L1Txs for a batch
150//nolint:structcheck
151type QueueStruct struct {
152	L1TxQueue    []common.L1Tx
153	TotalL1TxFee *big.Int
154}
155
156// NewQueueStruct creates a new clear QueueStruct.
157func NewQueueStruct() *QueueStruct {
158	return &QueueStruct{
159		L1TxQueue:    make([]common.L1Tx, 0),
160		TotalL1TxFee: big.NewInt(0),
161	}
162}
163
164// RollupVerifierStruct is the information about verifiers of the Rollup Smart Contract
165type RollupVerifierStruct struct {
166	MaxTx   *big.Int
167	NLevels *big.Int
168}
169
170// RollupState represents the state of the Rollup in the Smart Contract
171//nolint:structcheck,unused
172type RollupState struct {
173	StateRoot              *big.Int
174	ExitRoots              []*big.Int
175	ExitNullifierMap       map[[256 / 8]byte]bool
176	TokenList              []ethCommon.Address
177	TokenMap               map[ethCommon.Address]bool
178	MapL1TxQueue           map[int64]*QueueStruct
179	LastL1L2Batch          int64
180	CurrentToForgeL1TxsNum int64
181	LastToForgeL1TxsNum    int64
182	CurrentIdx             int64
183}
184
185// RollupEventL1UserTx is an event of the Rollup Smart Contract
186type RollupEventL1UserTx struct {
187	ToForgeL1TxsNum uint64 // QueueIndex       *big.Int
188	Position        uint8  // TransactionIndex *big.Int
189	L1Tx            common.L1Tx
190}
191
192// RollupEventL1UserTxAux is an event of the Rollup Smart Contract
193type RollupEventL1UserTxAux struct {
194	ToForgeL1TxsNum uint64 // QueueIndex       *big.Int
195	Position        uint8  // TransactionIndex *big.Int
196	L1Tx            []byte
197}
198
199// RollupEventAddToken is an event of the Rollup Smart Contract
200type RollupEventAddToken struct {
201	Address ethCommon.Address
202	TokenID uint32
203}
204
205// RollupEventForgeBatch is an event of the Rollup Smart Contract
206type RollupEventForgeBatch struct {
207	BatchNum  int64
208	EthTxHash ethCommon.Hash
209}
210
211// RollupEventUpdateForgeL1L2BatchTimeout is an event of the Rollup Smart Contract
212type RollupEventUpdateForgeL1L2BatchTimeout struct {
213	ForgeL1L2BatchTimeout uint8
214}
215
216// RollupEventUpdateFeeAddToken is an event of the Rollup Smart Contract
217type RollupEventUpdateFeeAddToken struct {
218	FeeAddToken *big.Int
219}
220
221// RollupEventWithdrawEvent is an event of the Rollup Smart Contract
222type RollupEventWithdrawEvent struct {
223	Idx             uint64
224	NumExitRoot     uint64
225	InstantWithdraw bool
226}
227
228// RollupEvents is the list of events in a block of the Rollup Smart Contract
229type RollupEvents struct { //nolint:structcheck
230	L1UserTx                    []RollupEventL1UserTx
231	AddToken                    []RollupEventAddToken
232	ForgeBatch                  []RollupEventForgeBatch
233	UpdateForgeL1L2BatchTimeout []RollupEventUpdateForgeL1L2BatchTimeout
234	UpdateFeeAddToken           []RollupEventUpdateFeeAddToken
235	WithdrawEvent               []RollupEventWithdrawEvent
236}
237
238// NewRollupEvents creates an empty RollupEvents with the slices initialized.
239func NewRollupEvents() RollupEvents {
240	return RollupEvents{
241		L1UserTx:                    make([]RollupEventL1UserTx, 0),
242		AddToken:                    make([]RollupEventAddToken, 0),
243		ForgeBatch:                  make([]RollupEventForgeBatch, 0),
244		UpdateForgeL1L2BatchTimeout: make([]RollupEventUpdateForgeL1L2BatchTimeout, 0),
245		UpdateFeeAddToken:           make([]RollupEventUpdateFeeAddToken, 0),
246		WithdrawEvent:               make([]RollupEventWithdrawEvent, 0),
247	}
248}
249
250// RollupForgeBatchArgs are the arguments to the ForgeBatch function in the Rollup Smart Contract
251//nolint:structcheck,unused
252type RollupForgeBatchArgs struct {
253	NewLastIdx        uint64
254	NewStRoot         *big.Int
255	NewExitRoot       *big.Int
256	L1CoordinatorTxs  []*common.L1Tx
257	L2TxsData         []*common.L2Tx
258	FeeIdxCoordinator []common.Idx
259	// Circuit selector
260	VerifierIdx uint8
261	L1Batch     bool
262	ProofA      [2]*big.Int
263	ProofB      [2][2]*big.Int
264	ProofC      [2]*big.Int
265}
266
267// RollupForgeBatchArgsAux are the arguments to the ForgeBatch function in the Rollup Smart Contract
268//nolint:structcheck,unused
269type RollupForgeBatchArgsAux struct {
270	NewLastIdx        uint64
271	NewStRoot         *big.Int
272	NewExitRoot       *big.Int
273	L1CoordinatorTxs  []byte
274	L2TxsData         []byte
275	FeeIdxCoordinator []byte
276	// Circuit selector
277	VerifierIdx uint8
278	L1Batch     bool
279	ProofA      [2]*big.Int
280	ProofB      [2][2]*big.Int
281	ProofC      [2]*big.Int
282}
283
284// RollupInterface is the inteface to to Rollup Smart Contract
285type RollupInterface interface {
286	//
287	// Smart Contract Methods
288	//
289
290	// Public Functions
291
292	RollupForgeBatch(*RollupForgeBatchArgs) (*types.Transaction, error)
293	RollupAddToken(tokenAddress ethCommon.Address) (*types.Transaction, error)
294	RollupWithdraw(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey,
295		numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error)
296	RollupForceExit(fromIdx int64, amountF common.Float16, tokenID int64) (*types.Transaction, error)
297	RollupForceTransfer(fromIdx int64, amountF common.Float16, tokenID, toIdx int64) (*types.Transaction, error)
298	RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey,
299		loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (*types.Transaction, error)
300	RollupDepositTransfer(fromIdx int64, loadAmountF, amountF common.Float16,
301		tokenID int64, toIdx int64) (*types.Transaction, error)
302	RollupDeposit(fromIdx int64, loadAmountF common.Float16, tokenID int64) (*types.Transaction, error)
303	RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte,
304		babyPubKey babyjub.PublicKey, loadAmountF common.Float16) (*types.Transaction, error)
305	RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF common.Float16,
306		tokenID int64) (*types.Transaction, error)
307
308	RollupGetCurrentTokens() (*big.Int, error)
309	// RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error)
310	// RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error)
311	// RollupGetQueue(queue int64) ([]byte, error)
312
313	// Governance Public Functions
314	RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (*types.Transaction, error)
315	RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error)
316
317	//
318	// Smart Contract Status
319	//
320
321	RollupConstants() (*RollupPublicConstants, error)
322	RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error)
323	RollupForgeBatchArgs(ethCommon.Hash) (*RollupForgeBatchArgs, error)
324}
325
326//
327// Implementation
328//
329
330// RollupClient is the implementation of the interface to the Rollup Smart Contract in ethereum.
331type RollupClient struct {
332	client      *EthereumClient
333	address     ethCommon.Address
334	contractAbi abi.ABI
335}
336
337// NewRollupClient creates a new RollupClient
338func NewRollupClient(client *EthereumClient, address ethCommon.Address) (*RollupClient, error) {
339	contractAbi, err := abi.JSON(strings.NewReader(string(Hermez.HermezABI)))
340	if err != nil {
341		return nil, err
342	}
343	return &RollupClient{
344		client:      client,
345		address:     address,
346		contractAbi: contractAbi,
347	}, nil
348}
349
350// RollupForgeBatch is the interface to call the smart contract function
351func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs) (*types.Transaction, error) {
352	log.Error("TODO")
353	return nil, errTODO
354}
355
356// RollupAddToken is the interface to call the smart contract function
357func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address) (*types.Transaction, error) {
358	log.Error("TODO")
359	return nil, errTODO
360}
361
362// RollupWithdrawSNARK is the interface to call the smart contract function
363// func (c *RollupClient) RollupWithdrawSNARK() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
364// 	return nil, errTODO
365// }
366
367// RollupWithdraw is the interface to call the smart contract function
368func (c *RollupClient) RollupWithdraw(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error) {
369	log.Error("TODO")
370	return nil, errTODO
371}
372
373// RollupForceExit is the interface to call the smart contract function
374func (c *RollupClient) RollupForceExit(fromIdx int64, amountF common.Float16, tokenID int64) (*types.Transaction, error) {
375	log.Error("TODO")
376	return nil, errTODO
377}
378
379// RollupForceTransfer is the interface to call the smart contract function
380func (c *RollupClient) RollupForceTransfer(fromIdx int64, amountF common.Float16, tokenID, toIdx int64) (*types.Transaction, error) {
381	log.Error("TODO")
382	return nil, errTODO
383}
384
385// RollupCreateAccountDepositTransfer is the interface to call the smart contract function
386func (c *RollupClient) RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey, loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (*types.Transaction, error) {
387	log.Error("TODO")
388	return nil, errTODO
389}
390
391// RollupDepositTransfer is the interface to call the smart contract function
392func (c *RollupClient) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (*types.Transaction, error) {
393	log.Error("TODO")
394	return nil, errTODO
395}
396
397// RollupDeposit is the interface to call the smart contract function
398func (c *RollupClient) RollupDeposit(fromIdx int64, loadAmountF common.Float16, tokenID int64) (*types.Transaction, error) {
399	log.Error("TODO")
400	return nil, errTODO
401}
402
403// RollupCreateAccountDepositFromRelayer is the interface to call the smart contract function
404func (c *RollupClient) RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte, babyPubKey babyjub.PublicKey, loadAmountF common.Float16) (*types.Transaction, error) {
405	log.Error("TODO")
406	return nil, errTODO
407}
408
409// RollupCreateAccountDeposit is the interface to call the smart contract function
410func (c *RollupClient) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF common.Float16, tokenID int64) (*types.Transaction, error) {
411	log.Error("TODO")
412	return nil, errTODO
413}
414
415// RollupGetTokenAddress is the interface to call the smart contract function
416/* func (c *RollupClient) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
417	return nil, errTODO
418} */
419
420// RollupGetCurrentTokens is the interface to call the smart contract function
421func (c *RollupClient) RollupGetCurrentTokens() (*big.Int, error) {
422	log.Error("TODO")
423	return nil, errTODO
424}
425
426// RollupGetL1TxFromQueue is the interface to call the smart contract function
427/* func (c *RollupClient) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
428	return nil, errTODO
429} */
430
431// RollupGetQueue is the interface to call the smart contract function
432/* func (c *RollupClient) RollupGetQueue(queue int64) ([]byte, error) {
433	return nil, errTODO
434}*/
435
436// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
437func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (*types.Transaction, error) {
438	log.Error("TODO")
439	return nil, errTODO
440}
441
442// RollupUpdateFeeAddToken is the interface to call the smart contract function
443func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error) {
444	log.Error("TODO")
445	return nil, errTODO
446}
447
448// RollupConstants returns the Constants of the Rollup Smart Contract
449func (c *RollupClient) RollupConstants() (*RollupPublicConstants, error) {
450	rollupConstants := new(RollupPublicConstants)
451	if err := c.client.Call(func(ec *ethclient.Client) error {
452		hermez, err := Hermez.NewHermez(c.address, ec)
453		if err != nil {
454			return err
455		}
456		rollupConstants.AbsoluteMaxL1L2BatchTimeout, err = hermez.ABSOLUTEMAXL1L2BATCHTIMEOUT(nil)
457		if err != nil {
458			return err
459		}
460		rollupConstants.TokenHEZ, err = hermez.TokenHEZ(nil)
461		if err != nil {
462			return err
463		}
464		for i := int64(0); i < int64(LenVerifiers); i++ {
465			newRollupVerifier := new(RollupVerifierStruct)
466			rollupVerifier, err := hermez.RollupVerifiers(nil, big.NewInt(i))
467			if err != nil {
468				return err
469			}
470			newRollupVerifier.MaxTx = rollupVerifier.MaxTx
471			newRollupVerifier.NLevels = rollupVerifier.NLevels
472			rollupConstants.Verifiers = append(rollupConstants.Verifiers, *newRollupVerifier)
473		}
474		rollupConstants.HermezAuctionContract, err = hermez.HermezAuctionContract(nil)
475		if err != nil {
476			return err
477		}
478		rollupConstants.HermezGovernanceDAOAddress, err = hermez.HermezGovernanceDAOAddress(nil)
479		if err != nil {
480			return err
481		}
482		rollupConstants.SafetyAddress, err = hermez.SafetyAddress(nil)
483		if err != nil {
484			return err
485		}
486		rollupConstants.WithdrawDelayerContract, err = hermez.WithdrawDelayerContract(nil)
487		return err
488	}); err != nil {
489		return nil, err
490	}
491	return rollupConstants, nil
492}
493
494var (
495	logHermezL1UserTXEvent               = crypto.Keccak256Hash([]byte("L1UserTxEvent(uint64,uint8,bytes)"))
496	logHermezAddToken                    = crypto.Keccak256Hash([]byte("AddToken(address,uint32)"))
497	logHermezForgeBatch                  = crypto.Keccak256Hash([]byte("ForgeBatch(uint64)"))
498	logHermezUpdateForgeL1L2BatchTimeout = crypto.Keccak256Hash([]byte("UpdateForgeL1L2BatchTimeout(uint8)"))
499	logHermezUpdateFeeAddToken           = crypto.Keccak256Hash([]byte("UpdateFeeAddToken(uint256)"))
500	logHermezWithdrawEvent               = crypto.Keccak256Hash([]byte("WithdrawEvent(uint48,uint48,bool)"))
501)
502
503// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
504func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error) {
505	var rollupEvents RollupEvents
506	var blockHash ethCommon.Hash
507
508	query := ethereum.FilterQuery{
509		FromBlock: big.NewInt(blockNum),
510		ToBlock:   big.NewInt(blockNum),
511		Addresses: []ethCommon.Address{
512			c.address,
513		},
514		BlockHash: nil,
515		Topics:    [][]ethCommon.Hash{},
516	}
517	logs, err := c.client.client.FilterLogs(context.Background(), query)
518	if err != nil {
519		return nil, nil, err
520	}
521	if len(logs) > 0 {
522		blockHash = logs[0].BlockHash
523	}
524	for _, vLog := range logs {
525		if vLog.BlockHash != blockHash {
526			return nil, nil, ErrBlockHashMismatchEvent
527		}
528		switch vLog.Topics[0] {
529		case logHermezL1UserTXEvent:
530			var L1UserTxAux RollupEventL1UserTxAux
531			var L1UserTx RollupEventL1UserTx
532			err := c.contractAbi.Unpack(&L1UserTxAux, "L1UserTxEvent", vLog.Data)
533			if err != nil {
534				return nil, nil, err
535			}
536			L1Tx, err := common.L1TxFromBytes(L1UserTxAux.L1Tx)
537			if err != nil {
538				return nil, nil, err
539			}
540			L1UserTx.ToForgeL1TxsNum = new(big.Int).SetBytes(vLog.Topics[1][:]).Uint64()
541			L1UserTx.Position = uint8(new(big.Int).SetBytes(vLog.Topics[2][:]).Uint64())
542			L1UserTx.L1Tx = *L1Tx
543			rollupEvents.L1UserTx = append(rollupEvents.L1UserTx, L1UserTx)
544		case logHermezAddToken:
545			var addToken RollupEventAddToken
546			err := c.contractAbi.Unpack(&addToken, "AddToken", vLog.Data)
547			if err != nil {
548				return nil, nil, err
549			}
550			addToken.Address = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
551			rollupEvents.AddToken = append(rollupEvents.AddToken, addToken)
552		case logHermezForgeBatch:
553			var forgeBatch RollupEventForgeBatch
554			forgeBatch.BatchNum = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64()
555			rollupEvents.ForgeBatch = append(rollupEvents.ForgeBatch, forgeBatch)
556		case logHermezUpdateForgeL1L2BatchTimeout:
557			var updateForgeL1L2BatchTimeout RollupEventUpdateForgeL1L2BatchTimeout
558			err := c.contractAbi.Unpack(&updateForgeL1L2BatchTimeout, "UpdateForgeL1L2BatchTimeout", vLog.Data)
559			if err != nil {
560				return nil, nil, err
561			}
562			rollupEvents.UpdateForgeL1L2BatchTimeout = append(rollupEvents.UpdateForgeL1L2BatchTimeout, updateForgeL1L2BatchTimeout)
563		case logHermezUpdateFeeAddToken:
564			var updateFeeAddToken RollupEventUpdateFeeAddToken
565			err := c.contractAbi.Unpack(&updateFeeAddToken, "UpdateFeeAddToken", vLog.Data)
566			if err != nil {
567				return nil, nil, err
568			}
569			rollupEvents.UpdateFeeAddToken = append(rollupEvents.UpdateFeeAddToken, updateFeeAddToken)
570		case logHermezWithdrawEvent:
571			var withdraw RollupEventWithdrawEvent
572			err := c.contractAbi.Unpack(&withdraw, "WithdrawEvent", vLog.Data)
573			if err != nil {
574				return nil, nil, err
575			}
576			withdraw.Idx = new(big.Int).SetBytes(vLog.Topics[1][:]).Uint64()
577			withdraw.NumExitRoot = new(big.Int).SetBytes(vLog.Topics[2][:]).Uint64()
578			rollupEvents.WithdrawEvent = append(rollupEvents.WithdrawEvent, withdraw)
579		}
580	}
581	return &rollupEvents, &blockHash, nil
582}
583
584// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
585func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*RollupForgeBatchArgs, error) {
586	tx, _, err := c.client.client.TransactionByHash(context.Background(), ethTxHash)
587	if err != nil {
588		return nil, err
589	}
590	txData := tx.Data()
591	method, err := c.contractAbi.MethodById(txData)
592	if err != nil {
593		return nil, err
594	}
595	aux := new(RollupForgeBatchArgsAux)
596	method.Inputs.Unpack(aux, txData)
597	rollupForgeBatchArgs := new(RollupForgeBatchArgs)
598	rollupForgeBatchArgs.L1Batch = aux.L1Batch
599	rollupForgeBatchArgs.NewExitRoot = aux.NewExitRoot
600	rollupForgeBatchArgs.NewLastIdx = aux.NewLastIdx
601	rollupForgeBatchArgs.NewStRoot = aux.NewStRoot
602	rollupForgeBatchArgs.ProofA = aux.ProofA
603	rollupForgeBatchArgs.ProofB = aux.ProofB
604	rollupForgeBatchArgs.ProofC = aux.ProofC
605	rollupForgeBatchArgs.VerifierIdx = aux.VerifierIdx
606
607	numTxsL1 := len(aux.L1CoordinatorTxs) / common.L1TxBytesLen
608	for i := 0; i < numTxsL1; i++ {
609		L1Tx, err := common.L1TxFromCoordinatorBytes(aux.L1CoordinatorTxs[i*common.L1CoordinatorTxBytesLen : (i+1)*common.L1CoordinatorTxBytesLen])
610		if err != nil {
611			return nil, err
612		}
613		rollupForgeBatchArgs.L1CoordinatorTxs = append(rollupForgeBatchArgs.L1CoordinatorTxs, L1Tx)
614	}
615	rollupConsts, err := c.RollupConstants()
616	if err != nil {
617		return nil, err
618	}
619	nLevels := rollupConsts.Verifiers[rollupForgeBatchArgs.VerifierIdx].NLevels.Int64()
620	lenL2TxsBytes := int((nLevels/8)*2 + 2 + 1)
621	numTxsL2 := len(aux.L2TxsData) / lenL2TxsBytes
622	for i := 0; i < numTxsL2; i++ {
623		L2Tx, err := common.L2TxFromBytes(aux.L2TxsData[i*lenL2TxsBytes:(i+1)*lenL2TxsBytes], int(nLevels))
624		if err != nil {
625			return nil, err
626		}
627		rollupForgeBatchArgs.L2TxsData = append(rollupForgeBatchArgs.L2TxsData, L2Tx)
628	}
629	lenFeeIdxCoordinatorBytes := int(nLevels / 8)
630	numFeeIdxCoordinator := len(aux.FeeIdxCoordinator) / lenFeeIdxCoordinatorBytes
631	for i := 0; i < numFeeIdxCoordinator; i++ {
632		var paddedFeeIdx [6]byte
633		if lenFeeIdxCoordinatorBytes < common.IdxBytesLen {
634			copy(paddedFeeIdx[6-lenFeeIdxCoordinatorBytes:], aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
635		} else {
636			copy(paddedFeeIdx[:], aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
637		}
638		FeeIdxCoordinator, err := common.IdxFromBytes(paddedFeeIdx[:])
639		if err != nil {
640			return nil, err
641		}
642		rollupForgeBatchArgs.FeeIdxCoordinator = append(rollupForgeBatchArgs.FeeIdxCoordinator, FeeIdxCoordinator)
643	}
644	return rollupForgeBatchArgs, nil
645	// tx := client.TransactionByHash(ethTxHash) -> types.Transaction
646	// txData := types.Transaction -> Data()
647	// m := abi.MethodById(txData) -> Method
648	// m.Inputs.Unpack(txData) -> Args
649	// client.TransactionReceipt()?
650}