账户、地址与钱包
内容
账户、地址与钱包¶
单击顶部栏上的🚀
-> Binder
在线运行此示例!
准备¶
本部分将准备web3
对象与私钥private_key
,提供后文代码所需的变量。
# 领取 1000 CFX 到私钥对应的账户
from pprint import pprint
from conflux_web3 import Web3
w3_ = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
acct = w3_.account.create()
w3_.cfx.default_account = acct
faucet = w3_.cfx.contract(name="Faucet")
tx_receipt = faucet.functions.claimCfx().transact().executed()
# 新建w3对象以便演示API的用法
w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
private_key: str = acct.key.hex()
账户与地址¶
在 web3 中,控制着一个帐户意味着知道一个私钥。虽然私钥应该保密,但地址不必。地址是从私钥单向派生的字符串,用于标识帐户。不同区块链常常会使用不同方式编码账户地址,例如比特币与以太坊的地址编码方式就存在区别。在 Conflux 中,地址以CIP-37定义的 base32 格式编码。
LocalAccount
对象¶
w3.account
是一个工厂对象,用于生成用来签署交易的LocalAccount
对象(例如random_account
)。
注意:手动签署交易相当繁琐。请参阅钱包部分了解如何使用钱包签名和发送交易。或者您可以参考从头构建交易了解如何正确手动签名交易。
更多文档:
w3.account
是一个cfx_account.Account
对象,其继承自eth_account.Account
,大部分api与eth_account一致。
random_account = w3.account.from_key(private_key)
print(f"account address: {random_account.address}")
print(f"account private key: {private_key}")
transaction = {
'to': w3.address.zero_address(),
'nonce': 1,
'value': 1,
'gas': 21000,
'gasPrice': 10**9,
'storageLimit': 0,
'epochHeight': 100,
'chainId': 1
}
print(f"signed raw tx: {random_account.sign_transaction(transaction).rawTransaction.hex()}")
account address: cfxtest:aat00gxdfxun3y9a4v6azn7ew0maj9vkta4a65cdkm
account private key: 0xb4a8134094df8b7544e6787da1ee92ba94ad68e2cbbe1141a3cabc3307778e32
signed raw tx: 0xf867e301843b9aca00825208940000000000000000000000000000000000000000018064018001a0c2ac330c9617078efdc6240d7ddb3aa7bc1ef0483625ee12c1f6c1ed66a5b3cca0657695c1012f6774e9eabd679e9f1fc1a14345f13c7494da43facb5b0ca14f25
怎样创建一个LocalAccount
对象¶
以下是创建LocalAccount
对象的几种方法:
通过使用
w3.account.create
生成随机密钥通过使用
w3.account.from_key
从已有密钥中创建通过使用
w3.account.from_mnemonic
从助记词创建通过使用
w3.account.decrypt
从密钥存储文件中创建
下面是使用上述 API 的示例:
# 随机生成
# 这个 API 会从操作系统中收集随机性来生成账户,参数可以提供额外的熵
generated_account = w3.account.create("extra_entropy")
# 从已有密钥中生成
generated_account = w3.account.from_key("0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364")
# 从助记词中生成
# "m/44'/503'/0'/0/0" 是 Conflux 默认派生路径
generated_account = w3.account.from_mnemonic(
"health embark april buyer eternal leopard want before nominee head thing tackle",
passphrase="",
account_path="m/44'/503'/0'/0/0"
)
# 由keystore文件中生成
# 当然,也可以使用 `w3.account.encrypt` 来获取一个keystore 文件对应的JSON
keystore = {
"version": 3,
"id": "db029583-f1bd-41cc-aeb5-b2ed5b33227b",
"address": "1cad0b19bb29d4674531d6f115237e16afce377c",
"crypto": {
"ciphertext": "3198706577b0880234ecbb5233012a8ca0495bf2cfa2e45121b4f09434187aba",
"cipherparams": {"iv": "a9a1f9565fd9831e669e8a9a0ec68818"},
"cipher": "aes-128-ctr",
"kdf": "scrypt",
"kdfparams": {
"dklen": 32,
"salt": "3ce2d51bed702f2f31545be66fa73d1467d24686059776430df9508407b74231",
"n": 8192,
"r": 8,
"p": 1,
},
"mac": "cf73832f328f3d5d1e0ec7b0f9c220facf951e8bba86c9f26e706d2df1e34890",
}
}
generated_account = w3.account.decrypt(keystore, password="password")
Conflux 地址¶
在 Conflux 中,地址按照CIP-37以 base32 格式编码。你可以简单地从地址字面推断出该地址属于主网、测试网或其他网络。
# "cfxtest" 代表该地址为测试网地址
assert random_account.address.startswith("cfxtest:")
SDK 返回的地址都被类Base32Address
包裹。该类提供了方便的方法来操作 base32 地址,但你也可以将Base32Address
对象用作普通的 python str
对象。Base32Address 文档提供了更详细的代码示例。
addr = random_account.address
print(f"the type of addr: {type(addr)}")
# a Base32Address object is also a `str`
assert isinstance(addr, str)
# encode a base32 address from hex address and network_id
# it is also supported to use `w3.address("cfxtest:aatp533cg7d0agbd87kz48nj1mpnkca8be1rz695j4")`
address = w3.address("0x1ecde7223747601823f7535d7968ba98b4881e09", network_id=1)
print(address)
pprint([
address.address_type,
address.network_id,
address.hex_address,
address.verbose_address,
address.abbr,
address.mapped_evm_space_address,
])
the type of addr: <class 'cfx_address.address.Base32Address'>
cfxtest:aatp533cg7d0agbd87kz48nj1mpnkca8be1rz695j4
['user',
1,
'0x1ECdE7223747601823f7535d7968Ba98b4881E09',
'CFXTEST:TYPE.USER:AATP533CG7D0AGBD87KZ48NJ1MPNKCA8BE1RZ695J4',
'cfxtest:aat...95j4',
'0x349f086998cF4a0C5a00b853a0E93239D81A97f6']
钱包¶
我们使用钱包中间件(w3.wallet
)来帮助我们签名发送交易。如果某未签名交易的from
账户已添加至w3.wallet
中,它将对通过w3.cfx.send_transaction
发送的未签名交易进行签名。
wallet
中间件的行为与web3.py
的construct_sign_and_send_raw_middleware
基本一致,但提供了更多功能。例如,我们可以使用w3.wallet.add_account
、w3.wallet.add_accounts
、w3.wallet.pop
来动态添加或删除帐户。
# wallet是 conflux_web3 的中间件,可向其中添加 LocalAccount
assert w3.wallet is w3.middleware_onion["wallet"]
w3.wallet.add_account(random_account)
assert random_account.address in w3.wallet
w3.cfx.send_transaction({
"from": random_account.address,
"to": random_account.address,
"value": 10**18
}).executed()
AttributeDict({'transactionHash': HexBytes('0x0eaef189cce96acaf1228176f07ec41a352f7e6ff450bffecd85240ae3473e21'),
'index': 0,
'blockHash': HexBytes('0x9fbaa224b1aef6d68fa03cdf0978e2246bfce06a23e4a0ac542825aa99f980a7'),
'epochNumber': 109112221,
'from': 'cfxtest:aat00gxdfxun3y9a4v6azn7ew0maj9vkta4a65cdkm',
'to': 'cfxtest:aat00gxdfxun3y9a4v6azn7ew0maj9vkta4a65cdkm',
'gasUsed': 21000,
'gasFee': 21000000000000 Drip,
'contractCreated': None,
'logs': [],
'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),
'stateRoot': HexBytes('0x178a81f8f52946355476db908c2ab75321e763f692f4f1cd7e1ebd268c04fa79'),
'outcomeStatus': 0,
'txExecErrorMsg': None,
'gasCoveredBySponsor': False,
'storageCoveredBySponsor': False,
'storageCollateralized': 0,
'storageReleased': []})
使用w3.cfx.default_account
将账户添加到钱包¶
当 w3.cfx.default_account
被设置后,若交易的 from
字段未指定,则将被自动设置为 w3.cfx.default_account
。
w3.cfx.default_account
是一个地址类型的变量,但可以使用LocalAccount
对象进行设置。在这种情况下,该LocalAccount
将同时添加到钱包中。
w3.cfx.default_account = random_account
相当于
w3.cfx.default_account = random_account.address
w3.wallet.add_account(random_account)