- pip install web3.py
( m$ y6 n9 z6 S: ~! @
2、注册 Infura 获得节点服务
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL
9 ^( ^( v( E9 \" _# I2 e$ g8 E
可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。
8 c) {: d+ a: n! A. z
3、代码示例
- from web3 import Web34 h' A$ j0 Z5 ?, {5 D% N4 e# {
- import json
- import time
- import os
- import logging# M; x: ~( W; \& @8 R! [
- from django.conf import settings+ [. k: S! Z$ P0 S/ p4 R
- from decimal import Decimal5 \8 a/ B* x1 ^- \/ v( Y
- + Q* J0 v3 l( `! ] O
- ; O, [9 D$ I1 b/ Y% f% d6 \
- class PayEthOrToken(object):; R8 I K& ^5 ^; Q5 }
- 4 K1 f6 y: g/ P! q' O
- def __init__(self):! k# a2 J _* q$ } d1 |; S1 r, t
- # 设置web3
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))- _2 j. X/ R% U) |0 M
- # token合约地址" Z: a1 c8 G; m9 Z8 h
- self.contract_address = 'your contract address'
- # 主钱包地址
- self.wallet = 'your wallet address'' D; v& W! ~7 X. B) P; v) W
- # 钱包的私钥) A/ A0 |! `! e1 Q) f( ^
- 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())
- # 生成合约, R, F& I ]4 o( {' X
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)7 W& X, T; h9 P6 P4 j
- # 代币简写4 X$ s# p+ i% O( n* M
- self.token_name = 'USDT'
-
- def transfer_usdt(self, to, value):% }4 D* P* x) L' j# S7 D3 E9 S1 x
- '''进行代币转账5 \* W3 A0 X2 X* ]8 z0 |
- args:8 O1 D- M u# w/ q" Z- ?
- to str:接收代币的地址- }8 D5 D) A( c W. w; G- Z
- value str/int:代币数量,以ether为单位,可以是字符串和int类型7 d8 | x+ f2 Q; m" I# Z5 j% [
- returns:6 K" K1 {: ~9 B2 Y4 D8 Y3 _
- (str, str):返回交易哈希,以及异常信息
- '''
- try:
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')( W9 ]* B/ ^- C# [6 |
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):, ^8 O7 p+ p9 s0 n
- return None, 'Platform USDT token is insufficient, please try again later'
- # 进行转账代币
- nonce = self.web3.eth.get_transaction_count(self.wallet)/ J/ y0 q1 I) U4 k- w4 h
- tx = {2 j$ _' i. M; A6 m' y
- 'from': self.wallet,
- 'nonce': nonce,; c" ^7 X* X0 V% t. V/ _' t* |
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),) p; ]/ A7 f, @ {5 t# B1 _1 |
- 'chainId': 1; z/ k. s8 x* J1 m) E
- }
- to = Web3.toChecksumAddress(to)$ _& s# L$ r, ?: j0 _0 ^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)& s. c% r6 c/ x+ O5 l) S& m1 c+ E2 }" c
- tx_hash = self.web3.eth.send_raw_transaction(signed_txn.rawTransaction)
- return self.web3.toHex(tx_hash), 'pay success'; ?4 a0 n S7 z2 c+ v: X
- except Exception as e:" i/ w& G" v! p; Q6 ^
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')9 s* c6 ^& q# E7 M* ^% {, }" F
- logging.exception(e)
- return None, str(e)
- 2 i r. y# e! g
- def transfer_eth(self, to, value):
- '''进行eth转账
- args:- Q9 C& o9 I9 [: \
- to str:接收以太坊的地址
- value str/int:数量,以ether为单位,可以是字符串和int类型) O% A( Q* K# f" S
- returns:
- str:返回交易哈希
- '''
- try:
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')
- # 如果代币不足返回异常" f- o$ D9 O( L) A0 ^5 T: @4 v& e
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform ETH token is insufficient, please try again later'0 w, w3 a3 s& `9 {' A. f
- # 获取 nonce,这个是交易计数+ W- C0 l5 T6 ^4 u: u* b8 Z8 A
- to = Web3.toChecksumAddress(to)" A7 h/ d: m5 y9 S
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {8 k9 O* {; p- d; ^; C( O% Y9 s* q9 J
- 'nonce': nonce,0 q9 S/ I. Z# p+ ~2 J6 v; c
- 'to': to,
- 'gas': 100000,$ G* W. Y z" e
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'value': self.web3.toWei(value, 'ether'),
- 'chainId': 1
- }) T- B9 y2 [0 L4 F/ o& j- J' s
- # 签名交易* l4 y" n4 M( z3 g( X
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)' `$ b g8 E8 h; L' y# t
- return self.web3.toHex(tx_hash), 'pay success'
- except Exception as e:
- logging.error(f'转账eth时发生异常:{e}')! r t# G2 z/ n' ] H2 t
- logging.exception(e)" a0 r% E3 p) o5 V
- return None, str(e)' D" \2 m) x, c( {/ m3 s+ h9 o0 P