# 手把手教学编写BQL脚本程序

By [Port3 Network中文社区](https://paragraph.com/@port3-network-2) · 2023-10-11

---

BQL的概念
------

BQL（Blockchain Quest Language）是一种开放的链上交互标记语言。我们可以使用BQL描述链上操作并将其提交给执行器执行。将多个链上操作汇集成一个Workflow，从而实现链上交互的自动化、流程化执行。

BQL可以应用于各种场景中，例如：

1.  实现链上交易的批量交互，节省用户的操作时间。
    
2.  项目方可以通过BQL将用户直接转化为自己的协议用户。
    
3.  可以执行各种链上策略，例如低买高卖或跨平台套利。
    

BQL支持超过10条的EVM公链，理论上可以使用它完成与任何合约的链上交互。

BQL的结构
------

在编写BQL脚本之前，我们需要先简单了解BQL的语法结构。以下是本次教程使用的BQL Workflow脚本示例：

![Workflow脚本示例](https://storage.googleapis.com/papyrus_images/012ddc21ef564272692ccaef25b7f6f21b9b86f59097798c51ded1c2f3b35964.png)

Workflow脚本示例

BQL采用YAML语法结构，通过缩进来表达层级结构。与JSON结构相比，它们可以相互转换。在BQL脚本中，可以定义Workflow，并在其下添加多个Action。Action描述了如何执行链上交互，例如，指定要交互的协议、合约和方法，以及传递的具体参数。

使用BQL预定义的关键词（如workflow、action、protocol、call、params等），可以构建完整的脚本程序。在BQL脚本中，可以实现以下操作：

1.  定义和引用变量
    
2.  常规的加减乘除运算
    
3.  字符串的拼接和截取
    
4.  条件判断
    
5.  合约调用的参数传递和返回接收
    

要深入了解BQL，可以阅读BQL的[Specification](https://github.com/Port3-Network/bql-spec/blob/main/spec/v0.0.1/spec.md)。BQL是一种开放的语言，关键词和语法的定义还在试验阶段，BQL的标准也在梳理和形成中。但是，当前版本的BQL已能实现大多数合约交互操作。

如何编写BQL脚本？
----------

SoQuest提供了BQL编辑器，您可以直接在编辑器中编写BQL程序，类似于使用Remix进行Solidity编程。我们将以在PancakeSwap上进行USDC兑换成BNB的示例为例，演示BQL的编程过程。

### 创建BQL

我们可以在SoQuest的BQL发现广场上，看到社区编写的各种公开的BQL脚本，可以点击进入任意脚本查看详情，包括其代码、执行的日志等。我们可以直接将公开的脚本Fork到自己的Library里面，当然我们也可以自主编写一个BQL的Workflow脚本。

![BQL Templates in discovery page](https://storage.googleapis.com/papyrus_images/e756c1ebafc5b2019ebf726c8c018f4cea6c6a0f957bf63ce08b5db36448adcf.png)

BQL Templates in discovery page

创建一个BQL非常简单。只需在“BQL WORKFLOW-Discovery”页面上单击“Create My BQL”按钮即可创建BQL脚本。首先，我们需要为此脚本制定一个标题，并撰写一个简要的描述。

![Create BQL, fill in title and description](https://storage.googleapis.com/papyrus_images/19658ba06ee461a9d8f5a78f59d13567ecbd0a71f7fab49920a4728922cea869.png)

Create BQL, fill in title and description

### BQL代码生成

我们要撰写的 Swap USDC to BNB on PancakeSwap 需要两个步骤：

第一步：执行 USDC Token 的 Approve 操作，授权给 PancakeSwap 合约。

第二步：调用 PancakeSwap 的 Swap 方法，实现 USDC 到 BNB 的兑换。

SoQuest的BQL编辑器提供了便利的BQL代码生成辅助工具。点击"How it work"可以呼出编辑器导航，跟着导航一步一步走，选择要交互的网络、协议、合约、方法即可生成Action的模板。

![BQL Editor Navigator](https://storage.googleapis.com/papyrus_images/43298f92995083234e77aeb7d10db06510f6950439bcbd65b5514e83e01d57d3.png)

BQL Editor Navigator

### 实现Approve

接下来，我们将使用编辑器的BQL代码生成功能，实现第一步的批准（Approve）操作。

首先，在左侧选择区块链为“BNB Chain”，协议选择“ERC20”，合约选择“USDC”，调用的函数选择“approve”。然后，点击“生成 BQL”按钮，即可生成如下代码。

![Using BQL generator helper to generate step1 code](https://storage.googleapis.com/papyrus_images/2d08ec60ae604ad5ee85c2ba36dd2da315f052f32d76710bc40b50f1eeddf20e.png)

Using BQL generator helper to generate step1 code

为了生成代码，我们需要填入具体的参数。这要求具备一定的合约和链上交互知识，只有传入准确的参数，交易才会正确运行。

在这里，我们需要填入spender和amount两个参数，这是approve方法的标准参数。spender是被授权花费token的地址，我们应该填入PancakeSwap的Router地址（0x10ED43C718714eb63d5aA57B78B54704E256024E）。而amount则是授予的额度（这里假设为 2 USDC）。由于amount下面也要用到，为了避免反复填写，我们定义一个swap\_amount变量，然后通过引用的方式来使用。于是代码变成如下所示：

![Step1 - Approve USDC to PancakeSwap router](https://storage.googleapis.com/papyrus_images/5e24d41e4e95708effdbc03b13b6235f2c16e288f85839ea5a992093f279f549.png)

Step1 - Approve USDC to PancakeSwap router

第一步操作就这样完成了，执行过程中，执行器会自动和您的钱包交互，请求发送交易。

### 实现Swap

接下来要实现核心的第二步Swap操作。这次我们需要与PancakeSwap的Router合约进行交互。因此，我们在左侧依次选择：BNB Chain - PancakeSwap - PancakeSwap Router - swapExactTokenForETH。然后点击“Generate BQL”，即可生成下面所示的代码块。

![Using BQL generator helper to generate step2 codes](https://storage.googleapis.com/papyrus_images/b01681c13d37f951a357908e21fd150c236115809800325dafb59ce78a6380f6.png)

Using BQL generator helper to generate step2 codes

生成的第二个action，需要填入amountIn等五个参数，我们依次填入。

![参数如下⬇️](https://storage.googleapis.com/papyrus_images/433f05f6dc7d5fc5deb897f54ec89af3832caf665bce4b5f4ac5f83342f34b09.png)

参数如下⬇️

**amountIn:** 输入的金额，我们依然填 $swap\_amount

**amountOutMin:** 表示兑换得到的最小的BNB金额，用于滑点的控制，我们假定当前BNB价格是220，滑点控制在2%，那么可以大致设定为 $swap\_amount / 220 \* 0.98

**path:** 进行兑换的路径，需输入代币合约地址，这里我们是从 USDC 到 WBNB 再到 BNB，故而需填入一个USDC和WBNB的地址数组 \["0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"\]

**to:** 兑换后的BNB接收地址，我们应该填写的是自己的钱包地址，在BQL中 $ADDRESS 表示当前运行时的钱包地址

**deadline:** 表示兑换的时间约束，超过这个时间不确认，则取消交易，我们设定超时时间是10分钟，用 $CURRENT\_TIMESTAMP + 600 表示10分钟后的时间戳

填入以上参数后，我们得到以下的代码：

![Step2 - call swapExactTokensForETH of PancakeSwap](https://storage.googleapis.com/papyrus_images/ad98622034887e203b4604abaa403bfe3fd4242173d7a8f3ca35dfff8a7165a0.png)

Step2 - call swapExactTokensForETH of PancakeSwap

BQL脚本的运行
--------

BQL脚本编写完成后，我们实际上已经完成了Workflow的定义。接下来，点击“Run”即可调用执行器进行流程的执行。

在第一个步骤执行时，它会呼出我的浏览器Metamask并提示我进行Approve操作。点击“Next”后，交易会被发送到链上。

稍等片刻，交易执行并上链后，在Console里打印出了执行的日志。该日志包括执行时的action环境，并输出了对应的txid和执行状态。我们可以看到，我们的交易已成功执行。

![](https://storage.googleapis.com/papyrus_images/0e2251d68b457382af93a17a98bad8692bead3a1fe7050008920eac75b3b6f23.png)

第一步完成后，继续执行第二步，调用MetaMask进行授权并发送交易。以下是输出日志，可以看到swapExactTokenForETH操作成功执行。

![](https://storage.googleapis.com/papyrus_images/12674d6108d9b34ddc510156a8779ad8c644c96d44f985b26fe5b524ae1ee16d.png)

在“My Library”中，您可以查看刚才的执行日志。

![Execution logs in My Library](https://storage.googleapis.com/papyrus_images/aeaa1aff5707702c49643d7dafd85cade6c0868f204d1af209025ea668268b67.png)

Execution logs in My Library

点击Txid即可跳往浏览器查看交易详情，可以看到该交易已经得到了确认，将2 USDC兑换成了 0.009 BNB。

![Transaction details on BSCScan](https://storage.googleapis.com/papyrus_images/d3cb2284ab7468f4b3e80aadd217676c0051d2c886890216c039c96840c44c4c.png)

Transaction details on BSCScan

定向邀请
----

目前，SoQuest当前已经启动了BQL的定向邀请体验，仅收到邀请的KOL才可以使用BQL的功能，普通用户暂时还不能访问。KOL可以生成10枚邀请码，将邀请码分享给朋友，他们进入SoQuest输入邀请码，也可以体验BQL的完整功能。

进入BQL WORKFLOW - Discovery模块时，输入邀请码，即可获得体验资格，邀请码仅限一次使用，先到先得，欢迎使用和分享BQL。

---

*Originally published on [Port3 Network中文社区](https://paragraph.com/@port3-network-2/bql)*
