ParaTonPortal

L1 and L2 data transmission/parsing/verification belong to the underlying contracts, and users can also make upper-level calls through open interfaces.

The ParaTonPortal is a foundational low-level contract that facilitates message passing between Layer 1 and Layer 2 within the TON and ParaTon ecosystems. This contract ensures that messages are transmitted efficiently and securely across layers, maintaining the integrity of cross-layer communications. However, it is important to note that messages sent directly to the ParaTonPortal lack replayability, meaning that each message can only be processed once and cannot be reused or replayed.

import "@stdlib/deploy";
import "@stdlib/ownable";

// Define the structure for ProvenWithdrawal
struct ProvenWithdrawal {
    outputRoot: Slice;
    timestamp: Int;
    outputIndex: Int;
}

// Contract StatePortal
contract StatePortal with Deployable, Ownable {
    // State variables
    outputOracle: Address;
    config: Address;
    systemConfig: Address;
    senderAddress: Address;
    version: String;
    finalizedWithdrawals: map<Int, Bool>;
    provenWithdrawals: map<Int, ProvenWithdrawal>;
    owner: Address; // Required by Ownable trait

    // Initial setup function
    // Initializes the contract with the given addresses
    init(outputOracle: Address, systemConfig: Address, config: Address) {
        self.outputOracle = outputOracle;
        self.systemConfig = systemConfig;
        self.config = config;
        self.senderAddress = myAddress(); // Initialize with the contract's own address
        self.version = "2.5.0";
        self.finalizedWithdrawals = emptyMap();
        self.provenWithdrawals = emptyMap();
        self.owner = sender(); // Initialize the owner as the sender of the deploy transaction
    }

    // Function to check if the contract is paused
    // Returns false as a placeholder
    get fun paused(): Bool {
        return false; // Placeholder logic, replace with actual pause check
    }

    // Function to compute the minimum gas limit for a deposit
    get fun minimumGasLimit(byteCount: Int): Int {
        return byteCount * 16 + 21000;
    }

    // Function to handle deposits
    receive("depositTransaction") {
        let to: Address = sender(); // Placeholder for target address
        let value: Int = 0; // Placeholder for value
        let gasLimit: Int = self.minimumGasLimit(0); // Placeholder for gas limit
        let opaqueData: Slice = beginCell().endCell().beginParse(); // Placeholder for opaque data

        // Emit a TransactionDeposited event
        emit(beginCell().storeAddress(sender()).storeAddress(to).storeUint(0, 256).storeSlice(opaqueData).endCell());
    }

    // Function to prove a withdrawal transaction
    receive("proveWithdrawalTransaction") {
        let tx: Slice = beginCell().endCell().beginParse(); // Placeholder for transaction data
        let outputIndex: Int = 0; // Placeholder for L2 output index
        let outputRootProof: Slice = beginCell().endCell().beginParse(); // Placeholder for output root proof
        let withdrawalProof: map<Int, Int> = emptyMap(); // Placeholder for withdrawal proof
        withdrawalProof.set(0, beginCell().endCell().hash()); // Adding a dummy entry

        // Logic to prove the withdrawal transaction (simplified placeholder)
        let withdrawalHash: Int = tx.hash(); // Simplified hash function
        let provenWithdrawal: ProvenWithdrawal = ProvenWithdrawal {
            outputRoot: outputRootProof,
            timestamp: now(),
            outputIndex: outputIndex
        };
        self.provenWithdrawals.set(withdrawalHash, provenWithdrawal);

        // Emit a WithdrawalProven event
        emit(beginCell().storeUint(withdrawalHash, 256).storeAddress(sender()).storeAddress(sender()).endCell());
    }

    // Function to finalize a withdrawal transaction
    receive("finalizeWithdrawalTransaction") {
        let tx: Slice = beginCell().endCell().beginParse(); // Placeholder for transaction data

        // Logic to finalize the withdrawal transaction (simplified placeholder)
        let withdrawalHash: Int = tx.hash(); // Simplified hash function
        let isFinalized: Bool? = self.finalizedWithdrawals.get(withdrawalHash);
        require(isFinalized == null || isFinalized == false, "StatePortal: withdrawal has already been finalized");

        self.finalizedWithdrawals.set(withdrawalHash, true);

        // Emit a WithdrawalFinalized event
        emit(beginCell().storeUint(withdrawalHash, 256).storeUint(1, 1).endCell()); // Assuming success
    }
}

Last updated