您正在查看: Ethereum-新手教程 分类下的文章

invalid opcode: opcode 0x5f not defined

问题

在低版本geth(quorum)上使用高版本solidity合约和编译(0.8.20及以上),部署时报以下错误

Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Returned error: invalid opcode: opcode 0x5f not defined
OR the EVM version used by the selected environment is not compatible with the compiler EVM version.

分析

原因是因为当前版本Evm未支持eip-3855

查看代码,代码未支持 PUSH0 0x5f
https://github.com/Consensys/quorum/blob/643b5dcb8e2f0c68a8c78dc01c778a11f0ed14ba/core/vm/opcodes.go#L109-L121

const (
    POP      OpCode = 0x50
    MLOAD    OpCode = 0x51
    MSTORE   OpCode = 0x52
    MSTORE8  OpCode = 0x53
    SLOAD    OpCode = 0x54
    SSTORE   OpCode = 0x55
    JUMP     OpCode = 0x56
    JUMPI    OpCode = 0x57
    PC       OpCode = 0x58
    MSIZE    OpCode = 0x59
    GAS      OpCode = 0x5a
    JUMPDEST OpCode = 0x5b
)

对标以太坊,https://github.com/ethereum/go-ethereum/pull/24039/files
添加了对eip-3855的支持

后续

将EIP合并,并测试

梳理Polygon zkEVM node 本地启动测试环境及配置

测试硬件环境

OS: Mac Pro {cpu intel} v11.7.5
注意:目前,Executor/Prover 不能在 ARM 驱动的 Mac 上运行。对于 Windows 用户,不建议使用 WSL/WSL2。

测试环境搭建

先按官方的测试环境进行部署,熟悉下部署细节,然后再做针对性补充
主要参考文章如下

官方是已Docker环境进行演示介绍的,我们精简下,主要说下关键操作

安装基础环境

自行安装go,dockerdocker-compose
可以参考以下官方文档,查看对应平台的安装方法:
https://go.dev/doc/install
https://www.docker.com/get-started
https://docs.docker.com/compose/install/

克隆代码

git clone https://github.com/0xPolygonHermez/zkevm-node.git

构建Docker镜像

cd zkevm-node/
make build-docker

运行 zkNode 环境

cd test/
make run

其他操作

make stop // 停止 zkNode
make restart // 重启整个 zkNode 环境

执行后,会创建和启动如下容器

  • zkevm-state-db
  • zkevm-pool-db
  • zkevm-mock-l1-network
  • zkevm-prover
  • zkevm-approve
  • zkevm-sync
  • zkevm-eth-tx-manager
  • zkevm-sequencer
  • zkevm-l2gaspricer
  • zkevm-aggregator
  • zkevm-json-rpc

根据Docker环境抽离各个模块配置

//TODO

L1网络配置

L2网络配置

访问环境

关键地址私钥

L1 Addresses

Address Description
0xa513E6E4b8f2a923D98304ec87F64353C4D5C853 Proof of Efficiency
0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 Bridge
0x5FbDB2315678afecb367f032d93F642f64180aa3 Matic token
0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 GlobalExitRootManager

Deployer Account

Address Private Key
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

Sequencer Account

Address Private Key
0x617b3a3528F9cDd6630fd3301B9c8911F7Bf063D 0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e

Accounts

