95 脚本与 Aave Pool V3合约交互,但调用的项目合约执行失败报错‘Fail with error 'not approve'’

大佬们好。 朋友想要我写一个脚本,用于与https://ultra.powermonger.vip/#/FlashLoans 进行闪电交易交互。 我大概看了一下网站代码,就吹牛逼说很容易,这不就是从网站api获取数据然后与Aave Pool V3进行带数据交互嘛,结果很快就打脸了。

微信图片_20240517042310.png

下面是我的脚本:

# 从网站API获取数据并与智能合约进行交互
def InteractWithUltra():
    url = 'https://mev.powermonger.vip/api/index/returndata?address=0xAe26Bf10E30AB7E4CFd0a4FE9bA275A700EdA0F5&amount=1'
    header = {
        'Accept': 'application/json, text/plain, */*',
        'Accept-Encoding': 'gzip, deflate, zstd',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
        'Cache-Control': 'no-cache',
        'Dnt': '1',
        'Origin': 'https://ultra.powermonger.vip',
        'Pragma': 'no-cache',
        'Referer': 'https://ultra.powermonger.vip/',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-site',
        'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, '
                      'like Gecko) Version/16.6 Mobile/15E148 Safari/604.1 '
    }
    re = requests.get(url, headers=header)
    data_json = re.json()['data']
    print(data_json)

    return data_json

# 调用智能合约
def InteractWithAAVER_V3():

    # 模仿发送交易
    WalletPrivateKey = ''
    MainAccount = w3.eth.account.from_key('')

    # 授权给DAI币
    DAI_abi = ''
    Contract = w3.eth.contract(address=Web3.to_checksum_address('0x8f3cf7ad23cd3cadbd9735aff958023239c6a063'),
                               abi=DAI_abi)
    token_balance = Contract.functions.balanceOf('0xAe26Bf10E30AB7E4CFd0a4FE9bA275A700EdA0F5').call()
    print(f'token_balance: {token_balance}')

    MainWallet = '0xAe26Bf10E30AB7E4CFd0a4FE9bA275A700EdA0F5'
    AAVE_V3_Address = '0x794a61358D6845594F94dc1DB02A252b5b4814aD'
    data = InteractWithUltra()
    gas_limit = 200000

    # 向AAVE_V3_Address授权
    nonce = w3.eth.get_transaction_count(MainAccount.address)
    AAVE_approve_tx = Contract.functions.approve(Web3.to_checksum_address(AAVE_V3_Address), int(1 * 10**18)).build_transaction({
        'chainId': 137,
        'from': MainWallet,
        'nonce': nonce,
        'gas': gas_limit,
        'gasPrice': w3.to_wei(100, 'gwei')
    })
    # 签名授权交易
    AAVE_signed_approve_tx = w3.eth.account.sign_transaction(AAVE_approve_tx, WalletPrivateKey)
    # 发送授权交易
    approve_tx_hash = w3.eth.send_raw_transaction(AAVE_signed_approve_tx.rawTransaction)
    AAVE_approve_tx_receipt = w3.eth.wait_for_transaction_receipt(approve_tx_hash)
    print(f'已向AAVE授权:{AAVE_approve_tx_receipt}')
    # 检查 AAVE_V3_Address 授权状态和数量
    allowance_AAVE = Contract.functions.allowance(MainWallet, AAVE_V3_Address).call()
    print(f'AAVE_V3_Address 的授权数量: {allowance_AAVE / 10 ** 18} DAI')
    time.sleep(15)

    # 构建交互交易
    txn = {
        'chainId': 137,
        'from': MainAccount.address,
        'to': Web3.to_checksum_address(AAVE_V3_Address),
        'nonce': w3.eth.get_transaction_count(MainAccount.address),
        'data': data,
        'gas': gas_limit,
        'gasPrice': w3.to_wei(100, 'gwei')
    }

    # 签名交易
    signed_txn = w3.eth.account.sign_transaction(txn, WalletPrivateKey)
    print(signed_txn)
    # 发送交易
    txn_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
    approve_tx_receipt = w3.eth.wait_for_transaction_receipt(txn_hash)
    print('https://polygonscan.com/tx/' + txn_hash.hex())
    print(f"approve_tx_receipt:{approve_tx_receipt}")

