# 简介

海神波塞冬，本工具库对常用的链上交互操作进行了模块化抽象与简洁式封装，让开发者能够轻松快速地与主流区块链网络进行交互。目前支持任意 EVM 链。

<figure><img src="https://2534165956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlMNqaNHxRNQzo5mgvqAr%2Fuploads%2FqLwew3rcgJ4jBUALxocy%2F1024x1024.png?alt=media&amp;token=644df355-eae8-4cd3-8172-43404298cde6" alt="" width="375"><figcaption></figcaption></figure>


# 安装

## 最简方式

直接使用 pip 安装，但有可能由于本地 python 环境依赖库紊乱而导致脚本运行出错。

```bash
pip install -U poseidon-python
```

## 推荐方式

基于 [模板库](https://github.com/B1ue1nWh1te/PoseidonTemplate) 使用 poetry 创建虚拟环境，这样可以保证脚本运行环境干净，减少出现意外错误的可能。

安装 poetry 虚拟环境管理工具（如果之前未安装）：

```bash
pip install -U poetry
```

克隆 [模板库](https://github.com/B1ue1nWh1te/PoseidonTemplate) 至本地（也可先使用该模板库创建一个副本至你自己的 Github 仓库中再克隆）：

```bash
git clone git@github.com:B1ue1nWh1te/PoseidonTemplate.git
```

切换至模板仓库目录并安装虚拟环境：

```bash
cd PoseidonTemplate
poetry install
```

之后假设你编写了一个名为 main.py 的脚本要运行：

```bash
poetry shell
python main.py
```


# 示例

* [测试样例](https://github.com/B1ue1nWh1te/Poseidon/tree/main/tests)
* [模板库](https://github.com/B1ue1nWh1te/PoseidonTemplate)

以下通过对比 Poseidon 与 web3.py 的使用，展示 Poseidon 的简洁性优势。

### 使用 Poseidon

```python
from poseidon.evm import Chain, Account, Contract, Utils

rpc_url = "https://<RPC_URL>"
chain = Chain(rpc_url)

address, private_key = Utils.generate_new_account()
account = Account(chain, private_key)
signature_data = account.sign_message_string("test")
signed_message_data = Utils.recover_message_string("test", signature_data.signature_data.signature)
account.send_transaction(to=ZERO_ADDRESS, data="0x", value=1)

Utils.set_solidity_version("0.8.28")
abi, bytecode = Utils.compile_solidity_contract("./Contract.sol", "Contract")
tx_receipt = account.deploy_contract(abi, bytecode)

contract: Contract = tx_receipt.contract
contract.call_function("anyWriteFunction", "(param1)", "(param2)")
contract.read_only_call_function("anyReadOnlyFunction", "(param1)", "(param2)")
```

### 使用 web3.py

```python
from web3 import Web3
from eth_account import Account as Web3Account
from eth_account.messages import encode_defunct
from solcx import compile_source, install_solc
import json

w3 = Web3(Web3.HTTPProvider("https://<RPC_URL>"))

account = Web3Account.create()
address = account.address
private_key = account.key.hex()
message = encode_defunct(text="test")
signed_message = w3.eth.account.sign_message(message, private_key=private_key)
recovered_address = w3.eth.account.recover_message(message, signature=signed_message.signature)
transaction = {
    'nonce': w3.eth.get_transaction_count(address),
    'to': ZERO_ADDRESS,
    'value': 1,
    'gas': 21000,
    'gasPrice': w3.eth.gas_price,
    'data': '0x'
}
signed_txn = w3.eth.account.sign_transaction(transaction, private_key)
tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)

install_solc('0.8.28')
with open('./Contract.sol', 'r') as file:
    source = file.read()
compiled_sol = compile_source(source)
contract_interface = compiled_sol['<stdin>:Contract']
bytecode = contract_interface['bin']
abi = contract_interface['abi']
contract = w3.eth.contract(abi=abi, bytecode=bytecode)
transaction = contract.constructor().build_transaction({
    'from': address,
    'nonce': w3.eth.get_transaction_count(address),
    'gas': 2000000,
    'gasPrice': w3.eth.gas_price
})
signed_txn = w3.eth.account.sign_transaction(transaction, private_key)
tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)

contract_instance = w3.eth.contract(address=tx_receipt.contractAddress, abi=abi)
write_txn = contract_instance.functions.anyWriteFunction("(param1)", "(param2)").build_transaction({
    'from': address,
    'nonce': w3.eth.get_transaction_count(address),
    'gas': 200000,
    'gasPrice': w3.eth.gas_price
})
signed_txn = w3.eth.account.sign_transaction(write_txn, private_key)
tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction)
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
result = contract_instance.functions.anyReadOnlyFunction("(param1)", "(param2)").call()
```


# 注意事项

1. **EVM** 模块的所有功能在 `Ethereum Sepolia`, `Arbitrum Sepolia`, `Optimism Sepolia`, `BSC Testnet`, `Polygon Amoy` **测试网络**中均正常通过测试。
2. 建议始终使用**全新生成的**账户进行导入，以避免意外情况下隐私数据泄露。
3. 关于安全性，代码完全开源并且基于常用的第三方库进行封装，可以自行进行审阅。
4. 如果你在使用过程中遇到了问题或者有任何好的想法和建议，欢迎提 [**Issues**](https://github.com/B1ue1nWh1te/Poseidon/issues) 或 [**PRs**](https://github.com/B1ue1nWh1te/Poseidon/pulls) 进行反馈和贡献。
5. 本工具库**开源的目的是进行技术开发上的交流与分享**，不涉及任何其他方面的内容。原则上该工具只应该在开发测试环境下与区块链测试网进行交互调试，作者并不提倡在其他情况下使用。若开发者自行选择在具有经济价值的区块链主网中使用，所造成的任何影响由其个人负责，与作者本人无关。


# 更新日志


# v2.0.1

* 完善文档内容
* 修复一些小瑕疵
* 例行更新依赖库版本
* 支持 EIP-7702 交易回执分类（发送逻辑太复杂本打算写但最后还是没写 在Foundry有现成的可用）
* 区分 sign\_message\_raw\_hash/recover\_message\_raw\_hash（原生） 和 sign\_message\_hash/recover\_message\_hash（EIP-191）


# v2.0.0

* 解决早期版本历史遗留问题
* 使用 Poetry 进行包环境管理
* 使用 bandit 和 gitroll 进行代码检查
* 尽量实现 Python 包规范，使用 snake\_case 风格重写
* 代码逻辑全面优化，删除部分不常用或无关的功能函数
* 优化测试样例与模板库
* 完善签名相关的功能函数
* 全面完善项目文档内容（使用 AI 自动生成）


# (DataClass)

DataClass 是数据类集合，用于规范化和结构化各种数据对象。

## 数据类列表

* [ChainInformationData](/evm/dataclass/chaininformationdata): 链信息数据结构
* [BlockInformationData](/evm/dataclass/blockinformationdata): 区块信息数据结构
* [TransactionReceiptData](/evm/dataclass/transactionreceiptdata): 交易回执数据结构
* [SignatureData](/evm/dataclass/signaturedata): 签名数据结构
* [SignedMessageData](/evm/dataclass/signedmessagedata): 已签名消息数据结构


# ChainInformationData

链信息数据结构。

## 字段说明

| 字段              | 类型             | 说明         |
| --------------- | -------------- | ---------- |
| chain\_id       | int            | 链 ID       |
| block\_number   | BlockNumber    | 当前区块高度     |
| gas\_price      | Wei            | Gas 价格     |
| timeslot        | Optional\[int] | 平均出块时间(可选) |
| client\_version | Optional\[str] | 客户端版本(可选)  |

## 示例代码

```python
from poseidon.evm import Chain

chain = Chain("https://eth-sepolia.g.alchemy.com/v2/YOUR-API-KEY")
info: ChainInformationData = chain.get_chain_information()

print(f"Chain ID: {info.chain_id}")
print(f"Current Block: {info.block_number}")
print(f"Gas Price: {Web3.from_wei(info.gas_price, 'gwei')} Gwei")
if info.timeslot:
    print(f"Average Block Time: {info.timeslot}s")
if info.client_version:
    print(f"Client Version: {info.client_version}")
```


# BlockInformationData

区块信息数据结构。

## 字段说明

| 字段            | 类型                                             | 说明         |
| ------------- | ---------------------------------------------- | ---------- |
| block\_hash   | HexBytes                                       | 区块哈希       |
| block\_number | BlockNumber                                    | 区块高度       |
| timestamp     | Timestamp                                      | 区块时间戳      |
| miner         | ChecksumAddress                                | 矿工地址       |
| gas\_used     | int                                            | 区块已使用的 Gas |
| gas\_limit    | int                                            | 区块 Gas 上限  |
| transactions  | Union\[Sequence\[HexBytes], Sequence\[TxData]] | 区块内的交易列表   |

## 示例代码

```python
block: BlockInformationData = chain.get_block_information("latest")

print(f"Block Hash: {block.block_hash.hex()}")
print(f"Block Number: {block.block_number}")
print(f"Timestamp: {block.timestamp}")
print(f"Miner: {block.miner}")
print(f"Gas Used: {block.gas_used}")
print(f"Gas Limit: {block.gas_limit}")
print(f"Transaction Count: {len(block.transactions)}")
```


# TransactionReceiptData

交易回执数据结构。

## 字段说明

| 字段                           | 类型                           | 说明                  |
| ---------------------------- | ---------------------------- | ------------------- |
| transaction\_hash            | HexBytes                     | 交易哈希                |
| block\_number                | BlockNumber                  | 区块高度                |
| transaction\_index           | int                          | 交易在区块中的索引           |
| transaction\_status          | int                          | 交易状态(1 成功,0 失败)     |
| transaction\_type            | int                          | 交易类型                |
| action                       | str                          | 交易动作类型              |
| sender                       | ChecksumAddress              | 发送者地址               |
| to                           | ChecksumAddress              | 接收者地址               |
| nonce                        | Nonce                        | 交易序号                |
| value                        | Wei                          | 转账金额                |
| gas\_used                    | int                          | 实际使用的 Gas           |
| gas\_limit                   | int                          | Gas 上限              |
| gas\_price                   | Optional\[Wei]               | Gas 价格              |
| max\_fee\_per\_gas           | Optional\[Wei]               | 最大 Gas 费用(EIP-1559) |
| max\_priority\_fee\_per\_gas | Optional\[Wei]               | 最大优先费用(EIP-1559)    |
| effective\_gas\_price        | Optional\[Wei]               | 实际 Gas 价格           |
| contract\_address            | Optional\[ChecksumAddress]   | 部署的合约地址(仅合约创建交易)    |
| contract                     | Optional\[Any]               | 合约实例(仅合约创建交易)       |
| logs                         | Optional\[List\[LogReceipt]] | 交易日志                |
| input\_data                  | HexBytes                     | 交易输入数据              |
| r                            | HexBytes                     | 签名 r 值              |
| s                            | HexBytes                     | 签名 s 值              |
| v                            | HexBytes                     | 签名 v 值              |

## 示例代码

```python
# 获取交易回执
receipt: TransactionReceiptData = chain.get_transaction_receipt_by_hash("0x...")

if receipt.transaction_status:
    print(f"Transaction successful: {receipt.transaction_hash.hex()}")
    print(f"Block Number: {receipt.block_number}")
    print(f"From: {receipt.sender}")
    print(f"To: {receipt.to}")
    print(f"Value: {Web3.from_wei(receipt.value, 'ether')} ETH")
    print(f"Gas Used: {receipt.gas_used}")

    if receipt.contract_address:
        print(f"Deployed Contract: {receipt.contract_address}")
```


# SignatureData

签名数据结构。

## 字段说明

| 字段        | 类型       | 说明     |
| --------- | -------- | ------ |
| signature | HexBytes | 完整签名   |
| r         | HexBytes | 签名 r 值 |
| s         | HexBytes | 签名 s 值 |
| v         | HexBytes | 签名 v 值 |

## 示例代码

```python
# 从签名生成签名数据
signature = HexBytes("0x...")  # 65 字节的签名
signature_data: SignatureData = Utils.generate_signature_data_with_signature(signature)

print(f"Full Signature: {signature_data.signature.hex()}")
print(f"R: {signature_data.r.hex()}")
print(f"S: {signature_data.s.hex()}")
print(f"V: {signature_data.v.hex()}")
```


# SignedMessageData

已签名消息数据结构。

## 字段说明

| 字段              | 类型              | 说明    |
| --------------- | --------------- | ----- |
| message\_hash   | HexBytes        | 消息哈希  |
| message         | Optional\[str]  | 原始消息  |
| signer          | ChecksumAddress | 签名者地址 |
| signature\_data | SignatureData   | 签名数据  |

## 示例代码

```python
# 签名消息
message = "Hello, Ethereum!"
signed: SignedMessageData = account.sign_message_string(message)

print(f"Message: {signed.message}")
print(f"Message Hash: {signed.message_hash.hex()}")
print(f"Signer: {signed.signer}")
print(f"Signature: {signed.signature_data.signature.hex()}")
```


# Chain

Chain 是 EVM 链实例，后续的所有链上交互操作都将发往该链处理。

## 成员变量

* `chain_id`: 链 ID
* `provider`: web3.py 原生的 HTTPProvider 实例
* `eth`: HTTPProvider 实例中的 eth 模块

## 方法列表

* [**init**](/evm/chain/__init__): 初始化 Chain 实例
* [get\_chain\_information](/evm/chain/get_chain_information): 获取链基本信息
* [get\_block\_information](/evm/chain/get_block_information): 获取区块信息
* [get\_transaction\_receipt\_by\_hash](/evm/chain/get_transaction_receipt_by_hash): 通过交易哈希获取交易回执
* [get\_transaction\_receipt\_by\_block\_id\_and\_index](/evm/chain/get_transaction_receipt_by_block_id_and_index): 通过区块和索引获取交易回执
* [get\_balance](/evm/chain/get_balance): 获取账户余额
* [get\_code](/evm/chain/get_code): 获取合约字节码
* [get\_storage](/evm/chain/get_storage): 获取存储值
* [dump\_storage](/evm/chain/dump_storage): 批量获取存储值


# \_\_init\_\_

实例初始化。根据给定的节点 RPC 地址以 HTTP/HTTPS 方式进行连接，可通过代理访问。

## 方法定义

```python
def __init__(self, rpc_url: str, request_params: Optional[dict] = None) -> None
```

## 参数说明

| 参数              | 类型              | 说明                   |
| --------------- | --------------- | -------------------- |
| rpc\_url        | str             | 节点 RPC 地址            |
| request\_params | Optional\[dict] | 连接时使用的 request 参数,可选 |

当需要使用代理进行访问时，request\_params 示例:

```python
request_params = {
    "proxies": {
        "http": "http://localhost:<ProxyPort>",
        "https": "http://localhost:<ProxyPort>"
    }
}
```

## 成员变量

| 变量        | 类型                    | 说明                          |
| --------- | --------------------- | --------------------------- |
| chain\_id | int                   | 链 ID                        |
| provider  | web3.HTTPProvider     | web3.py 原生的 HTTPProvider 实例 |
| eth       | web3.HTTPProvider.eth | HTTPProvider 实例中的 eth 模块    |

## 示例代码

```python
from poseidon.evm import Chain

# 直接连接
chain = Chain("https://eth-sepolia.g.alchemy.com/v2/YOUR-API-KEY")

# 使用代理连接
proxy_params = {
    "proxies": {
        "http": "http://localhost:7890",
        "https": "http://localhost:7890"
    }
}
chain = Chain("https://eth-sepolia.g.alchemy.com/v2/YOUR-API-KEY", proxy_params)
```


# get\_chain\_information

获取 EVM 链基本信息。

## 方法定义

```python
def get_chain_information(self, show_timeslot: bool = True, show_client_version: bool = True) -> ChainInformationData
```

## 参数说明

| 参数                    | 类型   | 说明                            |
| --------------------- | ---- | ----------------------------- |
| show\_timeslot        | bool | 是否显示 timeslot,默认为 True        |
| show\_client\_version | bool | 是否显示 client\_version,默认为 True |

## 返回值

返回 ChainInformationData 对象,包含以下字段:

| 字段              | 类型             | 说明         |
| --------------- | -------------- | ---------- |
| chain\_id       | int            | 链 ID       |
| block\_number   | BlockNumber    | 当前区块高度     |
| gas\_price      | Wei            | Gas 价格     |
| timeslot        | Optional\[int] | 平均出块时间(可选) |
| client\_version | Optional\[str] | 客户端版本(可选)  |

## 示例代码

```python
# 获取所有信息
info = chain.get_chain_information()
print(f"Chain ID: {info.chain_id}")
print(f"Current Block: {info.block_number}")
print(f"Gas Price: {Web3.from_wei(info.gas_price, 'gwei')} Gwei")
if info.timeslot:
    print(f"Average Block Time: {info.timeslot}s")
if info.client_version:
    print(f"Client Version: {info.client_version}")

# 不显示 timeslot 和 client_version
info = chain.get_chain_information(show_timeslot=False, show_client_version=False)
```


# get\_block\_information

根据区块 ID 获取该区块基本信息。

## 方法定义

```python
def get_block_information(self, block_id: BlockIdentifier) -> Optional[BlockInformationData]
```

## 参数说明

| 参数        | 类型              | 说明                                                    |
| --------- | --------------- | ----------------------------------------------------- |
| block\_id | BlockIdentifier | 区块 ID,可以是区块号、区块哈希或 'latest','earliest','pending' 等标识符 |

## 返回值

返回 BlockInformationData 对象,包含以下字段:

| 字段            | 类型                                             | 说明         |
| ------------- | ---------------------------------------------- | ---------- |
| block\_hash   | HexBytes                                       | 区块哈希       |
| block\_number | BlockNumber                                    | 区块高度       |
| timestamp     | Timestamp                                      | 区块时间戳      |
| miner         | ChecksumAddress                                | 矿工地址       |
| gas\_used     | int                                            | 区块已使用的 Gas |
| gas\_limit    | int                                            | 区块 Gas 上限  |
| transactions  | Union\[Sequence\[HexBytes], Sequence\[TxData]] | 区块内的交易列表   |

## 示例代码

```python
# 获取最新区块信息
latest_block = chain.get_block_information("latest")
print(f"Block Number: {latest_block.block_number}")
print(f"Block Hash: {latest_block.block_hash.hex()}")
print(f"Miner: {latest_block.miner}")
print(f"Gas Used: {latest_block.gas_used}")

# 通过区块号获取
block = chain.get_block_information(12345678)

# 通过区块哈希获取
block = chain.get_block_information("0x...")
```


# get\_transaction\_receipt\_by\_hash

根据交易哈希获取该交易的回执信息。

## 方法定义

```python
def get_transaction_receipt_by_hash(self, transaction_hash: _Hash32) -> Optional[TransactionReceiptData]
```

## 参数说明

| 参数                | 类型       | 说明   |
| ----------------- | -------- | ---- |
| transaction\_hash | \_Hash32 | 交易哈希 |

## 返回值

返回 TransactionReceiptData 对象,包含以下字段:

| 字段                           | 类型                           | 说明                     |
| ---------------------------- | ---------------------------- | ---------------------- |
| transaction\_hash            | HexBytes                     | 交易哈希                   |
| block\_number                | BlockNumber                  | 区块高度                   |
| transaction\_index           | int                          | 交易在区块中的索引              |
| transaction\_status          | int                          | 交易状态(1 成功,0 失败)        |
| transaction\_type            | int                          | 交易类型                   |
| action                       | str                          | 交易动作类型                 |
| sender                       | ChecksumAddress              | 发送者地址                  |
| to                           | ChecksumAddress              | 接收者地址                  |
| nonce                        | Nonce                        | 交易序号                   |
| value                        | Wei                          | 转账金额                   |
| gas\_used                    | int                          | 实际使用的 Gas              |
| gas\_limit                   | int                          | Gas 上限                 |
| gas\_price                   | Optional\[Wei]               | Gas 价格(EIP-155 交易)     |
| max\_fee\_per\_gas           | Optional\[Wei]               | 最大 Gas 费用(EIP-1559 交易) |
| max\_priority\_fee\_per\_gas | Optional\[Wei]               | 最大优先费用(EIP-1559 交易)    |
| effective\_gas\_price        | Optional\[Wei]               | 实际 Gas 价格              |
| contract\_address            | Optional\[ChecksumAddress]   | 部署的合约地址(仅合约创建交易)       |
| logs                         | Optional\[List\[LogReceipt]] | 交易日志                   |
| input\_data                  | HexBytes                     | 交易输入数据                 |
| r                            | HexBytes                     | 签名 r 值                 |
| s                            | HexBytes                     | 签名 s 值                 |
| v                            | HexBytes                     | 签名 v 值                 |

## 示例代码

```python
# 获取交易回执
receipt = chain.get_transaction_receipt_by_hash("0x...")
if receipt.transaction_status:
    print("Transaction Successful")
    print(f"Gas Used: {receipt.gas_used}")
    if receipt.contract_address:
        print(f"Deployed Contract: {receipt.contract_address}")
```


# get\_transaction\_receipt\_by\_block\_id\_and\_index

根据区块 ID 和索引来获取该交易的回执信息。

## 方法定义

```python
def get_transaction_receipt_by_block_id_and_index(self, block_id: BlockIdentifier, transaction_index: int) -> Optional[TransactionReceiptData]
```

## 参数说明

| 参数                 | 类型              | 说明                        |
| ------------------ | --------------- | ------------------------- |
| block\_id          | BlockIdentifier | 区块 ID(区块号/区块哈希/'latest'等) |
| transaction\_index | int             | 交易在区块中的索引                 |

## 返回值

返回 TransactionReceiptData 对象,字段说明与 get\_transaction\_receipt\_by\_hash 相同。

## 示例代码

```python
# 获取最新区块的第一笔交易
receipt = chain.get_transaction_receipt_by_block_id_and_index("latest", 0)
if receipt:
    print(f"Transaction Hash: {receipt.transaction_hash.hex()}")
    print(f"From: {receipt.sender}")
    print(f"To: {receipt.to}")
    print(f"Value: {Web3.from_wei(receipt.value, 'ether')} ETH")
```


# get\_balance

根据账户地址获取其原生代币余额。

## 方法定义

```python
def get_balance(self, address: ChecksumAddress) -> Optional[Wei]
```

## 参数说明

| 参数      | 类型              | 说明   |
| ------- | --------------- | ---- |
| address | ChecksumAddress | 账户地址 |

## 返回值

| 类型             | 说明            |
| -------------- | ------------- |
| Optional\[Wei] | 账户原生代币余额(Wei) |

## 示例代码

```python
# 获取账户余额
balance = chain.get_balance("0x...")
if balance is not None:
    print(f"Balance: {Web3.from_wei(balance, 'ether')} ETH")
```


# get\_code

根据合约地址获取其字节码。

## 方法定义

```python
def get_code(self, address: ChecksumAddress) -> Optional[HexBytes]
```

## 参数说明

| 参数      | 类型              | 说明   |
| ------- | --------------- | ---- |
| address | ChecksumAddress | 合约地址 |

## 返回值

| 类型                  | 说明    |
| ------------------- | ----- |
| Optional\[HexBytes] | 合约字节码 |

## 示例代码

```python
# 获取合约字节码
bytecode = chain.get_code("0x...")
if bytecode:
    print(f"Contract Bytecode: {bytecode.hex()}")
```


# get\_storage

根据合约地址和存储插槽索引获取存储值。

## 方法定义

```python
def get_storage(self, address: ChecksumAddress, slot_index: int) -> Optional[HexBytes]
```

## 参数说明

| 参数          | 类型              | 说明     |
| ----------- | --------------- | ------ |
| address     | ChecksumAddress | 合约地址   |
| slot\_index | int             | 存储插槽索引 |

## 返回值

| 类型                  | 说明  |
| ------------------- | --- |
| Optional\[HexBytes] | 存储值 |

## 示例代码

```python
# 获取存储值
storage = chain.get_storage("0x...", 0)
if storage:
    print(f"Storage Value: {storage.hex()}")
```


# dump\_storage

根据合约地址和起止插槽索引,批量获取存储值。

## 方法定义

```python
def dump_storage(self, address: ChecksumAddress, start_slot_index: int, end_slot_index: int) -> Optional[List[HexBytes]]
```

## 参数说明

| 参数                 | 类型              | 说明     |
| ------------------ | --------------- | ------ |
| address            | ChecksumAddress | 合约地址   |
| start\_slot\_index | int             | 起始插槽索引 |
| end\_slot\_index   | int             | 终止插槽索引 |

## 返回值

| 类型                         | 说明    |
| -------------------------- | ----- |
| Optional\[List\[HexBytes]] | 存储值列表 |

## 示例代码

```python
# 获取前10个存储槽的值
storage_list = chain.dump_storage("0x...", 0, 10)
if storage_list:
    for i, value in enumerate(storage_list):
        print(f"Slot {i}: {value.hex()}")

# 获取指定范围的存储值
storage_list = chain.dump_storage("0x...", 100, 120)
if storage_list:
    for i, value in enumerate(storage_list, start=100):
        print(f"Slot {i}: {value.hex()}")
```


# Account

Account 是账户实例，后续的交易将由该账户签署并发送至链上。

## 成员变量

* `eth_account`: eth\_account 的 LocalAccount 实例
* `address`: 账户地址
* `private_key`: 账户私钥

## 方法列表

* [**init**](/evm/account/__init__): 初始化 Account 实例
* [set\_need\_confirm\_before\_send\_transaction](/evm/account/set_need_confirm_before_send_transaction): 设置发送交易前是否需要确认
* [get\_self\_balance](/evm/account/get_self_balance): 获取账户余额
* [send\_transaction](/evm/account/send_transaction): 发送 EIP-155 交易
* [send\_transaction\_by\_eip1559](/evm/account/send_transaction_by_eip1559): 发送 EIP-1559 交易
* [deploy\_contract](/evm/account/deploy_contract): 部署合约
* [sign\_message\_string](/evm/account/sign_message_string): 签名消息字符串
* [sign\_message\_hash](/evm/account/sign_message_hash): 签名消息哈希
* [sign\_typed\_message](/evm/account/sign_typed_message): 签名 EIP-712 结构化数据


# \_\_init\_\_

实例初始化。通过私钥导入账户并与 Chain 实例绑定。

## 方法定义

```python
def __init__(self, chain: Chain, private_key: HexBytes) -> None
```

## 参数说明

| 参数           | 类型       | 说明      |
| ------------ | -------- | ------- |
| chain        | Chain    | EVM 链实例 |
| private\_key | HexBytes | 账户私钥    |

## 成员变量

| 变量           | 类型              | 说明                             |
| ------------ | --------------- | ------------------------------ |
| eth\_account | LocalAccount    | eth\_account 的 LocalAccount 实例 |
| address      | ChecksumAddress | 账户地址                           |
| private\_key | HexBytes        | 账户私钥                           |

## 示例代码

```python
from poseidon.evm import Chain, Account
from hexbytes import HexBytes

# 连接到链
chain = Chain("https://eth-sepolia.g.alchemy.com/v2/YOUR-API-KEY")

# 导入账户
private_key = HexBytes("0x...")  # 你的私钥
account = Account(chain, private_key)

print(f"Account Address: {account.address}")
```


# set\_need\_confirm\_before\_send\_transaction

设置在通过该账户发送每一笔交易之前是否需要控制台回车确认。开启后会在每笔交易即将发送前暂停流程，在控制台询问是否发送该笔交易。

## 方法定义

```python
def set_need_confirm_before_send_transaction(self, need_confirm: bool = True) -> None
```

## 参数说明

| 参数            | 类型   | 说明          |
| ------------- | ---- | ----------- |
| need\_confirm | bool | 是否需要控制台回车确认 |

## 返回值

无

## 示例代码

```python
# 开启发送交易前的确认
account.set_need_confirm_before_send_transaction(True)

# 关闭发送交易前的确认
account.set_need_confirm_before_send_transaction(False)
```


# get\_self\_balance

获取当前账户的原生代币余额。

## 方法定义

```python
def get_self_balance(self) -> Optional[Wei]
```

## 参数说明

无

## 返回值

| 类型             | 说明          |
| -------------- | ----------- |
| Optional\[Wei] | 当前账户的原生代币余额 |

## 示例代码

```python
# 获取账户余额
balance = account.get_self_balance()
if balance is not None:
    print(f"Balance: {Web3.from_wei(balance, 'ether')} ETH")
```


# send\_transaction

发送自定义 EIP-155 交易。

## 方法定义

```python
def send_transaction(self, to: Optional[ChecksumAddress] = None, data: HexBytes = HexBytes("0x"), value: Wei = Wei(0), gas_price: Optional[Wei] = None, gas_limit: int = 500000) -> Optional[TransactionReceiptData]
```

## 参数说明

| 参数         | 类型                         | 说明                         |
| ---------- | -------------------------- | -------------------------- |
| to         | Optional\[ChecksumAddress] | 接收者地址,为 None 时表示创建合约       |
| data       | HexBytes                   | 交易数据,默认为空                  |
| value      | Wei                        | 发送的原生代币数量,默认为 0            |
| gas\_price | Optional\[Wei]             | Gas 价格,默认使用链上当前 gas\_price |
| gas\_limit | int                        | Gas 最大使用量,默认为 500000       |

## 返回值

返回 TransactionReceiptData 对象,包含以下字段:

| 字段                  | 类型                           | 说明               |
| ------------------- | ---------------------------- | ---------------- |
| transaction\_hash   | HexBytes                     | 交易哈希             |
| block\_number       | BlockNumber                  | 区块高度             |
| transaction\_index  | int                          | 交易在区块中的索引        |
| transaction\_status | int                          | 交易状态(1 成功,0 失败)  |
| transaction\_type   | int                          | 交易类型             |
| action              | str                          | 交易动作类型           |
| sender              | ChecksumAddress              | 发送者地址            |
| to                  | ChecksumAddress              | 接收者地址            |
| nonce               | Nonce                        | 交易序号             |
| value               | Wei                          | 转账金额             |
| gas\_used           | int                          | 实际使用的 Gas        |
| gas\_limit          | int                          | Gas 上限           |
| gas\_price          | Optional\[Wei]               | Gas 价格           |
| contract\_address   | Optional\[ChecksumAddress]   | 部署的合约地址(仅合约创建交易) |
| logs                | Optional\[List\[LogReceipt]] | 交易日志             |
| input\_data         | HexBytes                     | 交易输入数据           |
| r                   | HexBytes                     | 签名 r 值           |
| s                   | HexBytes                     | 签名 s 值           |
| v                   | HexBytes                     | 签名 v 值           |

## 示例代码

```python
# 发送 ETH
receipt = account.send_transaction(
    to="0x...",
    value=Web3.to_wei(0.1, 'ether')
)
if receipt and receipt.transaction_status:
    print(f"Transaction successful: {receipt.transaction_hash.hex()}")

# 调用合约函数
contract_function_data = HexBytes("0x...")  # 合约函数的编码数据
receipt = account.send_transaction(
    to="0x...",  # 合约地址
    data=contract_function_data,
    gas_limit=100000
)
```


# send\_transaction\_by\_eip1559

发送自定义 EIP-1559 交易。

## 方法定义

```python
def send_transaction_by_eip1559(self, to: Optional[ChecksumAddress] = None, data: HexBytes = HexBytes("0x"), value: Wei = Wei(0), base_fee: Optional[Wei] = None, max_priority_fee: Optional[Wei] = None, gas_limit: int = 500000) -> Optional[TransactionReceiptData]
```

## 参数说明

| 参数                 | 类型                         | 说明                       |
| ------------------ | -------------------------- | ------------------------ |
| to                 | Optional\[ChecksumAddress] | 接收者地址,为 None 时表示创建合约     |
| data               | HexBytes                   | 交易数据,默认为空                |
| value              | Wei                        | 发送的原生代币数量,默认为 0          |
| base\_fee          | Optional\[Wei]             | 基础费用,默认使用链上当前 gas\_price |
| max\_priority\_fee | Optional\[Wei]             | 最高优先费用,默认使用链上建议值         |
| gas\_limit         | int                        | Gas 最大使用量,默认为 500000     |

## 返回值

返回值格式与 send\_transaction 相同。

## 示例代码

```python
# 发送 EIP-1559 交易
receipt = account.send_transaction_by_eip1559(
    to="0x...",
    value=Web3.to_wei(0.1, 'ether'),
    max_priority_fee=Web3.to_wei(2, 'gwei')
)
if receipt and receipt.transaction_status:
    print(f"Transaction successful: {receipt.transaction_hash.hex()}")
    print(f"Effective gas price: {Web3.from_wei(receipt.effective_gas_price, 'gwei')} Gwei")
```


# deploy\_contract

部署合约。

## 方法定义

```python
def deploy_contract(self, abi: dict, bytecode: HexBytes, value: Wei = Wei(0), gas_price: Optional[Wei] = None, *args: Optional[Any]) -> Optional[TransactionReceiptData]
```

## 参数说明

| 参数         | 类型             | 说明                         |
| ---------- | -------------- | -------------------------- |
| abi        | dict           | 合约 ABI                     |
| bytecode   | HexBytes       | 合约字节码                      |
| value      | Wei            | 发送给合约的原生代币数量,默认为 0         |
| gas\_price | Optional\[Wei] | Gas 价格,默认使用链上当前 gas\_price |
| \*args     | Optional\[Any] | 传给合约构造函数的参数                |

## 返回值

返回 TransactionReceiptData 对象,当合约部署成功时,返回值中会额外添加"contract"字段(Contract 实例)。其他字段与 send\_transaction 相同。

## 示例代码

```python
# 部署合约
abi = [...] # 合约 ABI
bytecode = HexBytes("0x...") # 合约字节码

receipt = account.deploy_contract(
    abi=abi,
    bytecode=bytecode,
    value=Web3.to_wei(0.1, 'ether'),  # 发送 0.1 ETH 到合约
    gas_price=Web3.to_wei(50, 'gwei')  # 使用 50 Gwei 的 gas 价格
)

if receipt and receipt.transaction_status:
    print(f"Contract deployed at: {receipt.contract_address}")
    # 可以直接使用返回的合约实例
    contract = receipt.contract
```


# sign\_message\_string

对消息字符串进行签名。

## 方法定义

```python
def sign_message_string(self, message: str) -> Optional[SignedMessageData]
```

## 参数说明

| 参数      | 类型  | 说明       |
| ------- | --- | -------- |
| message | str | 待签名消息字符串 |

## 返回值

返回 SignedMessageData 对象,包含以下字段:

| 字段              | 类型              | 说明    |
| --------------- | --------------- | ----- |
| message\_hash   | HexBytes        | 消息哈希  |
| message         | str             | 原始消息  |
| signer          | ChecksumAddress | 签名者地址 |
| signature\_data | SignatureData   | 签名数据  |

SignatureData 包含以下字段:

| 字段        | 类型       | 说明     |
| --------- | -------- | ------ |
| signature | HexBytes | 完整签名   |
| r         | HexBytes | 签名 r 值 |
| s         | HexBytes | 签名 s 值 |
| v         | HexBytes | 签名 v 值 |

## 示例代码

```python
# 签名消息
message = "Hello, Ethereum!"
signed = account.sign_message_string(message)

if signed:
    print(f"Message: {signed.message}")
    print(f"Message Hash: {signed.message_hash.hex()}")
    print(f"Signer: {signed.signer}")
    print(f"Signature: {signed.signature_data.signature.hex()}")
```


# sign\_message\_raw\_hash

对消息哈希进行原生签名。

## 方法定义

```python
def sign_message_raw_hash(self, message_raw_hash: HexBytes) -> Optional[SignedMessageData]
```

## 参数说明

| 参数                 | 类型       | 说明      |
| ------------------ | -------- | ------- |
| message\_raw\_hash | HexBytes | 待签名消息哈希 |

## 返回值

返回 SignedMessageData 对象,包含以下字段:

| 字段              | 类型              | 说明      |
| --------------- | --------------- | ------- |
| message\_hash   | HexBytes        | 消息哈希    |
| message         | None            | 原始消息(无) |
| signer          | ChecksumAddress | 签名者地址   |
| signature\_data | SignatureData   | 签名数据    |

SignatureData 包含以下字段:

| 字段        | 类型       | 说明     |
| --------- | -------- | ------ |
| signature | HexBytes | 完整签名   |
| r         | HexBytes | 签名 r 值 |
| s         | HexBytes | 签名 s 值 |
| v         | HexBytes | 签名 v 值 |

## 示例代码

```python
# 签名消息哈希
message_raw_hash = HexBytes("0x...")
signed = account.sign_message_raw_hash(message_raw_hash)

if signed:
    print(f"Message Hash: {signed.message_hash.hex()}")
    print(f"Signer: {signed.signer}")
    print(f"Signature: {signed.signature_data.signature.hex()}")
```


# sign\_message\_hash

对消息哈希进行 EIP-191 签名。

## 方法定义

```python
def sign_message_hash(self, message_hash: HexBytes) -> Optional[SignedMessageData]
```

## 参数说明

| 参数            | 类型       | 说明      |
| ------------- | -------- | ------- |
| message\_hash | HexBytes | 待签名消息哈希 |

## 返回值

返回 SignedMessageData 对象,包含以下字段:

| 字段              | 类型              | 说明      |
| --------------- | --------------- | ------- |
| message\_hash   | HexBytes        | 消息哈希    |
| message         | None            | 原始消息(无) |
| signer          | ChecksumAddress | 签名者地址   |
| signature\_data | SignatureData   | 签名数据    |

SignatureData 包含以下字段:

| 字段        | 类型       | 说明     |
| --------- | -------- | ------ |
| signature | HexBytes | 完整签名   |
| r         | HexBytes | 签名 r 值 |
| s         | HexBytes | 签名 s 值 |
| v         | HexBytes | 签名 v 值 |

## 示例代码

```python
# 签名消息哈希
message_hash = HexBytes("0x...")
signed = account.sign_message_hash(message_hash)

if signed:
    print(f"Message Hash: {signed.message_hash.hex()}")
    print(f"Signer: {signed.signer}")
    print(f"Signature: {signed.signature_data.signature.hex()}")
```


# sign\_typed\_message

对结构化消息数据进行 EIP-712 签名。

## 方法定义

```python
def sign_typed_message(self, domain_data: dict, message_types: dict, message_data: dict) -> Optional[SignedMessageData]
```

## 参数说明

| 参数             | 类型   | 说明       |
| -------------- | ---- | -------- |
| domain\_data   | dict | 域数据      |
| message\_types | dict | 消息类型定义   |
| message\_data  | dict | 待签名的消息数据 |

## 返回值

返回 SignedMessageData 对象,包含以下字段:

| 字段              | 类型              | 说明    |
| --------------- | --------------- | ----- |
| message\_hash   | HexBytes        | 消息哈希  |
| message         | str             | 原始消息  |
| signer          | ChecksumAddress | 签名者地址 |
| signature\_data | SignatureData   | 签名数据  |

SignatureData 包含以下字段:

| 字段        | 类型       | 说明     |
| --------- | -------- | ------ |
| signature | HexBytes | 完整签名   |
| r         | HexBytes | 签名 r 值 |
| s         | HexBytes | 签名 s 值 |
| v         | HexBytes | 签名 v 值 |

## 示例代码

```python
# EIP-712 结构化数据签名
domain_data = {
    "name": "MyDApp",
    "version": "1",
    "chainId": 1,
    "verifyingContract": "0x..."
}

message_types = {
    "Person": [
        {"name": "name", "type": "string"},
        {"name": "wallet", "type": "address"}
    ]
}

message_data = {
    "name": "Bob",
    "wallet": "0x..."
}

signed = account.sign_typed_message(domain_data, message_types, message_data)

if signed:
    print(f"Message Hash: {signed.message_hash.hex()}")
    print(f"Signer: {signed.signer}")
    print(f"Signature: {signed.signature_data.signature.hex()}")
```


# Contract

Contract 是合约实例，后续需要基于该实例调用合约中的函数。

## 成员变量

* `address`: 合约地址
* `web3py_contract`: web3.py 原生的 Contract 实例

## 方法列表

* [**init**](/evm/contract/__init__): 初始化 Contract 实例
* [call\_function](/evm/contract/call_function): 调用合约函数
* [call\_function\_with\_parameters](/evm/contract/call_function_with_parameters): 调用合约函数(可指定参数)
* [read\_only\_call\_function](/evm/contract/read_only_call_function): 调用只读函数
* [encode\_function\_calldata](/evm/contract/encode_function_calldata): 编码函数调用数据
* [decode\_function\_calldata](/evm/contract/decode_function_calldata): 解码函数调用数据


# \_\_init\_\_

实例初始化。通过合约地址与 ABI 来实例化合约，并与 Account 绑定，后续所有对该合约的调用都会由这一账户发起。

## 方法定义

```python
def __init__(self, account: Account, address: ChecksumAddress, abi: dict) -> None
```

## 参数说明

| 参数      | 类型              | 说明     |
| ------- | --------------- | ------ |
| account | Account         | 账户实例   |
| address | ChecksumAddress | 合约地址   |
| abi     | dict            | 合约 ABI |

## 成员变量

| 变量               | 类型                             | 说明                      |
| ---------------- | ------------------------------ | ----------------------- |
| address          | ChecksumAddress                | 合约地址                    |
| web3py\_contract | web3.HTTPProvider.eth.Contract | web3.py 原生的 Contract 实例 |

## 示例代码

```python
from poseidon.evm import Chain, Account, Contract

# 连接到链并导入账户
chain = Chain("https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY")
account = Account(chain, HexBytes("0x..."))  # 你的私钥

# 实例化合约
contract_address = "0x..."  # 合约地址
contract_abi = [...]  # 合约 ABI
contract = Contract(account, contract_address, contract_abi)
```


# call\_function

通过传入函数名称及参数来调用该合约内的函数。

## 方法定义

```python
def call_function(self, function_name: str, *args: Optional[Any]) -> Optional[TransactionReceiptData]
```

## 参数说明

| 参数             | 类型             | 说明   |
| -------------- | -------------- | ---- |
| function\_name | str            | 函数名称 |
| \*args         | Optional\[Any] | 函数参数 |

## 返回值

返回 TransactionReceiptData 对象,包含以下字段:

| 字段                  | 类型                           | 说明               |
| ------------------- | ---------------------------- | ---------------- |
| transaction\_hash   | HexBytes                     | 交易哈希             |
| block\_number       | BlockNumber                  | 区块高度             |
| transaction\_index  | int                          | 交易在区块中的索引        |
| transaction\_status | int                          | 交易状态(1 成功,0 失败)  |
| transaction\_type   | int                          | 交易类型             |
| action              | str                          | 交易动作类型           |
| sender              | ChecksumAddress              | 发送者地址            |
| to                  | ChecksumAddress              | 接收者地址            |
| nonce               | Nonce                        | 交易序号             |
| value               | Wei                          | 转账金额             |
| gas\_used           | int                          | 实际使用的 Gas        |
| gas\_limit          | int                          | Gas 上限           |
| gas\_price          | Optional\[Wei]               | Gas 价格           |
| contract\_address   | Optional\[ChecksumAddress]   | 部署的合约地址(仅合约创建交易) |
| logs                | Optional\[List\[LogReceipt]] | 交易日志             |
| input\_data         | HexBytes                     | 交易输入数据           |
| r                   | HexBytes                     | 签名 r 值           |
| s                   | HexBytes                     | 签名 s 值           |
| v                   | HexBytes                     | 签名 v 值           |

## 示例代码

```python
# 调用合约函数
receipt = contract.call_function(
    "transfer",  # 函数名
    "0x...",    # 接收者地址
    1000        # 转账金额
)

if receipt and receipt.transaction_status:
    print(f"Transaction successful: {receipt.transaction_hash.hex()}")
    print(f"Gas used: {receipt.gas_used}")
```


# call\_function\_with\_parameters

通过传入函数名称及参数来调用该合约内的函数(可指定发送的原生代币数量、Gas 价格、Gas 最大使用量)。

## 方法定义

```python
def call_function_with_parameters(self, value: Wei, gas_price: Optional[Wei], gas_limit: int, function_name: str, *args: Optional[Any]) -> Optional[TransactionReceiptData]
```

## 参数说明

| 参数             | 类型             | 说明                         |
| -------------- | -------------- | -------------------------- |
| value          | Wei            | 发送的原生代币数量                  |
| gas\_price     | Optional\[Wei] | Gas 价格,默认使用链上当前 gas\_price |
| gas\_limit     | int            | Gas 最大使用量                  |
| function\_name | str            | 函数名称                       |
| \*args         | Optional\[Any] | 函数参数                       |

## 返回值

返回值格式与 call\_function 相同。

## 示例代码

```python
# 调用合约函数并发送 ETH
receipt = contract.call_function_with_parameters(
    value=Web3.to_wei(0.1, 'ether'),     # 发送 0.1 ETH
    gas_price=Web3.to_wei(50, 'gwei'),   # 使用 50 Gwei 的 gas 价格
    gas_limit=100000,                     # 设置 gas 限制为 100000
    "deposit",                            # 函数名
    "0x..."                              # 函数参数
)

if receipt and receipt.transaction_status:
    print(f"Transaction successful: {receipt.transaction_hash.hex()}")
```


# read\_only\_call\_function

通过传入函数名称及参数来调用该合约内的只读函数。

## 方法定义

```python
def read_only_call_function(self, function_name: str, *args: Optional[Any]) -> Optional[Any]
```

## 参数说明

| 参数             | 类型             | 说明   |
| -------------- | -------------- | ---- |
| function\_name | str            | 函数名称 |
| \*args         | Optional\[Any] | 函数参数 |

## 返回值

| 类型             | 说明      |
| -------------- | ------- |
| Optional\[Any] | 只读函数返回值 |

## 示例代码

```python
# 调用只读函数
balance = contract.read_only_call_function(
    "balanceOf",    # 函数名
    "0x..."        # 账户地址
)
if balance is not None:
    print(f"Balance: {balance}")

# 调用多参数的只读函数
result = contract.read_only_call_function(
    "allowance",    # 函数名
    "0x...",       # owner 地址
    "0x..."        # spender 地址
)
```


# encode\_function\_calldata

通过传入函数名及参数进行编码,生成调用该函数的 CallData。

## 方法定义

```python
def encode_function_calldata(self, function_name: str, *args: Optional[Any]) -> Optional[HexStr]
```

## 参数说明

| 参数             | 类型             | 说明   |
| -------------- | -------------- | ---- |
| function\_name | str            | 函数名称 |
| \*args         | Optional\[Any] | 函数参数 |

## 返回值

| 类型                | 说明     |
| ----------------- | ------ |
| Optional\[HexStr] | 调用数据编码 |

## 示例代码

```python
# 编码函数调用数据
calldata = contract.encode_function_calldata(
    "transfer",     # 函数名
    "0x...",       # 接收者地址
    1000           # 转账金额
)
if calldata:
    print(f"Encoded CallData: {calldata}")

# 使用编码后的数据手动构造交易
if calldata:
    receipt = account.send_transaction(
        to=contract.address,
        data=HexBytes(calldata)
    )
```


# decode\_function\_calldata

解码针对当前合约执行调用的 CallData,得出所调用的函数名称及其参数值。

## 方法定义

```python
def decode_function_calldata(self, calldata: HexStr) -> Optional[tuple]
```

## 参数说明

| 参数       | 类型     | 说明                  |
| -------- | ------ | ------------------- |
| calldata | HexStr | 对当前合约执行调用的 CallData |

## 返回值

| 类型               | 说明             |
| ---------------- | -------------- |
| Optional\[tuple] | 包含函数名称及其参数值的元组 |

返回的元组格式为: (function\_name, parameters\_dict)

* function\_name: 函数名称
* parameters\_dict: 包含参数名和值的字典

## 示例代码

```python
# 解码函数调用数据
calldata = "0xa9059cbb000000000000000000000000ab5801a7d398351b8be11c439e05c5b3259aec9b0000000000000000000000000000000000000000000000000de0b6b3a7640000"

result = contract.decode_function_calldata(calldata)
if result:
    function_name, parameters = result
    print(f"Function Name: {function_name}")
    print(f"Parameters: {parameters}")

# 编码后解码验证
encoded = contract.encode_function_calldata(
    "transfer",
    "0xab5801a7d398351b8be11c439e05c5b3259aec9b",
    Web3.to_wei(1, 'ether')
)
if encoded:
    decoded = contract.decode_function_calldata(encoded)
    print(f"Decoded: {decoded}")
```


# Utils

Utils 是通用工具集，整合了常用的链下操作。静态类，无需实例化。

## 方法列表

* [set\_solidity\_version](/evm/utils/set_solidity_version): 选择 Solidity 版本
* [compile\_solidity\_contract](/evm/utils/compile_solidity_contract): 编译 Solidity 合约
* [import\_contract\_abi](/evm/utils/import_contract_abi): 导入合约 ABI
* [generate\_new\_account](/evm/utils/generate_new_account): 创建新账户
* [generate\_account\_from\_mnemonic](/evm/utils/generate_account_from_mnemonic): 从助记词生成账户
* [calculate\_create\_case\_contract\_address](/evm/utils/calculate_create_case_contract_address): 计算 CREATE 方式部署的合约地址
* [calculate\_create2\_case\_contract\_address](/evm/utils/calculate_create2_case_contract_address): 计算 CREATE2 方式部署的合约地址
* [generate\_signature\_data\_with\_signature](/evm/utils/generate_signature_data_with_signature): 使用签名生成签名数据
* [generate\_signature\_data\_with\_rsv](/evm/utils/generate_signature_data_with_rsv): 使用 R,S,V 生成签名数据
* [recover\_message\_string](/evm/utils/recover_message_string): 恢复消息字符串的签名者
* [recover\_message\_hash](/evm/utils/recover_message_hash): 恢复消息哈希的签名者
* [recover\_typed\_message](/evm/utils/recover_typed_message): 恢复结构化消息的签名者
* [convert\_equivalent\_signature](/evm/utils/convert_equivalent_signature): 生成等效签名
* [assembly\_to\_bytecode\_legacy](/evm/utils/assembly_to_bytecode_legacy): EVM 汇编转字节码
* [bytecode\_to\_assembly\_legacy](/evm/utils/bytecode_to_assembly_legacy): 字节码转 EVM 汇编


# set\_solidity\_version

选择 Solidity 版本,若该版本未安装则会自动安装。

## 方法定义

```python
@staticmethod
def set_solidity_version(solidity_version: str) -> None
```

## 参数说明

| 参数                | 类型  | 说明           |
| ----------------- | --- | ------------ |
| solidity\_version | str | Solidity 版本号 |

## 返回值

无

## 示例代码

```python
from poseidon.evm import Utils

# 设置 Solidity 版本
Utils.set_solidity_version("0.8.20")
```


# compile\_solidity\_contract

根据给定的参数使用 py-solc-x 编译合约。

## 方法定义

```python
@staticmethod
def compile_solidity_contract(file_path: str, contract_name: str, solidity_version: Optional[str] = None, evm_version: Optional[str] = None, optimize: bool = False, optimize_runs: int = 200, base_path: Optional[str] = None, allow_paths: Optional[str] = None) -> Optional[Tuple[dict, HexBytes]]
```

## 参数说明

| 参数                | 类型             | 说明                |
| ----------------- | -------------- | ----------------- |
| file\_path        | str            | 合约代码文件路径          |
| contract\_name    | str            | 要编译的合约的名称         |
| solidity\_version | Optional\[str] | 指定使用的 Solidity 版本 |
| evm\_version      | Optional\[str] | 指定编译时使用的 EVM 版本   |
| optimize          | bool           | 是否开启优化器           |
| optimize\_runs    | int            | 优化器运行次数参数         |
| base\_path        | Optional\[str] | 指定基础路径            |
| allow\_paths      | Optional\[str] | 指定许可路径            |

## 返回值

| 类型                                | 说明                     |
| --------------------------------- | ---------------------- |
| Optional\[Tuple\[dict, HexBytes]] | 由 ABI 和 Bytecode 组成的元组 |

## 示例代码

```python
# 编译合约
contract_data = Utils.compile_solidity_contract(
    file_path="Token.sol",
    contract_name="Token",
    solidity_version="0.8.20",
    optimize=True
)

if contract_data:
    abi, bytecode = contract_data
    print(f"Contract ABI: {abi}")
    print(f"Contract Bytecode: {bytecode.hex()}")
```


# import\_contract\_abi

导入指定的合约 ABI 文件内容。

## 方法定义

```python
@staticmethod
def import_contract_abi(file_path: str) -> Optional[dict]
```

## 参数说明

| 参数         | 类型  | 说明         |
| ---------- | --- | ---------- |
| file\_path | str | ABI 文件完整路径 |

## 返回值

| 类型              | 说明     |
| --------------- | ------ |
| Optional\[dict] | ABI 内容 |

## 示例代码

```python
# 导入 ABI 文件
abi = Utils.import_contract_abi("Token.abi.json")
if abi:
    print(f"Imported ABI: {abi}")
```


# generate\_new\_account

创建新账户。

## 方法定义

```python
@staticmethod
def generate_new_account() -> Optional[Tuple[ChecksumAddress, HexBytes]]
```

## 参数说明

无

## 返回值

| 类型                                           | 说明            |
| -------------------------------------------- | ------------- |
| Optional\[Tuple\[ChecksumAddress, HexBytes]] | 由账户地址和私钥组成的元组 |

## 示例代码

```python
# 创建新账户
account_data = Utils.generate_new_account()
if account_data:
    address, private_key = account_data
    print(f"New Account Address: {address}")
    print(f"Private Key: {private_key.hex()}")
```


# generate\_account\_from\_mnemonic

将助记词转换为账户地址与私钥。参考 BIP-39 标准。

## 方法定义

```python
@staticmethod
def generate_account_from_mnemonic(mnemonic: str, passphrase: str = "", account_path: str = "m/44'/60'/0'/0/0") -> Optional[Tuple[ChecksumAddress, HexBytes]]
```

## 参数说明

| 参数            | 类型  | 说明                  |
| ------------- | --- | ------------------- |
| mnemonic      | str | 助记词字符串,以空格分隔        |
| passphrase    | str | 助记词密码,可为空,默认为空字符串   |
| account\_path | str | 分层确定性钱包账户路径,默认为标准路径 |

## 返回值

| 类型                                           | 说明            |
| -------------------------------------------- | ------------- |
| Optional\[Tuple\[ChecksumAddress, HexBytes]] | 由账户地址和私钥组成的元组 |

## 示例代码

```python
# 从助记词生成账户
mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
account_data = Utils.generate_account_from_mnemonic(
    mnemonic=mnemonic,
    passphrase="optional password",
    account_path="m/44'/60'/0'/0/1"  # 使用自定义路径
)

if account_data:
    address, private_key = account_data
    print(f"Generated Account Address: {address}")
    print(f"Private Key: {private_key.hex()}")
```


# calculate\_create\_case\_contract\_address

计算某账户以 CREATE 方式部署的合约的地址。

## 方法定义

```python
@staticmethod
def calculate_create_case_contract_address(deployer: ChecksumAddress, nonce: Nonce) -> Optional[ChecksumAddress]
```

## 参数说明

| 参数       | 类型              | 说明                   |
| -------- | --------------- | -------------------- |
| deployer | ChecksumAddress | 部署者地址                |
| nonce    | Nonce           | 部署者发送合约部署交易的 nonce 值 |

## 返回值

| 类型                         | 说明       |
| -------------------------- | -------- |
| Optional\[ChecksumAddress] | 计算出的合约地址 |

## 示例代码

```python
# 计算合约地址
contract_address = Utils.calculate_create_case_contract_address(
    deployer="0x...",  # 部署者地址
    nonce=5            # 部署者的 nonce 值
)
if contract_address:
    print(f"Contract will be deployed at: {contract_address}")
```


# calculate\_create2\_case\_contract\_address

计算某合约账户以 CREATE2 方式部署的另一个合约的地址。

## 方法定义

```python
@staticmethod
def calculate_create2_case_contract_address(deployer: ChecksumAddress, salt: HexStr, creation_code: HexStr) -> Optional[ChecksumAddress]
```

## 参数说明

| 参数             | 类型              | 说明                   |
| -------------- | --------------- | -------------------- |
| deployer       | ChecksumAddress | 部署者地址(此处应该为合约地址)     |
| salt           | HexStr          | 盐值                   |
| creation\_code | HexStr          | 合约的创建时字节码(与运行时字节码不同) |

## 返回值

| 类型                         | 说明       |
| -------------------------- | -------- |
| Optional\[ChecksumAddress] | 计算出的合约地址 |

## 示例代码

```python
# 计算 CREATE2 部署的合约地址
contract_address = Utils.calculate_create2_case_contract_address(
    deployer="0x...",      # 工厂合约地址
    salt="0x123...",       # 盐值
    creation_code="0x..."  # 创建时字节码
)
if contract_address:
    print(f"Contract will be deployed at: {contract_address}")
```


# generate\_signature\_data\_with\_signature

使用签名数据生成 SignatureData 对象。

## 方法定义

```python
@staticmethod
def generate_signature_data_with_signature(signature: HexBytes) -> Optional[SignatureData]
```

## 参数说明

| 参数        | 类型       | 说明   |
| --------- | -------- | ---- |
| signature | HexBytes | 签名数据 |

## 返回值

返回 SignatureData 对象,包含以下字段:

| 字段        | 类型       | 说明     |
| --------- | -------- | ------ |
| signature | HexBytes | 完整签名   |
| r         | HexBytes | 签名 r 值 |
| s         | HexBytes | 签名 s 值 |
| v         | HexBytes | 签名 v 值 |

## 示例代码

```python
# 从签名生成签名数据
signature = HexBytes("0x...")  # 65 字节的签名数据
signature_data = Utils.generate_signature_data_with_signature(signature)
if signature_data:
    print(f"Signature: {signature_data.signature.hex()}")
    print(f"R: {signature_data.r.hex()}")
    print(f"S: {signature_data.s.hex()}")
    print(f"V: {signature_data.v.hex()}")
```


# generate\_signature\_data\_with\_rsv

使用 R,S,V 生成 SignatureData 对象。

## 方法定义

```python
@staticmethod
def generate_signature_data_with_rsv(r: HexBytes, s: HexBytes, v: HexBytes) -> Optional[SignatureData]
```

## 参数说明

| 参数 | 类型       | 说明     |
| -- | -------- | ------ |
| r  | HexBytes | 签名 r 值 |
| s  | HexBytes | 签名 s 值 |
| v  | HexBytes | 签名 v 值 |

## 返回值

返回 SignatureData 对象,包含以下字段:

| 字段        | 类型       | 说明     |
| --------- | -------- | ------ |
| signature | HexBytes | 完整签名   |
| r         | HexBytes | 签名 r 值 |
| s         | HexBytes | 签名 s 值 |
| v         | HexBytes | 签名 v 值 |

## 示例代码

```python
# 从 R,S,V 生成签名数据
r = HexBytes("0x...")  # 32 字节
s = HexBytes("0x...")  # 32 字节
v = HexBytes("0x...")  # 1 字节
signature_data = Utils.generate_signature_data_with_rsv(r, s, v)
if signature_data:
    print(f"Combined Signature: {signature_data.signature.hex()}")
```


# recover\_message\_string

通过消息原文和签名还原出签署者的账户地址。

## 方法定义

```python
@staticmethod
def recover_message_string(message: str, signature: HexBytes) -> Optional[SignedMessageData]
```

## 参数说明

| 参数        | 类型       | 说明   |
| --------- | -------- | ---- |
| message   | str      | 消息原文 |
| signature | HexBytes | 签名   |

## 返回值

返回 SignedMessageData 对象,包含以下字段:

| 字段              | 类型              | 说明    |
| --------------- | --------------- | ----- |
| message\_hash   | HexBytes        | 消息哈希  |
| message         | str             | 原始消息  |
| signer          | ChecksumAddress | 签名者地址 |
| signature\_data | SignatureData   | 签名数据  |

## 示例代码

```python
# 恢复消息签名者
message = "Hello, Ethereum!"
signature = HexBytes("0x...")  # 65 字节的签名
signed_data = Utils.recover_message_string(message, signature)
if signed_data:
    print(f"Message: {signed_data.message}")
    print(f"Signer: {signed_data.signer}")
    print(f"Signature: {signed_data.signature_data.signature.hex()}")
```


# recover\_message\_raw\_hash

通过消息哈希和签名还原出签署者的账户地址。

## 方法定义

```python
@staticmethod
def recover_message_raw_hash(message_raw_hash: HexBytes, signature: HexBytes) -> Optional[SignedMessageData]
```

## 参数说明

| 参数                 | 类型       | 说明   |
| ------------------ | -------- | ---- |
| message\_raw\_hash | HexBytes | 消息哈希 |
| signature          | HexBytes | 签名   |

## 返回值

返回 SignedMessageData 对象,包含以下字段:

| 字段              | 类型              | 说明      |
| --------------- | --------------- | ------- |
| message\_hash   | HexBytes        | 消息哈希    |
| message         | None            | 原始消息(无) |
| signer          | ChecksumAddress | 签名者地址   |
| signature\_data | SignatureData   | 签名数据    |

## 示例代码

```python
# 恢复消息哈希签名者
message_raw_hash = HexBytes("0x...")  # 32 字节的消息哈希
signature = HexBytes("0x...")     # 65 字节的签名
signed_data = Utils.recover_message_raw_hash(message_raw_hash, signature)
if signed_data:
    print(f"Message Hash: {signed_data.message_hash.hex()}")
    print(f"Signer: {signed_data.signer}")
    print(f"Signature: {signed_data.signature_data.signature.hex()}")
```


# recover\_message\_hash

通过 EIP-191 消息哈希和签名还原出签署者的账户地址。

## 方法定义

```python
@staticmethod
def recover_message_hash(message_hash: HexBytes, signature: HexBytes) -> Optional[SignedMessageData]
```

## 参数说明

| 参数            | 类型       | 说明   |
| ------------- | -------- | ---- |
| message\_hash | HexBytes | 消息哈希 |
| signature     | HexBytes | 签名   |

## 返回值

返回 SignedMessageData 对象,包含以下字段:

| 字段              | 类型              | 说明      |
| --------------- | --------------- | ------- |
| message\_hash   | HexBytes        | 消息哈希    |
| message         | None            | 原始消息(无) |
| signer          | ChecksumAddress | 签名者地址   |
| signature\_data | SignatureData   | 签名数据    |

## 示例代码

```python
# 恢复消息哈希签名者
message_hash = HexBytes("0x...")  # 32 字节的消息哈希
signature = HexBytes("0x...")     # 65 字节的签名
signed_data = Utils.recover_message_hash(message_hash, signature)
if signed_data:
    print(f"Message Hash: {signed_data.message_hash.hex()}")
    print(f"Signer: {signed_data.signer}")
    print(f"Signature: {signed_data.signature_data.signature.hex()}")
```


# recover\_typed\_message

通过结构化消息数据和签名还原出签署者的账户地址。

## 方法定义

```python
@staticmethod
def recover_typed_message(domain_data: dict, message_types: dict, message_data: dict, signature: HexBytes) -> Optional[SignedMessageData]
```

## 参数说明

| 参数             | 类型       | 说明     |
| -------------- | -------- | ------ |
| domain\_data   | dict     | 域数据    |
| message\_types | dict     | 消息类型定义 |
| message\_data  | dict     | 消息数据   |
| signature      | HexBytes | 签名     |

## 返回值

返回 SignedMessageData 对象,包含以下字段:

| 字段              | 类型              | 说明    |
| --------------- | --------------- | ----- |
| message\_hash   | HexBytes        | 消息哈希  |
| message         | str             | 原始消息  |
| signer          | ChecksumAddress | 签名者地址 |
| signature\_data | SignatureData   | 签名数据  |

## 示例代码

```python
# 恢复 EIP-712 结构化数据签名者
domain_data = {
    "name": "MyDApp",
    "version": "1",
    "chainId": 1,
    "verifyingContract": "0x..."
}

message_types = {
    "Person": [
        {"name": "name", "type": "string"},
        {"name": "wallet", "type": "address"}
    ]
}

message_data = {
    "name": "Bob",
    "wallet": "0x..."
}

signature = HexBytes("0x...")  # 65 字节的签名
signed_data = Utils.recover_typed_message(domain_data, message_types, message_data, signature)
if signed_data:
    print(f"Signer: {signed_data.signer}")
```


# convert\_equivalent\_signature

根据 ECDSA 签名可延展性原理，生成另一个等效的签名。

## 方法定义

```python
@staticmethod
def convert_equivalent_signature(signature: HexBytes) -> Optional[SignatureData]:
```

## 参数说明

| 参数        | 类型       | 说明   |
| --------- | -------- | ---- |
| signature | HexBytes | 原始签名 |

## 返回值

返回 SignatureData 对象,包含以下字段:

| 字段        | 类型       | 说明     |
| --------- | -------- | ------ |
| signature | HexBytes | 完整签名   |
| r         | HexBytes | 签名 r 值 |
| s         | HexBytes | 签名 s 值 |
| v         | HexBytes | 签名 v 值 |

## 示例代码

```python
# 生成等效签名
original_signature = HexBytes("0x...")
equivalent_signature = Utils.convert_equivalent_signature(original_signature)

if equivalent_signature:
    print(f"Equivalent Signature: {equivalent_signature.signature.hex()}")
    print(f"r: {equivalent_signature.r.hex()}")
    print(f"s: {equivalent_signature.s.hex()}")
    print(f"v: {equivalent_signature.v.hex()}")
```


# assembly\_to\_bytecode\_legacy

将 EVM Assembly 转为 EVM Bytecode。由于依赖的第三方库 pyevmasm 很久没有更新,所以该功能不一定能支持最新的 EVM 版本。

## 方法定义

```python
@staticmethod
def assembly_to_bytecode_legacy(assembly: str) -> Optional[HexBytes]
```

## 参数说明

| 参数       | 类型  | 说明           |
| -------- | --- | ------------ |
| assembly | str | EVM Assembly |

## 返回值

| 类型                  | 说明           |
| ------------------- | ------------ |
| Optional\[HexBytes] | EVM Bytecode |

## 示例代码

```python
# 将汇编转换为字节码
assembly = """
    PUSH1 0x80
    PUSH1 0x40
    MSTORE
    CALLVALUE
    DUP1
    ISZERO
    PUSH2 0x000f
    JUMPI
"""
bytecode = Utils.assembly_to_bytecode_legacy(assembly)
if bytecode:
    print(f"Bytecode: {bytecode.hex()}")
```


# bytecode\_to\_assembly\_legacy

将 EVM Bytecode 转为 EVM Assembly。由于依赖的第三方库 pyevmasm 很久没有更新,所以该功能不一定能支持最新的 EVM 版本。

## 方法定义

```python
@staticmethod
def bytecode_to_assembly_legacy(bytecode: HexBytes) -> Optional[str]
```

## 参数说明

| 参数       | 类型       | 说明           |
| -------- | -------- | ------------ |
| bytecode | HexBytes | EVM Bytecode |

## 返回值

| 类型             | 说明           |
| -------------- | ------------ |
| Optional\[str] | EVM Assembly |

## 示例代码

```python
# 将字节码转换为汇编
bytecode = HexBytes("0x6080604052...")
assembly = Utils.bytecode_to_assembly_legacy(bytecode)
if assembly:
    print(f"Assembly:\n{assembly}")
```


# (stay tuned)


# (stay tuned)


# (stay tuned)