Address Private Key
0x70997970C51812dc3A010C7d01b50e0d17dc79C8 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a
0x90F79bf6EB2c4f870365E785982E1f101E93b906 0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6
0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a
0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc 0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba
0x976EA74026E726554dB657fA54763abd0C3a0aa9 0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e
0x14dC79964da2C08b23698B3D3cc7Ca32193d9955 0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356
0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f 0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97
0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6
0xBcd4042DE499D14e55001CcbB24a551F3b954096 0xf214f2b2cd398c806f84e317254e0f0b801d0643303237d97a22a48e01628897
0x71bE63f3384f5fb98995898A86B02Fb2426c5788 0x701b615bbdfb9de65240bc28bd21bbc0d996645a3dd57e7b12bc2bdf6f192c82
0xFABB0ac9d68B0B445fB7357272Ff202C5651694a 0xa267530f49f8280200edf313ee7af6b827f2a8bce2897751d06a843f644967b1
0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec 0x47c99abed3324a2707c28affff1267e45918ec8c3f20b8aa892e8b065d2942dd
0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097 0xc526ee95bf44d8fc405a158bb884d9d1238d99f0612e9f33d006bb0789009aaa
0xcd3B766CCDd6AE721141F452C550Ca635964ce71 0x8166f546bab6da521a8369cab06c5d2b9e46670292d85c875ee9ec20e84ffb61
0x2546BcD3c84621e976D8185a91A922aE77ECEc30 0xea6c44ac03bff858b476bba40716402b03e41b8e97e276d1baec7c37d42484a0
0xbDA5747bFD65F08deb54cb465eB87D40e51B197E 0x689af8efa8c651a91ad287602527f3af2fe9f6501a7ac4b061667b5a93e037fd
0xdD2FD4581271e230360230F9337D5c0430Bf44C0 0xde9be858da4a475276426320d5e9262ecfc3ba460bfac56360bfa6c4c28b4ee0
0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199 0xdf57089febbacf7ba0bc227dafbffa9fc08a93fdc68e1e42411a14efcf23656e

Polygon zkEVM架构组成-思路梳理

Polygon zkEVM架构组成-思路梳理

  • zkNode

    • Synchronizer
      • 获取Sequencers提交的transactions
      • 获取Aggregators提交的validity proofs
      • 监听以太坊链上事件,包括new batches{events中读取的信息->存储database}
      • 处理可能的reorgs {检查last ethBlockNum 和 last ethBlockHash 是否已同步}
    • State子模块
      • 实现了Merkle Tree并连接到DB后台
        • 在block level检查integrity(即,关于gas、block size等相关信息)
        • 检查某些交易相关信息(如签名、足够的balance等)
        • 将smart contract(SC)代码存储到Merkle tree中,并使用EVM来处理交易
    • Sequencer
      • 支持模式:Trusted/Permissionless
      • 处理流程:接收L2交易+L2用户支付的交易手续费 -> 对L2交易进行排序 ->生成batches -> send tx{sequences形式}(为Aggregator验证支付费用) -> L1合约 {PolygonZkEVM.sol} -> 存储storage slots
      • 经济模型:向L1提交有效交易,以获利
        • 根据利润对pool中交易排序
        • 向L1提交batches,支付L1系统代币
    • Aggregator
      • 处理流程:L1合约 {PolygonZkEVM.sol} -> 获取Sequencer提交的L2 batches -> zkProver{特殊链下EVM解析器} -> 生成ZK proof{证明该batch的完整性}-> send tx -> L1合约 {PolygonZkEVM.sol} -> 更新 L2 State root
      • 经济模型:Sequencers提交L1 batch时支付的手续费
      • 开支
        • 向L1提交validity proof交易成本
        • 运行aggregator和zkProver服务器成本
  • Consensus Contract(PolygonZkEVM.sol)

    • 存储Sequencers提交的L2 batches
    • 对Aggregator新提交的L2 State root进行validity proof验证
  • zkProver

    • 本质:zk virtual machine来仿真EVM
    • 功能:为Aggregator使用,来验证batches并提供validity proofs
    • 生成proof:以多项式和汇编语言形式
    • 功能包含如下
      • Main State Machine Executor:处理zkEVM的执行
        • 使用zkASM解析EVM Bytecodes
        • 为每个transaction batch设置多项式约束
        • 对多项式约束使用PIL进行编码
      • secondary State Machines : zkEVM中证明交易正确性的每一步计算
        • zkProver是整个项目中最复杂的部分,包含了多个state machines:
          • 一些执行bitwise function的state machines(如XOR/Padding等等)
          • 执行哈希运算的的state machines(如Keccak、Poseidon等等)
          • 执行验签的state machines(如ECDSA等等)
        • 二级状态机有:
          • Binary SM
          • Memory SM
          • Storage SM
          • Poseidon SM
          • Keccak SM
          • Arithmetic SM
      • STARK-proof builder
        • State machines负责生成多项式约束,zk-STARKs用于证明batches满足这些多项式约束条件
        • zkProver使用FRI对zk-STARK证明加速
      • SNARK-proof builder
        • size: STARK-proof > SNARK-proof
          • SNARK-proof来证明STARK-proof的正确性
          • SNARK-proof做为validity proof
          • 更便宜地在L1上验证该validity proof
  • L1-to-L2 Bridge

    • L1 Contract:部署在以太坊,管理rollups之间的资产转移

      负责2个操作

      • bridge:将资产由一个rollup转移到另一个rollup

      • claim:当合约从任意rollup claim时,使用claim操作

      需要有2棵Merkle tree

      • globalExitTree:包括了所有rollups的exit trees的所有信息

      • mainnet exit tree:包含了用户与主网交互的交易信息

      global exit root manager L1的合约负责管理跨越多个网络的exit roots

    • L2 Contract:部署在某特定的rollup上,负责主网与该rollup之间的资产转移

      • 处理rollup端的bridge和claim操作
      • 与globalExitTree和rollup exit tree交互以更新exit roots