然后启动,交易链接: https://polygonscan.com/tx/0x131de664b7ff30b6402c820ebd1d9d510f176fe4027dc401b2bf6262f9985c70 看到tx出来了,以为交易成功了,然后查看了一下。发现报错,‘Fail with error 'not approve'’。 我很纳闷这啥玩意,data数据获取正确啊,授权给Aave Pool V3也正常,带数据data交互也正常。为啥会报错? 然后看了一下项目合约,发现合约未开源,只能找个工具反编译一下。反编译代码链接: https://app.dedaub.com/polygon/address/0xc42f00e55c15c84f900b86efa3f0e2ea8e2072cf/decompiled 查看反编译的代码,发现是在function executeOperation执行到68行“require(v5 > v0, Error('not approve'));”时报错。

function executeOperation(address asset, uint256 amount, uint256 premium, address initiator, bytes params) public payable { 
    require(4 + (msg.data.length - 4) - 4 >= 160);
    0x133a(amount);
    0x133a(premium);
    require(params <= uint64.max);
    require(4 + params + 31 < 4 + (msg.data.length - 4));
    require(params.length <= uint64.max);
    require(params.data + params.length <= 4 + (msg.data.length - 4));
    require(msg.sender == address(0x794a61358d6845594f94dc1db02a252b5b4814ad), Error('Untrusted source'));
    v0, v1, v2, v3 = 0x1f56(params.data, params.data + params.length);
    if (!(_executeOperation[initiator] - False)) {
        require(map_2[initiator] == False, Error('not flash'));
        map_2[initiator] = 1;
        require(v0 > 0, Error('no amount'));
        require(_isStart == True, Error('flash stop'));

        ******************************报错代码在下面这一段*******************************
        v4, /* uint256 */ v5 = address(v2).allowance(initiator, address(this)).gas(msg.gas);
        require(bool(v4), 0, RETURNDATASIZE()); // checks call status, propagates error data on error
        MEM[64] = MEM[64] + (RETURNDATASIZE() + 31 & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0);
        require(MEM[64] + RETURNDATASIZE() - MEM[64] >= 32);
        0x133a(v5);
        require(v5 > v0, Error('not approve'));
        ******************************报错代码在上面这一段*******************************

        v6, /* bool */ v7 = address(v2).transferFrom(initiator, address(this), v0).gas(msg.gas);
        require(bool(v6), 0, RETURNDATASIZE()); // checks call status, propagates error data on error
        MEM[64] = MEM[64] + (RETURNDATASIZE() + 31 & 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0);
        require(MEM[64] + RETURNDATASIZE() - MEM[64] >= 32);
        0x12a1(v7);
    }

这里边的V5看起来是由63行(代码中已标注)

v5 = address(v2).allowance(initiator, address(this)).gas(msg.gas);

执行后获得的,这里能看出来是一个地址调用allowance查看initiator这个用户地址授权给address(this)的DAI代币的授权额度。 看起来是用户地址并未给address(this)这个地址授权成功?然后我想本地要不脚本再给这个项目方合约授权一下试试。

# 调用智能合约
def InteractWithAAVER_V3():

    # 模仿发送交易
    WalletPrivateKey = ''
    MainAccount = w3.eth.account.from_key('')

    # 授权给DAI币
    DAI_abi = ''
    Contract = w3.eth.contract(address=Web3.to_checksum_address('0x8f3cf7ad23cd3cadbd9735aff958023239c6a063'),abi=DAI_abi)
    token_balance = Contract.functions.balanceOf('0xAe26Bf10E30AB7E4CFd0a4FE9bA275A700EdA0F5').call()
    print(f'token_balance: {token_balance}')

    MainWallet = '0xAe26Bf10E30AB7E4CFd0a4FE9bA275A700EdA0F5'
    AAVE_V3_Address = '0x794a61358D6845594F94dc1DB02A252b5b4814aD'
    UltraPower_Address = '0xC42f00e55C15C84f900B86EfA3F0E2EA8e2072cF'
    data = InteractWithUltra()
    gas_limit = 200000

    # 向AAVE_V3_Address授权
    nonce = w3.eth.get_transaction_count(MainAccount.address)
    AAVE_approve_tx = Contract.functions.approve(Web3.to_checksum_address(AAVE_V3_Address), int(1 * 10**18)).build_transaction({
        'chainId': 137,
        'from': MainWallet,
        'nonce': nonce,
        'gas': gas_limit,
        'gasPrice': w3.to_wei(100, 'gwei')
    })
    # 签名授权交易
    AAVE_signed_approve_tx = w3.eth.account.sign_transaction(AAVE_approve_tx, WalletPrivateKey)
    # 发送授权交易
    approve_tx_hash = w3.eth.send_raw_transaction(AAVE_signed_approve_tx.rawTransaction)
    AAVE_approve_tx_receipt = w3.eth.wait_for_transaction_receipt(approve_tx_hash)
    print(f'已向AAVE授权:{AAVE_approve_tx_receipt}')
    # 检查 AAVE_V3_Address 授权状态和数量
    allowance_AAVE = Contract.functions.allowance(MainWallet, AAVE_V3_Address).call()
    print(f'AAVE_V3_Address 的授权数量: {allowance_AAVE / 10 ** 18} DAI')
    time.sleep(15)

    ********************下面这段是新添加给UltraPower_Address项目合约的授权********************

    # 向UltraPower_Address授权
    print('开始向UltraPower合约授权')
    nonce = w3.eth.get_transaction_count(MainAccount.address)
    UltraPower_approve_tx = Contract.functions.approve(Web3.to_checksum_address(UltraPower_Address), int(1 * 10**18)).build_transaction({
        'chainId': 137,
        'from': MainWallet,
        'nonce': nonce,
        'gas': gas_limit,
        'gasPrice': w3.to_wei(100, 'gwei')
    })
    # 签名授权交易
    UltraPower_signed_approve_tx = w3.eth.account.sign_transaction(UltraPower_approve_tx, WalletPrivateKey)
    # 发送授权交易
    UltraPower_approve_tx_hash = w3.eth.send_raw_transaction(UltraPower_signed_approve_tx.rawTransaction)
    UltraPower_approve_tx_receipt = w3.eth.wait_for_transaction_receipt(UltraPower_approve_tx_hash)
    print(f'已向UltraPower授权:{UltraPower_approve_tx_receipt}')
    # 检查 UltraPower_Address 授权状态和数量
    allowance_UltraPower = Contract.functions.allowance(MainWallet, UltraPower_Address).call()
    print(f'UltraPower_Address 的授权数量: {allowance_UltraPower / 10 ** 18} DAI')
    time.sleep(30)

    ********************上面这段是新添加给UltraPower_Address项目合约的授权********************

    # 构建交互交易
    txn = {
        'chainId': 137,
        'from': MainAccount.address,
        'to': Web3.to_checksum_address(AAVE_V3_Address),
        'nonce': w3.eth.get_transaction_count(MainAccount.address),
        'data': data,
        'gas': gas_limit,
        'gasPrice': w3.to_wei(100, 'gwei')
    }

    # 签名交易
    signed_txn = w3.eth.account.sign_transaction(txn, WalletPrivateKey)
    print(signed_txn)
    # 发送交易
    txn_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
    approve_tx_receipt = w3.eth.wait_for_transaction_receipt(txn_hash)
    print('https://polygonscan.com/tx/' + txn_hash.hex())
    print(f"approve_tx_receipt:{approve_tx_receipt}")

但是执行后仍然报错 ‘Fail with error 'not approve'’。 那我就不懂了,查看前端代码也没啥东西,为啥这里交易会不成功呢?

求大佬指教我脚本应该怎么写,非常感谢。50学分双手奉上,感谢大佬的教导 Thanks♪(・ω・)ノ

请先 登录 后评论

最佳答案 2024-05-26 13:11

请先 登录 后评论

其它 3 个回答

Wade - Footprint Analytics CTO
  擅长:数据分析,GameFi,NFT
请先 登录 后评论
Wade - Footprint Analytics CTO
  擅长:数据分析,GameFi,NFT
请先 登录 后评论
xwisen
请先 登录 后评论
  • 3 关注
  • 0 收藏,1268 浏览
  • 用户_20014 提出于 2024-05-17 04:41