node.js를 이용한 방법은 많이 나와있지만 파이썬을 이용한 방법을 찾지 못하여 어렵게 방법을 찾았습니다.

어디에도 없는 파이썬을 이용한 BSC Smart Contract에서 claim하는 방법에 대하여 정리합니다.

 

pancakeswap 중 syrup에 있는 Alice pool에서 채굴 중인 cake을 자동으로 claim하는 코드입니다. 다른 pool의 경우에도 주소만 변경하면 같은 방식으로 claim이 가능합니다.

 

우선 alice 채굴 풀의 주소입니다.
'syrup-alice' : '0x4C32048628D0d32d4D6c52662FB4A92747782B56'

이 주소에 접속한 후 contract 부분을 보면 아래와 같은 정보를 확인할 수 있습니다.

  • 현재까지 채굴된 cake 수 : pendingReward(my_addr)
  • 현재까지 채굴된 cake claim : withdraw(0)

 

alice 채굴풀의 Smart Contract에서 채굴한 수량을 검색한 후 일정 수량이상 쌓여있다면 withdraw()를 하면 됩니다.

 

pendingReward() 함수는 직관적이라 설명을 생략하고요. 채굴된 cake을 claim하는 함수가 withdraw()입니다. 그런데 deposit한 cake도 뺄 때 사용하는 함수입니다. 따라서 deposit한 cake은 빼지않고, reward만 claim하는 방법은 인자로 0을 넣으면 됩니다.

pancakeswap에서 claim을 해보면 지갑이 뜨고, Confirm을 눌러야 claim이 됩니다. 이런 일을 코드로 전달해주어야 합니다. 그런데 이 부분이 아주 난감했습니다만, 어찌어찌하여 방법을 알아내었습니다.

코드는 아래와 같습니다.

 

sc_addr = {
    'bnb-busd' : '0x1B96B92314C44b159149f7E0303511fB2Fc4774f',
    'cake-bnb' : '0xA527a61703D82139F8a06Bc30097cC9CAA2df5A6',
    'ust-nflx' : '0xF609ade3846981825776068a8eD7746470029D1f',
    'syrup-alice' : '0x4C32048628D0d32d4D6c52662FB4A92747782B56',
}
sc_abis = {
    'syrup' : '[]'  # abi 코드가 길어서 삭제함.
}

my_addr  = 'my eth address'
my_priv = 'my private key'

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

print(w3.isConnected())

# alice harvest
if 1 : 
    addr = sc_addr['syrup-alice']
    abi = sc_abis['syrup']
    syrup = w3.eth.contract(address=addr, abi=abi)
    pending = syrup.functions.pendingReward(my_addr).call()
    print(pending)
    tx = syrup.functions.withdraw(0).buildTransaction({   # 채굴한 코인 claim시에는 0
                'gas': 150000,
                'gasPrice': w3.toWei('10', 'gwei'),
                'nonce':  w3.eth.getTransactionCount(my_addr),
            })
    signed_tx = w3.eth.account.signTransaction(tx, private_key=my_priv)
    ret = w3.eth.sendRawTransaction(signed_tx.rawTransaction)

이 코드의 결과를 bscscan에서 확인해보겠습니다.

 

 

 

원하는 결과가 나왔습니다.
앞으로는 주기적으로 자동으로 claim하고, 원하는 곳에 deposit을 할 수 있을 것 같습니다.

 

그동안 소개한 Smart Contract를 다루는 방법을 모아서 pancakeswap에서 채굴 중인 cake을 claim한 후 syrup pool에 deposit하는 작업을 마무리한 후 코드 공개하도록 하겠습니다.

 

반응형

설정

트랙백

댓글

BSC DeFi에 대한 간단한 소개에 이어 이제 실전으로 들어가보겠습니다.

우선 web3.py를 설치하여야 합니다. 설치 방법은 아래와 같이.

 

pip install web3

 

DeFi 프로젝트에 따라서 smart contract을 만드는 방식이 다양합니다. 따라서 사이트에 맞게 필요한 smart contract 주소를 잘 찾아야합니다. 예제로 선보인 pancakeswap은 아래와 같은 구조로 구성되어 있습니다.

 

pancakeswap 풀에 있는 모든 풀은 MasterChef라는 이름의 smart contract 만들어져있습니다. 각각의 풀도 smart contract이고 각 풀에 있는 token들도 smart contract로 만들어져있습니다.

 

 

각각의 smart contract 주소는 아래와 같습니다.

 

MasterChef : 0x73feaa1eE314F8c655E354234017bE2193C9E24E
   |
  +-- Cake-BNB LP : 0xA527a61703D82139F8a06Bc30097cC9CAA2df5A6
     |
    + Cake : 0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82
    + Bnb : 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c

 