共识算法PoE

Hermez 1.0 PoD共识缺点

  • 特定时间,网络由单一actor控制,可能作弊
  • 竞价协议,预测复杂性高
  • 参与竞争运营门槛高,导致运营集中,抗审查

Proof-of-Efficiency(PoE)实现

  • Sequencer:负责将L2的交易打包为batches并添加到L1的PoE智能合约
  • Aggregator:之间竞争,负责检查transaction batches的有效性,并提供validity proofs

PoE智能合约基本接口

  • sendBatch:用于接收Sequencer的batches
  • validateBatch:用于接收Aggregator的validity proof,进行validate batches

batch fee

根据网络负载情况,batch fee将是可变的,可根据protocol合约中的某个参数来计算

PoE的经济模型

  • Sequencer赚L2的交易手续费{相应的validity proof提交后}
  • Aggregator赚取Sequencer支付的batch MATIC手续费

Goerli 与zkEVM Testnet跨链测试

使用Polygon zkEVM Bridge 站点,将网络添加到我们的钱包,并将 Goerli Token 桥接到 zkEVM Testnet:

Goerli Token转0.01 ETH到zkEVM Testnet

交易:0x10210572d6b4924af7ef946136295e9b209e1fa0 -> 0xf6beeebb578e214ca9e23b0e9683454ff88ed2a7
tx hash: https://goerli.etherscan.io/tx/0x07aa6363c5854180b41b8c4584314ca6d6af989d48332375f06f9caef3270dd7

执行合约

bridgeAsset(uint32 destinationNetwork,address destinationAddress,uint256 amount,address token,bool forceUpdateGlobalExitRoot,bytes permitData)

执行参数

Name Type Data
0 destinationNetwork uint32 1
1 destinationAddress address 0x10210572d6b4924Af7Ef946136295e9b209E1FA0
2 amount uint256 10000000000000000
3 token address 0x0000000000000000000000000000000000000000
4 forceUpdateGlobalExitRoot bool true
5 permitData bytes

0xF6BEEeBB578e214CA9E23B0e9683454Ff88Ed2A7为代理合约,使用EIP-1967 Transparent Proxy
逻辑合约地址:0x39e780D8800f7396e8B7530A8925B14025AedC77
关键逻辑合约代码:https://goerli.etherscan.io/address/0x39e780d8800f7396e8b7530a8925b14025aedc77#code

合约bridgeAsset接口源码

