Input Dataを利用してABIが分からないコントラクトのトランザクションを通す@python

今回はKaiaネットワークです。
KaiaSwapにて0.001WKLAYをUSDC.eにスワップして、このトランザクションをもとにpythonでスワップコードを書こうとしたのですが、ABIが見つけられず、Input Dataに若干の手を加えてpythonコードで通した、という話です。


KaiaSwapでのトランザクション(コントラクトのABIが見つからない)

0.001WKLAYをUSDC.eにスワップする操作を何回かしたときのスクショを添付します。

トランザクション1
トランザクション2

それぞれのトランザクションをブロックエクスプローラで確認。

通常は、ここからコントラクトのページへ行き、ABIを拾ってこればpythonコードを書ける。
しかし、(少なくとも私は)コントラクトのABIにたどり着くことができなかった。

Input Dataを考察する

ABIが見つからないので、ゼロからInput Dataを構築することもできなければ、Input Dataをデコードすることもできない。
ならば、Input Dataをそのまま投げればトランザクションは通るのではないか?と考えた。

#0.001wklay_usdce.py

import json
from web3 import Web3
from datetime import datetime

baseRpc = "https://public-en.node.kaia.io"
walletAddress = 'my_wallet_address'
walletKey = 'my_private_key'
kaiaSwap = '0xc0ac932cac7b4d8f7c31792082e2e8f3cfe99c10'

web3 = Web3(Web3.HTTPProvider(baseRpc))

now = int(datetime.now().timestamp()) 
nonce = web3.eth.get_transaction_count(walletAddress) 

tx = {
    'value': web3.to_wei(0, 'ether'),
    'chainId': 8217,
    'gas': 20000000,
    'gasPrice': web3.eth.gas_price,
    'nonce': nonce,
    'from': walletAddress,
    'to': web3.to_checksum_address(kaiaSwap),
    'data': '0x88d527dc000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000f69fd1acae36de01e61e722cdf44b5bf9baadd5c00000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000000012100000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000067570e8b000000000000000000000000000000000000000000000000000000000000002b19aac5f612f524b754ca7e7c41cbfa2e981a44320001f4e2053bcf56d2030d2470fb454574237cf9ee3d4b000000000000000000000000000000000000000000'
}

print("tx = ")
print(tx)

signedTx = web3.eth.account.sign_transaction(tx, walletKey)
txHash = web3.eth.send_raw_transaction(signedTx.raw_transaction)

print('kaiaSwap transaction')
print(web3.to_hex(txHash))
result = web3.eth.wait_for_transaction_receipt(txHash)
status = result['status']
if status == 1:
   print('Transaction Succeeded')
else:
   print('Transaction Failed')
   

data部分に、下記のトランザクションのInput Dataをそのまま入れてみた。

通った・・・

ブロックエクスプローラでも。

しかし、時間が経つと失敗するようになる。

ここで、Input Dataの構造を思い出す。

deadlineという引数を取る場合もあると・・・

何度か実施した同様のスワップ(0.001WKLAY→USDC.e)のInput Dataを並べてみる。

トランザクション1
トランザクション2
トランザクション3
トランザクション4

argの7行目にdeadlineぽい数字が並んでいるのに気が付く。
ここを大きく設定してしまえば、トランザクションの有効期限が伸びる。

ただ、それ以外にもargの5行目と9行目も異なる場合があることに気が付く。

KaiaSwapのWebサイトからスワップしてInput Dataを確認して、という作業を繰り返していると、
・5行目はだんだんと値が小さくなる
・9行目はfee?が0.3%のときと0.05%のときで異なる
ということに気が付いた。

つまり、9行目は常に2択で、5行目は値を小さく設定し、7行目は値を大きく設定すればよいことが分かった。

トランザクションを通す

執筆現在は0.05%のパターンなのでInput Dataがこれに該当する方を選ぶ。

そして、まずは過去のInput Dataをそのまま通そうとしてみるが、通らない(deadline:有効期限)切れ。

では、上記txのdeadline部分:67570d07を69570d07に変えてみる。

しかし、通らない。何を意味しているかは分かりませんが5行目が時間とともに変化(小さくなっていく)からです。実際、5行目が変化しない時間間隔であればdeadlineを大きく設定するだけでトランザクションは通りました。

それでは、上記txの121の部分を000に変えてみます。

通りました。

ブロックエクスプローラでの確認は以下です。

fee?が0.3%のパターンのときも同様にできます。

最後にpythonコードを載せておきます。

#0.001wklay_usdce.py

import json
from web3 import Web3
from datetime import datetime

baseRpc = "https://public-en.node.kaia.io"
walletAddress = 'my_wallet_address'
walletKey = 'my_private_key'
kaiaSwap = '0xc0ac932cac7b4d8f7c31792082e2e8f3cfe99c10'

web3 = Web3(Web3.HTTPProvider(baseRpc))

now = int(datetime.now().timestamp()) 
nonce = web3.eth.get_transaction_count(walletAddress) 

tx = {
    'value': web3.to_wei(0, 'ether'),
    'chainId': 8217,
    'gas': 20000000,
    'gasPrice': web3.eth.gas_price,
    'nonce': nonce,
    'from': walletAddress,
    'to': web3.to_checksum_address(kaiaSwap),
    'data': '0x88d527dc000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000f69fd1acae36de01e61e722cdf44b5bf9baadd5c00000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000069570d07000000000000000000000000000000000000000000000000000000000000002b19aac5f612f524b754ca7e7c41cbfa2e981a44320001f4e2053bcf56d2030d2470fb454574237cf9ee3d4b000000000000000000000000000000000000000000'
}

print("tx = ")
print(tx)

signedTx = web3.eth.account.sign_transaction(tx, walletKey)
txHash = web3.eth.send_raw_transaction(signedTx.raw_transaction)

print('kaiaSwap transaction')
print(web3.to_hex(txHash))
result = web3.eth.wait_for_transaction_receipt(txHash)
status = result['status']
if status == 1:
   print('Transaction Succeeded')
else:
   print('Transaction Failed')
   

data部分を変更していくだけです。

いいなと思ったら応援しよう!