$ v4 o7 I1 n% c
- pip install web3.py
2、注册 Infura 获得节点服务
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL
![04ab0f6855e74cb6b49a35b1f466da1f.png 04ab0f6855e74cb6b49a35b1f466da1f.png](https://att.bitmere.com/forum/202303/20/003729dyhyhix9i09t2zjc.png)
% I* G7 N8 }( s+ r1 p
可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。( s3 ~% p. H: P$ H
3、代码示例
- from web3 import Web35 v8 J$ n$ y, M3 D& ^8 v3 d
- import json0 I0 z5 L$ p, E: S! H5 r
- import time3 Q2 r# [' n0 [1 B L3 a
- import os& r% ]+ R7 ^' W+ u- K6 `
- import logging
- from django.conf import settings
- from decimal import Decimal# Z, d3 r- {' U, j" \
- : Q. G' Q G4 [# U8 N/ }5 O6 n
- class PayEthOrToken(object):9 s9 a& b' ~) h) t- |+ E
-
- def __init__(self): a! q* h5 J* }: ^+ x/ |: }
- # 设置web35 r$ Z7 L# a$ a4 r+ e" y
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))
- # token合约地址
- self.contract_address = 'your contract address'
- # 主钱包地址
- self.wallet = 'your wallet address'4 L' Y5 x C3 l0 x/ F( M& A% M
- # 钱包的私钥
- self.wallet_key = 'your wallet key' S# m9 @4 }" n! b8 _! F
- # 合约的abi test.json 是eth的abi json文件,可以在eth区块链浏览器上获得
- with open('test.json', 'r') as f:
- self.abi = json.loads(f.read()) m4 H4 q9 n! l2 Z
- # 生成合约. e, w+ g C2 ], ?- s0 N! y
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)1 e4 p2 q% _4 Z* X' K
- # 代币简写7 J. e, ]8 b2 S
- self.token_name = 'USDT'
- , P/ T, L4 B: O9 Z' R% s! a
- def transfer_usdt(self, to, value):
- '''进行代币转账2 @+ \! v+ H( r
- args:
- to str:接收代币的地址' z2 _, k3 U5 J; P9 q3 M ~
- value str/int:代币数量,以ether为单位,可以是字符串和int类型
- returns:
- (str, str):返回交易哈希,以及异常信息1 p( ]0 z, c J8 O! c- d; h
- '''* Q# l9 w0 l3 {- y5 o9 T
- try:
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')' d7 g0 p: K8 g, J( q6 t) }6 ]' ^
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform USDT token is insufficient, please try again later', W B* e* ]5 P4 O# u, m: ^' r
- # 进行转账代币
- nonce = self.web3.eth.get_transaction_count(self.wallet)1 \, i( Z" ]( N! F1 z3 U
- tx = {% i' S/ q: Q0 _7 m6 n
- 'from': self.wallet,
- 'nonce': nonce,
- 'gas': 100000,- d1 Z5 {+ q- S" Z S+ c
- 'gasPrice': self.web3.toWei('50', 'gwei'),; z* |! T% @! j2 x, E7 J( A5 O
- 'chainId': 1
- }! n* o8 D& h/ p: O8 N; }
- 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)
- tx_hash = self.web3.eth.send_raw_transaction(signed_txn.rawTransaction)
- return self.web3.toHex(tx_hash), 'pay success'/ n+ Z j7 Z, r% p! T8 _0 a" G7 R( o
- except Exception as e:
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')
- logging.exception(e)
- return None, str(e)
- 2 ^) p! ]5 ` p; c$ A
- def transfer_eth(self, to, value):
- '''进行eth转账! T5 w% E# `% U- \
- args:# \; I4 Q4 y" y* N3 Q$ Z/ x
- to str:接收以太坊的地址
- value str/int:数量,以ether为单位,可以是字符串和int类型' ^8 t9 G5 x1 N6 T) Y
- returns:
- str:返回交易哈希% t1 t- A( b; u- g- ^
- '''9 d9 k J! @( Y) S+ J
- try:5 o! r( h5 Y' w: L+ P( Q
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')1 ?' y3 c8 [% z4 v5 R" `" h
- # 如果代币不足返回异常! H6 x9 k/ U: ^
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform ETH token is insufficient, please try again later'
- # 获取 nonce,这个是交易计数' W2 q+ |* {, M6 k
- to = Web3.toChecksumAddress(to)
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {
- 'nonce': nonce,
- 'to': to,
- 'gas': 100000,: O8 m) |/ {- J
- 'gasPrice': self.web3.toWei('50', 'gwei'),9 X7 R* K' T) t) s% @, {4 H- `
- 'value': self.web3.toWei(value, 'ether'),
- 'chainId': 1# }6 f" ?6 o6 K3 H" w: K
- }
- # 签名交易* L1 F' i, L" G( z+ w
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)- {3 J- z* j+ B( N+ F
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)
- return self.web3.toHex(tx_hash), 'pay success'
- except Exception as e:' G- G( u: p" @! u, k
- logging.error(f'转账eth时发生异常:{e}') ~! W5 e+ K) C5 z
- logging.exception(e); c$ t/ w$ _3 Y( a7 w
- return None, str(e)2 W2 @" d1 c7 x+ `