/**
     * @notice Deposit add a new leaf to the merkle tree
     * @param destinationNetwork Network destination
     * @param destinationAddress Address destination
     * @param amount Amount of tokens
     * @param token Token address, 0 address is reserved for ether
     * @param forceUpdateGlobalExitRoot Indicates if the new global exit root is updated or not
     * @param permitData Raw data of the call `permit` of the token
     */
    function bridgeAsset(
        uint32 destinationNetwork,
        address destinationAddress,
        uint256 amount,
        address token,
        bool forceUpdateGlobalExitRoot,
        bytes calldata permitData
    ) public payable virtual ifNotEmergencyState nonReentrant {
        if (
            destinationNetwork == networkID ||
            destinationNetwork >= _CURRENT_SUPPORTED_NETWORKS
        ) {
            revert DestinationNetworkInvalid();
        }

        address originTokenAddress;
        uint32 originNetwork;
        bytes memory metadata;
        uint256 leafAmount = amount;

        if (token == address(0)) {
            // Ether transfer
            if (msg.value != amount) {
                revert AmountDoesNotMatchMsgValue();
            }

            // Ether is treated as ether from mainnet
            originNetwork = _MAINNET_NETWORK_ID;
        } else {
            // Check msg.value is 0 if tokens are bridged
            if (msg.value != 0) {
                revert MsgValueNotZero();
            }

            TokenInformation memory tokenInfo = wrappedTokenToTokenInfo[token];

            if (tokenInfo.originTokenAddress != address(0)) {
                // The token is a wrapped token from another network

                // Burn tokens
                TokenWrapped(token).burn(msg.sender, amount);

                originTokenAddress = tokenInfo.originTokenAddress;
                originNetwork = tokenInfo.originNetwork;
            } else {
                // Use permit if any
                if (permitData.length != 0) {
                    _permit(token, amount, permitData);
                }

                // In order to support fee tokens check the amount received, not the transferred
                uint256 balanceBefore = IERC20Upgradeable(token).balanceOf(
                    address(this)
                );
                IERC20Upgradeable(token).safeTransferFrom(
                    msg.sender,
                    address(this),
                    amount
                );
                uint256 balanceAfter = IERC20Upgradeable(token).balanceOf(
                    address(this)
                );

                // Override leafAmount with the received amount
                leafAmount = balanceAfter - balanceBefore;

                originTokenAddress = token;
                originNetwork = networkID;

                // Encode metadata
                metadata = abi.encode(
                    _safeName(token),
                    _safeSymbol(token),
                    _safeDecimals(token)
                );
            }
        }

        emit BridgeEvent(
            _LEAF_TYPE_ASSET,
            originNetwork,
            originTokenAddress,
            destinationNetwork,
            destinationAddress,
            leafAmount,
            metadata,
            uint32(depositCount)
        );

        _deposit(
            getLeafValue(
                _LEAF_TYPE_ASSET,
                originNetwork,
                originTokenAddress,
                destinationNetwork,
                destinationAddress,
                leafAmount,
                keccak256(metadata)
            )
        );
        // Update the new root to the global exit root manager if set by the user
        if (forceUpdateGlobalExitRoot) {
            _updateGlobalExitRoot();
        }
    }

// TODO 代码分析

等待zkevm-test处理完成

zkevm-test处理完成

Bridge Details

zkevm-test 对应交易

交易 0xa49d20f2f5a26d4a8e6fe44409f862d744f5b1aa -> 0xf6beeebb578e214ca9e23b0e9683454ff88ed2a7
tx hash: https://testnet-zkevm.polygonscan.com/tx/0x830ac94e69eb9e3aacd384d4db8a46e7830b8f99b12b5c6b5176bd8326fddc4b

执行方法

claimAsset(bytes32[32] smtProof,uint32 index,bytes32 mainnetExitRoot,bytes32 rollupExitRoot,uint32 originNetwork,address originTokenAddress,uint32 destinationNetwork,address destinationAddress,uint256 amount,bytes metadata)

执行参数

