- pip install web3.py
% z; U" M( U, n5 X; F
2、注册 Infura 获得节点服务3 D7 o" b- U- _, |; r
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL0 p [* |* C8 v% q* B
5 J* o# C6 ? @2 f
可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。
3、代码示例 . O8 |$ n' T9 r0 @ _+ w
- from web3 import Web34 N' o! M+ J2 M- L0 M
- import json1 E1 V$ Q, o5 N# s
- import time
- import os
- import logging8 b- {3 f4 J. ~$ p
- from django.conf import settings- t. r. `( ]$ O# d1 [' O" N
- from decimal import Decimal7 K; W8 F) w* z
- 3 z1 @0 b4 v# [- v
- 1 y" a; P! O7 W0 o0 U @
- class PayEthOrToken(object):
- . N2 w" X! m6 ]0 B5 ^* f% o' r
- def __init__(self):
- # 设置web3
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))# Q M) l2 g6 b/ w+ x- V- G. }0 s
- # token合约地址
- self.contract_address = 'your contract address'
- # 主钱包地址7 b2 q6 S/ ?/ o. Z8 I7 i
- self.wallet = 'your wallet address'6 y4 ?. Y/ g4 e
- # 钱包的私钥
- self.wallet_key = 'your wallet key'
- # 合约的abi test.json 是eth的abi json文件,可以在eth区块链浏览器上获得5 M1 a, Q; j: B
- with open('test.json', 'r') as f:
- self.abi = json.loads(f.read())
- # 生成合约) K0 S2 a1 P6 [4 j5 z
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)
- # 代币简写
- self.token_name = 'USDT'; l0 D) `$ W3 M, y( z" t
-
- def transfer_usdt(self, to, value):
- '''进行代币转账- s0 o8 w4 ~" x+ {6 [
- args:- }3 U' L" a4 p9 i" }
- to str:接收代币的地址
- value str/int:代币数量,以ether为单位,可以是字符串和int类型
- returns:
- (str, str):返回交易哈希,以及异常信息1 Q, {2 R7 U! L0 v: F+ o! E
- '''
- try:" ~4 X. q8 F, C c
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')
- # 如果代币不足返回异常% j6 O% a4 h# H/ o
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform USDT token is insufficient, please try again later'7 w- Q* L8 j& M' m1 C
- # 进行转账代币4 M/ c# E: | U3 q$ J1 F' A
- nonce = self.web3.eth.get_transaction_count(self.wallet)+ \# {# c3 _* l+ g4 u/ j
- tx = {
- 'from': self.wallet," Q* D! X& I F4 M' | n) V8 M, S
- 'nonce': nonce,
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),: Q# c$ v; [, M9 K2 u* U
- 'chainId': 1
- }! r5 A4 s r/ v# L; j* j
- to = Web3.toChecksumAddress(to)! \' H6 a5 k8 h5 K9 ?8 ~# T# Q( }$ ?
- 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)
- tx_hash = self.web3.eth.send_raw_transaction(signed_txn.rawTransaction)* e+ \+ X7 {; A/ Q' w
- return self.web3.toHex(tx_hash), 'pay success'. Q3 w) E6 Q W$ ~: z- S
- except Exception as e:2 Q" O- ^; a& i* f& T. B
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')5 z0 }# b6 J* m6 x
- logging.exception(e)1 h* n1 v; `) g4 J* N/ T/ x
- return None, str(e)
-
- def transfer_eth(self, to, value):
- '''进行eth转账5 |3 k8 C0 j+ J% ~; C& z
- args:
- to str:接收以太坊的地址' I7 S% c) T) }3 O1 ~+ m
- value str/int:数量,以ether为单位,可以是字符串和int类型
- returns:4 E$ v' I, y2 @1 @5 z0 v
- str:返回交易哈希
- '''
- try:
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value): J+ H* z+ l- L1 i9 D
- return None, 'Platform ETH token is insufficient, please try again later'
- # 获取 nonce,这个是交易计数
- to = Web3.toChecksumAddress(to)! Z1 d q& E2 P* d
- nonce = self.web3.eth.get_transaction_count(self.wallet)6 `, F @+ N3 X# k1 O3 {
- tx = {; D- }; z* h* d# a3 G& Y
- 'nonce': nonce,. ~& }! f9 d" O+ E5 ?/ H1 h
- 'to': to, T1 Y( q( M& N) }# a% o7 _
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),( W" i7 [; N# e% {) }7 o- j# H
- 'value': self.web3.toWei(value, 'ether'),5 p8 W J5 D1 B7 y4 K
- 'chainId': 13 l) z' g5 U: g2 v: p
- }: K& k+ ~& B' L9 g& O+ r8 `+ h) G# I
- # 签名交易
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)5 i6 U: m+ Y# |4 m
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)
- return self.web3.toHex(tx_hash), 'pay success'! J& C' X6 i# J2 G
- except Exception as e:
- logging.error(f'转账eth时发生异常:{e}')6 b, B' N% T1 R! f$ R
- logging.exception(e)
- return None, str(e)