$ J0 ]9 ]: G, n, c7 t# z% W
- pip install web3.py
$ M, c9 h' J+ ]% X" n
2、注册 Infura 获得节点服务% J7 U3 d: ] i3 `! [, g& S# [
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL, V2 h: _. T8 \, T
; U3 B. A. B. t- B
可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。
3、代码示例 9 \5 |3 J/ {. ?% H0 x
- from web3 import Web3& z7 w8 B8 |) a; U. V* {& ]! b
- import json
- import time1 I' J* p8 |8 T9 B! ?1 U: k& w. v% ^7 {
- import os
- import logging4 X$ {$ O4 y3 a6 f& Z/ s* f' M
- from django.conf import settings/ V m" K. C% A+ H! D" z4 I. H# y
- from decimal import Decimal$ N3 N/ ~. I4 q5 K' I
- ! z" q* x% f1 T s/ Z2 k3 F. o9 d
- class PayEthOrToken(object):
- - g, R' X/ H$ _) i" i
- def __init__(self):2 Y- k; J* ]' m1 \+ `, i0 r
- # 设置web3% A" _# ^* b$ o9 x3 w4 T
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))
- # token合约地址
- self.contract_address = 'your contract address'% j; Y6 ~+ O$ ^: {) [" K
- # 主钱包地址/ P# L3 p2 K+ x% H% C$ z. [
- self.wallet = 'your wallet address'
- # 钱包的私钥% B4 _$ @4 u; i! B1 F0 h4 [
- self.wallet_key = 'your wallet key'
- # 合约的abi test.json 是eth的abi json文件,可以在eth区块链浏览器上获得
- with open('test.json', 'r') as f:! |& r9 t: e. g0 Z
- self.abi = json.loads(f.read())
- # 生成合约* h' }- f- B. E9 q" ?
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)
- # 代币简写
- self.token_name = 'USDT'% {$ W0 \# c5 b: |
- $ f4 l! O( F1 U* ]- V- J+ o' h
- def transfer_usdt(self, to, value):1 [/ S2 |, v, ~& ]: d
- '''进行代币转账
- args:0 D2 |$ L* H% X/ d+ R* n% _& a
- to str:接收代币的地址) o' P* W, H2 n' e8 L; J- N% \
- value str/int:代币数量,以ether为单位,可以是字符串和int类型
- returns:- y# j, G' t! b7 @# G/ T
- (str, str):返回交易哈希,以及异常信息
- '''
- try:$ s' u+ M: `: n% m- @! _
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')& i1 T2 _+ I' k- C6 U0 o
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform USDT token is insufficient, please try again later'8 B A7 @8 f( r9 I" E5 t
- # 进行转账代币7 ]$ A6 v* {# G" T# R4 I7 b
- nonce = self.web3.eth.get_transaction_count(self.wallet)# P$ T: v1 m9 H K
- tx = {
- 'from': self.wallet,
- 'nonce': nonce,
- 'gas': 100000,5 k6 ]8 T; G# t; D1 C
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'chainId': 1$ T1 F0 ~1 }1 V, [3 Z
- }1 ?# t1 m6 x% {% }- z
- to = Web3.toChecksumAddress(to)' K! s! Q2 F$ `2 \
- 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)# V L7 k8 l8 j9 ~3 Q+ J+ A
- tx_hash = self.web3.eth.send_raw_transaction(signed_txn.rawTransaction)& }# a8 F% p2 ^8 {5 Q/ n
- return self.web3.toHex(tx_hash), 'pay success'' F6 x7 X, s# E% {
- except Exception as e:
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')
- logging.exception(e)3 S/ G) z! p) F3 e- x/ f7 B! P
- return None, str(e)
-
- def transfer_eth(self, to, value):
- '''进行eth转账- U3 n. n! T% H- F( Y
- args:& h N$ k8 e. i, I
- to str:接收以太坊的地址+ N8 W8 G8 N, s) R; F
- value str/int:数量,以ether为单位,可以是字符串和int类型8 p/ ?/ Z0 E; e- I
- returns:. f+ ~' x9 B' l( _4 u2 u
- str:返回交易哈希
- '''7 G3 W* U- d5 I2 c! k: K$ U
- try:
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform ETH token is insufficient, please try again later'
- # 获取 nonce,这个是交易计数9 A. Y8 B) ~0 e
- to = Web3.toChecksumAddress(to)
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {
- 'nonce': nonce,3 |7 d/ P% i5 h3 l) J/ e9 @
- 'to': to,
- 'gas': 100000,( L' P: q7 z4 o# S, v2 J2 F! `0 C S5 K
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'value': self.web3.toWei(value, 'ether'),% r+ R; S- K* {' i4 u
- 'chainId': 1
- }
- # 签名交易; `4 F Q/ W# B8 _" ]8 X8 N: j
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)$ I# k ?3 D6 ~; K+ m
- return self.web3.toHex(tx_hash), 'pay success'' ^ W/ Y% B( p4 e$ r$ |
- except Exception as e:
- logging.error(f'转账eth时发生异常:{e}')
- logging.exception(e)" r# Y$ I2 S/ j( m8 D
- return None, str(e)



