Last active
August 16, 2024 09:07
-
-
Save gzeoneth/0a8bac381752e4b4f30650a0d3c76096 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { BigNumber, ethers } from 'ethers' | |
import dotenv from 'dotenv' | |
dotenv.config() | |
const rollupAbi = [ | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": false, | |
"internalType": "address", | |
"name": "previousAdmin", | |
"type": "address" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "address", | |
"name": "newAdmin", | |
"type": "address" | |
} | |
], | |
"name": "AdminChanged", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "address", | |
"name": "beacon", | |
"type": "address" | |
} | |
], | |
"name": "BeaconUpgraded", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "uint64", | |
"name": "nodeNum", | |
"type": "uint64" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "bytes32", | |
"name": "blockHash", | |
"type": "bytes32" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "bytes32", | |
"name": "sendRoot", | |
"type": "bytes32" | |
} | |
], | |
"name": "NodeConfirmed", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "uint64", | |
"name": "nodeNum", | |
"type": "uint64" | |
}, | |
{ | |
"indexed": true, | |
"internalType": "bytes32", | |
"name": "parentNodeHash", | |
"type": "bytes32" | |
}, | |
{ | |
"indexed": true, | |
"internalType": "bytes32", | |
"name": "nodeHash", | |
"type": "bytes32" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "bytes32", | |
"name": "executionHash", | |
"type": "bytes32" | |
}, | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"internalType": "bytes32[2]", | |
"name": "bytes32Vals", | |
"type": "bytes32[2]" | |
}, | |
{ | |
"internalType": "uint64[2]", | |
"name": "u64Vals", | |
"type": "uint64[2]" | |
} | |
], | |
"internalType": "struct GlobalState", | |
"name": "globalState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "enum MachineStatus", | |
"name": "machineStatus", | |
"type": "uint8" | |
} | |
], | |
"internalType": "struct RollupLib.ExecutionState", | |
"name": "beforeState", | |
"type": "tuple" | |
}, | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"internalType": "bytes32[2]", | |
"name": "bytes32Vals", | |
"type": "bytes32[2]" | |
}, | |
{ | |
"internalType": "uint64[2]", | |
"name": "u64Vals", | |
"type": "uint64[2]" | |
} | |
], | |
"internalType": "struct GlobalState", | |
"name": "globalState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "enum MachineStatus", | |
"name": "machineStatus", | |
"type": "uint8" | |
} | |
], | |
"internalType": "struct RollupLib.ExecutionState", | |
"name": "afterState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "numBlocks", | |
"type": "uint64" | |
} | |
], | |
"indexed": false, | |
"internalType": "struct RollupLib.Assertion", | |
"name": "assertion", | |
"type": "tuple" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "bytes32", | |
"name": "afterInboxBatchAcc", | |
"type": "bytes32" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "bytes32", | |
"name": "wasmModuleRoot", | |
"type": "bytes32" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "uint256", | |
"name": "inboxMaxCount", | |
"type": "uint256" | |
} | |
], | |
"name": "NodeCreated", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "uint64", | |
"name": "nodeNum", | |
"type": "uint64" | |
} | |
], | |
"name": "NodeRejected", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": false, | |
"internalType": "address", | |
"name": "account", | |
"type": "address" | |
} | |
], | |
"name": "Paused", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "uint64", | |
"name": "challengeIndex", | |
"type": "uint64" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "address", | |
"name": "asserter", | |
"type": "address" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "address", | |
"name": "challenger", | |
"type": "address" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "uint64", | |
"name": "challengedNode", | |
"type": "uint64" | |
} | |
], | |
"name": "RollupChallengeStarted", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": false, | |
"internalType": "bytes32", | |
"name": "machineHash", | |
"type": "bytes32" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "uint256", | |
"name": "chainId", | |
"type": "uint256" | |
} | |
], | |
"name": "RollupInitialized", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": false, | |
"internalType": "address", | |
"name": "account", | |
"type": "address" | |
} | |
], | |
"name": "Unpaused", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "address", | |
"name": "implementation", | |
"type": "address" | |
} | |
], | |
"name": "Upgraded", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "address", | |
"name": "implementation", | |
"type": "address" | |
} | |
], | |
"name": "UpgradedSecondary", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "address", | |
"name": "user", | |
"type": "address" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "uint256", | |
"name": "initialBalance", | |
"type": "uint256" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "uint256", | |
"name": "finalBalance", | |
"type": "uint256" | |
} | |
], | |
"name": "UserStakeUpdated", | |
"type": "event" | |
}, | |
{ | |
"anonymous": false, | |
"inputs": [ | |
{ | |
"indexed": true, | |
"internalType": "address", | |
"name": "user", | |
"type": "address" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "uint256", | |
"name": "initialBalance", | |
"type": "uint256" | |
}, | |
{ | |
"indexed": false, | |
"internalType": "uint256", | |
"name": "finalBalance", | |
"type": "uint256" | |
} | |
], | |
"name": "UserWithdrawableFundsUpdated", | |
"type": "event" | |
}, | |
{ | |
"inputs": [], | |
"name": "VALIDATOR_AFK_BLOCKS", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"name": "_stakerMap", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "amountStaked", | |
"type": "uint256" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "index", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "latestStakedNode", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "currentChallenge", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "bool", | |
"name": "isStaked", | |
"type": "bool" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "stakerAddress", | |
"type": "address" | |
} | |
], | |
"name": "addToDeposit", | |
"outputs": [], | |
"stateMutability": "payable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "staker", | |
"type": "address" | |
} | |
], | |
"name": "amountStaked", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "baseStake", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "bridge", | |
"outputs": [ | |
{ | |
"internalType": "contract IBridge", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "chainId", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "challengeManager", | |
"outputs": [ | |
{ | |
"internalType": "contract IChallengeManager", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "challengeIndex", | |
"type": "uint256" | |
}, | |
{ | |
"internalType": "address", | |
"name": "winningStaker", | |
"type": "address" | |
}, | |
{ | |
"internalType": "address", | |
"name": "losingStaker", | |
"type": "address" | |
} | |
], | |
"name": "completeChallenge", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "bytes32", | |
"name": "blockHash", | |
"type": "bytes32" | |
}, | |
{ | |
"internalType": "bytes32", | |
"name": "sendRoot", | |
"type": "bytes32" | |
} | |
], | |
"name": "confirmNextNode", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "confirmPeriodBlocks", | |
"outputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "", | |
"type": "uint64" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "nodeNum", | |
"type": "uint64" | |
} | |
], | |
"name": "countStakedZombies", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "nodeNum", | |
"type": "uint64" | |
} | |
], | |
"name": "countZombiesStakedOnChildren", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address[2]", | |
"name": "stakers", | |
"type": "address[2]" | |
}, | |
{ | |
"internalType": "uint64[2]", | |
"name": "nodeNums", | |
"type": "uint64[2]" | |
}, | |
{ | |
"internalType": "enum MachineStatus[2]", | |
"name": "machineStatuses", | |
"type": "uint8[2]" | |
}, | |
{ | |
"components": [ | |
{ | |
"internalType": "bytes32[2]", | |
"name": "bytes32Vals", | |
"type": "bytes32[2]" | |
}, | |
{ | |
"internalType": "uint64[2]", | |
"name": "u64Vals", | |
"type": "uint64[2]" | |
} | |
], | |
"internalType": "struct GlobalState[2]", | |
"name": "globalStates", | |
"type": "tuple[2]" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "numBlocks", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "bytes32", | |
"name": "secondExecutionHash", | |
"type": "bytes32" | |
}, | |
{ | |
"internalType": "uint256[2]", | |
"name": "proposedTimes", | |
"type": "uint256[2]" | |
}, | |
{ | |
"internalType": "bytes32[2]", | |
"name": "wasmModuleRoots", | |
"type": "bytes32[2]" | |
} | |
], | |
"name": "createChallenge", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "staker", | |
"type": "address" | |
} | |
], | |
"name": "currentChallenge", | |
"outputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "", | |
"type": "uint64" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "currentRequiredStake", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "extraChallengeTimeBlocks", | |
"outputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "", | |
"type": "uint64" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "firstUnresolvedNode", | |
"outputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "", | |
"type": "uint64" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"internalType": "bytes32[2]", | |
"name": "bytes32Vals", | |
"type": "bytes32[2]" | |
}, | |
{ | |
"internalType": "uint64[2]", | |
"name": "u64Vals", | |
"type": "uint64[2]" | |
} | |
], | |
"internalType": "struct GlobalState", | |
"name": "globalState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "enum MachineStatus", | |
"name": "machineStatus", | |
"type": "uint8" | |
} | |
], | |
"internalType": "struct RollupLib.ExecutionState", | |
"name": "beforeState", | |
"type": "tuple" | |
}, | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"internalType": "bytes32[2]", | |
"name": "bytes32Vals", | |
"type": "bytes32[2]" | |
}, | |
{ | |
"internalType": "uint64[2]", | |
"name": "u64Vals", | |
"type": "uint64[2]" | |
} | |
], | |
"internalType": "struct GlobalState", | |
"name": "globalState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "enum MachineStatus", | |
"name": "machineStatus", | |
"type": "uint8" | |
} | |
], | |
"internalType": "struct RollupLib.ExecutionState", | |
"name": "afterState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "numBlocks", | |
"type": "uint64" | |
} | |
], | |
"internalType": "struct RollupLib.Assertion", | |
"name": "assertion", | |
"type": "tuple" | |
} | |
], | |
"name": "getL2BlockHash", | |
"outputs": [ | |
{ | |
"internalType": "bytes32", | |
"name": "", | |
"type": "bytes32" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "nodeNum", | |
"type": "uint64" | |
} | |
], | |
"name": "getNode", | |
"outputs": [ | |
{ | |
"components": [ | |
{ | |
"internalType": "bytes32", | |
"name": "stateHash", | |
"type": "bytes32" | |
}, | |
{ | |
"internalType": "bytes32", | |
"name": "challengeHash", | |
"type": "bytes32" | |
}, | |
{ | |
"internalType": "bytes32", | |
"name": "confirmData", | |
"type": "bytes32" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "prevNum", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "deadlineBlock", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "noChildConfirmedBeforeBlock", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "stakerCount", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "childStakerCount", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "firstChildBlock", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "latestChildNumber", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "createdAtBlock", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "bytes32", | |
"name": "nodeHash", | |
"type": "bytes32" | |
} | |
], | |
"internalType": "struct Node", | |
"name": "", | |
"type": "tuple" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "staker", | |
"type": "address" | |
} | |
], | |
"name": "getStaker", | |
"outputs": [ | |
{ | |
"components": [ | |
{ | |
"internalType": "uint256", | |
"name": "amountStaked", | |
"type": "uint256" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "index", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "latestStakedNode", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "currentChallenge", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "bool", | |
"name": "isStaked", | |
"type": "bool" | |
} | |
], | |
"internalType": "struct IRollupCore.Staker", | |
"name": "", | |
"type": "tuple" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "stakerNum", | |
"type": "uint64" | |
} | |
], | |
"name": "getStakerAddress", | |
"outputs": [ | |
{ | |
"internalType": "address", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "inbox", | |
"outputs": [ | |
{ | |
"internalType": "contract IInbox", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "_stakeToken", | |
"type": "address" | |
} | |
], | |
"name": "initialize", | |
"outputs": [], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "isERC20Enabled", | |
"outputs": [ | |
{ | |
"internalType": "bool", | |
"name": "", | |
"type": "bool" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "staker", | |
"type": "address" | |
} | |
], | |
"name": "isStaked", | |
"outputs": [ | |
{ | |
"internalType": "bool", | |
"name": "", | |
"type": "bool" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "staker", | |
"type": "address" | |
} | |
], | |
"name": "isStakedOnLatestConfirmed", | |
"outputs": [ | |
{ | |
"internalType": "bool", | |
"name": "", | |
"type": "bool" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"name": "isValidator", | |
"outputs": [ | |
{ | |
"internalType": "bool", | |
"name": "", | |
"type": "bool" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "staker", | |
"type": "address" | |
} | |
], | |
"name": "isZombie", | |
"outputs": [ | |
{ | |
"internalType": "bool", | |
"name": "", | |
"type": "bool" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "lastStakeBlock", | |
"outputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "", | |
"type": "uint64" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "latestConfirmed", | |
"outputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "", | |
"type": "uint64" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "latestNodeCreated", | |
"outputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "", | |
"type": "uint64" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "staker", | |
"type": "address" | |
} | |
], | |
"name": "latestStakedNode", | |
"outputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "", | |
"type": "uint64" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "loserStakeEscrow", | |
"outputs": [ | |
{ | |
"internalType": "address", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "minimumAssertionPeriod", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "nodeNum", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "bytes32", | |
"name": "nodeHash", | |
"type": "bytes32" | |
} | |
], | |
"name": "newStakeOnExistingNode", | |
"outputs": [], | |
"stateMutability": "payable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"internalType": "bytes32[2]", | |
"name": "bytes32Vals", | |
"type": "bytes32[2]" | |
}, | |
{ | |
"internalType": "uint64[2]", | |
"name": "u64Vals", | |
"type": "uint64[2]" | |
} | |
], | |
"internalType": "struct GlobalState", | |
"name": "globalState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "enum MachineStatus", | |
"name": "machineStatus", | |
"type": "uint8" | |
} | |
], | |
"internalType": "struct RollupLib.ExecutionState", | |
"name": "beforeState", | |
"type": "tuple" | |
}, | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"internalType": "bytes32[2]", | |
"name": "bytes32Vals", | |
"type": "bytes32[2]" | |
}, | |
{ | |
"internalType": "uint64[2]", | |
"name": "u64Vals", | |
"type": "uint64[2]" | |
} | |
], | |
"internalType": "struct GlobalState", | |
"name": "globalState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "enum MachineStatus", | |
"name": "machineStatus", | |
"type": "uint8" | |
} | |
], | |
"internalType": "struct RollupLib.ExecutionState", | |
"name": "afterState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "numBlocks", | |
"type": "uint64" | |
} | |
], | |
"internalType": "struct RollupLib.Assertion", | |
"name": "assertion", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "bytes32", | |
"name": "expectedNodeHash", | |
"type": "bytes32" | |
}, | |
{ | |
"internalType": "uint256", | |
"name": "prevNodeInboxMaxCount", | |
"type": "uint256" | |
} | |
], | |
"name": "newStakeOnNewNode", | |
"outputs": [], | |
"stateMutability": "payable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "nodeNum", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "address", | |
"name": "staker", | |
"type": "address" | |
} | |
], | |
"name": "nodeHasStaker", | |
"outputs": [ | |
{ | |
"internalType": "bool", | |
"name": "", | |
"type": "bool" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "outbox", | |
"outputs": [ | |
{ | |
"internalType": "contract IOutbox", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "owner", | |
"outputs": [ | |
{ | |
"internalType": "address", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "paused", | |
"outputs": [ | |
{ | |
"internalType": "bool", | |
"name": "", | |
"type": "bool" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "proxiableUUID", | |
"outputs": [ | |
{ | |
"internalType": "bytes32", | |
"name": "", | |
"type": "bytes32" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "target", | |
"type": "uint256" | |
} | |
], | |
"name": "reduceDeposit", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "stakerAddress", | |
"type": "address" | |
} | |
], | |
"name": "rejectNextNode", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "startIndex", | |
"type": "uint256" | |
} | |
], | |
"name": "removeOldZombies", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "removeWhitelistAfterFork", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "removeWhitelistAfterValidatorAfk", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "zombieNum", | |
"type": "uint256" | |
}, | |
{ | |
"internalType": "uint256", | |
"name": "maxNodes", | |
"type": "uint256" | |
} | |
], | |
"name": "removeZombie", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "nodeNum", | |
"type": "uint256" | |
} | |
], | |
"name": "requireUnresolved", | |
"outputs": [], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "requireUnresolvedExists", | |
"outputs": [], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "blockNumber", | |
"type": "uint256" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "firstUnresolvedNodeNum", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "latestCreatedNode", | |
"type": "uint64" | |
} | |
], | |
"name": "requiredStake", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "stakerAddress", | |
"type": "address" | |
} | |
], | |
"name": "returnOldDeposit", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "rollupDeploymentBlock", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "rollupEventInbox", | |
"outputs": [ | |
{ | |
"internalType": "contract IRollupEventInbox", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "sequencerInbox", | |
"outputs": [ | |
{ | |
"internalType": "contract ISequencerInbox", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "nodeNum", | |
"type": "uint64" | |
}, | |
{ | |
"internalType": "bytes32", | |
"name": "nodeHash", | |
"type": "bytes32" | |
} | |
], | |
"name": "stakeOnExistingNode", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"internalType": "bytes32[2]", | |
"name": "bytes32Vals", | |
"type": "bytes32[2]" | |
}, | |
{ | |
"internalType": "uint64[2]", | |
"name": "u64Vals", | |
"type": "uint64[2]" | |
} | |
], | |
"internalType": "struct GlobalState", | |
"name": "globalState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "enum MachineStatus", | |
"name": "machineStatus", | |
"type": "uint8" | |
} | |
], | |
"internalType": "struct RollupLib.ExecutionState", | |
"name": "beforeState", | |
"type": "tuple" | |
}, | |
{ | |
"components": [ | |
{ | |
"components": [ | |
{ | |
"internalType": "bytes32[2]", | |
"name": "bytes32Vals", | |
"type": "bytes32[2]" | |
}, | |
{ | |
"internalType": "uint64[2]", | |
"name": "u64Vals", | |
"type": "uint64[2]" | |
} | |
], | |
"internalType": "struct GlobalState", | |
"name": "globalState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "enum MachineStatus", | |
"name": "machineStatus", | |
"type": "uint8" | |
} | |
], | |
"internalType": "struct RollupLib.ExecutionState", | |
"name": "afterState", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "uint64", | |
"name": "numBlocks", | |
"type": "uint64" | |
} | |
], | |
"internalType": "struct RollupLib.Assertion", | |
"name": "assertion", | |
"type": "tuple" | |
}, | |
{ | |
"internalType": "bytes32", | |
"name": "expectedNodeHash", | |
"type": "bytes32" | |
}, | |
{ | |
"internalType": "uint256", | |
"name": "prevNodeInboxMaxCount", | |
"type": "uint256" | |
} | |
], | |
"name": "stakeOnNewNode", | |
"outputs": [], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "stakeToken", | |
"outputs": [ | |
{ | |
"internalType": "address", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "stakerCount", | |
"outputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "", | |
"type": "uint64" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "totalWithdrawableFunds", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "validatorUtils", | |
"outputs": [ | |
{ | |
"internalType": "address", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "validatorWalletCreator", | |
"outputs": [ | |
{ | |
"internalType": "address", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "validatorWhitelistDisabled", | |
"outputs": [ | |
{ | |
"internalType": "bool", | |
"name": "", | |
"type": "bool" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "wasmModuleRoot", | |
"outputs": [ | |
{ | |
"internalType": "bytes32", | |
"name": "", | |
"type": "bytes32" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "withdrawStakerFunds", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "nonpayable", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "address", | |
"name": "user", | |
"type": "address" | |
} | |
], | |
"name": "withdrawableFunds", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "zombieNum", | |
"type": "uint256" | |
} | |
], | |
"name": "zombieAddress", | |
"outputs": [ | |
{ | |
"internalType": "address", | |
"name": "", | |
"type": "address" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [], | |
"name": "zombieCount", | |
"outputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "", | |
"type": "uint256" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
}, | |
{ | |
"inputs": [ | |
{ | |
"internalType": "uint256", | |
"name": "zombieNum", | |
"type": "uint256" | |
} | |
], | |
"name": "zombieLatestStakedNode", | |
"outputs": [ | |
{ | |
"internalType": "uint64", | |
"name": "", | |
"type": "uint64" | |
} | |
], | |
"stateMutability": "view", | |
"type": "function" | |
} | |
] | |
const helperAbi = [{"inputs":[{"components":[{"components":[{"components":[{"internalType":"bytes32[2]","name":"bytes32Vals","type":"bytes32[2]"},{"internalType":"uint64[2]","name":"u64Vals","type":"uint64[2]"}],"internalType":"struct GlobalState","name":"globalState","type":"tuple"},{"internalType":"enum MachineStatus","name":"machineStatus","type":"uint8"}],"internalType":"struct ExecutionState","name":"beforeState","type":"tuple"},{"components":[{"components":[{"internalType":"bytes32[2]","name":"bytes32Vals","type":"bytes32[2]"},{"internalType":"uint64[2]","name":"u64Vals","type":"uint64[2]"}],"internalType":"struct GlobalState","name":"globalState","type":"tuple"},{"internalType":"enum MachineStatus","name":"machineStatus","type":"uint8"}],"internalType":"struct ExecutionState","name":"afterState","type":"tuple"},{"internalType":"uint64","name":"numBlocks","type":"uint64"}],"internalType":"struct Assertion","name":"assertion","type":"tuple"}],"name":"getBlockHash","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"components":[{"components":[{"internalType":"bytes32[2]","name":"bytes32Vals","type":"bytes32[2]"},{"internalType":"uint64[2]","name":"u64Vals","type":"uint64[2]"}],"internalType":"struct GlobalState","name":"globalState","type":"tuple"},{"internalType":"enum MachineStatus","name":"machineStatus","type":"uint8"}],"internalType":"struct ExecutionState","name":"beforeState","type":"tuple"},{"components":[{"components":[{"internalType":"bytes32[2]","name":"bytes32Vals","type":"bytes32[2]"},{"internalType":"uint64[2]","name":"u64Vals","type":"uint64[2]"}],"internalType":"struct GlobalState","name":"globalState","type":"tuple"},{"internalType":"enum MachineStatus","name":"machineStatus","type":"uint8"}],"internalType":"struct ExecutionState","name":"afterState","type":"tuple"},{"internalType":"uint64","name":"numBlocks","type":"uint64"}],"internalType":"struct Assertion","name":"assertion","type":"tuple"}],"name":"getSendRoot","outputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"stateMutability":"pure","type":"function"}] | |
const fooAbi = [{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"getInt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_val","type":"uint256"}],"name":"setInt","outputs":[],"stateMutability":"nonpayable","type":"function"}] | |
const verifierAbi = [{"inputs":[{"internalType":"bytes","name":"_key","type":"bytes"},{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"get","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes","name":"_key","type":"bytes"},{"internalType":"bytes","name":"_value","type":"bytes"},{"internalType":"bytes","name":"_proof","type":"bytes"},{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"verifyInclusionProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}] | |
const outboxAbi = [{"inputs":[],"name":"AlreadyInit","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"AlreadySpent","type":"error"},{"inputs":[],"name":"BridgeCallFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"actualLength","type":"uint256"},{"internalType":"uint256","name":"maxProofLength","type":"uint256"}],"name":"MerkleProofTooLong","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"rollup","type":"address"}],"name":"NotRollup","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"maxIndex","type":"uint256"}],"name":"PathNotMinimal","type":"error"},{"inputs":[{"internalType":"uint256","name":"proofLength","type":"uint256"}],"name":"ProofTooLong","type":"error"},{"inputs":[],"name":"SimulationOnlyEntrypoint","type":"error"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"}],"name":"UnknownRoot","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"address","name":"l2Sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"zero","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"transactionIndex","type":"uint256"}],"name":"OutBoxTransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"outputRoot","type":"bytes32"}],"name":"SendRootUpdated","type":"event"},{"inputs":[],"name":"OUTBOX_VERSION","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract IBridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"l2Sender","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"l2Block","type":"uint256"},{"internalType":"uint256","name":"l1Block","type":"uint256"},{"internalType":"uint256","name":"l2Timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"calculateItemHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"path","type":"uint256"},{"internalType":"bytes32","name":"item","type":"bytes32"}],"name":"calculateMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"l2Sender","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"l2Block","type":"uint256"},{"internalType":"uint256","name":"l1Block","type":"uint256"},{"internalType":"uint256","name":"l2Timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"l2Sender","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"l2Block","type":"uint256"},{"internalType":"uint256","name":"l1Block","type":"uint256"},{"internalType":"uint256","name":"l2Timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"executeTransactionSimulation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IBridge","name":"_bridge","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"isSpent","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1BatchNum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"l2ToL1Block","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1EthBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1OutputId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1Sender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2ToL1Timestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rollup","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"roots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spent","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"bytes32","name":"l2BlockHash","type":"bytes32"}],"name":"updateSendRoot","outputs":[],"stateMutability":"nonpayable","type":"function"}] | |
const L1_ALCHEMY_KEY = process.env.L1_ALCHEMY_KEY | |
const L2_ALCHEMY_KEY = process.env.L2_ALCHEMY_KEY | |
if(!(L1_ALCHEMY_KEY && L2_ALCHEMY_KEY)) throw("set L1_ALCHEMY_KEY and L2_ALCHEMY_KEY") | |
const l1url = `https://eth-goerli.g.alchemy.com/v2/${L1_ALCHEMY_KEY}` | |
const l1provider = new ethers.providers.JsonRpcProvider(l1url); | |
const l2url = `https://arb-goerli.g.alchemy.com/v2/${L2_ALCHEMY_KEY}` | |
const l2provider = new ethers.providers.JsonRpcProvider(l2url); | |
console.log({l1url, l2url}) | |
// l2 addresses | |
const fooAddress = '0xe0fb944d3f724a79a4a3f7f3aabfcd2c85057c14' | |
const foo = new ethers.Contract(fooAddress, fooAbi, l2provider); | |
// l1 addresses | |
const rollupAddress = '0x45e5cAea8768F42B385A366D3551Ad1e0cbFAb17' | |
const helperAddress = '0x252656ea5274e178d91d6a8e102574ab0548e036' | |
const outboxAddress = '0x45Af9Ed1D03703e480CE7d328fB684bb67DA5049' | |
// Uses @eth-optimism/contracts/libraries/trie/Lib_SecureMerkleTrie.sol | |
// https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/trie/Lib_SecureMerkleTrie.sol | |
const verifierAddress = '0xde1f73BACbd1C13ceDBDB56aDE1c2c98284de5aa' | |
const rollup = new ethers.Contract(rollupAddress, rollupAbi, l1provider); | |
const helper = new ethers.Contract(helperAddress, helperAbi, l1provider); | |
const outbox = new ethers.Contract(outboxAddress, outboxAbi, l1provider); | |
const verifier = new ethers.Contract(verifierAddress, verifierAbi, l1provider); | |
async function main(){ | |
// console.log(await foo.getInt()) | |
const slot = '0x0000000000000000000000000000000000000000000000000000000000000000' | |
const nodeIndex = await rollup.latestNodeCreated() | |
console.log(3, nodeIndex) | |
const nodeEventFilter = await rollup.filters.NodeCreated(nodeIndex); | |
const nodeEvents = await rollup.queryFilter(nodeEventFilter); | |
const assertion = nodeEvents[0].args!.assertion | |
console.log(4, {assertion}) | |
const blockHash = await helper.getBlockHash(assertion) | |
const sendRoot = await helper.getSendRoot(assertion) | |
// const l2blockHash = await outbox.roots(sendRoot) | |
const confirmdata = ethers.utils.keccak256(ethers.utils.solidityPack(['bytes32','bytes32'], [blockHash, sendRoot])) | |
console.log(5, {blockHash, sendRoot}) | |
const l2block = (await l2provider.getBlock(blockHash)) | |
const l2blockNumber = l2block.number | |
console.log(6, l2blockNumber) | |
const rblock = await rollup.getNode(nodeIndex) | |
// compare these two | |
console.log(7, rblock.confirmData) // node or rollup block or rblock | |
console.log(8, confirmdata, rblock.confirmData === confirmdata) | |
// ^ This complete Proof a certain l2 block hash correspond to a node/rblock | |
// ^ Your L1 contract now know the L2 block hash | |
// Next step, you need to show the L1 contract the L1 state root | |
// You get all the field in the blockheader with the L2 RPC | |
const l2blockRaw = await l2provider.send('eth_getBlockByHash', [ | |
blockHash, | |
false | |
]); | |
console.log(l2blockRaw) | |
const stateroot = l2blockRaw.stateRoot | |
const blockarray = [ | |
l2blockRaw.parentHash, | |
l2blockRaw.sha3Uncles, | |
l2blockRaw.miner, | |
stateroot, | |
l2blockRaw.transactionsRoot, | |
l2blockRaw.receiptsRoot, | |
l2blockRaw.logsBloom, | |
BigNumber.from(l2blockRaw.difficulty).toHexString(), | |
BigNumber.from(l2blockRaw.number).toHexString(), | |
BigNumber.from(l2blockRaw.gasLimit).toHexString(), | |
BigNumber.from(l2blockRaw.gasUsed).toHexString(), | |
BigNumber.from(l2blockRaw.timestamp).toHexString(), | |
l2blockRaw.extraData, | |
l2blockRaw.mixHash, | |
l2blockRaw.nonce, | |
BigNumber.from(l2blockRaw.baseFeePerGas).toHexString(), | |
] | |
console.log(blockarray) | |
const calculated_blockhash = ethers.utils.keccak256(ethers.utils.RLP.encode(blockarray)) | |
console.log(calculated_blockhash) | |
console.log(calculated_blockhash === blockHash) | |
// ParentHash common.Hash `json:"parentHash" gencodec:"required"` | |
// UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` | |
// Coinbase common.Address `json:"miner"` | |
// Root common.Hash `json:"stateRoot" gencodec:"required"` | |
// TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` | |
// ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` | |
// Bloom Bloom `json:"logsBloom" gencodec:"required"` | |
// Difficulty *big.Int `json:"difficulty" gencodec:"required"` | |
// Number *big.Int `json:"number" gencodec:"required"` | |
// GasLimit uint64 `json:"gasLimit" gencodec:"required"` | |
// GasUsed uint64 `json:"gasUsed" gencodec:"required"` | |
// Time uint64 `json:"timestamp" gencodec:"required"` | |
// Extra []byte `json:"extraData" gencodec:"required"` | |
// MixDigest common.Hash `json:"mixHash"` | |
// Nonce BlockNonce `json:"nonce"` | |
// // BaseFee was added by EIP-1559 and is ignored in legacy headers. | |
// BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"` | |
// ^ with these, the L1 contract now know the state root (from the blockhash) | |
// For the last steps, you need to | |
// 1. prove the account is in the state root | |
// 2. prove the storage is in the account root | |
const proof = await l2provider.send('eth_getProof', [ | |
fooAddress, | |
[slot], | |
{blockHash} | |
]); | |
console.log(proof) | |
const proofKey = ethers.utils.keccak256(proof.address) | |
const accountProof = ethers.utils.RLP.encode(proof.accountProof) | |
console.log(7, { | |
address:proof.address, | |
proofKey, accountProof, stateroot | |
}) | |
const [acctExists, acctEncoded] = await verifier.get( | |
proofKey, accountProof, stateroot | |
) | |
// decodeEVMAccount | |
const storageRoot = ethers.utils.RLP.decode(acctEncoded)[2] | |
console.log({storageRoot: storageRoot}) | |
const slotKey = ethers.utils.keccak256(slot) | |
const storageProof = ethers.utils.RLP.encode((proof.storageProof as any[]).filter((x)=>x.key===slot)[0].proof) | |
const [storageExists, storageEncoded] = await verifier.get( | |
slotKey, storageProof, storageRoot | |
) | |
console.log({storageEncoded: storageEncoded}) | |
const storageValue = ethers.utils.RLP.decode(storageEncoded) | |
const actualValue = await l2provider.getStorageAt(fooAddress, slot, l2block.number) // should use blockhash here but some bug with the alchemy rpc | |
const actualValueRemoveLeading0 = BigNumber.from(actualValue).toHexString() | |
console.log({storageValue: storageValue, actualValue: actualValueRemoveLeading0, equal: storageValue===actualValueRemoveLeading0}) | |
// 1. Proof a certain l2 block hash correspond to a node/rblock state with the assertion | |
// 2. Proof the state root belong to the l2 block hash by supplying the blockheader | |
// 3. Proof the account storage inside the state root | |
// 4. Proof the storage slot is in the account root | |
} | |
main() |
Author
gzeoneth
commented
Dec 23, 2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment