- pip install web3.py
2、注册 Infura 获得节点服务
使用邮箱注册 Infura 账户后,创建一个项目,即可获得以太坊节点服务,进入设置即可看到链接的URL- b+ Z8 A" j: F5 X1 ?! a
' R5 N* k" u" ?8 z7 R8 w* j! m
可以选择主网测试网等,会有两个链接,一个是使用HTTPS的一个是使用WebSocket,按你的需求选择一个就行了,注意:Infura 个人免费请求次数,是每天有十万个请求。 @! O, |7 K. }6 P- W; I* W; U
4 J A0 v, x; R# m
3、代码示例 / i+ Q" p' m/ \& C' T1 H" x
- from web3 import Web3
- import json
- import time2 V5 X) K2 T9 p
- import os
- import logging4 y- c' @+ J5 Z" S" l+ A- T [ ^
- from django.conf import settings( D# P l2 e. Y4 a0 ]
- from decimal import Decimal+ E3 s8 k1 r7 }: v& K' D; h( e6 ~5 d
- / P% W# v& v* w) l3 X: |/ a0 ]
- class PayEthOrToken(object):
-
- def __init__(self):6 K: q% @$ y" u) ~( x- w
- # 设置web3
- self.web3 = Web3(Web3.HTTPProvider('your infura http url'))" s' [$ \7 y* m9 f# n
- # token合约地址
- self.contract_address = 'your contract address'
- # 主钱包地址
- self.wallet = 'your wallet address'
- # 钱包的私钥
- self.wallet_key = 'your wallet key'3 C1 ^; R5 J# k$ m
- # 合约的abi test.json 是eth的abi json文件,可以在eth区块链浏览器上获得
- with open('test.json', 'r') as f:6 B) B3 ]0 d2 q$ k2 s. T8 V6 e4 N
- self.abi = json.loads(f.read())
- # 生成合约 f& Y4 j9 n' V
- self.contract = self.web3.eth.contract(address=self.contract_address, abi=self.abi)
- # 代币简写
- self.token_name = 'USDT'
-
- def transfer_usdt(self, to, value):
- '''进行代币转账
- args:
- to str:接收代币的地址$ Y( B' p& U5 k6 \' n7 _- [
- value str/int:代币数量,以ether为单位,可以是字符串和int类型4 Y% g3 i2 V6 z5 Z8 W
- returns:- i( S+ |% u; D# i' y
- (str, str):返回交易哈希,以及异常信息, V4 v2 s3 {) ?/ T
- '''4 l9 w1 i, e1 _8 w) x' f4 v/ }3 Q
- try:
- token_balance = self.web3.fromWei(self.contract.functions.balanceOf(self.wallet).call(), 'ether')
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform USDT token is insufficient, please try again later'
- # 进行转账代币
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {
- 'from': self.wallet,
- 'nonce': nonce,* X) t s9 |7 t* _: z2 _
- 'gas': 100000,8 k' W; q% }2 n: f
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'chainId': 1
- }% O6 ]3 [5 Z+ J& g" Z: g
- to = Web3.toChecksumAddress(to)
- txn = self.contract.functions.transfer(to, self.web3.toWei(value, 'ether')).buildTransaction(tx)+ l* f0 g6 Y& s/ k7 A9 W0 @( b5 T
- signed_txn = self.web3.eth.account.sign_transaction(txn, private_key=self.wallet_key)0 a' i% M1 P4 z: b6 S' e! q; E+ @
- tx_hash = self.web3.eth.send_raw_transaction(signed_txn.rawTransaction)
- return self.web3.toHex(tx_hash), 'pay success'
- except Exception as e:0 w! }9 c6 ]( P7 Y
- logging.error(f'转账{self.token_name}代币时发生异常:{e}'), U1 W- w; x) J- ?: M
- logging.exception(e)
- return None, str(e)
- / [3 {( s% C' v4 f5 N6 J
- def transfer_eth(self, to, value):
- '''进行eth转账
- args:7 k7 {5 O! _" l4 m# r. t+ {
- to str:接收以太坊的地址+ n. L. L& f: H m
- value str/int:数量,以ether为单位,可以是字符串和int类型" J9 \. S v/ ^# b) |& [) a
- returns:# v' m& f, U3 `& `) m; f' y- G
- str:返回交易哈希
- '''2 Z( c+ \, o b
- try:' v) x. @7 y+ V9 ]4 z
- token_balance = self.web3.fromWei(self.web3.eth.get_balance(self.wallet), 'ether')
- # 如果代币不足返回异常
- if Decimal(token_balance) < Decimal(value):
- return None, 'Platform ETH token is insufficient, please try again later'
- # 获取 nonce,这个是交易计数
- to = Web3.toChecksumAddress(to)
- nonce = self.web3.eth.get_transaction_count(self.wallet)
- tx = {6 L, c. C) L& _0 l4 S' w5 _
- 'nonce': nonce,
- 'to': to,
- 'gas': 100000,% n- `' N: y$ [! H% {
- 'gasPrice': self.web3.toWei('50', 'gwei'),
- 'value': self.web3.toWei(value, 'ether'),6 i7 t' N0 _$ g: p
- 'chainId': 1- o8 p6 U U6 m
- }
- # 签名交易, F1 c: n9 X% o; N' T
- signed_tx = self.web3.eth.account.sign_transaction(tx, self.wallet_key)2 L! I6 v2 d" r2 ]: O
- tx_hash = self.web3.eth.send_raw_transaction(signed_tx.rawTransaction)
- return self.web3.toHex(tx_hash), 'pay success'
- except Exception as e:1 Z$ \3 }) l% [& j+ _
- logging.error(f'转账eth时发生异常:{e}')
- logging.exception(e)
- return None, str(e)+ e! u- p6 M3 t8 C4 Z5 \: u