简而言之
Blockradar的智能合约API使您能够直接从钱包与任何智能合约交互,无需自己管理RPC端点、签名流程或合约部署。
前置条件
在使用智能合约API之前,请确保您已具备:
已创建钱包
通过创建钱包API或控制台创建钱包。您需要walletId来执行所有智能合约操作。 原生货币余额
向您的钱包充值原生货币(ETH、BNB、MATIC等)以支付Gas费用。在执行前使用网络费用端点来估算成本。
支持的区块链
智能合约API支持Blockradar上可用的所有EVM兼容区块链和Tron。查看集成获取完整的支持网络列表和水龙头链接。
Solana不支持智能合约交互。智能合约API仅适用于EVM兼容链和Tron。
智能合约API将Blockradar从钱包基础设施转变为可编程的执行层。您可以读取合约状态、执行合约函数、估算Gas费用并签署交易——所有这些都通过统一的API接口实现。
使用场景
智能合约API为金融科技开发者解锁强大功能:
- DeFi集成:连接Uniswap、Aave或Compound等协议进行收益和流动性管理
- 资金库操作:在您的金融科技平台内自动化资金库管理
- 资产数字化:将现实世界资产整合到您的产品流程中
- 可编程结算:执行合规检查和自动化结算
- 自定义资产:管理自定义资产、奖励系统和忠诚度计划
主钱包 vs 子地址
智能合约API在两个层面可用:
主钱包
直接从主钱包执行合约操作。适用于资金库操作和集中式资金管理。
子地址
从单个子地址执行合约操作。适用于用户特定操作和分离式资金管理。
主钱包端点
| 操作 | 端点 | 描述 |
|---|
| 读取 | POST /v1/wallets/{walletId}/contracts/read | 从智能合约检索数据 |
| 写入 | POST /v1/wallets/{walletId}/contracts/write | 执行智能合约函数 |
| 网络费用 | POST /v1/wallets/{walletId}/contracts/network-fee | 估算Gas成本 |
| 仅签名 | POST /v1/wallets/{walletId}/contracts/write/sign | 签名但不广播 |
子地址端点
| 操作 | 端点 | 描述 |
|---|
| 读取 | POST /v1/wallets/{walletId}/addresses/{addressId}/contracts/read | 从智能合约检索数据 |
| 写入 | POST /v1/wallets/{walletId}/addresses/{addressId}/contracts/write | 执行智能合约函数 |
| 网络费用 | POST /v1/wallets/{walletId}/addresses/{addressId}/contracts/network-fee | 估算Gas成本 |
| 仅签名 | POST /v1/wallets/{walletId}/addresses/{addressId}/contracts/write/sign | 签名但不广播 |
请求结构
所有智能合约请求需要以下参数:
| 参数 | 类型 | 必填 | 描述 |
|---|
address | string | 是 | 智能合约的区块链地址 |
method | string | 是 | 要调用的函数名称 |
parameters | array | 是 | 与函数ABI顺序匹配的参数 |
abi | array | 是 | 合约的应用程序二进制接口 |
reference | string | 否 | 您的内部交易跟踪ID |
metadata | object | 否 | 用于附加交易详情的自定义键值对 |
reference 和 metadata 字段仅适用于写入操作。读取操作不支持这些字段。
理解ABI
ABI(应用程序二进制接口)定义了如何与智能合约交互。您可以从以下来源获取ABI:
- 区块浏览器:Etherscan、BscScan、PolygonScan(已验证的合约)
- 协议文档:DeFi协议的官方文档
- 合约源代码:从Solidity源代码编译
读取合约数据
使用读取端点查询合约状态而不修改区块链。
主钱包读取示例
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/contracts/read \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0x337610d27c682E347C9cD60BD4b3b107C9d34dDd",
"method": "balanceOf",
"parameters": ["0x947514e4B803e312C312da0F1B41fEDdbe15ae7a"],
"abi": [{
"constant": true,
"inputs": [{"name": "account", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "", "type": "uint256"}],
"stateMutability": "view",
"type": "function"
}]
}'
子地址读取示例
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/addresses/{addressId}/contracts/read \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0x337610d27c682E347C9cD60BD4b3b107C9d34dDd",
"method": "balanceOf",
"parameters": ["0x947514e4B803e312C312da0F1B41fEDdbe15ae7a"],
"abi": [{
"constant": true,
"inputs": [{"name": "account", "type": "address"}],
"name": "balanceOf",
"outputs": [{"name": "", "type": "uint256"}],
"stateMutability": "view",
"type": "function"
}]
}'
读取响应
{
"message": "合约读取成功",
"statusCode": 200,
"data": "10052335235393043"
}
读取错误响应
{
"message": "无效的合约地址",
"statusCode": 400,
"error": "BAD_REQUEST"
}
{
"message": "在ABI中未找到方法'balanceOf'",
"statusCode": 400,
"error": "ABI_METHOD_NOT_FOUND"
}
{
"message": "合约执行回滚",
"statusCode": 400,
"error": "EXECUTION_REVERTED",
"data": {
"reason": "ERC20:零地址余额查询"
}
}
{
"message": "参数数量不匹配。预期1个,收到2个",
"statusCode": 400,
"error": "INVALID_PARAMETERS"
}
写入合约
在智能合约上执行状态更改函数。
主钱包写入示例
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/contracts/write \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0x您的代币合约",
"method": "approve",
"parameters": ["0x您的授权地址", "1000000000000000000"],
"abi": [{
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"name": "approve",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "nonpayable",
"type": "function"
}]
}'
子地址写入示例
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/addresses/{addressId}/contracts/write \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0x您的代币合约",
"method": "approve",
"parameters": ["0x您的授权地址", "1000000000000000000"],
"abi": [{
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"name": "approve",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "nonpayable",
"type": "function"
}]
}'
写入响应
{
"message": "合约写入已启动",
"statusCode": 200,
"data": {
"id": "tx-uuid",
"hash": "0x...",
"status": "PENDING"
}
}
写入操作是异步的。初始响应显示PENDING状态。请监听custom-smart-contract.success webhook以确认交易完成。
写入错误响应
{
"message": "原生货币余额不足以支付Gas",
"statusCode": 400,
"error": "INSUFFICIENT_GAS",
"data": {
"required": "0.005",
"available": "0.001",
"token": "ETH"
}
}
{
"message": "余额不足",
"statusCode": 400,
"error": "INSUFFICIENT_BALANCE",
"data": {
"required": "1000000000000000000",
"available": "500000000000000000"
}
}
{
"message": "交易将会回滚",
"statusCode": 400,
"error": "EXECUTION_REVERTED",
"data": {
"reason": "ERC20:转账金额超过授权额度"
}
}
{
"message": "无效的ABI格式",
"statusCode": 400,
"error": "INVALID_ABI",
"data": {
"details": "ABI定义中缺少'inputs'字段"
}
}
{
"message": "钱包未找到",
"statusCode": 404,
"error": "NOT_FOUND"
}
估算网络费用
在执行写入操作之前始终估算费用,以确保您的钱包有足够的原生货币。
主钱包费用估算
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/contracts/network-fee \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0x您的代币合约",
"method": "approve",
"parameters": ["0x您的授权地址", "1000000000000000000"],
"abi": [{
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"name": "approve",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "nonpayable",
"type": "function"
}]
}'
子地址费用估算
curl --request POST \
--url https://api.blockradar.co/v1/wallets/{walletId}/addresses/{addressId}/contracts/network-fee \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '{
"address": "0x您的代币合约",
"method": "approve",
"parameters": ["0x您的授权地址", "1000000000000000000"],
"abi": [{
"inputs": [
{"name": "spender", "type": "address"},
{"name": "amount", "type": "uint256"}
],
"name": "approve",
"outputs": [{"name": "", "type": "bool"}],
"stateMutability": "nonpayable",
"type": "function"
}]
}'
费用响应
{
"message": "网络费用已获取",
"statusCode": 200,
"data": {
"networkFee": "0.00001247904",
"networkFeeInUSD": "0.01",
"nativeBalance": "0.5",
"nativeBalanceInUSD": "450.00",
"estimatedArrivalTime": 30
}
}
实践示例:Uniswap资产兑换
本节演示执行资产兑换的两种方法:不使用批量操作(顺序调用)和使用批量操作(单个API调用)。
示例1:不使用批量操作的资产兑换
此方法为每个步骤进行单独的API调用。当您需要对每个交易进行细粒度控制,或操作依赖于前一次调用的结果时使用此方法。
步骤1:检查资产余额
const balanceOfAbi = {
constant: true,
inputs: [{ name: 'account', type: 'address' }],
name: 'balanceOf',
outputs: [{ name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function'
};
const balance = await fetch(
`https://api.blockradar.co/v1/wallets/${walletId}/contracts/read`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },
body: JSON.stringify({
address: TOKEN_ADDRESS,
method: 'balanceOf',
parameters: [walletAddress],
abi: [balanceOfAbi]
})
}
).then(r => r.json());
console.log('资产余额:', balance.data);
步骤2:授权代币支出
const approveAbi = {
inputs: [
{ name: 'spender', type: 'address' },
{ name: 'amount', type: 'uint256' }
],
name: 'approve',
outputs: [{ name: '', type: 'bool' }],
stateMutability: 'nonpayable',
type: 'function'
};
const approval = await fetch(
`https://api.blockradar.co/v1/wallets/${walletId}/contracts/write`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },
body: JSON.stringify({
address: TOKEN_ADDRESS,
method: 'approve',
parameters: [UNISWAP_ROUTER, amountIn],
abi: [approveAbi]
})
}
).then(r => r.json());
console.log('授权交易:', approval.data.hash);
// 重要:在继续之前等待webhook确认
在执行兑换之前,始终等待custom-smart-contract.success webhook确认授权交易已被挖掘。
步骤3:估算兑换费用
const swapAbi = {
inputs: [
{ name: 'amountIn', type: 'uint256' },
{ name: 'amountOutMin', type: 'uint256' },
{ name: 'path', type: 'address[]' },
{ name: 'to', type: 'address' },
{ name: 'deadline', type: 'uint256' }
],
name: 'swapExactTokensForTokens',
outputs: [{ name: 'amounts', type: 'uint256[]' }],
stateMutability: 'nonpayable',
type: 'function'
};
const fees = await fetch(
`https://api.blockradar.co/v1/wallets/${walletId}/contracts/network-fee`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },
body: JSON.stringify({
address: UNISWAP_ROUTER,
method: 'swapExactTokensForTokens',
parameters: [
amountIn,
amountOutMin,
[TOKEN_A, TOKEN_B],
walletAddress,
deadline
],
abi: [swapAbi]
})
}
).then(r => r.json());
console.log('估算费用:', fees.data.networkFee);
步骤4:执行兑换
const swap = await fetch(
`https://api.blockradar.co/v1/wallets/${walletId}/contracts/write`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },
body: JSON.stringify({
address: UNISWAP_ROUTER,
method: 'swapExactTokensForTokens',
parameters: [
amountIn,
amountOutMin,
[TOKEN_A, TOKEN_B],
walletAddress,
deadline
],
abi: [swapAbi]
})
}
).then(r => r.json());
console.log('兑换交易:', swap.data.hash);
示例2:使用批量操作的资产兑换
此方法使用calls数组将授权+兑换合并为单个API调用。当您想要将多个操作排队在一起以提高效率时使用此方法。
批量操作按顺序执行。每个操作作为单独的交易提交,但您只需要一个API调用。
批量请求:一次调用完成授权+兑换
const approveAbi = {
inputs: [
{ name: 'spender', type: 'address' },
{ name: 'amount', type: 'uint256' }
],
name: 'approve',
outputs: [{ name: '', type: 'bool' }],
stateMutability: 'nonpayable',
type: 'function'
};
const swapAbi = {
inputs: [
{ name: 'amountIn', type: 'uint256' },
{ name: 'amountOutMin', type: 'uint256' },
{ name: 'path', type: 'address[]' },
{ name: 'to', type: 'address' },
{ name: 'deadline', type: 'uint256' }
],
name: 'swapExactTokensForTokens',
outputs: [{ name: 'amounts', type: 'uint256[]' }],
stateMutability: 'nonpayable',
type: 'function'
};
const batchSwap = await fetch(
`https://api.blockradar.co/v1/wallets/${walletId}/contracts/write`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },
body: JSON.stringify({
calls: [
{
address: TOKEN_ADDRESS,
method: 'approve',
parameters: [UNISWAP_ROUTER, amountIn],
abi: [approveAbi],
reference: 'approve-tx',
metadata: { step: '授权' }
},
{
address: UNISWAP_ROUTER,
method: 'swapExactTokensForTokens',
parameters: [
amountIn,
amountOutMin,
[TOKEN_A, TOKEN_B],
walletAddress,
deadline
],
abi: [swapAbi],
reference: 'swap-tx',
metadata: { step: '兑换' }
}
]
})
}
).then(r => r.json());
console.log('批量结果:', batchSwap.data);
批量响应
{
"message": "批量合约写入已成功启动",
"statusCode": 200,
"data": {
"success": [
{
"index": 0,
"id": "tx-uuid-1",
"hash": "0xapprove...",
"status": "PENDING",
"reference": "approve-tx"
},
{
"index": 1,
"id": "tx-uuid-2",
"hash": "0xswap...",
"status": "PENDING",
"reference": "swap-tx"
}
],
"errors": []
}
}
处理批量中的部分失败
const result = await batchSwap.json();
// 检查成功的操作
result.data.success.forEach(tx => {
console.log(`✓ ${tx.reference}: ${tx.hash}`);
});
// 检查失败的操作
result.data.errors.forEach(error => {
console.error(`✗ 操作 ${error.index} (${error.method}): ${error.error}`);
});
批量操作规则
| 规则 | 值 |
|---|
| 最大批量大小 | 20个操作 |
| 执行顺序 | 顺序执行 |
| 错误处理 | 部分成功(失败不会停止后续操作) |
何时使用每种方法
| 场景 | 推荐方法 |
|---|
| 需要在步骤之间检查结果 | 不使用批量 |
| 基于前一结果的动态参数 | 不使用批量 |
| 简单的授权+操作模式 | 使用批量 |
| 多个独立操作 | 使用批量 |
| 最小化API调用 | 使用批量 |
Webhook事件
智能合约操作触发webhook通知:
| 事件 | 描述 |
|---|
custom-smart-contract.success | 合约操作成功完成 |
custom-smart-contract.failed | 合约操作失败 |
Webhook负载
{
"event": "custom-smart-contract.success",
"data": {
"id": "tx-uuid",
"hash": "0x...",
"status": "SUCCESS",
"method": "approve",
"contractAddress": "0x...",
"blockchain": {
"name": "ethereum",
"network": "mainnet"
}
}
}
最佳实践
安全性
- 验证合约地址:在交互之前始终仔细核对合约地址
- 使用可信的ABI:从区块浏览器等经过验证的来源获取ABI
- 设置合理的限制:为DeFi操作使用滑点保护和金额上限
Gas管理
- 执行前估算:始终先调用网络费用端点
- 监控原生余额:确保有足够的ETH/BNB/MATIC支付Gas费用
- 使用批量操作:通过批量处理相关操作来减少开销
错误处理
- 实现webhook监听器:不要仅依赖API响应
- 处理部分失败:在批量响应中检查
success和errors数组
- 使用退避重试:对暂时性失败实施指数退避
API参考
主钱包端点
| 端点 | 描述 |
|---|
| 读取合约 | 读取合约状态 |
| 写入合约 | 执行合约函数 |
| 网络费用 | 估算Gas成本 |
| 仅签名 | 签名但不广播 |
子地址端点
| 端点 | 描述 |
|---|
| 读取合约 | 读取合约状态 |
| 写入合约 | 执行合约函数 |
| 网络费用 | 估算Gas成本 |
| 仅签名 | 签名但不广播 |
智能合约API使您能够构建复杂的区块链集成,而无需管理基础设施的复杂性。从简单的读取操作开始,随着您熟悉系统,逐步加入写入操作。