Checking result of an L1 -> L2 message/invoke in Starknet

459 views Asked by At

I've written a couple contracts for L1 (Ethereum) and L2 (Starknet) and have them communicate here.

I can see that L1 sent the message I'm expecting, see this TX on etherscan. The last message in there however never executed on my L2 contract. I'm trying to figure out whether the L2 Sequencer has invoked the handler function of my contract and if so, whether/how it failed.

Does anyone here know how to find the TX that handles the invoke on L2? Or any other ideas/tools that would help figuring out why the l1_handler never executed/failed?

1

There are 1 answers

0
Lucas On BEST ANSWER

First thing, transactions coming from L1 are regular transactions and therefore their hash can be computed the same way as invoke transactions. To have more information on this you can check the documentation here. Now this is helpful to understand the theory but not that much to actually compute the tx hash.

Here is the L1 event that send a message to StarkNet and this is where I get the needed information to compute the hash

Address 0xde29d060d45901fb19ed6c6e959eb22d8626708e
Name LogMessageToL2 (index_topic_1 address fromAddress, index_topic_2 uint256 toAddress, index_topic_3 uint256 selector, uint256[] payload, uint256 nonce)View Source

Topics
0 0x7d3450d4f5138e54dcb21a322312d50846ead7856426fb38778f8ef33aeccc01
1  0x779b989d7358acd6ce64237f16bbef09f35f6ecc
2  1524569076953457512425355396075576585145183562308719695739798372277154230742
3  1285101517810983806491589552491143496277809242732141897358598292095611420389
Data
payload :
1393428179030720295440092695193628168230707649901849797435563042612822742693
11819812303435348947619
0
nonce :
69106

Here is the script I use applied to your transaction (this may change in the future)

from starkware.cairo.lang.vm.crypto import pedersen_hash
from starkware.cairo.common.hash_state import compute_hash_on_elements
from starkware.crypto.signature.fast_pedersen_hash import pedersen_hash
from typing import List


def calculate_transaction_hash_common(
    tx_hash_prefix,
    version,
    contract_address,
    entry_point_selector,
    calldata,
    max_fee,
    chain_id,
    additional_data,
    hash_function=pedersen_hash,
) -> int:
    calldata_hash = compute_hash_on_elements(data=calldata, hash_func=hash_function)
    data_to_hash = [
        tx_hash_prefix,
        version,
        contract_address,
        entry_point_selector,
        calldata_hash,
        max_fee,
        chain_id,
        *additional_data,
    ]

    return compute_hash_on_elements(
        data=data_to_hash,
        hash_func=hash_function,
    )


def tx_hash_from_message(
    from_address: str, to_address: int, selector: int, nonce: int, payload: List[int]
) -> str:
    int_hash = calculate_transaction_hash_common(
        tx_hash_prefix=510926345461491391292786,    # int.from_bytes(b"l1_handler", "big")
        version=0,
        contract_address=to_address,
        entry_point_selector=selector,
        calldata=[int(from_address, 16), *payload],
        max_fee=0,
        chain_id=1536727068981429685321,  # StarknetChainId.TESTNET.value
        additional_data=[nonce],
    )
    return hex(int_hash)


print(
    tx_hash_from_message(
        from_address="0x779b989d7358acd6ce64237f16bbef09f35f6ecc",
        to_address=1524569076953457512425355396075576585145183562308719695739798372277154230742,
        selector=1285101517810983806491589552491143496277809242732141897358598292095611420389,
        nonce=69106,
        payload=[
            1393428179030720295440092695193628168230707649901849797435563042612822742693,
            11819812303435348947619,
            0,
        ],
    )
)

This outputs 0x4433250847579c56b12822a16205e12410f6ad35d8cfc2d6ab011a250eae77f that we can find here which was properly executed.