* `- H6 o+ @2 A: C# `
- pip install web3.py
. [. E% C- e! D; k7 |# n
2、注册 Infura 获得节点服务& Q9 o" I1 d0 e
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL

可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。
3、代码示例 1 }6 q1 ^5 k) J7 c
- 2 x. I5 \# @8 {9 }* g
- from web3 import Web3' x& A, ?( @1 r
- import json( y& ^, O j7 S, s2 R5 L
- import time
- import os( s! V R. J- j* r4 f1 V/ S
- import logging
- from django.conf import settings
- from decimal import Decimal N/ h2 g4 E+ H! t$ d' B+ B) K
- . l; d+ c! r+ d ~; r+ a
- class PayEthOrToken(object):5 N$ T5 ~8 q# Z) W/ R. ?0 K5 w
- " A) g; \, g6 k) ` @5 J7 A/ J
- def __init__(self):. F4 K6 v( Y8 w0 @
- # 设置web3* a) t0 F% d4 M) c2 X! |
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))# q% X @$ t; O* @; B& q e6 X% j8 C
- # token合约地址
- self.contract_address = 'your contract address'7 }: d' @ G% Z& ~% f; i
- # 主钱包地址
- self.wallet = 'your wallet address'
- # 钱包的私钥5 ]5 F6 E+ R" P
- self.wallet_key = 'your wallet key'
- # 合约的abi test.json 是eth的abi json文件,可以在eth区块链浏览器上获得
- with open('test.json', 'r') as f:
- self.abi = json.loads(f.read())0 `% U5 T5 x- [6 D( |( e! x
- # 生成合约
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)# n; u7 x0 K1 W: g- Y7 z
- # 代币简写
- self.token_name = 'USDT'
- 6 i8 @6 D+ v: C, C8 }
- def transfer_usdt(self, to, value):4 @. r$ I4 ~# ^ s
- '''进行代币转账' {( A, o* c4 H# I+ s9 y( f6 P
- args:
- to str:接收代币的地址, }0 r4 O6 b$ m5 |0 F
- value str/int:代币数量,以ether为单位,可以是字符串和int类型0 `8 F3 S* [, i0 K
- returns:/ ^4 O# y1 W. t, H* ]. R) V9 D
- (str, str):返回交易哈希,以及异常信息% v( ?; Y! s8 a- K' [
- '''( c6 A: a6 s% q5 {# S- j2 _6 ^. O' _* g
- try:# m8 j1 ^) s9 ^! k
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')/ _. ` E* T* C8 k3 \
- # 如果代币不足返回异常 |/ L- R; l0 W' B F
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform USDT token is insufficient, please try again later'
- # 进行转账代币
- nonce = self.web3.eth.get_transaction_count(self.wallet); s0 P, W; p0 C6 K' t
- tx = {) S( U, x! d; U: _
- 'from': self.wallet,
- 'nonce': nonce,3 ]. M" n8 _. Q$ T( l
- 'gas': 100000,' S2 E3 ^' o" C" r, K% Q7 @4 E, B
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'chainId': 1
- }
- to = Web3.toChecksumAddress(to)
- txn = self.contract.functions.transfer(to, self.web3.toWei(value, 'ether')).buildTransaction(tx) T4 e% `( q3 m2 k
- signed_txn = self.web3.eth.account.sign_transaction(txn, private_key=self.wallet_key)
- tx_hash = self.web3.eth.send_raw_transaction(signed_txn.rawTransaction), W! L& i6 |) b' s0 X
- return self.web3.toHex(tx_hash), 'pay success'
- except Exception as e:
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')
- logging.exception(e)
- return None, str(e)
- 9 g" {) C( U# r* r
- def transfer_eth(self, to, value):
- '''进行eth转账
- args:+ u9 O/ i( `$ v7 k" Y
- to str:接收以太坊的地址
- value str/int:数量,以ether为单位,可以是字符串和int类型- w$ H/ {; x7 ]$ C7 }+ I) F
- returns:( p' x: V0 U- L6 G9 {
- str:返回交易哈希
- '''
- try:8 d" X& V# y: f6 y$ T0 ^
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')
- # 如果代币不足返回异常9 W8 K6 E! v+ g" q* U9 `" y
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform ETH token is insufficient, please try again later'
- # 获取 nonce,这个是交易计数9 T6 V; d2 `' O3 i
- to = Web3.toChecksumAddress(to)* p) M4 J& u4 I; W
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {
- 'nonce': nonce,
- 'to': to,* K& f% w3 a$ H
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),5 G: A! l. U% n) U& t/ R6 a
- 'value': self.web3.toWei(value, 'ether'),
- 'chainId': 15 @, u2 L( Y' x( Q& q7 [9 ~
- }- C# l! E2 c5 D; ? `7 V8 M
- # 签名交易* |% ^' A3 i6 q4 T+ Y) z) K# M# N
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)( C! m. Q& K: x" _% i* j8 I' b
- return self.web3.toHex(tx_hash), 'pay success'
- except Exception as e:4 o+ D$ R( M% X) R* X0 g- P) j
- logging.error(f'转账eth时发生异常:{e}')6 P! ?0 A' L9 J2 L; {, C# i
- logging.exception(e)
- return None, str(e)+ w: G$ Q2 E' _3 \