& `- i# a5 X* s) I
- pip install web3.py
2、注册 Infura 获得节点服务1 f2 Z# v* ]/ K& I/ ~5 U L
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL/ H' U: M# ~5 D) k! h7 y* }

9 Q1 J# E0 O, P0 L( F3 P
可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。
/ A# l/ k. Z" L$ \. {8 d6 V
3、代码示例
- 1 h, W) F* y7 M7 e1 S
- from web3 import Web3
- import json8 d7 M1 p7 c' g4 |9 N
- import time
- import os
- import logging! X$ J$ R" k) E0 \) W9 c
- from django.conf import settings& A1 V- P$ Z/ i) C# T' G! E
- from decimal import Decimal
- 3 {# f, b; }3 }) C4 L* W3 S* G
- 6 u* q1 d$ j( M' x+ z
- class PayEthOrToken(object):+ H& S1 P P/ [0 D9 L
- # l4 ~6 ]) R; O' x% t; b; H
- def __init__(self):% N7 l8 c( c+ v% ~# Z
- # 设置web3
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))
- # token合约地址
- self.contract_address = 'your contract address'' @, R" \) K. L2 ~' }! N! u
- # 主钱包地址4 o; L; j& r- F$ K5 h. _1 V
- self.wallet = 'your wallet address'
- # 钱包的私钥+ B6 w/ o5 S" |! ]" m
- self.wallet_key = 'your wallet key'& x6 a& L& ~$ } `
- # 合约的abi test.json 是eth的abi json文件,可以在eth区块链浏览器上获得: C4 X$ J! e2 p$ ?$ d) S
- with open('test.json', 'r') as f:
- self.abi = json.loads(f.read())
- # 生成合约: K/ Q+ K" {8 |2 Q+ ~2 N+ W
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)8 Q$ B5 m& ~9 U+ F1 i
- # 代币简写4 [: h( _) n1 k
- self.token_name = 'USDT'; H4 y( e% E$ N# X! M4 V$ ]9 G) U
- / f, r- {2 _ m" T ^
- def transfer_usdt(self, to, value):5 C" H! f$ }2 X1 L( W' l
- '''进行代币转账
- args:
- to str:接收代币的地址( W' N3 X% N7 L- ]$ M, V( ?& Z' h+ E
- value str/int:代币数量,以ether为单位,可以是字符串和int类型
- returns:
- (str, str):返回交易哈希,以及异常信息, ^+ G" }! T2 k* k: z4 o
- '''# b! y+ }3 o3 X! u
- try:0 i; c* h: ]4 D$ I, w/ c3 p+ \, R, b
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')( T p% k$ N! r; A
- # 如果代币不足返回异常# c1 M# p$ c. k o/ ^, |3 n7 f' e
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform USDT token is insufficient, please try again later'
- # 进行转账代币. L/ I5 m$ r- T- V4 M3 [6 @
- nonce = self.web3.eth.get_transaction_count(self.wallet)0 d* R0 I: W) |5 T' D6 a! p' l
- tx = {
- 'from': self.wallet,
- 'nonce': nonce,, {; Y1 f* V4 t/ \1 b/ K- Z
- 'gas': 100000,9 ^. L, d6 a6 ?2 h% q/ u o
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'chainId': 1
- }9 Y# o" A* z; c' \ p
- to = Web3.toChecksumAddress(to)' B. a8 S. p$ E+ p% Y A
- txn = self.contract.functions.transfer(to, self.web3.toWei(value, 'ether')).buildTransaction(tx)3 @8 h/ |" D% @' \" S/ E
- 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) M; y, j' d' l2 K0 b
- return self.web3.toHex(tx_hash), 'pay success'$ W/ q0 S/ A$ }
- except Exception as e:
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')
- logging.exception(e): L/ _5 S- m. V2 j8 I2 x5 {$ d
- return None, str(e)
-
- def transfer_eth(self, to, value):2 ]8 l+ Q6 g# ^* U1 Z
- '''进行eth转账
- args:
- to str:接收以太坊的地址- b+ ]' l5 K* w; z: q0 y
- value str/int:数量,以ether为单位,可以是字符串和int类型
- returns:
- str:返回交易哈希
- '''1 e w+ ]/ ]9 l% C. _
- try:# w9 O/ s8 C( B3 o% Q, Z/ M# {
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether') }* K! R; ?* |" {
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform ETH token is insufficient, please try again later'. y: P5 m5 U- A4 y
- # 获取 nonce,这个是交易计数# k6 v# l# Y' Q Y; l( \
- to = Web3.toChecksumAddress(to)7 ^4 r3 v& }4 Q* S1 R/ k6 A# v
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {- L% h. w# X0 e" F$ v6 S' B
- 'nonce': nonce,
- 'to': to,) j$ K0 Q! w s L
- 'gas': 100000,3 K7 z" i4 L+ j5 H9 M. [
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'value': self.web3.toWei(value, 'ether'),& u; d N& f8 M. K3 L7 Q Q
- 'chainId': 1 Y" s8 M2 t& v
- }
- # 签名交易3 u/ b$ O0 _+ N, p* {$ F; @& o! J
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key). H/ U2 S( i! y; ?! ~
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)
- return self.web3.toHex(tx_hash), 'pay success'
- except Exception as e:
- logging.error(f'转账eth时发生异常:{e}')
- logging.exception(e)& j T/ `+ p" n8 a" p
- return None, str(e)+ [; r4 \# c# }9 ]7 h/ d& x