# Name Type Data
0 smtProof bytes32[32] 0x0000000000000000000000000000000000000000000000000000000000000000 0x5c4dafd55279a81649518c48d62f1e9105c9e7f5a8933aa2fce126d207755c14 0x890afe4ec8996c6ddd3977287b067f0f67dd25cd11cda85b22a93deac5675cdd 0xb6b78f0847e6ecdfc18ee568a1349fae5f336bdce9716be04db241b68b8dd60b 0x18dd01806c4a8a02ac0303f33fe609a944d81197cb52e8b8e159fbf9e45f12ed 0x0eb01ebfc9ed27500cd4dfc979272d1f0913cc9f66540d7e8005811109e1cf2d 0x4ac259557eb77da7cf4309feb02d02d0884d94e56bbf71f539bb3871e5c5f0db 0xffd70157e48063fc33c97a050f7f640233bf646cc98d9524c6b92bcf3ab56f83 0x08f9cb503a809cc64017397ec880786e6713c3ba6a85c181d02ae7536e9b58e3 0xcefad4e508c098b9a7e1d8feb19955fb02ba9675585078710969d3440f5054e0 0xf9dc3e7fe016e050eff260334f18a5d4fe391d82092319f5964f2e2eb7c1c3a5 0xa647f1787afe7ec81c77a49649ba32057b0550470d3c9318dda05fcb8168d914 0xe1f88e3362870dcdb9c43a352e2b031a0c71080b78cc2a5732c3a5c1c0c8e3b4 0xc1df82d9c4b87413eae2ef048f94b4d3554cea73d92b0f7af96e0271c691e2bb 0x5c67add7c6caf302256adedf7ab114da0acfe870d449a3a489f781d659e8becc 0xda7bce9f4e8618b6bd2f4132ce798cdc7a60e7e1460a7299e3c6342a579626d2 0x645b9978ad76c57db977fe48efb0b43110e3ebe78f9badd9047aac6bcd8d66a5 0xe1d3b5c807b281e4683cc6d6315cf95b9ade8641defcb32372f1c126e398ef7a 0x5a2dce0a8a7f68bb74560f8f71837c2c2ebbcbf7fffb42ae1896f13f7c7479a0 0xb46a28b6f55540f89444f63de0378e3d121be09e06cc9ded1c20e65876d36aa0 0xc65e9645644786b620e2dd2ad648ddfcbf4a7e5b1a3a4ecfe7f64667a3f0b7e2 0xf4418588ed35a2458cffeb39b93d26f18d2ab13bdce6aee58e7b99359ec2dfd9 0x5a9c16dc00d6ef18b7933a6f8dc65ccb55667138776f7dea101070dc8796e377 0x4df84f40ae0c8229d0d6069e5c8f39a7c299677a09d367fc7b05e3bc380ee652 0xcdc72595f74c7b1043d0e1ffbab734648c838dfb0527d971b602bc216c9619ef 0x0abf5ac974a1ed57f4050aa510dd9c74f508277b39d7973bb2dfccc5eeb0618d 0xb8cd74046ff337f0a7bf2c8e03e10f642c1886798d71806ab1e888d9e5ee87d0 0x838c5655cb21c6cb83313b5a631175dff4963772cce9108188b34ac87c81c41e 0x662ee4dd2dd7b2bc707961b1e646c4047669dcb6584f0d8d770daf5d7e7deb2e 0x388ab20e2573d171a88108e79d820e98f26c0b84aa8b2f4aa4968dbb818ea322 0x93237c50ba75ee485f4c22adf2f741400bdf8d6a9cc7df7ecae576221665d735 0x8448818bb4ae4562849e949e17ac16e0be16688e156b5cf15e098c627c0056a9
1 index uint32 72030
2 mainnetExitRoot bytes32 0x8ac4bfc9b4381015f4d41ca9d127a0a4065827d9c61ae290ffbf401ae446a97a
3 rollupExitRoot bytes32 0xd226edaccb2a0c0dc760d2a670a84862a271af7916e0a289b286f61435378411
4 originNetwork uint32 0
5 originTokenAddress address 0x0000000000000000000000000000000000000000
6 destinationNetwork uint32 1

