>백엔드 개발 >파이썬 튜토리얼 >web3.py를 통해 Python으로 Ethereum에 액세스하세요.

web3.py를 통해 Python으로 Ethereum에 액세스하세요.

王林
王林앞으로
2023-04-12 13:46:061795검색

web3.py를 통해 Python으로 Ethereum에 액세스하세요.

Python을 통해 Ethereum에 액세스하려면 Ethereum의 공식 Github에서 이를 수행할 수 있는 두 가지 모듈인 web3.py와 pyethereum이 있음을 확인할 수 있습니다. 현재 내가 이해하는 한, 둘 사이의 차이점은 web3.py가 주로 이더리움에 대한 외부 액세스를 위한 클라이언트로 사용된다는 것입니다. 즉, web3.py 함수 라이브러리 자체는 블록체인 노드가 되지 않으며 앞으로도 그럴 것입니다. 체인 동기화는 블록체인의 노드를 연결하고 블록체인을 외부 데이터베이스로 사용하는 반면, 파이이더리움은 자체적으로 블록체인 노드를 만드는 데 사용되는 geth와 유사하며 정상적으로 수행할 수 있습니다. 또한 광부로서 채굴을 시작합니다.

이 글에서는 블록체인과 상호 작용할 수 있는 가벼운 클라이언트를 원하고, 블록체인 데이터를 저장하기 위해 거대한 저장 공간을 준비하고 싶지 않기 때문에 web3.py를 기본 클라이언트로 사용하겠습니다.

  • web3.py 실행 환경 구성
  • web3.py를 통해 Ethereum 노드 연결
  • 블록체인에서 ERC20 계약에 액세스
  • 트랜잭션 서명 및 보내기

web3.py 실행 환경 구성

web3.py 확인 다음을 통해 직접 설치 씨.

pip install web3

Windows에 설치하려면 Visual C++ Builder를 미리 설치해야 하며, 그렇지 않으면 설치 마지막 단계에서 컴파일할 수 없어 실패하게 된다는 점에 유의해야 합니다.

web3.py를 통해 이더리움 노드에 연결

web3.py는 블록체인 노드로 존재하지 않으므로 블록체인의 데이터에 액세스하려면 노드가 필요합니다. 일반적으로 가장 안전한 방법은 geth 또는 parity를 ​​사용하여 자체 노드를 구축하는 것입니다. 그러나 자체 노드를 구축하고 싶지 않다면 infura에서 제공하는 HTTP 노드 서비스를 살펴보는 것이 좋습니다.

infura의 현재 API를 기준으로 Ropsten 테스트 체인에 연결하려면 링크 URL은 https://ropsten.infura.io/v3/api_key이며, 계정을 얻으려면 api_key를 등록해야 합니다. 다음 프로그램은 환경 변수에서 INFURA_API_KEY 매개변수를 읽어 Ropsten 테스트 체인과의 연결을 설정하는 데 사용되는 infura.io의 HTTP 주소를 형성하는 web3.py의 내장 auto.infura의 실행을 모방합니다.

블록체인에서 ERC20 계약 입출금

import os
from web3 import (
HTTPProvider,
Web3,
)
INFURA_ROPSTEN_BASE_URL = 'https://ropsten.infura.io/v3'
def load_infura_url():
key = os.environ.get('INFURA_API_KEY', '')
return "%s/%s" % (INFURA_ROPSTEN_BASE_URL, key)
w3 = Web3(HTTPProvider(load_infura_url()))

계약 입출금을 시작하기 전에 ABI가 무엇인지 이야기해야 합니다. 이더리움에서는 컨트랙트가 모두 컴파일된 바이너리 코드 형태로 존재하기 때문에 컨트랙트의 반환 값이 모두 바이너리이기 때문에 컨트랙트가 전송한 내용이 무엇인지 함수 라이브러리에서 직접 알 수 있는 방법이 없습니다. 따라서 계약을 실행하기 전에 함수 라이브러리에 계약 사용 방법을 알려주는 ABI 파일을 제공해야 합니다.

# Assume the contract we're going to invoke is a standard ERC20 contract.
with open("erc20.abi.json") as f:
erc20_abi = json.load(f)
# Web3 accept only checksum address. So we should ensure the given address is a
# checksum address before accessing the corresponding contract.
contract_addr = w3.toChecksumAddress('0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6');
erc20_contract = w3.eth.contract(address=contract_addr, abi=erc20_abi)
for func in erc20_contract.all_functions():
logger.debug('contract functions: %s', func)
logger.debug("Name of the token: %s", erc20_contract.functions.name().call())

