- pip install web3.py
2、注册 Infura 获得节点服务
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL
" O, I8 p- X% Z
可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。 H0 w/ U" Q" }+ ?4 X3 w7 {- z- H
4 f+ ]6 G% u$ I P% F) o6 C$ e0 Q
3、代码示例
- 3 Z1 J) g" o; x8 w2 q& \
- from web3 import Web3, Y, L3 i, l9 [1 K
- import json ~8 T: q6 `2 S/ j) U( M
- import time% a7 u; x6 @6 e; `
- import os) k3 _4 d$ w. C
- import logging% H) V' T f0 m- g% w: e
- from django.conf import settings; R2 ?, K* B1 [
- from decimal import Decimal
- . k# k h. p1 R% a7 E
- class PayEthOrToken(object):
- 6 t3 m6 Q' U+ a; r2 f
- def __init__(self):0 `/ D0 b: N0 Y
- # 设置web3
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))
- # token合约地址
- self.contract_address = 'your contract address'; e% V5 s) a9 X8 t1 ~9 \) n
- # 主钱包地址
- self.wallet = 'your wallet address' p- `# B8 O# ?. y t; E# J
- # 钱包的私钥
- self.wallet_key = 'your wallet key') R, {+ d7 @- `% Y2 `
- # 合约的abi test.json 是eth的abi json文件,可以在eth区块链浏览器上获得
- with open('test.json', 'r') as f:
- self.abi = json.loads(f.read())0 t8 }8 X& p# G! a
- # 生成合约) V( t- B0 e. j( q/ _% U
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)# m/ d; U0 z8 N. u6 ?
- # 代币简写2 W2 q: S1 L' h( Y' m6 ]* J5 W
- self.token_name = 'USDT'5 z9 l+ Q0 s8 ^+ v3 x0 g. X4 c
- , r) w" Q: U" ]4 W6 S1 f
- def transfer_usdt(self, to, value):( `7 Q, K7 _* a. _
- '''进行代币转账" s5 X+ v) y" |+ J5 R& x3 X
- args:
- to str:接收代币的地址+ }1 M0 Y5 b4 d9 P0 T; {
- value str/int:代币数量,以ether为单位,可以是字符串和int类型
- returns:6 h# r7 |4 {" g$ Q, x
- (str, str):返回交易哈希,以及异常信息. ]5 E9 F# l9 O8 j
- '''3 \: k" V4 ^) h% |; \
- try:
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')# c: t/ \2 a# p& p1 b1 C" W3 O
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):; S6 O' ^5 K- s* g5 J h
- return None, 'Platform USDT token is insufficient, please try again later'
- # 进行转账代币
- nonce = self.web3.eth.get_transaction_count(self.wallet): @; u) S+ O2 q! y+ A) B9 Y3 q; \. a
- tx = {4 Y/ E6 b2 i! h1 D" S
- 'from': self.wallet,0 n, u4 _2 h) Y* f7 a
- 'nonce': nonce,
- 'gas': 100000,4 T! o* G! C4 F
- 'gasPrice': self.web3.toWei('50', 'gwei'),) V: n( b3 i5 i- }! Z
- 'chainId': 1
- }
- to = Web3.toChecksumAddress(to)
- txn = self.contract.functions.transfer(to, self.web3.toWei(value, 'ether')).buildTransaction(tx)
- signed_txn = self.web3.eth.account.sign_transaction(txn, private_key=self.wallet_key): I. P, e5 S! U' t$ N6 I" ~( w
- tx_hash = self.web3.eth.send_raw_transaction(signed_txn.rawTransaction). \/ L, \9 n3 D8 |% g% _" P
- return self.web3.toHex(tx_hash), 'pay success'! b2 V& G9 D C. X0 f( ~
- except Exception as e:
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')
- logging.exception(e)+ N- J% O: R" i& U5 N$ d$ G
- return None, str(e)# k. [% r4 \$ o M% ]% S
- " B+ r# e4 A# l
- def transfer_eth(self, to, value):
- '''进行eth转账
- args:) m& R6 S! X/ q S
- to str:接收以太坊的地址
- value str/int:数量,以ether为单位,可以是字符串和int类型4 W+ B- c9 J _: F
- returns:
- str:返回交易哈希$ y7 I [& x6 z
- '''; i0 `+ x) l1 ~
- try:8 h0 J4 l# Z8 t5 c; n
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')+ l2 U) y' g- q* |
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform ETH token is insufficient, please try again later'
- # 获取 nonce,这个是交易计数
- to = Web3.toChecksumAddress(to)& G* S; X1 B& w- N, J: f+ x
- nonce = self.web3.eth.get_transaction_count(self.wallet)2 V+ G! ]0 E1 ?+ R2 S3 z5 O0 X
- tx = {7 ^( M6 H& t7 U7 ^" [$ e
- 'nonce': nonce,1 b* Z, l0 z2 O: W- W# G
- 'to': to,' d/ }$ n( [3 o5 q f5 k) g6 ~
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'value': self.web3.toWei(value, 'ether'),
- 'chainId': 1: b& G/ ?5 ~6 r% o: O- @
- }
- # 签名交易. b& w3 Q/ n! z# ^ t
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)& W6 P2 n d/ l& ^
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)
- return self.web3.toHex(tx_hash), 'pay success'$ \) L5 Q( N1 a6 f+ r& r9 n$ V
- except Exception as e:
- logging.error(f'转账eth时发生异常:{e}')
- logging.exception(e); q# G( Q; L: G
- return None, str(e)1 e2 P8 T/ Y! W" v+ ~