; u8 I/ t5 m( T: ]
- pip install web3.py
2、注册 Infura 获得节点服务5 r: D% d6 Y/ }1 A/ C8 N
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL* ^$ J/ m* G( {
可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。* R4 c9 I% p; Y6 @7 w+ g1 i W
X- y$ ]' D0 W' f* m! o" D4 j- Y
3、代码示例 : A; e1 O x6 E( y# W; [0 a
- ) {8 v* [+ B' p' v
- from web3 import Web3
- import json
- import time
- import os3 J; r. v# k+ V' w1 p6 X8 G
- import logging& R4 y8 E, {9 b/ V: E8 V* i
- from django.conf import settings
- from decimal import Decimal7 J- a+ s5 O8 j
- 0 c+ z- j4 r0 Z" w* s. Y
- class PayEthOrToken(object):
-
- def __init__(self):
- # 设置web3
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))# Q0 ^. o a2 V- s5 f
- # token合约地址; P3 F+ z7 x, J
- self.contract_address = 'your contract address' P/ L$ f4 m& E7 m
- # 主钱包地址
- self.wallet = 'your wallet address'
- # 钱包的私钥
- self.wallet_key = 'your wallet key'
- # 合约的abi test.json 是eth的abi json文件,可以在eth区块链浏览器上获得
- with open('test.json', 'r') as f:6 x8 b; d1 L+ { p5 C+ ~+ y
- self.abi = json.loads(f.read())
- # 生成合约8 P. `! \2 B7 `6 z" |$ D; {! }
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)9 S! z9 ^1 T! }8 }! z& w
- # 代币简写' ~' M6 k9 q; f) @9 Z* r
- self.token_name = 'USDT'. \4 f) c8 s& J0 y7 P J
-
- def transfer_usdt(self, to, value):
- '''进行代币转账* K9 N& ?6 m: g/ B+ I
- args:$ P8 M+ e0 e, I+ N l
- to str:接收代币的地址) {2 N- m' z' c. a
- value str/int:代币数量,以ether为单位,可以是字符串和int类型
- returns:1 j0 U/ W' k4 _8 U, B& y% N2 b
- (str, str):返回交易哈希,以及异常信息
- '''# w# m/ j; ^6 ~
- try:. O; t/ t4 \& [- L9 v; I
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')# g! @9 e4 i% O4 J
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform USDT token is insufficient, please try again later'& z& \1 Q* V9 `1 M" A; }
- # 进行转账代币
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {, {: m/ f* t- f
- 'from': self.wallet,( l0 Y: @. {0 Y8 E2 Q' Q
- 'nonce': nonce,
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'chainId': 1- N; F, {& X: b- @0 v8 M7 k0 K+ F
- }
- to = Web3.toChecksumAddress(to)
- txn = self.contract.functions.transfer(to, self.web3.toWei(value, 'ether')).buildTransaction(tx)4 Z2 e0 c; k. F$ D- y
- 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)$ A, y C; I- m# c2 h& v; C
- return self.web3.toHex(tx_hash), 'pay success'! F% e+ k0 ?% C8 a. V1 \- B
- except Exception as e:5 X( E. Q, x8 v, p
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')+ \! c- L! N4 Z6 s, P# H
- logging.exception(e)
- return None, str(e)3 T/ [4 j# o+ e$ @
-
- def transfer_eth(self, to, value):& |$ z8 p# I( x$ \- y
- '''进行eth转账
- args:
- to str:接收以太坊的地址: z! X6 z# w% P1 j% `$ S
- value str/int:数量,以ether为单位,可以是字符串和int类型
- returns:
- str:返回交易哈希+ N! l/ y! _" p* d8 K+ C" S4 G
- '''/ m$ p# V( m, ]3 ?
- try:. v! x3 c* Z) R/ |! s4 d5 q* e0 r
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):) O7 h0 l" B, T: P& S$ H
- return None, 'Platform ETH token is insufficient, please try again later'# K8 L2 k, p, [5 I! f
- # 获取 nonce,这个是交易计数& H' ^- S; Z, {% d
- to = Web3.toChecksumAddress(to)& |9 E9 d. j+ |) V' N
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {$ V5 H# h0 Z4 z+ T/ B
- 'nonce': nonce,
- 'to': to,
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'value': self.web3.toWei(value, 'ether'),3 {: j- ?5 |0 C2 \
- 'chainId': 1
- }
- # 签名交易) U% E7 p9 C/ W# u; ~& g
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)( O! l4 d$ c5 A6 x5 H- @" \8 @
- return self.web3.toHex(tx_hash), 'pay success') }4 u, C. }/ Q
- except Exception as e:3 R e% b" a1 n% s1 f
- logging.error(f'转账eth时发生异常:{e}')0 {: y8 g0 K0 W2 t7 O2 q9 A+ O
- logging.exception(e)6 k' o2 |2 i. T0 W2 E
- return None, str(e)4 ]: l, }( J0 U