- pip install web3.py
- B X0 h1 J7 H4 N2 p! _
2、注册 Infura 获得节点服务& ~0 c2 j4 M) B/ f* i4 A7 b ~! F6 }
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL0 b* P. d' U- X) s" u0 I. _
3 X3 b+ f' m R5 ]
可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。
3、代码示例
- from web3 import Web3
- import json& d0 X* a8 a I4 Q
- import time
- import os
- import logging
- from django.conf import settings
- from decimal import Decimal8 ?2 I' x4 h1 A. d- @" x; x
- r3 j: g3 B: F. a: v1 f
- class PayEthOrToken(object):
- ) q# t3 h+ @- f$ o) w
- def __init__(self):
- # 设置web3
- self.web3 = Web3(Web3.HTTPProvider('your infura http url')). l/ x8 C" N g+ O& H- Y
- # token合约地址( ^- ~8 x* _+ O/ I, e/ v
- self.contract_address = 'your contract address'
- # 主钱包地址
- self.wallet = 'your wallet address'; I( n5 j+ Y/ Z
- # 钱包的私钥+ |+ R8 z% `$ S
- 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())
- # 生成合约
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)% Z! I- W9 \/ D, |* p
- # 代币简写- c, `% T! I7 }" h
- self.token_name = 'USDT'0 n) X; V; f. f+ l) t
- K/ A% o) |3 E8 {5 `- f
- def transfer_usdt(self, to, value):. p3 y) m$ E! Q2 i1 N$ f) t* {
- '''进行代币转账
- args:" R# B% W- B6 R. Q
- to str:接收代币的地址8 ` ]6 U' Q) W4 a0 f3 \
- value str/int:代币数量,以ether为单位,可以是字符串和int类型/ L) W# x$ e/ _: D1 F+ p) G( |
- returns:3 _4 z/ G9 ~* }% @
- (str, str):返回交易哈希,以及异常信息% z' z6 W' D# d! h* q$ X# c
- '''' V |0 m; J& K
- try:5 V+ N+ u7 G; p% |/ I- P4 S
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')9 L" X) n9 x, Y9 a2 ~/ E+ K
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):4 b8 w/ j; m9 Y6 A
- return None, 'Platform USDT token is insufficient, please try again later'# H8 R% k( D' M0 ~. x; V, a
- # 进行转账代币
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {
- 'from': self.wallet, z) z8 c* [, N: C7 t
- 'nonce': nonce,3 T) h6 I/ c, {& y& l. o
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'chainId': 1
- }
- to = Web3.toChecksumAddress(to)& a& p! C- {! H
- 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)! J* z# c! M m
- return self.web3.toHex(tx_hash), 'pay success'" P+ T9 G5 e9 K7 @
- except Exception as e:9 `. c* R8 a0 C* |% A
- logging.error(f'转账{self.token_name}代币时发生异常:{e}')
- logging.exception(e)" s% V4 a6 \9 Q x( l
- return None, str(e)7 \1 ]0 M% F% d- H, v
-
- def transfer_eth(self, to, value):
- '''进行eth转账- r i/ V2 ~8 k
- args:0 F6 M% \! |5 x1 B
- to str:接收以太坊的地址
- value str/int:数量,以ether为单位,可以是字符串和int类型
- returns:
- str:返回交易哈希9 A0 M* I' T% ^: ]9 q
- '''. T" o9 q* v7 `6 R& P) d
- try:
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')8 r9 a; v8 y$ j5 T( @5 a
- # 如果代币不足返回异常! {, }8 s% x Y7 u$ @
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform ETH token is insufficient, please try again later'
- # 获取 nonce,这个是交易计数
- to = Web3.toChecksumAddress(to)4 J* b6 D6 P$ J& O; w4 t v
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {1 A5 q5 t' z% W
- 'nonce': nonce,
- 'to': to,( W+ n+ `" T+ \
- 'gas': 100000,
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'value': self.web3.toWei(value, 'ether'),
- 'chainId': 1
- }" }, C5 w _9 D
- # 签名交易
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)2 D/ x4 C% `. x3 I8 B5 R4 K) U) [
- return self.web3.toHex(tx_hash), 'pay success'
- except Exception as e:
- logging.error(f'转账eth时发生异常:{e}')! m W0 O$ d( D. l
- logging.exception(e)
- return None, str(e)