您正在查看: 2024年11月

Solana 手续费燃烧设置

背景

Solana 默认配置手续费会燃烧50%,有些时候不需要燃烧

配置

先直接说如何配置
拿multinode-demo/setup.sh 举例,初始化genesis时,传入 --fee-burn-percentage 0
例如尾部加一行

...
default_arg --fee-burn-percentage 0

$solana_genesis "${args[@]}"

代码分析

genesis创建时,会读取传入参数

genesis/src/main.rs

...
.arg(
    Arg::with_name("fee_burn_percentage")
    .long("fee-burn-percentage")
    .value_name("NUMBER")
    .takes_value(true)
    .default_value(default_fee_burn_percentage)
    .help("percentage of collected fee to burn")
    .validator(is_valid_percentage),
)
...

手续费派发逻辑

runtime/src/bank/fee_distribution.rs

pub(super) fn distribute_transaction_fees(&self) {
        let collector_fees = self.collector_fees.load(Relaxed);
        if collector_fees != 0 {
            let (deposit, mut burn) = self.fee_rate_governor.burn(collector_fees); // 燃烧一定比例
            if deposit > 0 {
                let validate_fee_collector = self.validate_fee_collector_account();
                match self.deposit_fees(
                    &self.collector_id,
                    deposit,
                    DepositFeeOptions {
                        check_account_owner: validate_fee_collector,
                        check_rent_paying: validate_fee_collector,
                    },
                ) {
                    Ok(post_balance) => {
                        self.rewards.write().unwrap().push((
                            self.collector_id,
                            RewardInfo {
                                reward_type: RewardType::Fee,
                                lamports: deposit as i64,
                                post_balance,
                                commission: None,
                            },
                        ));
                    }
                    Err(err) => {
                        debug!(
                            "Burned {} lamport tx fee instead of sending to {} due to {}",
                            deposit, self.collector_id, err
                        );
                        datapoint_warn!(
                            "bank-burned_fee",
                            ("slot", self.slot(), i64),
                            ("num_lamports", deposit, i64),
                            ("error", err.to_string(), String),
                        );
                        burn += deposit;
                    }
                }
            }
            self.capitalization.fetch_sub(burn, Relaxed);
        }
    }

sdk/program/src/fee_calculator.rs

pub fn burn(&self, fees: u64) -> (u64, u64) {
    let burned = fees * u64::from(self.burn_percent) / 100;
    (fees - burned, burned)
}

Solana Hello World(安装和故障排除)

这是 Solana 的 Hello World 教程。我们将引导您完成安装 Solana 的步骤并解决可能出现的问题。
如果您遇到问题,请查看本文末尾的故障排除部分。

安装步骤

安装 Rust

如果您已经安装了 Rust,请跳过此步骤。

# install rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

安装 Yarn

您需要它来运行单元测试。如果您已经安装了 yarn,请跳过此步骤。

# install yarn -- assumes node js is installed
corepack enable # corepack comes with node js

安装 Solana cli

我们强烈建议使用stable版本,而不是latest。 Solana 安装不再支持符号通道名称(edge、beta、stable),因此我们必须指定版本。

# install solana
sh -c "$(curl -sSfL https://release.solana.com/v1.16.25/install)"

安装锚点

Anchor 是 Solana 开发的框架。它在很多方面与 hardhat 非常相似。

# install anchor
cargo install --git https://github.com/coral-xyz/anchor avm --locked --force

avm install latest
avm use latest

测试安装

初始化并构建一个锚点程序(用于 hello world)

Mac 用户:我们建议调用您的程序day_1而不是day1因为 Anchor 有时似乎会在 Mac 机器上默默插入下划线。

anchor init day1 # use day_1 if you have a mac
cd day1
anchor build

根据您的机器和互联网连接,此步骤可能需要一段时间。这也是您可能遇到安装问题的地方,因此如有必要,请参阅故障排除部分。

配置 Solana 在本地主机上运行

# shell 1
solana config set --url localhost

运行测试验证器节点

在新的 shell 中(而不是在 Anchor 项目中)运行以下命令。但不要关闭运行的 shell anchor build。这会在您的机器上运行本地(测试)Solana 节点实例:

# shell 2

solana-test-validator

确保 program_id 与 Anchor 键同步