合约地址0xf6beeebb578e214ca9e23b0e9683454ff88ed2a7 为 EIP-1967 Transparent Proxy代理合约,代理的逻辑合约地址为0x39e780d8800f7396e8b7530a8925b14025aedc77
合约源码:https://testnet-zkevm.polygonscan.com/address/0x39e780d8800f7396e8b7530a8925b14025aedc77#code

/**
     * @notice Verify merkle proof and withdraw tokens/ether
     * @param smtProof Smt proof
     * @param index Index of the leaf
     * @param mainnetExitRoot Mainnet exit root
     * @param rollupExitRoot Rollup exit root
     * @param originNetwork Origin network
     * @param originTokenAddress  Origin token address, 0 address is reserved for ether
     * @param destinationNetwork Network destination
     * @param destinationAddress Address destination
     * @param amount Amount of tokens
     * @param metadata Abi encoded metadata if any, empty otherwise
     */
    function claimAsset(
        bytes32[_DEPOSIT_CONTRACT_TREE_DEPTH] calldata smtProof,
        uint32 index,
        bytes32 mainnetExitRoot,
        bytes32 rollupExitRoot,
        uint32 originNetwork,
        address originTokenAddress,
        uint32 destinationNetwork,
        address destinationAddress,
        uint256 amount,
        bytes calldata metadata
    ) external ifNotEmergencyState {
        // Verify leaf exist and it does not have been claimed
        _verifyLeaf(
            smtProof,
            index,
            mainnetExitRoot,
            rollupExitRoot,
            originNetwork,
            originTokenAddress,
            destinationNetwork,
            destinationAddress,
            amount,
            metadata,
            _LEAF_TYPE_ASSET
        );

        // Transfer funds
        if (originTokenAddress == address(0)) {
            // Transfer ether
            /* solhint-disable avoid-low-level-calls */
            (bool success, ) = destinationAddress.call{value: amount}(
                new bytes(0)
            );
            if (!success) {
                revert EtherTransferFailed();
            }
        } else {
            // Transfer tokens
            if (originNetwork == networkID) {
                // The token is an ERC20 from this network
                IERC20Upgradeable(originTokenAddress).safeTransfer(
                    destinationAddress,
                    amount
                );
            } else {
                // The tokens is not from this network
                // Create a wrapper for the token if not exist yet
                bytes32 tokenInfoHash = keccak256(
                    abi.encodePacked(originNetwork, originTokenAddress)
                );
                address wrappedToken = tokenInfoToWrappedToken[tokenInfoHash];

                if (wrappedToken == address(0)) {
                    // Get ERC20 metadata
                    (
                        string memory name,
                        string memory symbol,
                        uint8 decimals
                    ) = abi.decode(metadata, (string, string, uint8));

                    // Create a new wrapped erc20 using create2
                    TokenWrapped newWrappedToken = (new TokenWrapped){
                        salt: tokenInfoHash
                    }(name, symbol, decimals);

                    // Mint tokens for the destination address
                    newWrappedToken.mint(destinationAddress, amount);

                    // Create mappings
                    tokenInfoToWrappedToken[tokenInfoHash] = address(
                        newWrappedToken
                    );

                    wrappedTokenToTokenInfo[
                        address(newWrappedToken)
                    ] = TokenInformation(originNetwork, originTokenAddress);

                    emit NewWrappedToken(
                        originNetwork,
                        originTokenAddress,
                        address(newWrappedToken),
                        metadata
                    );
                } else {
                    // Use the existing wrapped erc20
                    TokenWrapped(wrappedToken).mint(destinationAddress, amount);
                }
            }
        }

        emit ClaimEvent(
            index,
            originNetwork,
            originTokenAddress,
            destinationAddress,
            amount
        );
    }

// TODO 代码分析

确认余额

https://testnet-zkevm.polygonscan.com/address/0x10210572d6b4924af7ef946136295e9b209e1fa0
// Note: Our ETH balance display is temporarily unavailable. Please check back later.
testnet-zkevm.polygonscan.com 浏览器余额出问题了,直接MetaMask查看

