Flutter开发DApp:如何用WalletConnect_dart发送ETH以外的代币?
在Flutter中通过WalletConnect发送ERC20代币(如DAI)
要实现发送DAI等ERC20代币,核心区别于原生ETH转账:你需要调用代币合约的transfer方法,而非直接发起ETH原生交易。以下是具体实现步骤和代码示例:
1. 准备核心信息
- 代币合约地址:每个ERC20代币在对应链上都有唯一合约地址(比如以太坊主网DAI地址为
0x6B175474E89094C44Da98b954EedeAC495271d0F) - 代币小数位数:ERC20代币的金额单位转换依赖此参数(DAI为18,即1 DAI = 10^18 wei)
- ERC20
transfer方法ABI:标准ERC20的transfer方法ABI片段用于编码交易数据
2. 实现代币转账逻辑
依赖准备
首先在pubspec.yaml中添加web3dart(用于ABI编码和金额处理):
dependencies: web3dart: ^0.52.0 wallet_connect_dart: ^1.0.0 # 确保使用你当前的版本
完整转账代码示例
import 'package:web3dart/web3dart.dart'; import 'package:wallet_connect_dart/wallet_connect_dart.dart'; // 示例配置:以太坊主网DAI const _daiContractAddress = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; const _daiDecimals = 18; // ERC20标准transfer方法ABI const _erc20TransferAbi = ''' [ { "constant": false, "inputs": [ {"name": "_to", "type": "address"}, {"name": "_value", "type": "uint256"} ], "name": "transfer", "outputs": [{"name": "", "type": "bool"}], "payable": false, "stateMutability": "nonpayable", "type": "function" } ] '''; Future<String?> sendERC20Token( WalletConnectSession session, String recipientAddress, String amountStr, // 用字符串避免浮点精度问题,比如"1.5"代表1.5 DAI int chainId, // 链ID,主网1/Goerli5/Polygon137等 ) async { try { // 1. 将用户输入的金额转换为代币最小单位(wei) final totalAmount = _convertToWei(amountStr, _daiDecimals); // 2. 初始化合约对象 final contract = DeployedContract( ContractAbi.fromJson(_erc20TransferAbi, 'ERC20'), EthereumAddress.fromHex(_daiContractAddress), ); final transferFunc = contract.function('transfer'); // 3. 编码合约调用数据 final data = contract.encodeFunctionCall( transferFunc, [ EthereumAddress.fromHex(recipientAddress), totalAmount, ], ); // 4. 构造交易请求(关键:to是代币合约地址,value设为0) final transaction = { 'to': _daiContractAddress, 'data': bytesToHex(data, include0x: true), 'value': '0x0', // 无需转ETH,设为0 // gas和gasPrice可留空,由MetaMask自动计算 }; // 5. 发送交易到MetaMask final result = await session.sendTransaction( transaction: transaction, chainId: chainId, ); return result['transactionHash']; } catch (e) { print('转账失败:$e'); return null; } } // 安全的金额转wei方法(避免浮点误差) BigInt _convertToWei(String amountStr, int decimals) { final parts = amountStr.split('.'); final integerPart = BigInt.parse(parts[0]); final fractionalPart = parts.length > 1 ? BigInt.parse( parts[1].padRight(decimals, '0').substring(0, decimals), ) : BigInt.zero; return integerPart * BigInt.from(10).pow(decimals) + fractionalPart; }
3. 关键注意事项
- 链匹配:确保合约地址、chainId与用户MetaMask当前网络一致
- 精度处理:始终用字符串接收用户输入的金额,避免浮点运算导致的精度丢失
- Gas设置:无需手动指定gas/gasPrice,留空让MetaMask自动计算更适配当前网络状况
- 异常处理:捕获用户拒绝交易、网络错误等异常情况,给用户对应的提示
内容的提问来源于stack exchange,提问作者Long
相关产品推荐
相关产品推荐

