Skip to main content

Week16: 10.24 - 10.28 python-sdk

本周将对新版 python-conflux-sdk 进行介绍。python-conflux-sdk 基于 web3.py 进行开发,尽量保证了API的兼容。目前 python sdk 支持 3.8 <= python version <= 3.10

安装方式

python -m venv venv
source ./venv/bin/activate
pip install conflux-web3

10.24 python-conflux-sdk: Base32Address

Conflux 目前将 Base32 格式地址作为默认的地址格式,python sdk 也提供了相应类便于开发者操作地址。 Base32Address 类继承自 python 内置字符串类 str ,并提供了常用的编码、解码方法,重写了 ==运算符(__eq__)的判断方式。详细文档可以参考 -> Base32Address

>>> from cfx_address import Base32Address
>>> address = Base32Address("0x1ecde7223747601823f7535d7968ba98b4881e09", network_id=1)
'cfxtest:aatp533cg7d0agbd87kz48nj1mpnkca8be1rz695j4'
>>> address_ = Base32Address(address, network_id=1029, verbose=True)
>>> address_
'CFX:TYPE.USER:AATP533CG7D0AGBD87KZ48NJ1MPNKCA8BE7GGP3VPU'
>>> isinstance(address_, str)
True
>>> address_ == 'cfxtest:aatp533cg7d0agbd87kz48nj1mpnkca8be1rz695j4'
True
>>> [
...     address.address_type,
...     address.network_id,
...     address.hex_address,
...     address.verbose_address,
...     address.abbr,
...     address.mapped_evm_space_address,
...     address.eth_checksum_address,
... ]
['user', 1, '0x1ecde7223747601823f7535d7968ba98b4881e09', 'CFXTEST:TYPE.USER:AATP533CG7D0AGBD87KZ48NJ1MPNKCA8BE1RZ695J4', 'cfxtest:aat...95j4', '0x349f086998cF4a0C5a00b853a0E93239D81A97f6', '0x1ECdE7223747601823f7535d7968Ba98b4881E09']

在 python-conflux-sdk(conflux-web3) 中所有的地址类型返回值均使用 Base32Address 进行了封装方便开发者进行操作;对于输入,conflux-web3 也支持str/Base32Address类型的地址作为输入。

>>> from conflux_web3 import Web3
>>> w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
>>> miner = w3.cfx.get_block_by_epoch_number("latest_mined")["miner"]
>>> miner.address_type
'user'

10.25 python-conflux-sdk: wallet

web3.py中,一般需要通过手动调用函数construct_sign_and_send_raw_middleware构造自动签名中间件,进而实现send_transaction方法与合约方法的自动签名。

# `web3.py`的文档中提供了`construct_sign_and_send_raw_middleware`的使用方法
from web3 import Web3, EthereumTesterProvider
w3 = Web3(EthereumTesterProvider)
from web3.middleware import construct_sign_and_send_raw_middleware
from eth_account import Account
acct = Account.create('random string')
w3.middleware_onion.add(construct_sign_and_send_raw_middleware(acct))
w3.eth.default_account = acct.address
legacy_transaction = {
    'to': Account.create('another random string'),
    'value': 22,
    'gasPrice': 123456,  # optional - if not provided, gas_price_strategy (if exists) or eth_gasPrice is used
}
w3.eth.send_transaction(legacy_transaction)

python-conflux-sdk 支持类似的使用方式(但需要从conflux_web3.middleware中引入construct_sign_and_send_raw_middleware),同时优化了中间件的实现方式与API的使用方式,提供了更友好的API。

from conflux_web3 import Web3
from cfx_account import LocalAccount
w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
acct:LocalAccount = w3.account.create("random string")

w3.cfx.default_account = acct
# default_account 被设置为 LocalAccount 类型变量时等价于
# w3.wallet.add_account(acct)
# w3.cfx.default_account = acct.address

# 在钱包中添加账户后交易会根据交易的 from 字段进行自动签名
# 若 from 字段为空则会将 w3.cfx.default_account 作为交易的 from 账户
transaction = {
    'to': w3.address.zero_address(network_id=1),
    'value': 22,
    'gasPrice': 10**9,
}
w3.cfx.send_transaction(transaction).executed()
# wallet 中允许存在多个 account
assert acct.address in w3.wallet
acct_ = w3.account.from_key("FILL YOUR SECRET KEY HERE")
w3.wallet.add_account(acct_)
assert (acct.address in w3.wallet) and (acct_ in w3.wallet)

transaction = {
    'to': w3.address.zero_address(network_id=1),
    'value': 22,
    'gasPrice': 10**9,
  	'from': acct_.address
}
w3.cfx.send_transaction(transaction).executed()

10.26 python-conflux-sdk: 交易状态的追踪

向节点发送交易后,常常需要跟踪交易的状态。在以太坊中,交易状态相对简单,因此 web3.py 仅提供了 wait_for_transaction_receipt 方法用于交易状态的追踪。Conflux 中交易的状态稍复杂,可分为以下五个阶段:

  1. pending:交易发送至节点,但并未被包含在区块中。
  2. mined:交易已被包含在上链区块中。
  3. executed:交易已被执行(交易上链 5 个 epoch 后才会被执行)。
  4. confirmed:交易已被 PoW 链确认,除非受到算力攻击,一般可认为交易不会被 revert。
  5. finalized:交易被 PoS 链确认,即使遭到算力攻击交易也不会被 revert ,但往往需要5-10分钟才能确认。

python-conflux-sdk 中也提供了对应的 API, 开发者可以使用wait_till_transaction_mined, wait_till_transaction_executed, wait_till_transaction_executed, wait_till_transaction_confirmed, wait_till_transaction_finalized API 以等待交易状态,同时sdk也对交易返回的哈希值进行了封装,以提供更简洁的 API。

from conflux_web3 import Web3
w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
acct = w3.account.create("random string")
w3.cfx.default_account = acct

transaction = {
    'to': w3.address.zero_address(network_id=1),
    'value': 22,
    'gasPrice': 10**9,
}
tx_hash = w3.cfx.send_transaction(transaction)

tx_hash.mined()
tx_hash.executed()
tx_hash.confirmed()
tx_hash.finalized()

10.27 python-conflux-sdk: 构造 contract 时的 name 参数

python-conflux-sdk 对内置合约与部分使用频率较高的合约提供了特殊的支持:在构造合约时,可以通过name参数指定特定合约名,便捷地构造合约对象,从而免去指定abi,bytecode,address等合约参数的麻烦。

from conflux_web3 import Web3
w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
acct = w3.account.create()
w3.default_account = acct

# 从 测试网水龙头领取测试网CFX
faucet = w3.cfx.contract(name="Faucet")
assert faucet.address == "cfxtest:acejjfa80vj06j2jgtz9pngkv423fhkuxj786kjr61"
faucet.functions.claimCfx().transact().executed()

# 部署ERC20合约
erc20_factory = w3.cfx.contract(name="ERC20")
contract_address = (erc20_factory.constructor(name="Coin", symbol="C", initialSupply=10**18)
                    .transact()
                    .executed()["contractCreated"])

# 使用部署的ERC20合约转账
erc20_instance = erc20_factory(contract_address)
erc20_instance.functions.transfer(w3.cfx.address.zero_address(network_id=1), 100).transact().executed()