返回 Anchor 项目的 shell 并运行以下命令:

# shell 1

anchor keys sync

运行测试

在 Anchor 项目中运行此命令

# shell 1

anchor test --skip-local-validator

上面的命令运行我们程序的测试。如果您尚未创建测试钱包,Anchor 将为您提供如何创建钱包的说明。我们在此不提供这些说明,因为它取决于您的操作系统和文件结构。您可能还需要通过在终端中运行来为自己空投一些本地 Sol 。您可以通过在命令行中solana airdrop 100 {YOUR_WALLET_ADDRESS}运行来获取您的钱包地址。solana address
预期输出如下:

你好世界

现在让我们让程序输出“Hello, world!”。将以下标有 的行添加NEW LINE HERE到programs/day_1/src/lib.rs。

use anchor_lang::prelude::*;

declare_id!("...");

#[program]
pub mod day_1 {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        msg!("Hello, world!"); // **** NEW LINE HERE ****
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize {}

再次运行测试之前,请终止本地验证器进程并使用以下命令重新启动它:

solana-test-validator --reset

再次运行测试

anchor test --skip-local-validator

通过运行查找日志文件

ls .anchor/program-logs/

打开该文件即可看到记录的“Hello world”

实时 Solana 日志

或者,您可以通过打开第三个 shell 并运行以下命令来查看日志:

# shell 3

solana logs

现在再次运行测试,您应该在运行的终端中看到相同的消息solana logs。

问答

为什么 declared_id! 和 msg! 后面有感叹号?

在 Rust 中,感叹号表示这些是宏。我们将在后面的教程中重新讨论宏。

我需要一个初始化函数吗?

不,这是由 Anchor 框架自动生成的。您可以随意命名。

在此上下文中,initialize 这个名称没有什么特殊之处,因此我们可以将其更改为任何我们喜欢的名称。这与其他一些关键字和语言不同,例如 main 在某些语言中是一个特殊名称,或者在 Solidity 中,constructor 是一个特殊名称。
练习:尝试将initialize中的programs/day_1/src/lib.rs和initialize中的重命名为 ,tests/day_1.ts然后initialize2再次运行测试。请参见下面橙色圆圈中标记的更改。

为什么我们要使用 –skip-local-validator 来运行测试?

当测试针对某个节点运行时,我们将能够查询该节点的状态变化。如果您无法让节点运行,则可以anchor test在不使用--skip-local-validator标志的情况下运行。但是,这将使您的开发和测试变得更加困难,因此我们建议让本地验证器正常工作。

故障排除

Solana 是一款快速发展的软件,您可能会遇到安装问题。我们在以下部分记录了您最有可能遇到的问题。
我们的教程系列使用以下版本编写: Anchor = 版本 0.29.0 Solana = 版本 1.16.25 * Rustc = 1.77.0-nightly
您可以通过运行以下命令来更改 Anchor 版本:

avm install 0.29.0
avm use 0.29.0

错误:solana-program v1.18.0无法构建包

error: package `solana-program v1.18.0` cannot be built because it requires rustc 1.72.0 or newer, while the currently active rustc version is 1.68.0-dev
Either upgrade to rustc 1.72.0 or newer, or use
cargo update -p solana-program@1.18.0 --precise ver

检查您正在使用的 Solana 版本solana --version。然后将该版本插入到ver上面的内容中。示例解决方案如下所示:

错误[E0658]:使用不稳定库功能“build_hasher_simple_hash_one”

如果出现以下错误:

error[E0658]: use of unstable library feature 'build_hasher_simple_hash_one'
--> src/random_state.rs:463:5
|
463 | / fn hash_one<T: Hash>(&self, x: T) -> u64 {
464 | | RandomState::hash_one(self, x)
465 | | }
| |_____^
|
= note: see issue #86161 https://github.com/rust-lang/rust/issues/86161 for more information
= help: add #![feature(build_hasher_simple_hash_one)] to the crate attributes to enable

运行以下命令:cargo update -p ahash@0.8.7 --precise 0.8.6。

来源:https ://solana.stackexchange.com/questions/8800/cant-build-hello-world

错误:部署程序失败:错误处理指令 1:自定义程序错误:0x1

Error: Deploying program failed: Error processing Instruction 1: custom program error: 0x1
There was a problem deploying: Output { status: ExitStatus(unix_wait_status(256)), stdout: "", stderr: "" }.

如果出现此错误,则表示您的密钥未同步。运行anchor keys sync。

错误:无法发送交易:交易模拟失败:尝试加载不存在的程序

您的密钥未同步。运行anchor keys sync。

错误:您配置的 rpc 端口:8899 已被使用

当验证器在后台运行时,您anchor test没有运行--skip-local-validator。请关闭验证器并运行,anchor test或在验证器运行时运行anchor test --skip-local-validator。跳过本地验证器意味着跳过它为项目创建的临时验证器,而不是在后台运行的验证器。

错误:帐户 J7t…zjK 资金不足,无法消费

运行以下命令将 100 SOL 空投到您的开发地址:

solana airdrop 100 J7t...zjK

错误:RPC 请求错误:集群版本查询失败

Error: RPC request error: cluster version query failed: error sending request for url (http://localhost:8899/): error trying to connect: tcp connect error: Connection refused (os error 61)
There was a problem deploying: Output { status: ExitStatus(unix_wait_status(256)), stdout: "", stderr: "" }.

这意味着solana-test-validator不在后台运行。solana-test-validator在另一个 shell 中运行。

线程“main”因“调用Option::unwrap()某个None值”而惊慌失措

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /Users/username/.cargo/git/checkouts/anchor-50c4b9c8b5e0501f/347c225/lang/syn/src/idl/file.rs:214:73
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

你可能还没跑anchor build。

我在使用 Mac,出现错误:无法启动验证器:无法在测试分类账中创建分类账:块存储错误

按照此Stack Exchange 线程中的说明进行操作。

我的 Mac 上有 node.js,但是没有 corepack

运行以下命令:

brew install corepack
brew link --overwrite corepack

来源:https ://stackoverflow.com/questions/70082424/command-not-found-corepack-when-installing-yarn-on-node-v17-0-1

错误:不是目录:

BPF SDK: /Users/rareskills/.local/share/solana/install/releases/stable-43daa37937907c10099e30af10a5a0b43e2dd2fe/solana-release/bin/sdk/bpf
cargo-build-bpf child: rustup toolchain list -v
cargo-build-bpf child: rustup toolchain link bpf /Users/rareskills/.local/share/solana/install/releases/stable-43daa37937907c10099e30af10a5a0b43e2dd2fe/solana-release/bin/sdk/bpf/dependencies/bpf-tools/rust
error: not a directory:

清除缓存:运行rm -rf ~/.cache/solana/*。

错误:target/idl/day_1.json 不存在。您运行了吗anchor build?

创建一个新项目并将其命名为 day_1 而不是 day1。Anchor 似乎会在某些机器上默默插入下划线。

原文:https://www.rareskills.io/post/hello-world-solana

如何查看infura是否稳定

背景

一些服务为了稳定和省去自己维护同步节点,常会使用infura 类似的三方节点服务,但有时服务报访问不稳定,需要排查下infura官方服务是否有异常

查看对应类型网关,一段时间内是否有异常

https://status.infura.io/

查看对外通知

https://status.infura.io/history

解决方式

使用多个三方RPC提供方,通过类似 eRPC服务实现高容错

Solana 中的 Tx.origin、msg.sender 和 onlyOwner:识别调用者

在 Solidity 中,msg.sender是一个全局变量,表示调用或发起智能合约函数调用的地址。全局变量tx.origin是签署交易的钱包。
在 Solana 中,没有与 等效的东西msg.sender。
有一个等效的tx.origin,但是你应该知道 Solana 交易可以有多个签名者,所以我们可以将其视为具有“多个 tx.origins”。
要在 Solana 中获取“ tx.origin”地址,需要通过将 Signer 帐户添加到函数上下文来设置它,并在调用函数时将调用者的帐户传递给它。
让我们看一个如何在 Solana 中访问交易签名者地址的示例:

use anchor_lang::prelude::*;

declare_id!("Hf96fZsgq9R6Y1AHfyGbhi9EAmaQw2oks8NqakS6XVt1");

#[program]
pub mod day14 {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let the_signer1: &mut Signer = &mut ctx.accounts.signer1;

        // Function logic....

        msg!("The signer1: {:?}", *the_signer1.key);

        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub signer1: Signer<'info>,
}

从上面的代码片段来看,Signer<'info>用于验证账户结构signer1中的账户Initialize<'info>是否签署了交易。
在initialize函数中,signer1帐户从上下文中可变地引用并分配给the_signer1变量。
最后,我们使用宏并传入来记录signer1的公钥(地址),它取消引用并访问指向的实际值上的字段或方法。msg!*the_signer1.keykeythe_signer1

接下来就是针对上面的程序编写测试:

describe("Day14", () => {
  // Configure the client to use the local cluster.
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.Day14 as Program<Day14>;

  it("Is signed by a single signer", async () => {
    // Add your test here.
    const tx = await program.methods.initialize().accounts({
      signer1: program.provider.publicKey
    }).rpc();

    console.log("The signer1: ", program.provider.publicKey.toBase58());
  });
});

测试中,我们将钱包账户作为 signer 传入账户signer1,然后调用初始化函数,最后在控制台上打印钱包账户,验证和程序中的一致。
练习:运行测试后,你从shell_1(命令终端)和shell_3 (日志终端)的输出中注意到了什么?

多名签名者

在 Solana 中,我们还可以让多个签名者签署一笔交易,你可以将其视为批量处理一堆签名并将其发送至一笔交易中。一个用例是在一笔交易中执行多重签名交易。
为此,我们只需在程序中的帐户结构中添加更多签名者结构,然后确保在调用函数时传递必要的帐户:

use anchor_lang::prelude::*;

declare_id!("Hf96fZsgq9R6Y1AHfyGbhi9EAmaQw2oks8NqakS6XVt1");

#[program]
pub mod day14 {
    use super::*;

    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        let the_signer1: &mut Signer = &mut ctx.accounts.signer1;
        let the_signer2: &mut Signer = &mut ctx.accounts.signer2;

        msg!("The signer1: {:?}", *the_signer1.key);
        msg!("The signer2: {:?}", *the_signer2.key);

        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    pub signer1: Signer<'info>,
    pub signer2: Signer<'info>,
}

上述示例与单个签名者示例有些相似,但有一个明显的区别。在本例中,我们signer2在结构中添加了另一个签名者帐户()Initialize,并在初始化函数中记录了两个签名者的公钥。

与单个签名者相比,使用多个签名者调用初始化函数有所不同。以下测试显示了如何使用多个签名者调用函数:

describe("Day14", () => {
  // Configure the client to use the local cluster.
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.Day14 as Program<Day14>;

  // generate a signer to call our function
  let myKeypair = anchor.web3.Keypair.generate();

  it("Is signed by multiple signers", async () => {
    // Add your test here.
    const tx = await program.methods
      .initialize()
      .accounts({
        signer1: program.provider.publicKey,
        signer2: myKeypair.publicKey,
      })
      .signers([myKeypair])
      .rpc();

    console.log("The signer1: ", program.provider.publicKey.toBase58());
    console.log("The signer2: ", myKeypair.publicKey.toBase58());
  });
});

那么上述测试有什么不同?首先是signers()方法,它接受一个签名者数组,这些签名者将对交易进行签名作为参数。但是数组中只有一个签名者,而不是两个。Anchor 会自动将提供商中的钱包账户作为签名者传递,因此我们不需要再次将其添加到签名者数组中。

生成随机地址进行测试

第二个变化是变量,它存储模块随机生成的myKeypair密钥对(用于访问帐户的公钥和相应的私钥anchor.web3) 。在测试中,我们将密钥对(存储在myKeypair变量中)的公钥分配给signer2帐户,这就是为什么它作为参数传递到.signers([myKeypair])方法中的原因。

多次运行测试,你会注意到signer1pubkey 没有改变,但signer2pubkey 发生了变化。这是因为分配给该signer1账户的钱包账户(在测试中)来自提供商,这也是你本地机器中的 Solana 钱包账户,并且分配给的账户signer2是每次运行时随机生成的anchor test —skip-local-validator。

练习:创建另一个需要三个签名者(提供者钱包账户和两个随机生成的账户)的函数(您可以随意称呼它),并为其编写测试。

唯一所有者

这是 Solidity 中常用的模式,用于将函数的访问权限限制为合约所有者。使用#[access_control]Anchor 中的属性,我们还可以实现唯一所有者模式,即将 Solana 程序中函数的访问权限限制为 PubKey(所有者的地址)。

以下是如何在 Solana 中实现“onlyOwner”功能的示例:

use anchor_lang::prelude::*;

declare_id!("Hf96fZsgq9R6Y1AHfyGbhi9EAmaQw2oks8NqakS6XVt1");

// NOTE: Replace with your wallet's public key
const OWNER: &str = "8os8PKYmeVjU1mmwHZZNTEv5hpBXi5VvEKGzykduZAik";

#[program]
pub mod day14 {
    use super::*;

    #[access_control(check(&ctx))]
    pub fn initialize(ctx: Context<OnlyOwner>) -> Result<()> {
        // Function logic...

        msg!("Holla, I'm the owner.");
        Ok(())
    }
}

fn check(ctx: &Context<OnlyOwner>) -> Result<()> {
    // Check if signer === owner
    require_keys_eq!(
        ctx.accounts.signer_account.key(),
        OWNER.parse::<Pubkey>().unwrap(),
        OnlyOwnerError::NotOwner
    );

    Ok(())
}

#[derive(Accounts)]
pub struct OnlyOwner<'info> {
    signer_account: Signer<'info>,
}

// An enum for custom error codes
#[error_code]
pub enum OnlyOwnerError {
    #[msg("Only owner can call this function!")]
    NotOwner,
}

在上述代码的上下文中,OWNER变量存储与我的本地 Solana 钱包关联的公钥(地址)。在测试之前,请务必将 OWNER 变量替换为您的钱包的公钥。您可以通过运行solana address命令轻松检索您的公钥。

该#[access_control]属性在运行主指令之前执行给定的访问控制方法。调用初始化函数时,访问控制方法 ( check) 先于初始化函数执行。该check方法接受引用的上下文作为参数,然后检查交易的签名者是否等于OWNER变量的值。require_keys_eq!宏确保两个公钥值相等,如果相等,则执行初始化函数,否则,将使用自定义错误进行恢复NotOwner。

测试 onlyOwner 功能 — 令人满意的情况

在下面的测试中,我们调用初始化函数并使用所有者的密钥对签署交易:

import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { Day14 } from "../target/types/day14";

describe("day14", () => {
  // Configure the client to use the local cluster.
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.Day14 as Program<Day14>;

  it("Is called by the owner", async () => {
    // Add your test here.
    const tx = await program.methods
      .initialize()
      .accounts({
        signerAccount: program.provider.publicKey,
      })
      .rpc();

    console.log("Transaction hash:", tx);
  });
});

我们调用了初始化函数,并将提供程序中的钱包账户(本地 Solana 钱包账户signerAccount)传递给具有结构体的Signer<'info>,以验证钱包账户是否确实签署了交易。 另请记住,Anchor 使用提供程序中的钱包账户秘密签署任何交易。

运行测试anchor test --skip-local-validator,如果一切正确完成,测试应该通过:

测试签名者是否不是所有者——攻击案例

使用非所有者的其他密钥对来调用初始化函数并签署交易将引发错误,因为函数调用仅限于所有者:

describe("day14", () => {
  // Configure the client to use the local cluster.
  anchor.setProvider(anchor.AnchorProvider.env());

  const program = anchor.workspace.Day14 as Program<Day14>;

  let Keypair = anchor.web3.Keypair.generate();

  it("Is NOT called by the owner", async () => {
    // Add your test here.
    const tx = await program.methods
      .initialize()
      .accounts({
        signerAccount: Keypair.publicKey,
      })
      .signers([Keypair])
      .rpc();

    console.log("Transaction hash:", tx);
  });
});

这里我们生成了一个随机密钥对并用它来签署交易。让我们再次运行测试:

正如预期的那样,我们得到了一个错误,因为签名者的公钥不等于所有者的公钥。

修改所有者

要在程序中更改所有者,需要将分配给所有者的公钥存储在链上。不过,有关 Solana 中“存储”的讨论将在未来的教程中介绍。

所有者可以重新部署字节码。

练习:升级类似上述程序,以获得新的所有者。

英文原文:https://www.rareskills.io/post/msg-sender-solana

跨链桥跨链过程中数据变化

发起的两笔跨链交易 (L1->L2)
https://sepolia.etherscan.io/tx/0xd2db346f588d3eb9c90b0a9da2e8382d5c3275916288131f3701ae62bae56c44
https://sepolia.etherscan.io/tx/0x13a2ac45a973524d704463fe16d4d8e3410efc09cf6d3e53b6052c8a17ece4a4

bridge_db=# select * FROM sync.block;
 id | block_num |                             block_hash                             |                            parent_hash                             | network_id |      received_at       
----+-----------+--------------------------------------------------------------------+--------------------------------------------------------------------+------------+------------------------
  0 |           | \x5c7830                                                           |                                                                    |            | 1970-01-01 00:00:00+00
  1 |   7092388 | \xe984c5267a0e675df842c9ad91a1d0825080cfc581791250955a7a7dd41b71ab | \x5fcd8aa7d9b8650488fcfcf93db2c2dfb03100d02e2e0f927b0ee8d758dfb2b4 |          0 | 2024-11-17 01:21:24+00
  2 |   7092528 | \xcd588c08198efdbe40a4bfc731f906594dd0e80f78acff528a84bf36c8341f03 | \xec136b1e2d7fe0fd4fdb4c4c11cb1b5cc578c97e26d6073652a1d31702b12999 |          0 | 2024-11-17 01:51:36+00
bridge_db=# SELECT * FROM sync.deposit;

leaf_type | network_id | orig_net |                 orig_addr                  |         amount         | dest_net |                 dest_addr                  | block_id | deposit_cnt |                              tx_hash                               |                                                                                                                                                                                                                              metadata                                                                                                                                                                                                                              | id | ready_for_claim 
-----------+------------+----------+--------------------------------------------+------------------------+----------+--------------------------------------------+----------+-------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----+-----------------
         0 |          0 |        0 | \x3ec3d234625cde1e0f3267014e26e193610e50ac | 1000000000000000000000 |        1 | \xc2df13b6ad0753e0547a318f65f99ac62aec6e2b |        1 |           0 | \xd2db346f588d3eb9c90b0a9da2e8382d5c3275916288131f3701ae62bae56c44 | \x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000084d4158546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d41580000000000000000000000000000000000000000000000000000000000 |  1 | f
         0 |          0 |        0 | \x3ec3d234625cde1e0f3267014e26e193610e50ac | 2000000000000000000000 |        1 | \xc2df13b6ad0753e0547a318f65f99ac62aec6e2b |        2 |           1 | \x13a2ac45a973524d704463fe16d4d8e3410efc09cf6d3e53b6052c8a17ece4a4 | \x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000084d4158546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d41580000000000000000000000000000000000000000000000000000000000 |  2 | f

等待一段时间 ready_for_claim变为true

 leaf_type | network_id | orig_net |                 orig_addr                  |         amount         | dest_net |                 dest_addr                  | block_id | deposit_cnt |                              tx_hash                               |                                                                                                                                                                                                                              metadata                                                                                                                                                                                                                              | id | ready_for_claim 
-----------+------------+----------+--------------------------------------------+------------------------+----------+--------------------------------------------+----------+-------------+--------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----+-----------------
         0 |          0 |        0 | \x3ec3d234625cde1e0f3267014e26e193610e50ac | 1000000000000000000000 |        1 | \xc2df13b6ad0753e0547a318f65f99ac62aec6e2b |        1 |           0 | \xd2db346f588d3eb9c90b0a9da2e8382d5c3275916288131f3701ae62bae56c44 | \x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000084d4158546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d41580000000000000000000000000000000000000000000000000000000000 |  1 | t
         0 |          0 |        0 | \x3ec3d234625cde1e0f3267014e26e193610e50ac | 2000000000000000000000 |        1 | \xc2df13b6ad0753e0547a318f65f99ac62aec6e2b |        2 |           1 | \x13a2ac45a973524d704463fe16d4d8e3410efc09cf6d3e53b6052c8a17ece4a4 | \x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000084d4158546f6b656e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d41580000000000000000000000000000000000000000000000000000000000 |  2 | t

然后交易会被claimtxman模块,会调用L2桥合约进行相应资产的转出
注:首次部署时,跨链桥claim地址需要在genesis allocs中初始化一定代币,用于首次跨链的手续费