[암호화폐] 아무도 알려주지 않는 LP의 의미(3)

in SteemCoinPan •  9 months ago  (Edited)

그리고 보니 아무도 알려주지 않는다기 보다는 나만 모르는 LP의 의미일 수도 있겠다는 생각이 갑자기 들었습니다. 앞으로 더 열심히 공부해야할 듯 합니다.

지난 편에서는 LP contract에 나오는 값의 의미에 대하여 알아보았습니다. 이번에는 토큰을 swap하는 부분에 대하여 기술합니다.

우선 토큰 swap을 해야하는데, 너무 막막했습니다. 어떻게 하는지 도저히 감이 잡히지 않았습니다. 그래서 지인 찬스를 사용하였습니다. sct의 주 개발자이신 @happyberrysboy님께 swap 하는 api에 대하여 문의를 하였습니다. 그랬더니 당신이 사용하고 계신 node.js 코드를 알려주셨습니다. 이 지면을 빌어 다시 한번 감사드립니다.

비록 언어는 틀리지만 관련 소스를 확보하였으니, 진도가 팍팍 나갑니다.

신기하게도 swap도 smart contract로 이루어져있습니다. pancakeswap도 uniswap을 참고한 듯 합니다. uniswap 코드도 비슷하더군요.

자 이제 본론으로 들어갑니다.

pancakeswap에서 토큰 swap을 위한 스마트 컨트랙트는 아래와 같습니다. 이런 류의 contract를 router라고 부르는군요.

PancakeSwap: Router : 0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F

해당 contract에 가보면 다수의 함수가 보입니다. lp 만들고, staking하고, 해제하는 모든 API가 보입니다.

아래 함수는 swapping을 하기 전에 A 토큰에서 B 토큰으로 바꿀 때 몇 개가 나오는지 알아보는 함수입니다.

getAmountsOut(amountIn=amount, path=pair)
- amount : 바꿀 수량
- path : [ 'from token contract', 'to token contract']

즉 바꿀 수량과 A 토큰 주소, B 토큰 주소를 주면 [바꿀수량, 바꾼수량] 정보를 돌려줍니다.

코드로 확인해보겠습니다. 아래 코드는 1 usdt를 busd로 바꾸는 코드입니다. 한번 돌려보겠습니다.

w3 = Web3(Web3.HTTPProvider('https://bsc-dataseed.binance.org/'))
print(w3.isConnected())

# pancakeswap router 
exch_addr = '0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F'
exch_abi = '[{"inputs":[{"inter ... :"payable","type":"receive"}]'  # abi는 길어서 생략하였음

addr = w3.toChecksumAddress(exch_addr)
exchange = w3.eth.contract(address=addr, abi=exch_abi)

# amount_in, addr
pair = []
addr1 = w3.toChecksumAddress(sc_tokens['usdt'])
pair.append(addr1)
addr2 = w3.toChecksumAddress(sc_tokens['busd'])
pair.append(addr2)

amount = 1 * (10 ** 18)

ret = exchange.functions.getAmountsOut(amountIn=amount, path=pair).call()
print (ret)

아쉽게도 오류가 발생하는군요.

이 오류 원인을 찾느라 주말을 또 하얗게 불태웠습니다. stackoverflow에서 유사한 문제에 대한 질문이 있었지만, 특별한 답을 찾지 못하였습니다. web3 버전을 update하라는 답신이 있어서 업데이트하였지만 문제가 해결되지는 않았습니다. 결론적으로 원인을 발견하는데 실패!!!!

오늘 다시 @happyberrysboy님께 문의를 해 보았습니다. 당신이 사용하고 있는 코드라고 하더군요. 그렇다면 코드는 문제가 없고, 다른 곳에 문제가 있다는 의미입니다.

다시 한번 찬찬히 오류를 읽어보았습니다.

File "C:\MyPrograms\lib\site-packages\web3\utils\abi.py", line 50, in <listcomp>
    abi['name'] == name
KeyError: 'name'

주말에 몇시간을 봐도 전혀 원인을 알 수 없었는데, 갑자기 문제점이 보이더군요. 이 오류는 abi 항목 중 'name'이라는 항목이 없다는 의미입니다. 오류 창에 나오는 abi.py를 열어서 50 번 째 줄에 가 보았습니다.
이 코드는 결국 getAmountsOut() 함수를 찾는 부분입니다. contract도 문제없고, abi에 getAmountsOut함수도 명시되어 있습니다. 그렇다면 무엇이 문제일까요?

def filter_by_name(name, contract_abi):
    return [
        abi
        for abi
        in contract_abi
        if (
            abi['type'] not in ('fallback', 'constructor') and
            abi['name'] == name
        )
    ]

abi 파일 전체를 보니 function인 경우에만 'name'이라는 keyword가 있더군요. fallback, constructor에는 name 항목이 없고요. 순각적으로 무엇이 문제인지 생각이 났습니다. 원인은 'name' 항목이 없는 abi 항목이 더 있을 것 같았습니다. 함수가 너무 많아 간단하게 abi 내용을 출력하는 코드를 만들어보았습니다. 역시나 같은 오류가 발생합니다.

문제는 'receive' 라는 항목이 추가되었더군요. 아마도 web3가 최신 contract를 읽지 못해서 발생한 문제로 보입니다. 해결책은 간단하죠. web3.py에 있는 abi.py중 문제가 되는 부분을 아래와 같이 바꾸면 됩니다.

def filter_by_name(name, contract_abi):
    return [
        abi
        for abi
        in contract_abi
        if (
            abi['type'] not in ('fallback', 'constructor', 'receive') and
            abi['name'] == name
        )
    ]

이렇게 하고 다시 돌려보니,, 잘 돌아갑니다.

web3.py 가 오픈 소스이니 이렇게 수정도 할 수 있군요. 만약 다른 회사의 lib를 사용하였다면.. 영원히 사용할 수 없는 상태일텐데요. 오픈소스의 장점을 다시 한번 확인하는 계기가 되었습니다.

다음은 실제 스왑을 하는 코드인데요.

swapExactTokensForTokens(given_amount, min_amount, pair, my_addr, deadline)
given_amount : 바꿀 수량
min_amount : 받을 최소 수량
pair : [from  contract address, to contract address]
my_addr : 본인의 eth 지갑 주소
deadline : swap이 끝날 때 까지 기다릴 시간

그런데 이 함수에서 다시 문제가 발생하였습니다. 쉽게 가지를 않는군요.

아우.. 이 문제는 이번 주말에 또 풀어보겠습니다.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

[US$49.00](▼14%)[Nespresso]스타벅스 네스프레소 호환 캡슐 7종 / 120 캡슐 골라담기 / 20개씩 총 6종류 교차 선택 가능 / 중복 선택 가능 / 재고 확보 / 무료배송 / 개당 약 486원 최저가★

WWW.QOO10.COM

@tradingideas transfered 21 KRWP to @krwp.burn. voting percent : 70.64%, voting power : 80.09%, steem power : 1728262.57, STU KRW : 1200.
@tradingideas staking status : 10500 KRWP
@tradingideas limit for KRWP voting service : 31.5 KRWP (rate : 0.003)
What you sent : 21 KRWP [52028556 - ce8ceacd8629fa77c85f4e49c8c2cb796793d587]

오류 원인을 찾느라 주말을 또 하얗게 불태웠습니다.

정말 존경합니다.~~

멋집니다 트아형님..
전 귀찮아서 못하는....
화이팅입니다~!!

ㅋ 이제는 스왑까지 직접 만드시려고 하시는구나 ㅋㅋㅋ.

Thank You for Your insights...