- pip install web3.py
2、注册 Infura 获得节点服务8 H) c, z- B1 l& d8 j- T+ r
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL

可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。
+ _7 E/ F7 n; h, n5 V9 v! \
3、代码示例 6 m" w+ h" O9 Y% p& x7 `. s
- from web3 import Web3# l6 {' U h$ L3 ^
- import json
- import time
- import os$ o @+ J: w* C2 l; E
- import logging7 X! {4 [7 f, j
- from django.conf import settings+ U$ c& O; e1 x( l; `% C
- from decimal import Decimal4 ?- e0 p2 z/ ?* ^8 h [2 @* j* u
- ' s9 L/ t+ T H o
- class PayEthOrToken(object):3 g0 j1 \/ @ f4 n
- / H2 m% F, c: q Q2 K
- def __init__(self):
- # 设置web3" h% V' }# j7 x e* n {
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))
- # token合约地址' e; i+ s) `! T1 \; G* v- [. W8 {
- self.contract_address = 'your contract address'% J" s; M9 |4 ~
- # 主钱包地址
- self.wallet = 'your wallet address'
- # 钱包的私钥3 L) H: w+ y5 q& U! ^4 {( O
- self.wallet_key = 'your wallet key'
- # 合约的abi test.json 是eth的abi json文件,可以在eth区块链浏览器上获得8 g, d; z. M& L. e& I- I1 j! n" p
- with open('test.json', 'r') as f:1 m6 t1 X+ @+ t) p. S
- self.abi = json.loads(f.read())! G8 s3 ` G( |5 E' G, w8 @
- # 生成合约 G q* Z3 e3 D
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)
- # 代币简写$ L- l- y* H2 A1 ?' ]
- self.token_name = 'USDT'8 o: ^ X" A7 j! G+ A5 C, D
- ; w8 q: y1 f% p
- def transfer_usdt(self, to, value):' Z# Z& m; ^+ m' b& |) P* S
- '''进行代币转账0 R) M* S: c: h. ^5 o6 W& ]4 L
- args:: F- ^8 t# M% P5 i
- to str:接收代币的地址
- value str/int:代币数量,以ether为单位,可以是字符串和int类型1 y* t, p& s; S7 ]) T. P6 o
- returns:# F( {: ?9 B) [: C+ V3 p6 d
- (str, str):返回交易哈希,以及异常信息! Q8 x0 y# R; f- O3 H H
- ''', R* G* p9 R: g+ G* V; G9 V
- try:4 C0 L2 q* K2 l1 D0 [, Z1 A
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')6 i0 p4 W1 {, `. l" |
- # 如果代币不足返回异常* w/ n- {5 o4 \
- if Decimal(token_balance) < Decimal(value):( @: e1 F+ k5 \: }
- return None, 'Platform USDT token is insufficient, please try again later'/ }8 a# x0 ]( C# x# |9 o# h
- # 进行转账代币
- nonce = self.web3.eth.get_transaction_count(self.wallet)# L# ?! |& s% L U% A! l
- tx = {! `0 c0 z( f1 ^/ D- q+ {- t* d
- 'from': self.wallet,
- 'nonce': nonce,
- 'gas': 100000, z/ n! u( w3 D! C
- 'gasPrice': self.web3.toWei('50', 'gwei'),6 f- C7 ~7 u( [4 X) t& K
- 'chainId': 1: u& k7 t, }& q+ |
- }" Y/ | T, k( w+ p& }) r- y
- to = Web3.toChecksumAddress(to)+ ^* P- i" S) I* M- h0 M7 _ ~
- txn = self.contract.functions.transfer(to, self.web3.toWei(value, 'ether')).buildTransaction(tx)" z4 u! K5 A- X$ o9 p4 ] q% N: {
- signed_txn = self.web3.eth.account.sign_transaction(txn, private_key=self.wallet_key)" E1 u. L' `3 U4 c1 N3 w) N
- tx_hash = self.web3.eth.send_raw_transaction(signed_txn.rawTransaction)
- return self.web3.toHex(tx_hash), 'pay success'9 Y/ G1 ?$ l% ]" g) n
- except Exception as e:
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')
- logging.exception(e)
- return None, str(e)
-
- def transfer_eth(self, to, value):
- '''进行eth转账% l; w+ _* v0 \) d' {/ T
- args:
- to str:接收以太坊的地址% ~5 @3 k2 o, l7 ^
- value str/int:数量,以ether为单位,可以是字符串和int类型
- returns:
- str:返回交易哈希
- '''- Y. M( _$ L9 W- k; c
- try:9 F1 {3 s/ U2 i: H( C5 v& Y
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')* }+ w2 D" ^! Z3 i& u. B, C6 E. F8 E
- # 如果代币不足返回异常+ }! A/ F0 j# W; y4 G" b6 d; L6 R
- if Decimal(token_balance) < Decimal(value):' F5 @) D0 w7 d% {. {- `( w+ k
- return None, 'Platform ETH token is insufficient, please try again later'+ o& T! d) H# O8 y; A
- # 获取 nonce,这个是交易计数- W: I8 Y( z# U/ F1 s; w% u
- to = Web3.toChecksumAddress(to)
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {# b/ n% ]& u/ B5 o' ?! B3 b3 ?& s
- 'nonce': nonce,
- 'to': to,
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),5 Z: M/ P& G5 `* _
- 'value': self.web3.toWei(value, 'ether')," T6 z8 d3 i7 q, _5 [, b/ q4 z
- 'chainId': 1
- }- M( ` M' S5 \. P
- # 签名交易
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)) A" Y: p0 ~5 A4 d# ?' e
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)# R: @$ e& H% y2 h! B( ?8 m( _& q
- return self.web3.toHex(tx_hash), 'pay success'2 }- o0 ^' o6 t7 {
- except Exception as e:) V0 y4 H' o- _$ C; L5 L
- logging.error(f'转账eth时发生异常:{e}')
- logging.exception(e)
- return None, str(e)