전 글에서 언급하였듯이 smart contract의 ABI가 필요합니다. bscscan에 접속하여 해당 주소를 입력한 후 ABI 값을 복사해옵니다.

 

Cake-BNB LP와 Cake, Bnb의 경우에는 Cake-BNB LP smart contract를 사용합니다. 일반적인 smart contract에 있는 함수만 사용하기 때문에 각각의 ABI 파일을 다운받을 필요가 없지만 각 contract 고유의 기능을 사용하려면 별도로 모두 받아야합니다. 이 절차가 조금 번거롭기는 합니다.

 

파이썬 프로그램으로 해당 smart contract의 값을 읽어오는 절차입니다.

 

우선 bsc network으로 Web3를 기동시킵니다. 사용하는 블럭체인에 맞는 주소를 입력해주면 됩니다.

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

 다음으로는 검색할 pool에 대한 주소와 ABI 값을 dict구조에 추가합니다. 앞으로 여러 pool을 대상으로 검색을 할 수 있도록 dict 형태로 작업을 했습니다.

그리고 common abi도 하나 복사해두었습니다. 이건 Cake-BNB LP에서 가져온 ABI입니다.

 

이러한 정보를 바탕으로 w3.eth.contract() 함수를 호출합니다.

pools = { 
        'pancake' : 
            {   'addr':'0x73feaa1eE314F8c655E354234017bE2193C9E24E',
                'abi' : '[{"inputs":[{"internalType"...]' # 너무 길어서 생략
            },
}

# 일반적인 풀의 abi. 만약 함수명이 틀린 풀이 있으면 해당 풀의 abi로 대체
contract_common_abi = '[{"inputs":[],"payable":false, ...]' # 너무 길어서 생략

def pool_info():
    for name in pools : 
        ee = w3.eth.contract(pools[name]['addr'], abi=pools[name]['abi'])
        

 

pancakswap MasterChef ABI를 보고서 필요한 함수를 부릅니다. 이 ABI에는 pool의 갯수를 알려주는 함수가 있습니다. 풀 갯수만큼 루프를 돌리면서 본인이 staking한 풀에 채굴된 cake 수량을 출력해주는 함수입니다.

 

        # 풀의 총 갯수를 얻는다.
        poolLength = ee.functions.poolLength().call()
        for 풀 수량 만큼 :
            # 해당 풀에 deposit한 수량을 얻는다.
            user_info = ee.functions.userInfo(i, my_addr).call()
	
            # 만약 내가 staking한 pool이면
            if user_info[0] > 0 :  # for only staked pools
                # 풀에 대한 정보를 얻는다.
                poolInfo = ee.functions.poolInfo(i).call()

                # deposit한 LP 수량을 얻는다.
                deposit = user_info[0] / (10 ** 18 ) 

                # 채굴된 cake의 수량을 얻는다.
                pending_cakes = ee.functions.pendingCake(i, my_addr).call() 
                pending_cakes_real = pending_cakes/(10 ** 18 )


                # 해당 풀의 smart contract 주소를 얻는다.
                addr1 = poolInfo[0]

                # 해당 풀의 토큰의 주소와 abi로 smart contract 정보를 얻는다.
                e1 = w3.eth.contract(addr1, abi=contract_common_abi)

                # 1번 토큰의 주소를 얻은 후 smart contract 정보를 얻는다.
                token1 = e1.functions.token0().call()
                t1 = w3.eth.contract(token1, abi=contract_common_abi)

                # 1번 토큰 정보를 얻는다
                name1 = t1.functions.name().call()
                sym1 = t1.functions.symbol().call()

                # 2번 토큰의 주소를 얻은 후 smart contract 정보를 얻는다.
                token2 = e1.functions.token1().call()
                t2 = w3.eth.contract(token2, abi=contract_common_abi)

                # 2번 토큰 정보를 얻는다
                name2 = t2.functions.name().call()
                sym2 = t2.functions.symbol().call()

                print("[%6s - %6s] %10.3f   %10.3f"%(sym1, sym2, deposit, pending_cakes_real))

 

 결과를 확인해보겠습니다.

 

화면에서 보는 수량과 일치하는 값을 얻을 수 있었습니다.

이 방식을 기반으로 여러 DeFi 프로젝트의 smart contract 주소와 ABI 파일을 구하면 본인이 투자한 DeFi에서 채굴한 토큰의 수량을 바로 파악을 할 수 있을 것 같습니다.

 

다음으로 할 일은 채굴된 토큰들을 자동으로 claim하는 부분입니다. 이 또한 예제가 부실하여 아직 작업이 마무리되지 못하였습니다. 이번 주말에 작업해서 성공한다면 정리해서 올리도록 하겠습니다.

 

