- pip install web3.py
2、注册 Infura 获得节点服务
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL
& d& [& Q' F1 F) j
可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。2 J; |4 f( n3 m4 s* O: ?
: p U. y) w7 L% ?! p
3、代码示例
- from web3 import Web3/ E9 L8 ]. G" q* [; |% K' B
- import json
- import time
- import os/ V( e* r* y( ?
- import logging, F% u, F2 ^6 R5 O( c
- from django.conf import settings0 p9 K F: ?4 m- l# M7 @5 F
- from decimal import Decimal( ]9 j: w( R* r' u. q) {
- " {3 Y& \1 g0 r: Z: W( k- ]
- class PayEthOrToken(object):) x$ j6 @! w; x4 ?
-
- def __init__(self):5 i4 i- E* f! D1 z
- # 设置web3
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))
- # token合约地址1 f; B) H5 d/ Y U( a
- self.contract_address = 'your contract address': @& _( W+ n7 M5 V' G3 m$ L
- # 主钱包地址
- self.wallet = 'your wallet address'
- # 钱包的私钥. ]1 Q. \ @2 A& y% }3 E+ C
- self.wallet_key = 'your wallet key' K- b2 m! v& _2 W0 g
- # 合约的abi test.json 是eth的abi json文件,可以在eth区块链浏览器上获得2 L- t) B6 e% ?9 j# v
- with open('test.json', 'r') as f:: Q9 `; h6 w9 [# g/ a
- self.abi = json.loads(f.read()), H3 X% E1 H3 I# w% R
- # 生成合约
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi); {# P) k! {( m# H0 g$ s
- # 代币简写
- self.token_name = 'USDT'
- & l. T4 s9 [0 t; r: R& I
- def transfer_usdt(self, to, value):1 F8 I# @6 e, l/ t
- '''进行代币转账
- args:! W4 h% z7 Q! h" i9 P0 W
- to str:接收代币的地址
- value str/int:代币数量,以ether为单位,可以是字符串和int类型
- returns:, C& B2 o9 V, k! R( |+ [
- (str, str):返回交易哈希,以及异常信息% q5 i7 C2 y: s( G' H; U
- '''
- try:- v, R6 J; Z+ ~6 h* v' \$ K8 _% r
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')
- # 如果代币不足返回异常; L4 M. s& v) z$ O+ b9 Q! v4 I
- if Decimal(token_balance) < Decimal(value):. |8 C a+ O8 V( b2 j6 H4 S
- return None, 'Platform USDT token is insufficient, please try again later'
- # 进行转账代币8 L' O. N% x/ U- n. C' H
- nonce = self.web3.eth.get_transaction_count(self.wallet), g0 H+ p8 I% _+ E
- tx = {3 Q# V; S* p" l' C% R. P9 L
- 'from': self.wallet,8 k) u. [ }, V; _+ x/ n
- 'nonce': nonce,
- 'gas': 100000,; D$ M) N& r* Y L# z& F
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'chainId': 1. t/ {; i" [% J$ _" j
- }
- to = Web3.toChecksumAddress(to) t" k( B1 D) H7 d; y2 p6 k
- txn = self.contract.functions.transfer(to, self.web3.toWei(value, 'ether')).buildTransaction(tx) z) l) r3 h9 w! m9 `
- signed_txn = self.web3.eth.account.sign_transaction(txn, private_key=self.wallet_key)8 r. `" E q, L+ U
- tx_hash = self.web3.eth.send_raw_transaction(signed_txn.rawTransaction)
- return self.web3.toHex(tx_hash), 'pay success'8 l8 ]9 B5 K3 k* ?& ?1 y
- except Exception as e:4 \2 |' m6 x% r3 G
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')
- logging.exception(e)
- return None, str(e)
- ) D0 S6 R9 [. c1 X
- def transfer_eth(self, to, value):
- '''进行eth转账
- args:
- to str:接收以太坊的地址
- value str/int:数量,以ether为单位,可以是字符串和int类型
- returns:- T5 {+ b$ K$ k6 t2 _% V
- str:返回交易哈希
- ''') P/ \! P `" k& n9 J: M2 f9 Z
- try:7 z. x0 [$ z9 ]
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')0 D, e6 @* o4 v9 u) x* g
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform ETH token is insufficient, please try again later'* \3 H. n( S, d( c3 |3 K- g% C
- # 获取 nonce,这个是交易计数( J4 ]1 p+ h, _; I
- to = Web3.toChecksumAddress(to)
- nonce = self.web3.eth.get_transaction_count(self.wallet)+ ~& {$ F! |- S9 E: t8 [
- tx = {
- 'nonce': nonce,7 e8 _* c9 H1 \! _, B; b3 i; s
- 'to': to,0 Q& k7 s) O% |3 ? W2 \! s( u
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),- @- f7 l, u8 G- @
- 'value': self.web3.toWei(value, 'ether'),$ A1 S& q. v- f: R" k2 w' A
- 'chainId': 1
- }) ~8 W4 R7 D3 U6 Y% t" I. S
- # 签名交易
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)' H5 S7 v8 a7 ^4 H. ^: R/ |) g
- return self.web3.toHex(tx_hash), 'pay success'7 ]6 Q- }0 r# W; X" A7 J
- except Exception as e:
- logging.error(f'转账eth时发生异常:{e}'), g9 B/ q1 r6 F" t/ E* ^8 N. M/ x1 i
- logging.exception(e)
- return None, str(e); r3 k% d3 v' q8 w# D% u3 T