여기에서는 Ropsten 테스트 체인의 0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6 주소로 스마트 계약에 액세스하려고 한다고 가정합니다. 본 컨트랙트는 이더스캔을 통해 무작위로 찾아낸 ERC20 컨트랙트이므로 표준 ERC20 ABI를 이용하여 접근할 수 있습니다. 이 계약의 인스턴스를 생성할 때 먼저 루프를 실행하여 계약의 모든 함수를 인쇄한 다음(이 단계는 실제로 ABI에 대한 정보를 나열합니다) 계약에서 name()을 호출하여 계약 선언. 토큰 이름. 최종 출력은 다음과 같습니다.

2018-09-07 15:02:53,815 | __main__ | DEBUG | contract functions: <Function name()>
2018-09-07 15:02:53,816 | __main__ | DEBUG | contract functions: <Function approve(address,uint256)>
2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function totalSupply()>
2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function transferFrom(address,address,uint256)>
2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function decimals()>
2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function balanceOf(address)>
2018-09-07 15:02:53,824 | __main__ | DEBUG | contract functions: <Function symbol()>
2018-09-07 15:02:53,825 | __main__ | DEBUG | contract functions: <Function transfer(address,uint256)>
2018-09-07 15:02:53,825 | __main__ | DEBUG | contract functions: <Function allowance(address,address)>
2018-09-07 15:02:54,359 | __main__ | DEBUG | Name of the token: KyberNetwork

Sign and send the transaction

위의 예에서 스마트 계약을 호출할 때 계약의 함수를 직접 호출하지만 이는 일반적으로 데이터를 읽는 데만 사용할 수 있습니다. 블록체인 현황. 스마트 계약을 호출하여 블록체인에 데이터를 쓰려면 다른 방식으로 계약을 호출해야 합니다. 즉, 먼저 트랜잭션에 서명한 다음 트랜잭션을 실행하기 위해 가스를 지불해야 합니다.

ERC20 계약을 호출하고 계약에서 transferFrom() 함수를 실행한다고 가정해 보겠습니다. transferFrom()에는 _from, _to, _value 세 개의 매개변수가 필요합니다. 즉, 이체 금액이 _from 계정에서 _to 계정으로 이체되며 이체 금액은 _value입니다.

# Set the account which makes the transaction.
account = w3.toChecksumAddress(os.environ.get('ETHEREUM_ACCOUNT', ''))
w3.eth.defaultAccount = account
# Web3 accept only checksum address. So we should ensure the given address is a
# checksum address before accessing the corresponding contract.
contract_address = w3.toChecksumAddress('0x4e470dc7321e84ca96fcaedd0c8abcebbaeb68c6')
contract = w3.eth.contract(address=contract_address, abi=contract_abi)
# Prepare the necessary parameters for making a transaction on the blockchain.
estimate_gas = contract.functions.transferFrom(account, account, w3.toWei('1', 'eth')).estimateGas()
nonce = w3.eth.getTransactionCount(account)
# Build the transaction.
txn = contract.functions.transferFrom(account, account, w3.toWei('1', 'eth')).buildTransaction({
'chainId': 3,
'gas': estimate_gas,
'gasPrice': w3.toWei('1', 'gwei'),
'nonce': nonce
})
logger.debug('Transaction: %s', txn)
# Sign the transaction.
private_key = bytes.fromhex(os.environ.get('ETHEREUM_ACCOUNT_PKEY', ''))
signed_txn = w3.eth.account.signTransaction(txn, private_key=private_key)
tx_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
logger.debug('Txhash: 0x%s', bytes.hex(tx_hash))

위 프로그램에서 2~3번째 줄은 먼저 환경 변수에서 사용하려는 계정을 읽어옵니다. 이 계정은 트랜잭션을 보내는 데 사용됩니다. 물론 가스를 지불할 때도 이 계정에서 차감됩니다. 10~20번째 줄은 raw transaction을 생성하는데, 이번 transaction에서는 gas, nonce 등의 매개변수를 지정해야 하므로 이전 11~12번째 줄에서 몇 개의 매개변수를 설정할지 확인해야 합니다. 그런 다음 가장 중요한 라인 25~26은 개인 키를 읽고 개인 키를 사용하여 트랜잭션에 서명합니다. 여기서는 개인 키가 Hex로 인코딩된 텍스트로 구성된다고 가정하므로 bytes.fromhex는 Hex 인코딩을 다시 바이트 형식으로 변환하는 데 사용됩니다. 서명 후 트랜잭션을 보냅니다. 트랜잭션을 보낼 때 API는 트랜잭션 해시를 바이트 형식으로 반환합니다. 그런 다음 etherscan에서 트랜잭션을 검색할 수 있습니다.

위 내용은 web3.py를 통해 Python으로 Ethereum에 액세스하세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 51cto.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제