파이썬으로 BSC Smart contract를 다루는 예제를 발견하기 어려운데요. 이렇게 간단하게 구현할 수 있는 것을 아주 아주 힘들게 돌아온 것 같습니다. 

 

본 글에 나오는 예제는 아래 github에 있습니다.

 

github.com/multizone-quant/DeFi/blob/main/WatchingDeFi.py

반응형

설정

트랙백

댓글

요즘은 트레이딩 보다는 DeFi에 집중을 하다보니, 자동매매 관련 글을 못올리고 있습니다. pancake, mir 등등 안정적이면서 높은 수익률을 보여주는 DeFi가 많이 있습니다. 이외도 현재 채굴 중인 DeFi가 많다보니, 매일같이 접속해서 채굴된 코인 claim하고 현재가에 매도하는 것만 해도 많은 시간이 소요됩니다.

 

이렇다보니, 검증된 DeFi의 현재 staking 상황, 채굴된 토큰 수량, 심지어 현재가 기준으로 자산 평가액까지 보여주는 사이트도 등장하였습니다. 대표적인 사이트가 yieldwatch.net/ 입니다. 원하는 DeFi를 선택한 후 주소를 입력하면 현재 투자한 DeFi에 대한 시가 평가액을 보여줍니다. 한눈에 투자 상황을 볼 수 있어서 엄청나게 편리합니다. 

 

 

심지어는 투자중인 DeFi를 등록하면 채굴된 토큰을 주기적으로 claim한 후 해당 LP에 추가해주는 사이트까지 등장하였습니다. 대표적인 사이트가 https://autofarm.network/ 입니다. 이 사이는 auto라고 하는 자체 token도 발행하여 타 사이트에 비하여 높은 수익률을 제공해주고 있습니다.

 

 

yieldwatch 덕분에 투자 상황을 한눈에 파악할 수 있고, autofarm 덕분에 claim하는 수고를 들기는 했지만 그래도 직접 claim하는 경우도 많이있습니다.

 

이에 현재 채굴 중인 Binance Smart Contract 이하 BSC 기반 DeFi의 채굴 상황을 확인하고, 필요하다면 claim까지 하는 프로그램을 만들어보고자 합니다.

 

BSC는 이더리움 기반이다보니 DeFi에 사용하는 smart contact는 solidity언어로 개발되어 있습니다. 이미 만들어진 smart contract를 읽고/쓰기 위해서는 다양한 언어를 이용할 수 있습니다.

 

전 파이썬을 주로 사용하기 때문에 파이썬을 이용하여 smart contract를 다루어 보도록 하겠습니다. 그런데 문제는 파이썬을 이용하여 BSC smart contract를 다루는 예제가 많지 않았습니다. 구글링을 통해서 조각을 맞쳐가면서 작업을 진행하고 있습니다.

 

우선 파이썬을 이용하여 이더리움 기반 smart contract를 다룰 수 있는 패키지는 web3.py입니다.

 

 

web3.py 덕분에 새로운 언어를 배우지 않고도 원하는 작업을 할 수 있어서 다행입니다.

 

다음으로는 Smart contract에 대하여 간단하게 알아보겠습니다.

 

BSC DeFi 대명사인 pancakeswap입니다. 무려 80여개의 채굴 풀이 동작 중입니다. 그러다보니 본인이 채굴 중인 풀을 찾기가 힘들었었는데요. 최근 staked only 항목이 생겨서 채굴 중인 풀을 한 눈에 볼 수 있어서 많이 편해졌습니다.

 

 

채굴 풀은 smart contract로 만들어져있습니다. 한번 만들어진 smart contract는 절대 변경할 수가 없습니다. 따라서 코드 오류만 없다면 안전하다고 볼 수 있습니다. 특정 풀의 smart contract는 bscscan.com/에서 확인이 가능합니다.

pancakeswap의 smart contract 주소는 0x73feaa1eE314F8c655E354234017bE2193C9E24E 입니다.

bscscan.com에서 해당 주소를 입력해보면 아래와 같은 내용을 볼 수 있습니다. 이 중 contract를 클릭하면 해당 smart contract의 소스코드를 볼 수 있습니다.

 

 

이 중 우리가 필요한 것은 ABI 입니다. abi는 Application Binary Interface의 약자로 해당 smart contract를 외부에서 사용할 수 있는 api라고 보시면 됩니다. 오른쪽에 있는 복사 아이콘을 사용하여 복사한 후 프로그램에서 사용하면 됩니다.

 

 

이제 pancakeswap에 있는 풀의 내용을 읽을 수 있는 준비가 되었습니다.

다음 글에서는 web3.py를 이용하여  pancakeswap 풀을 읽는 예제를 파이썬 코드로 소개하도록 하겠습니다.

 

반응형

설정

트랙백

댓글