You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用initRaffle时LINK代币授权失败的问题排查与解决

问题原因分析
  1. 授权未完成:触发"Allowance failed"的核心原因是调用initRaffle前,用户账户未给合约授权足够的LINK额度。LINKToken.allowance(msg.sender, address(this))返回的是用户允许合约从自己账户转走的LINK数量,该值小于ChainlinkFee,所以检查不通过。
  2. 缺失转账逻辑:当前代码仅做了余额和授权检查,但没有实际执行LINK转账操作,即便授权通过,合约也无法获取到用户的LINK。
可行实现方案

方案1:先授权再让合约转账(传统ERC20方式)

修改initRaffle函数,在检查通过后调用transferFrom完成LINK转账:

function initRaffle(address _tokenContract, uint256 _tokenId, uint256 _ticketPrice) external {
    require(_ticketPrice > 0, "Ticket price must be bigger than 0");
    require(LINKToken.balanceOf(msg.sender) >= ChainlinkFee, "Insufficient LINK supplied");
    require(LINKToken.allowance(msg.sender, address(this)) >= ChainlinkFee, "Allowance failed");

    // 执行LINK转账,从用户账户转至合约
    bool transferSuccess = LINKToken.transferFrom(msg.sender, address(this), ChainlinkFee);
    require(transferSuccess, "LINK transfer failed");

    // 后续抽奖初始化逻辑(比如存储NFT信息、设置票价等)
}

使用流程:用户需先调用LINK代币合约的approve(address(this), ChainlinkFee)(或更大额度),授权合约可从自己账户转走指定数量的LINK,再调用initRaffle。

方案2:用户直接转账+合约回调(ERC677简化流程)

利用LINK的ERC677代币特性(支持转账时触发合约回调),让用户一次性完成转账和抽奖初始化,无需单独授权:

// 实现ERC677的回调函数,接收用户转账的LINK并处理抽奖初始化
function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external {
    require(msg.sender == address(LINKToken), "Only LINK token is allowed");
    require(amount >= ChainlinkFee, "Insufficient LINK supplied");

    // 解析data中的抽奖参数
    (address tokenContract, uint256 tokenId, uint256 ticketPrice) = abi.decode(data, (address, uint256, uint256));
    require(ticketPrice > 0, "Ticket price must be bigger than 0");

    // 后续抽奖初始化逻辑
}

使用流程:用户调用LINK代币合约的transferAndCall(address(this), ChainlinkFee, abi.encode(_tokenContract, _tokenId, _ticketPrice)),即可完成LINK转账并触发抽奖初始化。

内容的提问来源于stack exchange,提问作者gggggggggg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 18:01:07