pragma solidity ^0.8.20;
pragma abicoder v2;

import '@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol';
import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';

contract SwapExamples {
ISwapRouter public immutable swapRouter;

// Token contract addresses used for the WETH to USDC swap
address public constant WETH9 = 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619;

address public constant USDC = 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359;

uint24 public constant poolFee = 3000;

constructor(ISwapRouter _swapRouter) {
swapRouter = _swapRouter;
}

// @notice swapExactInputSingle swaps a fixed amount of WETH9 for a maximum possible amount of USDC
// using the WETH9/USDC 0.3% pool by calling exactInputSingle in the swap router. // @dev The calling address must approve this contract to spend at least amountIn worth of its WETH9 for this function to succeed. // @param amountIn The exact amount of WETH9 that will be swapped for USDC. // @return amountOut The amount of USDC received. function swapExactInputSingle(uint256 amountIn) external returns (uint256 amountOut) { // msg.sender must approve this contract // Transfer the specified amount of WETH9 to this contract. TransferHelper.safeTransferFrom(WETH9, msg.sender, address(this), amountIn); // Approve the router to spend WETH9. TransferHelper.safeApprove(WETH9, address(swapRouter), amountIn); // Naively set amountOutMinimum to 0. In production, use an oracle or other data source to choose a safer value for amountOutMinimum. // We also set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact input amount. ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({ tokenIn: WETH9, tokenOut: USDC, fee: poolFee, recipient: msg.sender, deadline: block.timestamp, amountIn: amountIn, amountOutMinimum: 0, sqrtPriceLimitX96: 0 }); // The call to exactInputSingle executes the swap. amountOut = swapRouter.exactInputSingle(params); } // @notice swapExactOutputSingle swaps a minimum possible amount of WETH9 for a fixed amount of USDC. // @dev The calling address must approve this contract to spend its WETH9 for this function to succeed. As the amount of input WETH9 is variable, // the calling address will need to approve for a slightly higher amount, anticipating some variance. // @param amountOut The exact amount of USDC to receive from the swap. // @param amountInMaximum The amount of WETH9 we are willing to spend to receive the specified amount of USDC. // @return amountIn The amount of WETH9 actually spent in the swap. function swapExactOutputSingle(uint256 amountOut, uint256 amountInMaximum) external returns (uint256 amountIn) { // Transfer the specified amount of WETH9 to this contract. TransferHelper.safeTransferFrom(WETH9, msg.sender, address(this), amountInMaximum); // Approve the router to spend the specified amountInMaximum of WETH9. // In production, you should choose the maximum amount to spend based on oracles or other data sources to achieve a better swap. TransferHelper.safeApprove(WETH9, address(swapRouter), amountInMaximum); ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams({ tokenIn: WETH9, tokenOut: USDC, fee: poolFee, recipient: msg.sender, deadline: block.timestamp, amountOut: amountOut, amountInMaximum: amountInMaximum, sqrtPriceLimitX96: 0 }); // Executes the swap returning the amountIn needed to spend to receive the desired amountOut. amountIn = swapRouter.exactOutputSingle(params); // For exact output swaps, the amountInMaximum may not have all been spent. // If the actual amount spent (amountIn) is less than the specified maximum amount, we must refund the msg.sender and approve the swapRouter to spend 0. if (amountIn < amountInMaximum) { TransferHelper.safeApprove(WETH9, address(swapRouter), 0); TransferHelper.safeTransfer(WETH9, msg.sender, amountInMaximum - amountIn); } } }

編譯智能合約

在部署智能合約之前,我們需要對其進行編譯,以獲取 ABI(Application Binary Interface)和字節(jié)碼。為此,我們將使用 Remix IDE。打開 Remix IDE

創(chuàng)建新文件

編譯合約

復(fù)制 ABI 和 Bytecode

為什么需要此步驟?

編譯智能合約會生成 ABI 和字節(jié)碼,這對于在區(qū)塊鏈上部署合約并與之交互至關(guān)重要。ABI 定義了合約的接口,允許我們調(diào)用其函數(shù),而字節(jié)碼是部署到區(qū)塊鏈的合約的編譯版本。

部署智能合約

要使用 Circle 的 SDK 部署編譯好的合約,請執(zhí)行以下步驟:

安裝和導(dǎo)入所需的軟件包

首先,確保您已安裝必要的軟件包:

npm install @circle-fin/smart-contract-platform @circle-fin/developer-controlled-wallets --save

這些軟件包提供了與 Circle 的智能合約平臺交互和處理開發(fā)人員控制的錢包所需的工具。

然后,在您的項目中導(dǎo)入所需的包:

const circleContractSdk = require('@circle-fin/smart-contract-platform');
const developerControlledWallets = require('@circle-fin/developer-controlled-wallets');

準備部署參數(shù):

部署合約:

 const response = await circleContractSdk.deployContract({
name: 'Swap Contract',
description: 'Contract for swapping WETH9 to USDC using Uniswap',
walletId: '046b6c7f-0b8a-43b9-b35d-6489e6daee91',// Replace with your walletId
blockchain: 'MATIC-AMOY',
fee: {
type: 'level',
config: {
feeLevel: 'MEDIUM'
}
},
constructorParameters: ['0xYourWalletAddress'], // Replace with your wallet address
entitySecretCiphertext: '0NtD3d3+nmgb4GqYQXzAjKF8h5Zq6sHM2k/...', // Replace with your entitySecretCipher text
abiJSON: '[...]', // Replace with actual stringified ABI JSON
bytecode: '0x...' // Replace with actual bytecode prefixed with 0x
});

成功部署智能合約后,您將收到包含 contractId 和 transactionId 的響應(yīng)。

{ 
"data": {
"contractId": "0189db84-72b7-7fcc-832b-5bf886b9a0ef",
"transactionId": "7b989c65-9678-56d8-a998-d295b8b04535"
}
}

檢查部署狀態(tài):

const response = await circleContractSdk.getContract({
id: '0189db84-72b7-7fcc-832b-5bf886b9a0ef'
});
{
"data": {
"contract": {
"id": "0189db84-72b7-7fcc-832b-5bf886b9a0ef",
"deploymentTransactionId": "7b989c65-9678-56d8-a998-d295b8b04535",
"name": "Swap Contract",
"description": "Contract for swapping WETH9 to USDC using Uniswap",
"contractInputType": "BYTECODE",
"createDate": "2023-08-09T18:17:17Z",
"updateDate": "2023-08-09T18:17:17Z",
"archived": false,
"contractAddress": "0x1e124d7384cd34448ea5907bd0052a79355ab5eb",
"blockchain": "MATIC-AMOY",
"status": "COMPLETE",
"deployerAddress": "0x1bf9ad0cc2ad298c69a2995aa806ee832788218c",
"txHash": "0x241c4df6f08f9ed2b569c9f9b1cc48fb6074ffffaeee7552e716ce059161a743",
"abiJSON": "[\n\t{\n\t\t\"inputs\": [],\n\t\t\"stateMutability\": \"nonpayable\",\n\t\t\"type\": \"constructor\"\n\t},\n\t{\n\t\t\"anonymous\": false,",
"functions": [
{
"name": "swapExactInputSingle",
"type": "function",
"inputs": [
{
"name": "amountIn",
"type": "uint256"
}
],
"stateMutability": "nonpayable"
}
],
"verificationStatus": "UNVERIFIED"
}
}
}

與已部署的合約交互

部署合約后,您可以與它交互以執(zhí)行代幣交換。下面介紹如何調(diào)用 swapExactInputSingle 函數(shù):

準備交互參數(shù):

調(diào)用函數(shù):

 const response = await circleDeveloperSdk.createContractExecutionTransaction({
walletId: 'ce714f5b-0d8e-4062-9454-61aa1154869b', // Replace with your wallet ID
contractAddress: '0x2f3A40A3db8a7e3D09B0adfEfbCe4f6F81927557', // Replace with your contract address
abiFunctionSignature: 'swapExactInputSingle(uint256)',
abiParameters: [1000], // Example amountIn value
fee: {
type: 'level',
config: {
feeLevel: 'MEDIUM'
}
}
});

結(jié)論

我們展示了如何利用Circle的智能合約平臺部署智能合約,并與之交互,以通過Uniswap實現(xiàn)從ETH到USDC的代幣轉(zhuǎn)換。借助Circle的SDK,您可以輕松地管理智能合約并執(zhí)行區(qū)塊鏈交易。

上一篇:

輕松實現(xiàn)順豐單號查詢:Python 快速獲取物流信息

下一篇:

極速查詢快遞信息:輕松實現(xiàn)極兔快遞查詢 API 應(yīng)用
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費