5 我想实现在scroll测试链,部署脚本交互,ETH/USDC的交换,但是每次都有hash报错 Error: execution reverted,有人能帮我看下代码调整下么?

import web3
import math
import requests

headers = {
    'content-type': 'application/json',
    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
}

class Rpc:
    """
    eth rpc方法
    """

    def __init__(self, rpc='https://eth-goerli.g.alchemy.com/v2/xxxx-P', chainid=5, proxies=None, timeout=30):
        self.rpc = rpc
        self.chainid = chainid
        self.proxies = proxies
        self.timeout = timeout

    def get_current_block(self):
        """获取最新区块"""
        data = {"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}
        res = requests.post(self.rpc, json=data, headers=headers, proxies=self.proxies, timeout=self.timeout)
        return res.json()

    def get_block_detail(self, number):
        """获取区块hash"""
        if isinstance(number, int):
            number = hex(number)
        data = {"jsonrpc": "2.0", "method": "eth_getBlockByNumber", "params": [number, True], "id": 1}
        res = requests.post(self.rpc, json=data, headers=headers, proxies=self.proxies, timeout=self.timeout)
        return res.json()

    def get_transaction(self, txhash):
        """获取的交易详情"""
        data = {"jsonrpc": "2.0", "method": "eth_getTransactionByHash", "params": [txhash], "id": 1}
        res = requests.post(self.rpc, json=data, headers=headers, proxies=self.proxies, timeout=self.timeout)
        return res.json()

    def get_gas_price(self):
        """获取gas"""
        data = {"jsonrpc": "2.0", "method": "eth_gasPrice", "params": [], "id": 1}
        res = requests.post(self.rpc, json=data, headers=headers, proxies=self.proxies, timeout=self.timeout)
        return res.json()

    def get_transaction_count_by_address(self, address):
        data = {"jsonrpc": "2.0", "method": "eth_getTransactionCount", "params": [address, 'latest'], "id": 1}
        res = requests.post(self.rpc, json=data, headers=headers, proxies=self.proxies, timeout=self.timeout)
        return res.json()

    def call(self, to, data):
        data = {"jsonrpc": "2.0", "method": "eth_call", "params": [{"to": to, "data": data}, "latest"], "id": 1}
        res = requests.post(self.rpc, json=data, headers=headers, proxies=self.proxies, timeout=self.timeout)
        return res.json()

    def send_raw_transaction(self, hex):
        """广播交易"""
        data = {"jsonrpc": "2.0", "method": "eth_sendRawTransaction", "params": [hex], "id": 1}
        res = requests.post(self.rpc, json=data, headers=headers, proxies=self.proxies, timeout=self.timeout)
        return res.json()

    def get_balance(self, address):
        """获取余额"""
        data = {"jsonrpc": "2.0", "method": "eth_getBalance", "params": [address, 'latest'], "id": 1}
        res = requests.post(self.rpc, json=data, headers=headers, proxies=self.proxies, timeout=self.timeout)
        return res.json()  # (int(res.json()['result'], 16)) / math.pow(10,18)

    def transfer(self, account, to, amount, gaslimit, **kw):
        """离线交易
        account
        to: 收款地址
        gaslimit: 由当前区块的gaslimit获取
        gasprice: get_gas_price获取
        nonce: 交易总数 get_transaction_count_by_address获取
        chainId: 链id
        """
        amount = int(amount, 16) if isinstance(amount, str) else int(amount)
        gaslimit = int(gaslimit, 16) if not isinstance(gaslimit, int) else gaslimit
        gasprice = int(self.get_gas_price()['result'], 16)
        nonce = int(self.get_transaction_count_by_address(account.address)['result'], 16)
        tx = {'from': account.address, 'value': amount, 'to': to, 'gas': gaslimit, 'gasPrice': gasprice, 'nonce': nonce,
              'chainId': self.chainid}
        if kw:
            tx.update(**kw)
        signed = account.signTransaction(tx)
        return self.send_raw_transaction(signed.rawTransaction.hex())

if __name__ == '__main__':
    privkeys = 'xxxxxxxxx'  # 这里替换成自己的私钥
    value = 0.005  # 要存款的数量
    account = web3.Account.from_key(privkeys)
    BALANCE_PRECISION = math.pow(10, 18)  # 主币精度,18位
    rpc = Rpc('https://alpha-rpc.scroll.io/l2', chainid=534353)
    value = int(value * BALANCE_PRECISION)
    gaslimit = 300004  # gaslimit
    to = '0xD9880690bd717189cC3Fbe7B9020F27fae7Ac76F'  # 交互的合约地址
    method = '0x5ae401dc'  # 存款方法hash值
    data = method
    res = rpc.transfer(account, to=to, amount=value, gaslimit=gaslimit, data=data)  # 发送交易
    print(res)

1680984038409.jpg

请先 登录 后评论

最佳答案 2024-07-01 12:23

看上去,这是一个需要填入参数的合约,我随便找了一笔正常的合约交易0x7d32be82edd7503e4a105dc99c60aefb0ddb5645127aeda66fe6b4277b8344de,他的inputdata为0x5ae401dc0000000000000000000000000000000000000000000000000000000064367c8900000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf000000000000000000000000a1ea0b2354f5a344110af2b6ad68e75545009a03000000000000000000000000a0d71b9877f44c744546d649147e3f1e70a937600000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000006fc37b666694b6a1ad4dd617c294aa7527ac44fc00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000002f568954c5602a917b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 里面需要两个参数

input.png data input里跟在函数id后的第一段0000000000000000000000000000000000000000000000000000000064367c89是deadline 16进制后填充到uint32再去掉前面的0x,deadline像是一个机器时间,再找一笔正常的交易0x88ff402f5ec1b74ed650bc62ea25f1bb714d60d7b09120346fc7abf07ace65ed去对照:0x5ae401dc0000000000000000000000000000000000000000000000000000000064367cf200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf000000000000000000000000a1ea0b2354f5a344110af2b6ad68e75545009a03000000000000000000000000a0d71b9877f44c744546d649147e3f1e70a9376000000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000fce09ad36566585adcc964fd022e0093b4a4e2f40000000000000000000000000000000000000000000000000001d463c80f300000000000000000000000000000000000000000000000001860986ca84f49592c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 其中从deadline之后一大段是相同的: 00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e404e45aaf000000000000000000000000a1ea0b2354f5a344110af2b6ad68e75545009a03000000000000000000000000a0d71b9877f44c744546d649147e3f1e70a9376 应该是一个固定参数e404e45aaf,接着wethtoken地址和usdctoken地址。 接下来我们继续看到一段 00000000000000000000000000000000000000000000000000000000000001f4看上去像是一个开关参数,发现交易里右bb8和1f4的。后面是调用者地址,继续是weth数量转换16进制后填充uint32和usdc数量一样的操作。 作者可以根据这个思路把data填充好再发送交易,其中可能有一些细节上的出入。 可以参考:https://docs.soliditylang.org/en/latest/abi-spec.html

请先 登录 后评论

其它 2 个回答

Tiny熊
  擅长:智能合约,以太坊
请先 登录 后评论
用户_14807
请先 登录 后评论
  • 3 关注
  • 0 收藏,1952 浏览
  • blackshor 提出于 2023-04-09 04:06