以正确到账

//TODO testnet-zkevm反向Goerli的转账跟踪

opside 跨链测试

Opside介绍

Opside 是一个三层区块链平台,形式为“Base chains <- Opside chain <- Rollups”。 它具有资产多样性和无限可扩展性等优势,为高吞吐量的web3应用提供友好的运行环境。

三层架构

测试三层跨链转账

1.MetaMask添加Opside测试网络信息

2.MetaMask添加Opside zkEVM 测试网络信息

3. 从水龙头获取代币

领取网址:https://faucet-testnet.opside.network/
领取时需要对指定消息进行签名

交易hash

https://opside.info/address/0x10210572d6b4924Af7Ef946136295e9b209E1FA0

领取代币类型和数量

MetaMask手动添加代币合约地址到资产

USDT:0xDEd24358C0d7C96BC419F479771D1da3443Fe52d
USDC:0x407d6E2bF44A1B70eBd51CcF0aFCFBbD5F0b6d15
VTP:0x956a81C7D7031Fd123961cC69C28a2a49884FC68

4. 测试第1层->第2层桥接

跨链桥网址: https://bridge-testnet.opside.network/

sepolia转1USDT到opside

// TODO

opside转1USDT到Opside zkEVM Testnet

跨链桥网址:https://zkbridge-testnet.opside.network/

  1. Approve USDT spending cap
    0x10210572d6b4924af7ef946136295e9b209e1fa0 -> 0xded24358c0d7c96bc419f479771d1da3443fe52d
    https://opside.info/tx/0xc0d592c5edcc533abddf83f0b38c40a4099ef2ef3de0b6fd862048df24b06036
  2. Bridge Asset
    0x10210572d6b4924af7ef946136295e9b209e1fa0 -> 0xfb15d16f87ad92f0a6d54a9fbc951676701071f9
    https://opside.info/tx/0x1d2dfc8ce07e3039b46e92f27a7bbd5dc461874f4b5020ee3931b0b12804db04

备注:https://testrpc.zkevm.opside.network/bridge-service/bridges/0x10210572d6b4924af7ef946136295e9b209e1fa0?limit=10000&offset=0
测试时这个API,ssl证书有问题:ERR_SSL_VERSION_OR_CIPHER_MISMATCH

Opside zkRollup L3 测试网的RPC同样问题 ERR_SSL_VERSION_OR_CIPHER_MISMATCH
https://testrpc.zkevm.opside.network/

// TODO 等待解决后继续测试,先忙其他

opside转1USDT到sepolia

  1. Approve USDT spending cap
    0x10210572d6b4924af7ef946136295e9b209e1fa0 -> 0x10210572d6b4924af7ef946136295e9b209e1fa0
    https://opside.info/tx/0xca2d7fdf791b7432a3e2067bc814ce9ca66ad2163d55bc805743fad6996ffc98
  2. Deposit
    0x10210572d6b4924af7ef946136295e9b209e1fa0 -> 0x832e50eec9d7f9e2b5d4286a5834400dfaeafc3f
    https://opside.info/tx/0x6b6a505b4aa1aa4b314d5b69a316713d6443f0092e7e9f2b96e8b18bc8778fe6
  3. sepolia.etherscan
    0x91b126ff9af242408090a223829eb88a61724aa5 -> 0xe8b0a865e4663636bf4d6b159c57333210b0c229
    ERC-20 Tokens Transferred: 0x89a5f2c62213b18ee5f83b21cb1a323920c9b101 -> 0x10210572d6b4924af7ef946136295e9b209e1fa0
    https://sepolia.etherscan.io/tx/0x369078b11063231d35738c6afcde52477c5fe5dd78535c9f282f1e36fcac5de8
    获得1 USDT

    https://sepolia.etherscan.io/token/0x969d499507b4f437953db24a4980fdeeda6db8a1?a=0x10210572d6b4924Af7Ef946136295e9b209E1FA0

参考文档

https://docs.opside.network/
https://docs.opside.network/user-guides/video-tutorial