Repository: Conflux-Chain/python-conflux-sdk (language: python)

Issue:
doc: pretranslate using machine

[See review request for 01-quickstart.ipynb on GitLocalize](https://gitlocalize.com/repo/8175/zh-CN/review/54494)
[See review request for 02-address_account_and_wallet.ipynb on GitLocalize](https://gitlocalize.com/repo/8175/zh-CN/review/54495)
[See review request for 03-trace_transaction_status.ipynb on GitLocalize](https://gitlocalize.com/repo/8175/zh-CN/review/54496)
[See review request for 04-query_data_via_RPC.ipynb on GitLocalize](https://gitlocalize.com/repo/8175/zh-CN/review/54497)
[See review request for 05-interact_with_contracts_and_process_logs.ipynb on GitLocalize](https://gitlocalize.com/repo/8175/zh-CN/review/54498)
[See review request for 10-send_raw_transaction.ipynb on GitLocalize](https://gitlocalize.com/repo/8175/zh-CN/review/54499)
[See review request for 11-construct_transaction_from_scratch.ipynb on GitLocalize](https://gitlocalize.com/repo/8175/zh-CN/review/54500)

<!-- Reviewable:start -->
- - -
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/conflux-chain/python-conflux-sdk/13)
<!-- Reviewable:end -->



Discussion / hints:

Fix patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 1af92e0..9446e6b 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 1.0.0-beta.6
+current_version = 1.0.0-beta.7
 commit = True
 tag = True
 parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(-(?P<stage>[^.]*)\.(?P<devnum>\d+))?
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
new file mode 100644
index 0000000..91f8605
--- /dev/null
+++ b/.github/workflows/coverage.yml
@@ -0,0 +1,30 @@
+name: coverage
+
+on:
+  pull_request:
+    branches: ["v1"]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        python-version: ["3.7"]
+    name: Test python API
+    steps:
+    - uses: actions/checkout@v1
+    - name: Install requirements
+      run: pip install ".[tester]"
+    - name: Run tests and collect coverage
+      run:
+        export TESTNET_URL=${{secrets.TESTNET_URL}} &&
+        export USE_TESTNET=1 &&
+        export ENS_ACCOUNT_NAME=${{secrets.ENS_ACCOUNT_NAME}} &&
+        export ENS_ACCOUNT_SECRET=${{secrets.ENS_ACCOUNT_SECRET}} &&
+        pytest --cov tests
+    - name: Upload coverage reports to Codecov
+      run: |
+        curl -Os https://uploader.codecov.io/latest/linux/codecov
+        chmod +x codecov
+        ./codecov -t ${{secrets.CODECOV_TOKEN}}
diff --git a/.github/workflows/localization.yml b/.github/workflows/localization.yml
new file mode 100644
index 0000000..6e01d26
--- /dev/null
+++ b/.github/workflows/localization.yml
@@ -0,0 +1,22 @@
+name: dev-localization
+
+on:
+  push:
+    branches: [ "dev" ]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+    steps:
+    - uses: actions/checkout@v3
+    - name: Sync changes
+      run: |
+        git config --global user.email "17946284+darwintree@users.noreply.github.com" &&
+        git config --global user.name "localization bot" &&
+        git checkout -b dev-zh-CN &&
+        cp ./.readthedocs-zh-CN.yaml ./.readthedocs.yaml &&
+        git add . &&
+        git commit -m "doc: change .readthedocs.yaml to zh-CN version" && 
+        git push origin dev-zh-CN -f
diff --git a/.gitignore b/.gitignore
index c1f93db..9d509ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,6 @@
 .env
 build
 dist
-docs/*
 tests/__pycache__
 venv*/
 conflux/__init__.pyc
@@ -20,4 +19,6 @@ private_tests
 legacy_tests
 note*.ipynb
 share
-main*.py
\ No newline at end of file
+main*.py
+*.bk.py
+docs/*/_build
diff --git a/.readthedocs-zh-CN.yaml b/.readthedocs-zh-CN.yaml
new file mode 100644
index 0000000..d8e7b00
--- /dev/null
+++ b/.readthedocs-zh-CN.yaml
@@ -0,0 +1,17 @@
+version: 2
+
+# Set the version of Python and other tools you might need
+build:
+  os: ubuntu-20.04
+  tools:
+    python: "3.10"
+  jobs:
+    pre_build:
+      # Generate on-the-fly Sphinx configuration from Jupyter Book's _config.yml
+      - "jupyter-book config sphinx docs/zh-CN/"
+
+python:
+  install:
+  - requirements: docs/requirements-doc.txt
+  # - method: pip
+  #   path: ".[docs]"
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
new file mode 100644
index 0000000..d43296f
--- /dev/null
+++ b/.readthedocs.yaml
@@ -0,0 +1,17 @@
+version: 2
+
+# Set the version of Python and other tools you might need
+build:
+  os: ubuntu-20.04
+  tools:
+    python: "3.10"
+  jobs:
+    pre_build:
+      # Generate on-the-fly Sphinx configuration from Jupyter Book's _config.yml
+      - "jupyter-book config sphinx docs/en/"
+
+python:
+  install:
+  - requirements: docs/requirements-doc.txt
+  # - method: pip
+  #   path: ".[docs]"
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index da4b11e..0000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,34 +0,0 @@
-# Change Logs
-
-## 1.0.0-dev4
-
-* Response containing "address" from rpc is wrapped by `Base32Address`
-  * including contract return values
-* Introduces token unit `CFX`, `GDrip` and `Drip`
-  * responses are formatted using Drip/GDrip/CFX
-  * Drip/GDrip/CFX can be used as gas price or value
-* CNS support
-  * available by using `w3.cns` or `w3.ens`
-  * supports name service resolve as web3.py (as receiver/sender/parameter)
-  * (unstable) supports `w3.cns.setup_address` and `w3.cns.setup_owner`
-
-## 1.0.0-dev3
-
-* bump web3.py version
-  * web3.py: 6.0.0b4->6.0.0b5
-  * eth-account(required by cfx-account): ~=7.0.0
-
-## 1.0.0-dev2
-
-* Optimizes web3.py hacking mechanisms
-  * hacking codes are moved to `conflux_web3._hook.py`
-* Basic support for ethpm (furthur supports are not in plan)
-* The default account will be added to wallet if `w3.cfx.default_account` setter receives a `LocalAccount` object
-  * `w3.cfx.default_account` is still a `Base32Address`
-* `.finalized()` apis are tests.
-* Fix contract constructor's `build_transaction()` bugs
-* Add `name` parameter to `w3.cfx.contract()`
-  * supports internal contracts including `AdminControl`, `SponsorWhitelistControl`, `Staking`, `PoSRegister`, `CrossSpaceCall`, `ParamsControl`
-  * supports specific contracts added in genesis block, including `Create2Factory`, `ERC1820`
-  * supports `Faucet` in testnet
-  * supports `cUSDT` and `FC` in mainnet and testnet
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 120000
index 0000000..30c817f
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,1 @@
+docs/en/CHANGELOG.md
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 85e6ee8..eeaca7c 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,10 @@ build: clean
 publish: 
 	twine upload dist/* --repository conflux-web3
 
+doc:
+	jupyter-book config sphinx docs/en/
+	jupyter-book build docs/en/
+
 # gen-docs:
 # 	cd ./docs && \
 # 	sphinx-apidoc -o ./source ../cfx_address -f -M --separate && \
diff --git a/README.md b/README.md
deleted file mode 100644
index 85d0163..0000000
--- a/README.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# conflux-web3 
-Python SDK for interacting with Conflux network.
-
-- [conflux-web3](#conflux-web3)
-  - [Quick start](#quick-start)
-  - [Overview](#overview)
-    - [Code Examples](#code-examples)
-      - [initialization with providers](#initialization-with-providers)
-      - [Contract Interaction](#contract-interaction)
-      - [RPC support](#rpc-support)
-      - [Base32 Address Operation](#base32-address-operation)
-
-## Quick start
-
-Requirements: python version >= 3.8
-
-```shell
-$ pip3 install --pre conflux-web3
-```
-
-```python
-from conflux_web3 import Web3
-
-w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
-# fill your secret key
-# and you can claim testnet token from https://faucet.confluxnetwork.org/
-acct = w3.account.from_key("0xxxxxxxxxxxxxx") 
-w3.wallet.add_account(acct)
-w3.cfx.default_account = acct.address
-
-w3.cfx.send_transaction({
-    'to': w3.cfx.account.create().address,
-    'value': 22,
-}).executed()
-```
-
-## Overview
-
-conflux-web3 helps to interact with Conflux network using python, and most of its APIs are consistent with [web3.py](https://github.com/ethereum/web3.py). 
-
-> conflux-web3 is a wrapping layer over [web3.py](https://github.com/ethereum/web3.py).
-
-### Code Examples
-
-Here are some simple code examples. More detailed code examples are in the folder `examples`
-
-#### initialization with providers
-
-```python
-# same as web3.py
-from conflux_web3 import Web3
-w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:12537"))
-
-# or
-# conflux_web3's additional functions
-# using local default HTTP provider or Conflux's public RPC FOR DEVELOPMENT
-from conflux_web3.dev import (
-    get_local_web3, # "http://127.0.0.1:12537"
-    get_testnet_web3, # "https://test.confluxrpc.com"
-    get_mainnet_web3, # "https://main.confluxrpc.com"
-)
-w3 = get_testnet_web3()
-```
-
-#### Contract Interaction
-
-``` py
-import os, json
-from conflux_web3 import Web3
-
-w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
-acct = w3.cfx.account.from_key(os.environ.get('PRIVATE_KEY'))
-w3.wallet.add_account(acct)
-w3.cfx.default_account = acct.address
-
-# if you want to get contract object from metadata file, uses 
-# >>> erc20_metadata = json.load(open("path/to/ERC20metadata.json"))
-# >>> erc20 = web3.cfx.contract(bytecode=erc20_metadata["bytecode"], abi=erc20_metadata["abi"])
-erc20 = web3.cfx.contract(name="ERC20")
-hash = erc20.constructor(name="Coin", symbol="C", initialSupply=10**18).transact()
-contract_address = w3.cfx.wait_for_transaction_receipt(hash)["contractCreated"]
-assert contract_address is not None
-contract = w3.cfx.contract(contract_address, name="ERC20")
-
-# transfer
-random_account = w3.account.create()
-hash = contract.functions.transfer(random_account.address, 100).transact()
-transfer_receipt = w3.cfx.wait_for_transaction_receipt(hash)
-balance = contract.functions.balanceOf(random_account.address).call()
-```
-
-#### RPC support
-
-Visit [JSON-RPC methods](https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc/#json-rpc-methods) to check the full RPC list. Currently, most frequently used RPCs are supported.
-
-``` python
-w3.cfx.get_balance("cfx:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg", "latest_state")
-# the returned value from RPC will be formatted
-# 158972490234375000
-```
-
-#### Base32 Address Operation
-
-You can use `from cfx_address import Base32Address` or simply use `w3.address` or `w3.cfx.address` to use the `Base32Address` class. This class provides several methods for you to convert or validate base32 addresses. See [cfx_address documentation](https://conflux-fans.github.io/cfx-address/cfx_address.html#module-cfx_address.address) for the full documentation.
-
-```py
-from cfx_address import Base32Address
-
-address = Base32Address("0x1ecde7223747601823f7535d7968ba98b4881e09", network_id=1)
-address
-# 'cfxtest:aatp533cg7d0agbd87kz48nj1mpnkca8be1rz695j4'
-[
-    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']
-```
diff --git a/README.md b/README.md
new file mode 120000
index 0000000..6ff62a3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1 @@
+docs/en/README.md
\ No newline at end of file
diff --git a/conflux_web3/_utils/cns.py b/conflux_web3/_utils/cns.py
index c2dd603..b129da3 100644
--- a/conflux_web3/_utils/cns.py
+++ b/conflux_web3/_utils/cns.py
@@ -36,7 +36,8 @@ def validate_cns_existence(w3: "Web3"):
 def resolve_if_cns_name(w3: "Web3", cns_name: str) -> Union[str, Base32Address]:
     if is_cns_name(cns_name):
         validate_cns_existence(w3)
-        if addr := w3.cns.address(cns_name):
+        addr = w3.cns.address(cns_name)
+        if addr:
             return addr
         raise NameNotFound(f"{cns_name} resolve failed")
     return cns_name
diff --git a/conflux_web3/_utils/events.py b/conflux_web3/_utils/events.py
index 1e90adb..4db2bf9 100644
--- a/conflux_web3/_utils/events.py
+++ b/conflux_web3/_utils/events.py
@@ -109,7 +109,7 @@ def cfx_get_event_data(
     )
 
     decoded_topic_data = [
-        abi_codec.decode_single(topic_type, topic_data)
+        abi_codec.decode([topic_type], topic_data)[0]
         for topic_type, topic_data in zip(log_topic_types, log_topics)
     ]
     normalized_topic_data = map_abi_data(
diff --git a/conflux_web3/client.py b/conflux_web3/client.py
index 0799898..87dfdf2 100644
--- a/conflux_web3/client.py
+++ b/conflux_web3/client.py
@@ -3,7 +3,6 @@
     Any,
     Callable,
     List,
-    Literal,
     Optional,
     Sequence,
     Tuple,
@@ -13,11 +12,13 @@
     cast,
     overload
 )
-import functools
+from typing_extensions import (
+    Literal
+)
 import warnings
 from hexbytes import HexBytes
 
-from cytoolz import ( keyfilter, merge, dissoc,) # type:ignore
+from cytoolz import ( keyfilter, merge ) # type:ignore
 from eth_typing.encoding import (
     HexStr
 )
@@ -49,7 +50,6 @@
 )
 from cfx_address import (
     Base32Address,
-    validate_base32
 )
 from cfx_address.address import (
     get_base32_address_factory,
@@ -131,7 +131,7 @@ class BaseCfx(BaseEth):
     
     @property
     def default_account(self) -> Base32Address:
-        """default account ADDRESS rather than a local account with private key
+        """default account address, this address will be used as default `from` address if transaction `from` field is empty
         """
         return self._default_account # type: ignore
     
@@ -141,13 +141,15 @@ def default_account(self, account: Union[Base32Address, str, LocalAccount]) -> N
         """set default account address
         """
         if isinstance(account, LocalAccount):
-            self._default_account = (normalized_address := Base32Address(account.address))
+            normalized_address = Base32Address(account.address)
+            self._default_account = normalized_address
             if (self.w3.wallet is not None and account.address not in self.w3.wallet):
                 self.w3.wallet.add_account(account)
             if self.w3.cns:
                 self.w3.cns.w3.cfx.default_account = normalized_address
         else:
-            self._default_account = (normalized_address := Base32Address(resolve_if_cns_name(self.w3, account)))
+            normalized_address = Base32Address(resolve_if_cns_name(self.w3, account))
+            self._default_account = normalized_address
             if self.w3.cns:
                 self.w3.cns.w3.cfx.default_account = normalized_address
     
@@ -412,6 +414,18 @@ def contract(
                 (1) "name" parameter specified and corresponding contract has deployment info 
                 (2) with_deployment_info is not False
 
+        >>> from conflux_web3.dev import get_mainnet_web3
+        >>> w3 = get_mainnet_web3()
+        >>> from conflux_web3.contract import get_contract_metadata
+        >>> abi = get_contract_metadata("ERC20")["abi"]
+        >>> bytecode = get_contract_metadata("ERC20")["bytecode"]
+        >>> erc20_factory = w3.cfx.contract(abi=abi, bytecode=bytecode)
+
+        >>> c1 = w3.cfx.contract(name="AdminControl")
+        >>> assert c1.address # address is added by default
+        >>> c2 = w3.cfx.contract(name="AdminControl", with_deployment_info=False)
+        >>> assert not c2.address # address is not added by explicitly specified
+
         Parameters
         ----------
         address : Optional[Union[Base32Address, str]], optional
@@ -430,19 +444,6 @@ def contract(
         -------
         Union[Type[ConfluxContract], ConfluxContract]
             returns a contract factory or contract
-            
-        >>> from conflux_web3.dev import get_mainnet_web3
-        >>> w3 = get_mainnet_web3()
-        >>> from conflux_web3.contract import get_contract_metadata
-        >>> abi = get_contract_metadata("ERC20")["abi"]
-        >>> bytecode = get_contract_metadata("ERC20")["bytecode"]
-        >>> erc20_factory = w3.cfx.contract(abi=abi, bytecode=bytecode)
-
-        >>> c1 = w3.cfx.contract(name="AdminControl")
-        >>> assert c1.address
-        >>> c2 = w3.cfx.contract(name="AdminControl", with_deployment_info=False)
-        >>> assert not c2.address
-
         """        
         metadata = {}
         if name is not None:
@@ -539,38 +540,90 @@ def get_work(self):
     
     def get_status(self) -> NodeStatus:
         """
-        Returns:
-            AttributeDict: node status
-            e.g.
-            {
-                "bestHash": "0xe4bf02ad95ad5452c7676d3dfc2e57fde2a70806c2e68231c58c77cdda5b7c6c",
-                "chainId": "0x1",
-                "networkId": "0x1",
-                "blockNumber": "0x1a80325",
-                "epochNumber": "0xaf28ab",
-                "latestCheckpoint": "0xada520",
-                "latestConfirmed": "0xaf2885",
-                "latestState": "0xaf28a7",
-                "latestFinalized": "0x2a420c",
-                "ethereumSpaceChainId": "0x22b9",
-                "pendingTxNumber": "0x0"
-            },
-        """
+        get the blockchain status from the provider
+        
+        >>> w3.cfx.get_status()
+        AttributeDict({'bestHash': HexBytes('0xb91109cc301209921b33533f8ae228615016b9104e8229ddaad55b370fe586d3'),
+            'chainId': 1,
+            'ethereumSpaceChainId': 71,
+            'networkId': 1,
+            'epochNumber': 97105091,
+            'blockNumber': 124293823,
+            'pendingTxNumber': 69,
+            'latestCheckpoint': 97000000,
+            'latestConfirmed': 97105034,
+            'latestState': 97105087,
+            'latestFinalized': 97104660})
+        >>> w3.cfx.get_status().chainId # support but not recommended because of missing type hints
+        1
+        >>> w3.cfx.get_status()['chainId'] # recommended
+        1
+
+        Returns
+        -------
+        NodeStatus
+            a dict representing node status
+        """        
         return self._get_status()
     
     @property
     def gas_price(self) -> Drip:
+        """
+        Get the current gas price
+        
+        >>> w3.cfx.gas_price
+        1000000000 Drip
+        >>> w3.cfx.gas_price.value
+        1000000000
+        >>> w3.cfx.gas_price.to("GDrip")
+        1 GDrip
+
+        Returns
+        -------
+        Drip
+            gas price wrapped by Drip, which can be used as transaction value or gas price
+        """        
         return self._gas_price()
     
     @property
     def accounts(self) -> Tuple[Base32Address]:
+        """
+        Returns the accounts controlled by the provider 
+        ## this method is not supported by public rpcs
+
+        Returns
+        -------
+        Tuple[Base32Address]
+            a Tuple containing the address of the accounts
+        """
         return self._accounts()
     
     @property
     def epoch_number(self) -> EpochNumber:
+        """
+        Returns latest_mined epoch number
+
+        Returns
+        -------
+        EpochNumber
+            latest mined epoch number
+        """
         return self._epoch_number(None)
     
     def epoch_number_by_tag(self, epoch_tag: EpochLiteral) -> EpochNumber:
+        """
+        Returns the epoch numebr with the provided epoch tag
+
+        Parameters
+        ----------
+        epoch_tag : EpochLiteral
+            String "latest_mined", "latest_state", "latest_confirmed", "latest_checkpoint" or "earliest"
+
+        Returns
+        -------
+        EpochNumber
+            the epoch number corrensponding to the epoch tag
+        """        
         return self._epoch_number(epoch_tag)
     
     @cached_property
@@ -584,7 +637,6 @@ def chain_id(self) -> int:
         int
             chain id of the blockchain, 1 for conflux testnet and 1029 for conflux mainnet
         """
-
         return self._get_status()["chainId"]
 
     @property
@@ -595,50 +647,123 @@ def client_version(self):
     #     return 
     
     def get_balance(self,
-                    address: Union["Base32Address", str], 
+                    address: Union[Base32Address, str], 
                     block_identifier: Optional[EpochNumberParam] = None) -> Drip:
+        """
+        Returns the balance of the given account, identified by its address.
+
+        >>> balance = w3.cfx.get_balance("cfx:type.user:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg")
+        >>> balance
+        "1000000000000000000 Drip"
+        >>> balance.value
+        1000000000000000000
+        >>> balance.to("CFX")
+        "1 CFX"
+
+        Parameters
+        ----------
+        address : Union[Base32Address, str]
+            the address of the account 
+        block_identifier : Optional[EpochNumberParam], optional
+            integer epoch number, or the string "latest_state", "latest_confirmed", "latest_checkpoint" or "earliest", by default None
+
+        Returns
+        -------
+        Drip
+            balance wrapped by Drip
+        """        
         return self._get_balance(address, block_identifier)
     
     def get_staking_balance(self,
                     address: Union[Base32Address, str], 
                     block_identifier: Optional[EpochNumberParam] = None) -> Drip:
+        """
+        Returns the staking balance of the given account, identified by its address.
+
+        Parameters
+        ----------
+        address : Union[Base32Address, str]
+            the address of the account 
+        block_identifier : Optional[EpochNumberParam], optional
+            integer epoch number, or the string "latest_state", "latest_confirmed", "latest_checkpoint" or "earliest", by default None
+
+        Returns
+        -------
+        Drip
+            balance wrapped by Drip
+        """        
         return self._get_staking_balance(address, block_identifier)
     
     
     def call(self, 
              transaction: TxParam, 
              block_identifier: Optional[EpochNumberParam]=None, 
-             **kwargs: Dict[str, Any]):
-        """
-        Args:
-            transaction (TxParam): _description_
-            block_identifier (Optional[EpochNumberParam], optional): _description_. Defaults to None.
-            kwargs is provided for web3 internal api compatiblity, they will be ignored
-        Returns:
-            _type_: _description_
+             **kwargs: Dict[str, Any]) -> Any:
         """
+        Virtually calls a contract, returns the output data. The transaction will not be added to the blockchain.
+
+        Parameters
+        ----------
+        transaction : TxParam
+            {
+                "chainId": int,
+                "data": Union[bytes, HexStr],
+                "from": Union[Base32Address, str],
+                "gas": int,
+                "gasPrice": Drip,
+                "nonce": Nonce,
+                "to": Base32Address,
+                "value": Drip,
+                "epochHeight": int,
+                "storageLimit": int
+            }
+        block_identifier : Optional[EpochNumberParam], optional
+            integer epoch number, or the string "latest_state", "latest_confirmed", "latest_checkpoint" or "earliest", by default None
+
+        Returns
+        -------
+        Any
+        """        
         return self._call(transaction, block_identifier)
     
-    def get_next_nonce(self, address: Optional[Union[Base32Address, str]]=None, block_identifier: Optional[EpochNumberParam] = None) -> int:
+    def get_next_nonce(self, address: Union[Base32Address, str], block_identifier: Optional[EpochNumberParam] = None) -> int:
+        """
+        Returns the next nonce that should be used by the given account when sending a transaction.
+
+        Parameters
+        ----------
+        address : Union[Base32Address, str]
+            the address of the account
+        block_identifier : Optional[EpochNumberParam], optional
+            integer epoch number, or the string "latest_state", "latest_confirmed", "latest_checkpoint" or "earliest", by default None
+
+        Returns
+        -------
+        int
+        """        
         return self._get_next_nonce(address, block_identifier)
 
-    def get_transaction_count(self, address: Optional[Union[Base32Address, str]]=None, block_identifier: Optional[EpochNumberParam] = None) -> int:
+    def get_transaction_count(self, address: Union[Base32Address, str], block_identifier: Optional[EpochNumberParam] = None) -> int:
+        """
+        Compatibility API for conflux. Equivalent to `get_next_nonce`
+        """        
         return self.get_next_nonce(address, block_identifier)
 
     def estimate_gas_and_collateral(self, transaction: TxParam, block_identifier: Optional[EpochNumberParam]=None) -> EstimateResult:
-        return self._estimate_gas_and_collateral(transaction, block_identifier)
-
-    def estimate_gas(self, transaction: TxParam, block_identifier: Optional[EpochNumberParam] = None) -> EstimateResult:
         """
-        Compatibility API for conflux. Equivalent to estimate_gas_and_collateral
+        Virtually executes a transaction, returns an estimate for the size of storage collateralized and the gas used by the transaction. The transaction will not be added to the blockchain.
+        For most cases, you don't need to invoke this api to fill the transaction fields unless you need to manually sign the transactions.
+
+        >>> w3.cfx.estimate_gas_and_collateral({"to": "cfx:type.contract:acc7uawf5ubtnmezvhu9dhc6sghea0403y2dgpyfjp"})
+        >>> {"gasLimit": 21000, "gasUsed": 21000, "storageCollateralized": 0}
 
         Parameters
         ----------
-        transaction : TxParam
+        transaction: TxParam
             {
                 "chainId": int,
                 "data": Union[bytes, HexStr],
-                "from": Base32Address,
+                "from": Union[Base32Address, str],
                 "gas": int,
                 "gasPrice": Drip,
                 "nonce": Nonce,
@@ -648,35 +773,162 @@ def estimate_gas(self, transaction: TxParam, block_identifier: Optional[EpochNum
                 "storageLimit": int
             }
         block_identifier : Optional[EpochNumberParam], optional
-            _description_, by default None
+            integer epoch number, or the string "latest_state", "latest_confirmed", "latest_checkpoint" or "earliest", by default None
 
         Returns
         -------
         EstimateResult
-        
-        e.g.
-        {
-            "gasLimit": 28000,
-            "gasUsed": 21000,
-            "storageCollateralized": 0
-        }
+        """        
+        return self._estimate_gas_and_collateral(transaction, block_identifier)
+
+    def estimate_gas(self, transaction: TxParam, block_identifier: Optional[EpochNumberParam] = None) -> EstimateResult:
+        """
+        Compatibility API for conflux. Equivalent to `estimate_gas_and_collateral`
         """        
         return self.estimate_gas_and_collateral(transaction, block_identifier)
 
     def send_raw_transaction(self, raw_transaction: Union[HexStr, bytes]) -> TransactionHash:
+        """
+        Sends a signed transaction into the network for processing
+        
+        >>> tx_hash = w3.cfx.send_raw_transaction("0xf86eea8201a28207d0830f4240943838197c0c88d0d5b13b67e1bfdbdc132d4842e389056bc75e2d631000008080a017b8b26f473820475edc49bd153660e56b973b5985bbdb2828fceacb4c91f389a03452f9a69da34ef35acc9c554d7b1d63e9041141674b42c3abb1b57b9f83a2d3")
+        >>> tx_hash.executed() # equivalent to w3.cfx.wait_for_transaction_receipt(tx_hash)
+
+        Parameters
+        ----------
+        raw_transaction : Union[HexStr, bytes]
+            a signed transaction as hex string or bytes
+
+        Returns
+        -------
+        TransactionHash
+            the hash of the transaction in bytes and wrapped by TransactionHash object which provides chained operations
+        """        
         # TODO: remove pending middleware and changes here
         return cast(TransactionHash, self._send_raw_transaction(raw_transaction))
     
     def send_transaction(self, transaction: TxParam) -> TransactionHash:
+        """
+        Send a transaction by using transaction params. 
+        ## The node MUST support cfx_sendTransaction rpc (which is typically not supported by public rpc services)
+        ## or account is added to w3.wallet
+        
+        >>> account = w3.account.create()
+        >>> w3.wallet.add_account(account)
+        >>> w3.cfx.send_transaction({
+        ...    "to": w3.address.zero_address(),
+        ...    "from": account.address,
+        ...    "value": 100,
+        ... }).executed()
+
+        Parameters
+        ----------
+        transaction : TxParam
+            {
+                "chainId": int,
+                "data": Union[bytes, HexStr],
+                "from": Union[Base32Address, str],
+                "gas": int,
+                "gasPrice": Drip,
+                "nonce": Nonce,
+                "to": Base32Address,
+                "value": Drip,
+                "epochHeight": int,
+                "storageLimit": int
+            }
+
+        Returns
+        -------
+        TransactionHash
+            the hash of the transaction in bytes and wrapped by TransactionHash object which provides chained operations
+        """        
         # TODO: remove pending middleware and changes here
         return cast(TransactionHash, self._send_transaction(transaction))
     
     def get_transaction_receipt(self, transaction_hash: _Hash32) -> TxReceipt:
+        """
+        Returns a transaction receipt, identified by the corresponding transaction hash.
+        
+        >>> w3.cfx.get_transaction_receipt("0x5ffa11a44c6db42cc30967d4de5949b17ee319c4aba72f3380c60136993a8980")
+        AttributeDict({'transactionHash': HexBytes('0x5ffa11a44c6db42cc30967d4de5949b17ee319c4aba72f3380c60136993a8980'),
+            'index': 227,
+            'blockHash': HexBytes('0xceda961d541c78fa2c99907620bb2b13707f72b004b7c70362a5642177e6aae2'),
+            'epochNumber': 97108737,
+            'from': 'cfxtest:aaksxj04phv0hp02jh3cbym9vghwkzap867jagb043',
+            'to': 'cfxtest:aaksxj04phv0hp02jh3cbym9vghwkzap867jagb043',
+            'gasUsed': 21000,
+            'gasFee': 21000000000000 Drip,
+            'contractCreated': None,
+            'logs': [],
+            'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),
+            'stateRoot': HexBytes('0x89dd70006e4714eb81a210a20badf4c37adc7fcbe992b8458460876fcac38ea3'),
+            'outcomeStatus': 0,
+            'txExecErrorMsg': None,
+            'gasCoveredBySponsor': False,
+            'storageCoveredBySponsor': False,
+            'storageCollateralized': 0,
+            'storageReleased': []})
+
+        Parameters
+        ----------
+        transaction_hash : _Hash32
+            the hash of the transaction, could be byte or hex string
+
+        Returns
+        -------
+        TxReceipt
+            the receipt of the transaction
+        """        
         return self._get_transaction_receipt(transaction_hash)
     
     def wait_till_transaction_mined(
         self, transaction_hash: _Hash32, timeout: float = 60, poll_latency: float = 0.5
     ) -> TxData:
+        """
+        Returns information about a transaction when it is mined.
+        If TxData is returned, the transaction is found contained in a block, but might not be executed.
+        (Transaction will only be executed after 5 epochs)
+        
+        >>> w3.cfx.wait_till_transaction_mined("0x5ffa11a44c6db42cc30967d4de5949b17ee319c4aba72f3380c60136993a8980")
+        AttributeDict({'hash': HexBytes('0x5ffa11a44c6db42cc30967d4de5949b17ee319c4aba72f3380c60136993a8980'),
+            'nonce': 8230,
+            'blockHash': HexBytes('0xceda961d541c78fa2c99907620bb2b13707f72b004b7c70362a5642177e6aae2'),
+            'transactionIndex': 227,
+            'from': 'cfxtest:aaksxj04phv0hp02jh3cbym9vghwkzap867jagb043',
+            'to': 'cfxtest:aaksxj04phv0hp02jh3cbym9vghwkzap867jagb043',
+            'value': 0 Drip,
+            'gasPrice': 1000000000 Drip,
+            'gas': 21000,
+            'contractCreated': None,
+            'data': HexBytes('0x'),
+            'storageLimit': 0,
+            'epochHeight': 97108719,
+            'chainId': 1,
+            'status': 0,
+            'v': 1,
+            'r': HexBytes('0x1d16cb28acf3973df4f4cc29ffffdba5d36ca1e38f1904f64780fa505691c1b7'),
+            's': HexBytes('0x1549267bc4f60af38d23112b47a54dc36481e77eb44dd5ee2c3277810c1c6297')})
+
+
+        Parameters
+        ----------
+        transaction_hash : _Hash32
+            the hash of the transaction, could be byte or hex string
+        timeout : float, optional
+            maximum wait time before timeout in seconds, by default 60
+        poll_latency : float, optional
+            time interval to query transaction status in seconds, by default 0.5
+
+        Returns
+        -------
+        TxData
+            the transaction data as a dict
+
+        Raises
+        ------
+        TimeExhausted
+            if timeout
+        """        
         try:
             with Timeout(timeout) as _timeout:
                 while True:
@@ -698,36 +950,8 @@ def wait_till_transaction_mined(
     def wait_for_transaction_receipt(
         self, transaction_hash: _Hash32, timeout: float = 300, poll_latency: float = 0.5
     ) -> TxReceipt:
-        """_summary_
-
-        Args:
-            transaction_hash (_Hash32): _description_
-            timeout (float, optional): _description_. Defaults to 300.
-            poll_latency (float, optional): _description_. Defaults to 0.5.
-
-        Returns:
-            TxReceipt
-            {
-                "transactionHash": _Hash32,
-                "index": int,
-                "blockHash": _Hash32,
-                "epochNumber": int,
-                "from": Union[Base32Address, str],
-                "to": Union[Base32Address, str],
-                "gasUsed": int,
-                "gasFee": Drip,
-                "gasCoveredBySponsor": bool,
-                "storageCollateralized": Storage,
-                "storageCoveredBySponsor": bool,
-                "storageReleased": List[Storage],
-                "contractCreated": Union[Base32Address, str, None],
-                
-                "stateRoot": _Hash32,
-                "outcomeStatus": int,
-                "logsBloom": HexBytes,
-                
-                "logs": List[LogReceipt]
-            },
+        """
+        Alias for `wait_till_transaction_executed`
         """
         try:
             receipt = cast(TxReceipt, super().wait_for_transaction_receipt(transaction_hash, timeout, poll_latency)) # type: ignore
@@ -743,12 +967,104 @@ def wait_for_transaction_receipt(
     def wait_till_transaction_executed(
         self, transaction_hash: _Hash32, timeout: float = 300, poll_latency: float = 0.5
     ) -> TxReceipt:
+        """
+        Returns transaction receipt after it is executed.
+        If TxReceipt is returned, the transaction is found executed successfully
+        
+        >>> w3.cfx.wait_till_transaction_executed("0x5ffa11a44c6db42cc30967d4de5949b17ee319c4aba72f3380c60136993a8980")
+        AttributeDict({'transactionHash': HexBytes('0x5ffa11a44c6db42cc30967d4de5949b17ee319c4aba72f3380c60136993a8980'),
+            'index': 227,
+            'blockHash': HexBytes('0xceda961d541c78fa2c99907620bb2b13707f72b004b7c70362a5642177e6aae2'),
+            'epochNumber': 97108737,
+            'from': 'cfxtest:aaksxj04phv0hp02jh3cbym9vghwkzap867jagb043',
+            'to': 'cfxtest:aaksxj04phv0hp02jh3cbym9vghwkzap867jagb043',
+            'gasUsed': 21000,
+            'gasFee': 21000000000000 Drip,
+            'contractCreated': None,
+            'logs': [],
+            'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),
+            'stateRoot': HexBytes('0x89dd70006e4714eb81a210a20badf4c37adc7fcbe992b8458460876fcac38ea3'),
+            'outcomeStatus': 0,
+            'txExecErrorMsg': None,
+            'gasCoveredBySponsor': False,
+            'storageCoveredBySponsor': False,
+            'storageCollateralized': 0,
+            'storageReleased': []})
+
+        Parameters
+        ----------
+        transaction_hash : _Hash32
+            the hash of the transaction, could be byte or hex string
+        timeout : float, optional
+            maximum wait time before timeout in seconds, by default 300
+        poll_latency : float, optional
+            time interval to query transaction status in seconds, by default 0.5
+
+        Returns
+        -------
+        TxReceipt
+            transaction receipt as a dict
+
+        Raises
+        ------
+        TimeExhausted
+            if timeout
+        RuntimeError
+            if transaction is not executed successfully
+        """  
         return self.wait_for_transaction_receipt(transaction_hash, timeout, poll_latency)
         
     
     def wait_till_transaction_confirmed(
         self, transaction_hash: _Hash32, timeout: float = 600, poll_latency: float = 0.5
     ) -> TxReceipt:
+        """
+        Returns transaction receipt after a transaction is confirmed.
+        If TxReceipt is returned, the chances that the transaction execution result to be reverted is tiny.
+        But there are still chances that the transaction might be reverted.
+        ## Developers should use `wait_till_transaction_finalized` if the transaction is REALLY IMPORTANT.
+        
+        >>> w3.cfx.get_transaction_receipt("0x5ffa11a44c6db42cc30967d4de5949b17ee319c4aba72f3380c60136993a8980")
+        AttributeDict({'transactionHash': HexBytes('0x5ffa11a44c6db42cc30967d4de5949b17ee319c4aba72f3380c60136993a8980'),
+            'index': 227,
+            'blockHash': HexBytes('0xceda961d541c78fa2c99907620bb2b13707f72b004b7c70362a5642177e6aae2'),
+            'epochNumber': 97108737,
+            'from': 'cfxtest:aaksxj04phv0hp02jh3cbym9vghwkzap867jagb043',
+            'to': 'cfxtest:aaksxj04phv0hp02jh3cbym9vghwkzap867jagb043',
+            'gasUsed': 21000,
+            'gasFee': 21000000000000 Drip,
+            'contractCreated': None,
+            'logs': [],
+            'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),
+            'stateRoot': HexBytes('0x89dd70006e4714eb81a210a20badf4c37adc7fcbe992b8458460876fcac38ea3'),
+            'outcomeStatus': 0,
+            'txExecErrorMsg': None,
+            'gasCoveredBySponsor': False,
+            'storageCoveredBySponsor': False,
+            'storageCollateralized': 0,
+            'storageReleased': []})
+
+        Parameters
+        ----------
+        transaction_hash : _Hash32
+            the hash of the transaction, could be byte or hex string
+        timeout : float, optional
+            maximum wait time before timeout in seconds, by default 600
+        poll_latency : float, optional
+            time interval to query transaction status in seconds, by default 0.5
+
+        Returns
+        -------
+        TxReceipt
+            transaction receipt as a dict
+
+        Raises
+        ------
+        TimeExhausted
+            if timeout
+        RuntimeError
+            if transaction is not executed successfully
+        """  
         try:
             with Timeout(timeout) as _timeout:
                 while True:
@@ -772,7 +1088,31 @@ def wait_till_transaction_confirmed(
     def wait_till_transaction_finalized(
         self, transaction_hash: _Hash32, timeout: float = 1200, poll_latency: float = 0.5
     ) -> TxReceipt:
-        warnings.warn("10 ~ 15 minutes are required to finalize a transaction", UserWarning)
+        """
+        Returns transaction receipt after a transaction is finalized by PoS chain.
+        It will take 5 ~ 10 minutes to finalize a transaction but the finalized transaction won't be reverted.
+        It is recommended for developers to use this api to confirm important transactions.
+
+        Parameters
+        ----------
+        transaction_hash : _Hash32
+            the hash of the transaction, could be byte or hex string
+        timeout : float, optional
+            maximum wait time before timeout in seconds, by default 1200
+        poll_latency : float, optional
+            time interval to query transaction status in seconds, by default 0.5
+
+        Returns
+        -------
+        TxReceipt
+            transaction receipt as a dict
+
+        Raises
+        ------
+        TimeExhausted
+            If timeout
+        """        
+        warnings.warn("5 ~ 10 minutes are required to finalize a transaction", UserWarning)
         try:
             with Timeout(timeout) as _timeout:
                 while True:
@@ -794,86 +1134,282 @@ def wait_till_transaction_finalized(
             )
     
     def get_transaction_by_hash(self, transaction_hash: _Hash32) -> TxData:
+        """
+        Returns information about a transaction, identified by its hash.
+        ## Note: the transaction is not mined if `blockHash` field is None
+        
+        >>> w3.cfx.get_transaction_by_hash('0x5ffa11a44c6db42cc30967d4de5949b17ee319c4aba72f3380c60136993a8980')
+        AttributeDict({'hash': HexBytes('0x5ffa11a44c6db42cc30967d4de5949b17ee319c4aba72f3380c60136993a8980'),
+            'nonce': 8230,
+            'blockHash': HexBytes('0xceda961d541c78fa2c99907620bb2b13707f72b004b7c70362a5642177e6aae2'),
+            'transactionIndex': 227,
+            'from': 'cfxtest:aaksxj04phv0hp02jh3cbym9vghwkzap867jagb043',
+            'to': 'cfxtest:aaksxj04phv0hp02jh3cbym9vghwkzap867jagb043',
+            'value': 0 Drip,
+            'gasPrice': 1000000000 Drip,
+            'gas': 21000,
+            'contractCreated': None,
+            'data': HexBytes('0x'),
+            'storageLimit': 0,
+            'epochHeight': 97108719,
+            'chainId': 1,
+            'status': 0,
+            'v': 1,
+            'r': HexBytes('0x1d16cb28acf3973df4f4cc29ffffdba5d36ca1e38f1904f64780fa505691c1b7'),
+            's': HexBytes('0x1549267bc4f60af38d23112b47a54dc36481e77eb44dd5ee2c3277810c1c6297')})
+
+
+        Parameters
+        ----------
+        transaction_hash : _Hash32
+            the hash of the transaction, could be byte or hex string
+
+        Returns
+        -------
+        TxData
+            transaction data as a dict
+        """        
         return self._get_transaction_by_hash(transaction_hash)
     
     # same as web3.py
     def get_transaction(self, transaction_hash: _Hash32) -> TxData:
+        """Alias for `get_transaction_by_hash`
+        """
         return self.get_transaction_by_hash(transaction_hash)
     
     def get_block_by_hash(
         self, block_hash: _Hash32, full_transactions: bool=False
-    ) -> BlockData:
+    ) -> Union[BlockData, None]:
+        """
+        Returns information about a block, identified by its hash.
+
+        >>> w3.cfx.get_block_by_hash("0x4752f93f61b43e3b09bcbcd36871d4894ac64254df367fa9d7a6253cfb618ece")
+        AttributeDict({'hash': HexBytes('0x4752f93f61b43e3b09bcbcd36871d4894ac64254df367fa9d7a6253cfb618ece'),
+            'parentHash': HexBytes('0x06a695ab273255341f24f955ce696d45007df4df66f0c61b1818965926c2e808'),
+            'height': 97111729,
+            'miner': 'cfxtest:aanpu16mtgc7dke5xhuktyfyef8f00pz8a2z5mc14g',
+            'deferredStateRoot': HexBytes('0xeaf792fff684ce3f04c84614442ab38e8bb4622bacba1c01e857449ef97425f2'),
+            'deferredReceiptsRoot': HexBytes('0x09f8709ea9f344a810811a373b30861568f5686e649d6177fd92ea2db7477508'),
+            'deferredLogsBloomHash': HexBytes('0xd397b3b043d87fcd6fad1291ff0bfd16401c274896d8c63a923727f077b8e0b5'),
+            'blame': 0,
+            'transactionsRoot': HexBytes('0x6058a7cf739d94882638cada6e15a4f3b53b757c7195c5cafd04c2061f6de00d'),
+            'epochNumber': 97111729,
+            'blockNumber': 124302546,
+            'gasLimit': 30000000,
+            'gasUsed': 75291,
+            'timestamp': 1666755747,
+            'difficulty': 57822922,
+            'powQuality': HexBytes('0x04ebbe82'),
+            'refereeHashes': [],
+            'adaptive': False,
+            'nonce': HexBytes('0x14b30ccfa7cf95b2'),
+            'size': 311,
+            'custom': [HexBytes('0x02')],
+            'posReference': HexBytes('0x2bac96d8e4205badeab4138d1f7b671a436a68ab50c54e7b154243cbf0c9205b'),
+            'transactions': [HexBytes('0x70d17ef32c0544075078cb1ca777dab3728d443f00826cf3d05b9c01b76b5f5c')]})
+                    
+        Parameters
+        ----------
+        block_hash : _Hash32
+            hash of a block
+        full_transactions : bool, optional
+            if true, it returns the full transaction objects. If false, only the hashes of the transactions are returned, by default False
+
+        Returns
+        -------
+        Union[BlockData, None]
+            the block data as a dict, or None if no block was found
+        """        
         return self._get_block_by_hash(block_hash, full_transactions)
     
     def get_block_by_epoch_number(
         self, epoch_number_param: EpochNumberParam, full_transactions: bool=False
     ) -> BlockData:
+        """
+        Returns information about a pivot block, identified by its epoch number.
+
+        >>> w3.cfx.get_block_by_epoch_number(97111729)
+        AttributeDict({'hash': HexBytes('0x4752f93f61b43e3b09bcbcd36871d4894ac64254df367fa9d7a6253cfb618ece'),
+            'parentHash': HexBytes('0x06a695ab273255341f24f955ce696d45007df4df66f0c61b1818965926c2e808'),
+            'height': 97111729,
+            'miner': 'cfxtest:aanpu16mtgc7dke5xhuktyfyef8f00pz8a2z5mc14g',
+            'deferredStateRoot': HexBytes('0xeaf792fff684ce3f04c84614442ab38e8bb4622bacba1c01e857449ef97425f2'),
+            'deferredReceiptsRoot': HexBytes('0x09f8709ea9f344a810811a373b30861568f5686e649d6177fd92ea2db7477508'),
+            'deferredLogsBloomHash': HexBytes('0xd397b3b043d87fcd6fad1291ff0bfd16401c274896d8c63a923727f077b8e0b5'),
+            'blame': 0,
+            'transactionsRoot': HexBytes('0x6058a7cf739d94882638cada6e15a4f3b53b757c7195c5cafd04c2061f6de00d'),
+            'epochNumber': 97111729,
+            'blockNumber': 124302546,
+            'gasLimit': 30000000,
+            'gasUsed': 75291,
+            'timestamp': 1666755747,
+            'difficulty': 57822922,
+            'powQuality': HexBytes('0x04ebbe82'),
+            'refereeHashes': [],
+            'adaptive': False,
+            'nonce': HexBytes('0x14b30ccfa7cf95b2'),
+            'size': 311,
+            'custom': [HexBytes('0x02')],
+            'posReference': HexBytes('0x2bac96d8e4205badeab4138d1f7b671a436a68ab50c54e7b154243cbf0c9205b'),
+            'transactions': [HexBytes('0x70d17ef32c0544075078cb1ca777dab3728d443f00826cf3d05b9c01b76b5f5c')]})
+
+        Parameters
+        ----------
+        epoch_number_param : EpochNumberParam
+            the epoch number, or the string "latest_mined", "latest_state", "latest_confirmed", "latest_checkpoint" or "earliest"
+        full_transactions : bool, optional
+            if true, it returns the full transaction objects. If false, only the hashes of the transactions are returned, by default False
+
+        Returns
+        -------
+        BlockData
+            the block data as a dict
+        """        
         return self._get_block_by_epoch_number(epoch_number_param, full_transactions)
     
     def get_block_by_block_number(
         self, block_number: int, full_transactions: bool=False
     ) -> BlockData:
+        """
+        Returns information about a block, identified by its block number.
+
+        >>> w3.cfx.get_block_by_block_number(124302546)
+        AttributeDict({'hash': HexBytes('0x4752f93f61b43e3b09bcbcd36871d4894ac64254df367fa9d7a6253cfb618ece'),
+            'parentHash': HexBytes('0x06a695ab273255341f24f955ce696d45007df4df66f0c61b1818965926c2e808'),
+            'height': 97111729,
+            'miner': 'cfxtest:aanpu16mtgc7dke5xhuktyfyef8f00pz8a2z5mc14g',
+            'deferredStateRoot': HexBytes('0xeaf792fff684ce3f04c84614442ab38e8bb4622bacba1c01e857449ef97425f2'),
+            'deferredReceiptsRoot': HexBytes('0x09f8709ea9f344a810811a373b30861568f5686e649d6177fd92ea2db7477508'),
+            'deferredLogsBloomHash': HexBytes('0xd397b3b043d87fcd6fad1291ff0bfd16401c274896d8c63a923727f077b8e0b5'),
+            'blame': 0,
+            'transactionsRoot': HexBytes('0x6058a7cf739d94882638cada6e15a4f3b53b757c7195c5cafd04c2061f6de00d'),
+            'epochNumber': 97111729,
+            'blockNumber': 124302546,
+            'gasLimit': 30000000,
+            'gasUsed': 75291,
+            'timestamp': 1666755747,
+            'difficulty': 57822922,
+            'powQuality': HexBytes('0x04ebbe82'),
+            'refereeHashes': [],
+            'adaptive': False,
+            'nonce': HexBytes('0x14b30ccfa7cf95b2'),
+            'size': 311,
+            'custom': [HexBytes('0x02')],
+            'posReference': HexBytes('0x2bac96d8e4205badeab4138d1f7b671a436a68ab50c54e7b154243cbf0c9205b'),
+            'transactions': [HexBytes('0x70d17ef32c0544075078cb1ca777dab3728d443f00826cf3d05b9c01b76b5f5c')]})
+
+        Parameters
+        ----------
+        epoch_number_param : EpochNumberParam
+            the epoch number, or the string "latest_mined", "latest_state", "latest_confirmed", "latest_checkpoint" or "earliest"
+        full_transactions : bool, optional
+            if true, it returns the full transaction objects. If false, only the hashes of the transactions are returned, by default False
+
+        Returns
+        -------
+        BlockData
+            the block data as a dict
+        """  
         return self._get_block_by_block_number(block_number, full_transactions)
     
     def get_best_block_hash(self) -> HexBytes:
+        """
+        Returns the best block hash, which is the block hash of the latest pivot block
+
+        Returns
+        -------
+        HexBytes
+            best block hash in bytes
+        """        
         return self._get_best_block_hash()
     
     def get_blocks_by_epoch(self, epoch_number_param: EpochNumberParam) -> Sequence[HexBytes]:
+        """
+        Returns the block hashes in the specified epoch.
+
+        Parameters
+        ----------
+        epoch_number_param : EpochNumberParam
+            the epoch number, or the string "latest_mined", "latest_state", "latest_confirmed", "latest_checkpoint" or "earliest"
+
+        Returns
+        -------
+        Sequence[HexBytes]
+            a list of block hash in bytes
+        """        
         return self._get_blocks_by_epoch(epoch_number_param)
     
     def get_skipped_blocks_by_epoch(self, epoch_number_param: EpochNumberParam) -> Sequence[HexBytes]:
+        """
+        Returns the list of non-executed blocks in an epoch. By default, Conflux only executes the last 200 blocks in each epoch (note that under normal circumstances, epochs should be much smaller).
+
+        Parameters
+        ----------
+        epoch_number_param : EpochNumberParam
+            the epoch number, or the string "latest_mined", "latest_state", "latest_confirmed", "latest_checkpoint" or "earliest"
+
+        Returns
+        -------
+        Sequence[HexBytes]
+            a list of block hash in bytes
+        """        
         return self._get_skipped_blocks_by_epoch(epoch_number_param)
 
     def get_block_by_hash_with_pivot_assumptions(self, block_hash: _Hash32, assumed_pivot_hash: _Hash32, epoch_number: int) -> BlockData:
+        """
+        Returns the requested block if the provided pivot hash is correct, returns an error otherwise.
+
+        Parameters
+        ----------
+        block_hash : _Hash32
+            block hash
+        assumed_pivot_hash : _Hash32
+            assumed pivot hash
+        epoch_number : int
+            integer epoch number
+
+        Returns
+        -------
+        BlockData
+            returns block data if pivot hash is correct
+        """        
         return self._get_block_by_hash_with_pivot_assumptions(block_hash, assumed_pivot_hash, epoch_number)
     
     def get_confirmation_risk_by_hash(self, block_hash: _Hash32) -> float:
+        """
+        Returns the confirmation risk of a given block, identified by its hash
+
+        Parameters
+        ----------
+        block_hash : _Hash32
+            block hash
+
+        Returns
+        -------
+        float
+            the confirmation risk in float
+        """        
         return self._get_confirmation_risk_by_hash(block_hash)
     
     def get_block(self, block_identifier: Union[_Hash32, EpochNumberParam], full_transactions: bool = False) -> BlockData:
         """
-        a simple wrapper combining web3.cfx.get_block_by_hash and web3.cfx.get_block_by_epoch_number
+        a simple wrapper combining `get_block_by_hash` and `get_block_by_epoch_number`
+        # note: DON'T USE *BLOCK NUMBER* as the parameter. A number will be considered as epoch number
+        
+        >>> block_data = w3.cfx.get_block(97112003)
+        >>> block_data_ = w3.cfx.get_block("0x1aa5c0d8d6778bd72ac842a52fd26042458b4f70a4d969dfa0d80f81f5eac790")
+        >>> assert block_data == block_data_
 
         Parameters
         ----------
         block_identifier : Union[_Hash32, EpochNumberParam]
             block hash or epoch number parameter(e.g. string "latest_state" or epoch number)
-            # note: DON'T USE BLOCK NUMBER as the parameter #
         full_transactions : bool, optional
             whether the return block data contains full transaction info or just transaction hash, by default False
 
         Returns
         -------
         BlockData
-            e.g.
-            {
-                "adaptive": false,
-                "blame": 0,
-                "deferredLogsBloomHash": "0xd397b3b043d87fcd6fad1291ff0bfd16401c274896d8c63a923727f077b8e0b5",
-                "deferredReceiptsRoot": "0x522717233b96e0a03d85f02f8127aa0e23ef2e0865c95bb7ac577ee3754875e4",
-                "deferredStateRoot": "0xd449df4ba49f5ab02abf261e976197beecf93c5198a6f0b6bd2713d84115c4ec",
-                "difficulty": "0xeee440",
-                "epochNumber": "0x1394cb",
-                "gasLimit": "0xb2d05e00",
-                "gasUsed": "0xad5ae8",
-                "hash": "0x692373025c7315fa18b2d02139d08e987cd7016025920f59ada4969c24e44e06",
-                "height": "0x1394c9",
-                "miner": "CFX:TYPE.USER:AARC9ABYCUE0HHZGYRR53M6CXEDGCCRMMYYBJGH4XG",
-                "nonce": "0x329243b1063c6773",
-                "parentHash": "0xd1c2ff79834f86eb4bc98e0e526de475144a13719afba6385cf62a4023c02ae3",
-                "powQuality": "0x2ab0c3513",
-                "refereeHashes": [
-                "0xcc103077ede14825a5667bddad79482d7bbf1f1a658fed6894fa0e9287fc6be1"
-                ],
-                "size": "0x180",
-                "timestamp": "0x5e8d32a1",
-                "transactions": [
-                "0xedfa5b9c38ba51e791cc72b8f75ff758533c8c38f426eddee3fd95d984dd59ff"
-                ],
-                "custom": ["0x12"],
-                "transactionsRoot": "0xfb245dae4539ea49812e822adbffa9dd2ee9b3de8f3d9a7d186d351dcc9a6ed4",
-                "posReference": "0xd1c2ff79834f86eb4bc98e0e526de475144a13719afba6385cf62a4023c02ae3",
-            } 
         """
         # TODO: more fine-grained munger
         if block_identifier == "latest":
@@ -983,9 +1519,32 @@ def check_balance_against_transaction(
     def get_logs(self, filter_params: FilterParams) -> List[LogReceipt]:...
     
     @overload
-    def get_logs(self, filter_params: None=None, **kwargs: Dict[str, Any]) -> List[LogReceipt]:...
+    def get_logs(self, filter_params: None=None, **kwargs: Any) -> List[LogReceipt]:...
     
-    def get_logs(self, filter_params: Optional[FilterParams]=None, **kwargs: Dict[str, Any]) -> List[LogReceipt]:
+    def get_logs(self, filter_params: Optional[FilterParams]=None, **kwargs: Any) -> List[LogReceipt]:
+        """
+        Returns logs matching the filter provided.
+        It is accepted to pass filter_params as a dict or by direclty specifying field name (but cannot mix)
+        
+        >>> logs = w3.cfx.get_logs({"fromEpoch": 97134060, "toEpoch: 97134160"})
+        >>> assert logs == w3.cfx.get_logs(fromEpoch=97134060, toEpoch=97134160})
+
+        Parameters
+        ----------
+        filter_params : Optional[FilterParams], optional
+            FilterParams is a dict with optional fields:
+                fromEpoch: EpochNumberParam
+                toEpoch: EpochNumberParam
+                blockHashes: Sequence[_Hash32]
+                address: Union[Base32Address, List[Base32Address]]
+                topics: Sequence[Optional[Union[_Hash32, Sequence[_Hash32]]]]
+            visit https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc/#cfx_getlogs for more information
+
+        Returns
+        -------
+        List[LogReceipt]
+            a list of LogReceipt. It is recommended to read https://github.com/Conflux-Chain/python-conflux-sdk/blob/v1/examples/04-interact_with_contracts_and_logs.py to know how to process the returned logs
+        """        
         if filter_params is None:
             filter_params = cast(FilterParams, keyfilter(lambda key: key in FilterParams.__annotations__.keys(), kwargs)) # type: ignore
             return self._get_logs(filter_params)
@@ -993,4 +1552,3 @@ def get_logs(self, filter_params: Optional[FilterParams]=None, **kwargs: Dict[st
             if len(kwargs.keys()) != 0:
                 raise ValueError("Redundant Param: FilterParams as get_logs first parameter is already provided")
             return self._get_logs(filter_params)
-
diff --git a/conflux_web3/contract/metadata/__init__.py b/conflux_web3/contract/metadata/__init__.py
index 01c4816..4fbca0e 100644
--- a/conflux_web3/contract/metadata/__init__.py
+++ b/conflux_web3/contract/metadata/__init__.py
@@ -100,7 +100,8 @@ def get_contract_metadata(
             metadata = json.load(f)
         metadata = keyfilter(lambda x: x in ["abi", "bytecode"], metadata)
     except ContractMetadataNotFound as e:
-        if abi := getattr(abis, contract_name, None):
+        abi = getattr(abis, contract_name, None)
+        if abi:
             metadata = {
                 "abi": abi
             }
diff --git a/conflux_web3/middleware/wallet.py b/conflux_web3/middleware/wallet.py
index d4c5a2f..86a577a 100644
--- a/conflux_web3/middleware/wallet.py
+++ b/conflux_web3/middleware/wallet.py
@@ -5,6 +5,8 @@
     Optional,
     Sequence,
     Union,
+    Callable,
+    Any,
 )
 import warnings
 
@@ -13,7 +15,8 @@
 )
 
 from cfx_utils.types import (
-    HexAddress
+    HexAddress,
+    TxDict,
 )
 from cfx_account.account import (
     LocalAccount,
@@ -22,8 +25,8 @@
 from cfx_address import (
     Base32Address
 )
-from cfx_address.utils import validate_network_id as validate_chain_id
 from cfx_address.utils import (
+    validate_network_id as validate_chain_id,
     normalize_to
 )
 from conflux_web3._utils.cns import (
@@ -125,17 +128,17 @@ def normalize_private_key_to_account(self, private_key: _PrivateKey) -> LocalAcc
         # any account added to wallet is a brand new object
         return Account.from_key(private_key, self._chain_id)
     
-    def __call__(self, make_request, w3: "Web3"):
-        def inner(method, params):
+    def __call__(self, make_request: Callable[..., Dict[str, Any]], w3: "Web3"):
+        def inner(method: str, params: Sequence[Any]):
             if method != RPC.cfx_sendTransaction:
                 return make_request(method, params)
             
-            transaction = params[0]
+            transaction: TxDict = params[0]
             if "from" not in transaction:
                 return make_request(method, params)
             else:
                 transaction["from"] = resolve_if_cns_name(w3, transaction["from"])
-                if transaction.get("from") not in self:
+                if transaction["from"] not in self:
                     return make_request(method, params)
             
             account = self[transaction["from"]]
@@ -163,12 +166,18 @@ def __getitem__(self, address: str) -> LocalAccount:
         else:
             return self._accounts_map[address]
     
-    def __contains__(self, address: str):
+    def __contains__(self, address: str) -> bool:
         try:
             self[address]
             return True
         except KeyError:
             return False
+    
+    def pop(self, address: str) -> LocalAccount:
+        if self._chain_id is None:
+            return self._accounts_map.pop(normalize_to(address, None))
+        else:
+            return self._accounts_map.pop(address)
 
 
 def construct_sign_and_send_raw_middleware(
diff --git a/conflux_web3/types/__init__.py b/conflux_web3/types/__init__.py
index 0d25dc4..0ac49f4 100644
--- a/conflux_web3/types/__init__.py
+++ b/conflux_web3/types/__init__.py
@@ -3,14 +3,16 @@
     Any,
     Callable,
     List,
-    Literal,
     NewType,
     Optional,
     Sequence,
-    TypedDict,
     Union,
     Dict
 )
+from typing_extensions import (
+    Literal,
+    TypedDict,
+)
 from hexbytes import HexBytes
 
 from web3.types import (
@@ -43,6 +45,23 @@
     from conflux_web3 import Web3
 
 class NodeStatus(TypedDict):
+    """
+    Node status as dict
+
+    Dict keys and corresponding value type
+    ----------
+    bestHash: bytes
+    chainId: int
+    networkId: int
+    blockNumber: int
+    epochNumber: int
+    latestCheckpoint: int
+    latestConfirmed: int
+    latestState: int
+    latestFinalized: int
+    ethereumSpaceChainId: int
+    pendingTxNumber: int
+    """    
     bestHash: Hash32
     chainId: int
     networkId: int
@@ -55,13 +74,33 @@ class NodeStatus(TypedDict):
     ethereumSpaceChainId: int
     pendingTxNumber: int
 
-class EstimateResult(TypedDict):    
+class EstimateResult(TypedDict):
+    """
+    Estimation result of a transaction as dict
+
+    Parameters
+    ----------
+    gasLimit: int
+    gasUsed: int
+    storageCollateralized: Storage
+    """       
     gasLimit: int
     gasUsed: int
     storageCollateralized: Storage
 
 
 class FilterParams(TypedDict, total=False):
+    """
+    Parameter dict to filter logs, more information at https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc/#cfx_getlogs
+
+    Key and type of corresponding value
+    ----------
+    fromEpoch: EpochNumberParam, optional
+    toEpoch: EpochNumberParam, optional
+    blockHashes: Sequence[_Hash32], optional
+    address: Union[Base32Address, List[Base32Address]], optional
+    topics: Sequence[Optional[Union[_Hash32, Sequence[_Hash32]]]], optional
+    """
     fromEpoch: EpochNumberParam
     toEpoch: EpochNumberParam
     blockHashes: Sequence[_Hash32]
@@ -70,12 +109,36 @@ class FilterParams(TypedDict, total=False):
 
 
 class TransactionLogReceipt(TypedDict):
+    """
+    Log receipt in transaction receipt
+
+    Key and type of corresponding value
+    ----------
+    address: Base32Address
+    topics: Sequence[HexBytes]
+    data: HexBytes
+    """
     address: Base32Address
     topics: Sequence[HexBytes]
     data: HexBytes
 
 
 class LogReceipt(TypedDict):
+    """
+    Full log receipt
+
+    Key and type of corresponding value
+    ----------
+    address: Base32Address
+    topics: Sequence[HexBytes]
+    data: HexBytes
+    blockHash: Hash32
+    epochNumber: int
+    transactionHash: Hash32
+    transactionIndex: int
+    logIndex: int
+    transactionLogIndex: int
+    """
     address: Base32Address
     topics: Sequence[HexBytes]
     data: HexBytes
@@ -87,6 +150,20 @@ class LogReceipt(TypedDict):
     transactionLogIndex: int
 
 class TransactionEventData(TypedDict):
+    """
+    Transaction event data as a dict
+
+    Key and type of corresponding value
+    ----------
+    address: Base32Address
+    args: Dict[str, Any]
+    event: str
+    blockHash: Hash32
+    epochNumber: int
+    transactionHash: Hash32
+    transactionIndex: int
+    transactionLogIndex: int
+    """
     address: Base32Address
     args: Dict[str, Any]
     event: str
@@ -97,6 +174,21 @@ class TransactionEventData(TypedDict):
     transactionLogIndex: int
 
 class EventData(TransactionEventData, total=False):
+    """
+    Transaction event data
+
+    Key and type of corresponding value
+    ----------
+    address: Base32Address
+    args: Dict[str, Any]
+    event: str
+    blockHash: Hash32
+    epochNumber: int
+    transactionHash: Hash32
+    transactionIndex: int
+    transactionLogIndex: int
+    logIndex: int, Optional
+    """
     logIndex: int
 
 
@@ -124,6 +216,30 @@ class EventData(TransactionEventData, total=False):
         "txExecErrorMsg": Union[str, None]
     },
 )
+"""
+Transaction receipt as a dict
+
+Key and type of corresponding value
+----------
+"transactionHash": Hash32,
+"index": int,
+"blockHash": Hash32,
+"epochNumber": int,
+"from": Base32Address,
+"to": Base32Address,
+"gasUsed": int,
+"gasFee": Drip,
+"gasCoveredBySponsor": bool,
+"storageCollateralized": Storage,
+"storageCoveredBySponsor": bool,
+"storageReleased": List[Storage],
+"contractCreated": Union[Base32Address, None],
+"stateRoot": Hash32,
+"outcomeStatus": int,
+"logsBloom": HexBytes,
+"logs": List[TransactionLogReceipt],
+"txExecErrorMsg": Union[str, None]
+"""
 
 
 # syntax b/c "from" keyword not allowed w/ class construction
@@ -151,8 +267,61 @@ class EventData(TransactionEventData, total=False):
     },
     total=False,
 )
+"""
+Transaction data as a dict
+
+Key and type of corresponding value
+----------
+"blockHash": Union[None, Hash32],
+"chainId": int,
+"contractCreated": Union[None, Base32Address],
+"data": HexBytes,
+"epochHeight": int,
+"from": Base32Address,
+"gas": int,
+"gasPrice": Drip,
+"hash": Hash32,
+"nonce": Nonce,
+"r": HexBytes,
+"s": HexBytes,
+"status": Union[None, int],
+"storageLimit": Storage,
+"to": Union[None, Base32Address],
+"transactionIndex": Union[None, int],
+"v": int,
+"value": Drip,
+"""
 
 class BlockData(TypedDict):
+    """
+    Block data as a dict
+
+    Key and type of corresponding value
+    ----------
+    hash: Hash32
+    parentHash: Hash32
+    height: int
+    miner: Base32Address
+    deferredStateRoot: Hash32
+    deferredReceiptsRoot: Hash32
+    deferredLogsBloomHash: Hash32
+    blame: int
+    transactionsRoot: Hash32
+    epochNumber: Union[int, None]
+    blockNumber: Union[int, None]
+    gasLimit: int
+    gasUsed: Union[int, None]
+    timestamp: int
+    difficulty: int
+    powQuality: Union[HexBytes, None]
+    refereeHashes: Sequence[Hash32]
+    adaptive: bool
+    nonce: HexBytes
+    size: int
+    custom: Sequence[HexBytes]
+    posReference: Hash32
+    transactions: Sequence[Union[Hash32, TxData]]
+    """
     hash: Hash32
     parentHash: Hash32
     height: int
@@ -182,11 +351,29 @@ class BlockData(TypedDict):
 MiddlewareOnion = NamedElementOnion[str, Middleware]
 
 class StorageRoot(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    delta: Union[Hash32, Literal["TOMBSTONE", None]]
+    intermediate: Union[Hash32, Literal["TOMBSTONE", None]]
+    snapshot: Union[Hash32, Literal["TOMBSTONE", None]]
+    """
     delta: Union[Hash32, Literal["TOMBSTONE", None]]
     intermediate: Union[Hash32, Literal["TOMBSTONE", None]]
     snapshot: Union[Hash32, Literal["TOMBSTONE", None]]
 
 class SponsorInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    sponsorBalanceForCollateral: Drip
+    sponsorBalanceForGas: Drip
+    sponsorForCollateral: Base32Address
+    sponsorForGas: Base32Address
+    sponsorGasBound: Drip
+    """
     sponsorBalanceForCollateral: Drip
     sponsorBalanceForGas: Drip
     sponsorForCollateral: Base32Address
@@ -194,6 +381,19 @@ class SponsorInfo(TypedDict):
     sponsorGasBound: Drip
     
 class AccountInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    address: Base32Address
+    balance: Drip
+    nonce: Nonce
+    codeHash: Hash32
+    stakingBalance: Drip
+    collateralForStorage: Storage
+    accumulatedInterestReturn: Drip
+    admin: Base32Address
+    """
     address: Base32Address
     balance: Drip
     nonce: Nonce
@@ -204,15 +404,40 @@ class AccountInfo(TypedDict):
     admin: Base32Address
     
 class DepositInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    accumulatedInterestRate: int
+    amount: Drip
+    depositTime: int
+    """
     accumulatedInterestRate: int
     amount: Drip
     depositTime: int # assumed blockNumber
     
 class VoteInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    amount: Drip
+    unlockBlockNumber: int
+    """
     amount: Drip
     unlockBlockNumber: int
 
 class BlockRewardInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    blockHash: Hash32
+    author: Base32Address
+    totalReward: Drip
+    baseReward: Drip
+    txFee: Drip
+    """
     blockHash: Hash32
     author: Base32Address
     totalReward: Drip
@@ -223,24 +448,64 @@ class BlockRewardInfo(TypedDict):
 PoSEpochNumber = NewType("PoSEpochNumber", int)
 
 class PoSEconomicsInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    distributablePosInterest: Drip
+    lastDistributeBlock: PoSBlockNumber
+    totalPosStakingTokens: Drip
+    """
     distributablePosInterest: Drip
     lastDistributeBlock: PoSBlockNumber
     totalPosStakingTokens: Drip
     
 class PoSAccountRewardsInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    posAddress: Base32Address
+    powAddress: Base32Address
+    reward: Drip
+    """
     posAddress: Base32Address
     powAddress: Base32Address
     reward: Drip
 
 class PoSEpochRewardInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    accountRewards: Sequence[PoSAccountRewardsInfo]
+    powEpochHash: Hash32
+    """
     accountRewards: Sequence[PoSAccountRewardsInfo]
     powEpochHash: Hash32
 
 class DAOVoteInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    powBaseReward: Drip
+    interestRate: int
+    """
     powBaseReward: Drip
     interestRate: int
 
 class SupplyInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    totalIssued: Drip
+    totalCollateral: Drip
+    totalStaking: Drip
+    totalCirculating: Drip
+    totalEspaceTokens: Drip
+    """
     totalIssued: Drip
     totalCollateral: Drip
     totalStaking: Drip
@@ -248,6 +513,15 @@ class SupplyInfo(TypedDict):
     totalEspaceTokens: Drip
 
 class PendingInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    localNonce: Nonce
+    pendingNonce: Nonce
+    pendingCount: int
+    nextPendingTx: Hash32
+    """
     localNonce: Nonce
     pendingNonce: Nonce
     pendingCount: int
@@ -257,13 +531,66 @@ class PendingTransactionStatus(TypedDict):
     pending: Literal["futureNonce", "notEnoughCash"]
 
 class PendingTransactionsInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    firstTxStatus: Union[PendingTransactionStatus, Literal["ready"]]
+    pendingCount: int
+    pendingTransactions: Sequence[TxData]
+    """
     firstTxStatus: Union[PendingTransactionStatus, Literal["ready"]]
     pendingCount: int
     pendingTransactions: Sequence[TxData]
 
 class TransactionPaymentInfo(TypedDict):
+    """
+
+    Key and type of corresponding value
+    ----------
+    isBalanceEnough: bool
+    willPayCollateral: bool
+    willPayTxFee: bool
+    """
     isBalanceEnough: bool
     willPayCollateral: bool
     willPayTxFee: bool
 
-# TODO: add __all__ here
+__all__ = [
+    "TxDict",
+    "TxParam",
+    "HexAddress",
+    "Drip",
+    "CFX",
+    "GDrip",
+    "AddressParam",
+    "Storage",
+    "EpochNumberParam",
+    "EpochLiteral",
+    "EpochNumber",
+    "NodeStatus",
+    "EstimateResult",
+    "FilterParams",
+    "TransactionLogReceipt",
+    "LogReceipt",
+    "TransactionEventData",
+    "EventData",
+    "TxReceipt",
+    "TxData",
+    "BlockData",
+    "MiddlewareOnion",
+    "StorageRoot",
+    "SponsorInfo",
+    "AccountInfo",
+    "DepositInfo",
+    "VoteInfo",
+    "BlockRewardInfo",
+    "PoSEconomicsInfo",
+    "PoSAccountRewardsInfo",
+    "PoSEpochRewardInfo",
+    "DAOVoteInfo",
+    "SupplyInfo",
+    "PendingInfo",
+    "PendingTransactionsInfo",
+    "TransactionPaymentInfo"
+]
diff --git a/docs/en/CHANGELOG.md b/docs/en/CHANGELOG.md
new file mode 100644
index 0000000..69c658d
--- /dev/null
+++ b/docs/en/CHANGELOG.md
@@ -0,0 +1,47 @@
+# Change Logs
+
+## 1.0.0-dev7
+
+* type hints: migrate to `Pylance`; add `py.typed`
+* fix: cns recursive import problem
+* feature: default network id by using `web3.address`
+* feature: support python3.7
+* doc: add inline documents for frequently used RPCs
+* change: recover `estimate_gas_and_collateral`, `gas_price` returned token units
+
+## 1.0.0-dev6
+
+* bug fix: include the contract metadata in the release
+
+## 1.0.0-dev4
+
+* Response containing "address" from rpc is wrapped by `Base32Address`
+  * including contract return values
+* Introduces token unit `CFX`, `GDrip` and `Drip`
+  * responses are formatted using Drip/GDrip/CFX
+  * Drip/GDrip/CFX can be used as gas price or value
+* CNS support
+  * available by using `w3.cns` or `w3.ens`
+  * supports name service resolve as web3.py (as receiver/sender/parameter)
+  * (unstable) supports `w3.cns.setup_address` and `w3.cns.setup_owner`
+
+## 1.0.0-dev3
+
+* bump web3.py version
+  * web3.py: 6.0.0b4->6.0.0b5
+  * eth-account(required by cfx-account): ~=7.0.0
+
+## 1.0.0-dev2
+
+* Optimizes web3.py hacking mechanisms
+  * hacking codes are moved to `conflux_web3._hook.py`
+* Basic support for ethpm (furthur supports are not in plan)
+* The default account will be added to wallet if `w3.cfx.default_account` setter receives a `LocalAccount` object
+  * `w3.cfx.default_account` is still a `Base32Address`
+* `.finalized()` apis are tests.
+* Fix contract constructor's `build_transaction()` bugs
+* Add `name` parameter to `w3.cfx.contract()`
+  * supports internal contracts including `AdminControl`, `SponsorWhitelistControl`, `Staking`, `PoSRegister`, `CrossSpaceCall`, `ParamsControl`
+  * supports specific contracts added in genesis block, including `Create2Factory`, `ERC1820`
+  * supports `Faucet` in testnet
+  * supports `cUSDT` and `FC` in mainnet and testnet
diff --git a/docs/en/README.md b/docs/en/README.md
new file mode 100644
index 0000000..6268b51
--- /dev/null
+++ b/docs/en/README.md
@@ -0,0 +1,78 @@
+# Introduction
+
+[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/conflux-chain/python-conflux-sdk/dev?urlpath=tree/docs/en/examples/01-quickstart.ipynb)
+[![Documentation Status](https://readthedocs.org/projects/python-conflux-sdk/badge/?version=latest)](https://python-conflux-sdk.readthedocs.io/en/latest/?badge=latest)
+[![gitlocalized ](https://gitlocalize.com/repo/8175/whole_project/badge.svg)](https://gitlocalize.com/repo/8175/whole_project?utm_source=badge)
+
+[README](https://python-conflux-sdk.readthedocs.io/en/latest/README.html) | [中文文档](https://python-conflux-sdk.readthedocs.io/zh_CN/latest/README.html)
+
+- [Introduction](#introduction)
+  - [Overview](#overview)
+  - [Quickstart](#quickstart)
+  - [Documentations](#documentations)
+    - [Run Code Examples Online!](#run-code-examples-online)
+    - [Localization](#localization)
+
+
+## Overview
+
+Python-conflux-sdk helps to interact with Conflux network using python. It is built over [web3.py](https://github.com/ethereum/web3.py) and most of its APIs are consistent with [web3.py](https://github.com/ethereum/web3.py).
+
+## Quickstart
+
+Requirements: python version >= 3.7
+
+```bash
+$ pip3 install conflux-web3
+```
+
+```python
+from conflux_web3 import Web3
+
+w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
+
+acct = w3.account.from_key("0xxxxxxxxxxxxxx")
+w3.cfx.default_account = acct
+w3.cfx.contract(name="Faucet").claimCfx().transact().executed()
+
+w3.cfx.send_transaction({
+    'to': w3.address.zero_address(),
+    'value': 10**18,
+}).executed()
+```
+
+Or you can also use API as you do in `web3.py`: 
+
+``` python
+# modified from https://web3py.readthedocs.io/en/stable/middleware.html#signing
+from conflux_web3 import Web3
+w3 = Web3("https://test.confluxrpc.com")
+from conflux_web3.middleware import construct_sign_and_send_raw_middleware
+from cfx_account import Account
+acct = Account.create('KEYSMASH FJAFJKLDSKF7JKFDJ 1530')
+w3.middleware_onion.add(construct_sign_and_send_raw_middleware(acct))
+w3.cfx.default_account = acct.address
+
+transaction = {
+    'to': w3.address.zero_address(),
+    'value': 22,
+}
+w3.cfx.send_transaction(transaction)
+```
+
+## Documentations
+
+More detailed code examples are provided in the [documentation](https://python-conflux-sdk.readthedocs.io/en/latest/README.html).
+
+### Run Code Examples Online!
+
+All code examples can be run online in [mybinder](https://mybinder.org/). You can click `🚀` -> `Binder` on the top bar to activate the running environment. All dependencies wil be installed and the example can be run immediately.
+
+### Localization
+
+Currently this documentation supports:
+
+* English version
+* Chinese version
+
+And welcome to provide translation in [GitLocalize](https://gitlocalize.com/repo/8175).
diff --git a/docs/en/_config.yml b/docs/en/_config.yml
new file mode 100644
index 0000000..a62aa2e
--- /dev/null
+++ b/docs/en/_config.yml
@@ -0,0 +1,24 @@
+# Book settings
+# Learn more at https://jupyterbook.org/customize/config.html
+# Comprehensive example: https://github.com/executablebooks/jupyter-book/blob/master/docs/_config.yml
+
+title: python-conflux-sdk
+author: Read the Docs team
+logo: ../logo.png
+
+# Force re-execution of notebooks on each build.
+# See https://jupyterbook.org/content/execute.html
+execute:
+  execute_notebooks: cache
+
+# Information about where the book exists on the web
+repository:
+  url: https://github.com/conflux-chain/python-conflux-sdk  # Online location of your book
+  path_to_book: docs/en  # Optional path to your book, relative to the repository root
+  branch: dev  # Which branch of the repository should be used when creating links (optional)
+
+# Add GitHub buttons to your book
+# See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository
+html:
+  use_issues_button: true
+  use_repository_button: true
diff --git a/docs/en/_toc.yml b/docs/en/_toc.yml
new file mode 100644
index 0000000..729c24b
--- /dev/null
+++ b/docs/en/_toc.yml
@@ -0,0 +1,15 @@
+# Table of contents
+# Learn more at https://jupyterbook.org/customize/toc.html
+
+format: jb-book
+root: README
+parts:
+- caption: Examples
+  chapters:
+  - file: examples/01-quickstart
+  - file: examples/02-address_account_and_wallet
+  - file: examples/03-trace_transaction_status
+  - file: examples/04-query_data_via_RPC
+  - file: examples/05-interact_with_contracts_and_process_logs
+  - file: examples/10-send_raw_transaction
+  - file: examples/11-construct_transaction_from_scratch
diff --git a/docs/en/examples/01-quickstart.ipynb b/docs/en/examples/01-quickstart.ipynb
new file mode 100644
index 0000000..0f64835
--- /dev/null
+++ b/docs/en/examples/01-quickstart.ipynb
@@ -0,0 +1,198 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Quickstart\n",
+    "\n",
+    "Run this example online by clicking `🚀` -> `Binder` on the top bar!\n",
+    "\n",
+    "This example will present:\n",
+    "\n",
+    "* how to connect to the blockchain via a node\n",
+    "* how to create and use an account\n",
+    "* how to interact with a contract or simply send a transaction"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Connect to a Node\n",
+    "\n",
+    "We are supposed to connect to the Conflux network via a node. You can run a node locally following [this tutorial](https://developer.confluxnetwork.org/conflux-doc/docs/get_started/). In this example, we use [Conflux public RPC endpoint](https://developer.confluxnetwork.org/sdks-and-tools/en/conflux_rpcs) to connect to Conflux testnet. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from conflux_web3 import Web3\n",
+    "\n",
+    "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+    "assert w3.is_connected()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Create an Account\n",
+    "\n",
+    "In web3, owning an account means knowing a **secret**, which is called **private key/secret key**. In other words, who knows the private key owns the account. So the key should be kept secret, \n",
+    "\n",
+    "We can create a new account from `w3.account.create()`. This function creates an account from a random generated secret key.\n",
+    "\n",
+    "It is also supported to use `w3.account.from_key(\"0x....\")` to use your secret key (**but don't run it in an unsafe environment!**)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "account address: cfxtest:aaswj28188e35rh1vguksgnuz2xy4f8apye3745zxb\n",
+      "account secret key: 0x54d957b2485980fc2119ccce6480ad0d53219161595424fbf7dc452d59c6bc82\n",
+      "balance for cfxtest:aaswj28188e35rh1vguksgnuz2xy4f8apye3745zxb: 0 Drip\n"
+     ]
+    }
+   ],
+   "source": [
+    "acct = w3.account.create()\n",
+    "print(f\"account address: {acct.address}\")\n",
+    "# WARNING: Don't run the following line in unsafe environment, private key should be kept secret\n",
+    "print(f\"account secret key: {acct._private_key.hex()}\")\n",
+    "balance = w3.cfx.get_balance(acct.address)\n",
+    "# this is a random accoun, so its balance should be 0\n",
+    "assert balance == 0\n",
+    "print(f\"balance for {acct.address}: {balance}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Claim CFX via Testnet Faucet Contract\n",
+    "\n",
+    "Because the account's balance is `0`, it cannot afford the transaction fee (gas) to send a transaction. However, Conflux's [sponsorship mechanism](https://forum.conflux.fun/t/conflux-sponsorship-mechanism/12764) allows user to interact with a smart contract without paying gas, so we can claim CFX from [testnet faucet contract](https://testnet.confluxscan.net/address/cfxtest:acejjfa80vj06j2jgtz9pngkv423fhkuxj786kjr61).\n",
+    "\n",
+    "> smart contract: A smart contract is a program deployed on the blockchain. It provides interfaces to complete specific logic. In the example, invoking the `claimCfx` method of faucet contract will give you 1000 testnet CFX."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "tx hash is: 0xf174cf4be19b33da58504ef850bfd055bd031324135093276abbee1c34df854d\n",
+      "conflux scan link: https://testnet.confluxscan.net/transaction/0xf174cf4be19b33da58504ef850bfd055bd031324135093276abbee1c34df854d\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Firstly we will set `w3.cfx.default_account` to `acct`, \n",
+    "# after that transactions can be automatically singed and sent.\n",
+    "w3.cfx.default_account = acct\n",
+    "\n",
+    "# interact with testnet Faucet contract\n",
+    "faucet = w3.cfx.contract(name=\"Faucet\")\n",
+    "tx_hash = faucet.functions.claimCfx().transact()\n",
+    "\n",
+    "print(f\"tx hash is: {tx_hash.hex()}\\n\"\n",
+    "      f\"confluxscan link: https://testnet.confluxscan.net/transaction/{tx_hash.hex()}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "balance for cfxtest:aaswj28188e35rh1vguksgnuz2xy4f8apye3745zxb: 1000 CFX\n"
+     ]
+    }
+   ],
+   "source": [
+    "# in Conflux, the transaction will be executed only after it appears on the chain for 5 epoch\n",
+    "# `tx_hash.executed()` is equivalent to `w3.cfx.wait_for_transaction_receipt(tx_hash)`\n",
+    "tx_hash.executed()\n",
+    "# Drip and CFX are token units in Conflux network\n",
+    "# 1 CFX = 10**18 Drip\n",
+    "print(f\"balance for {acct.address}: {w3.cfx.get_balance(acct.address).to('CFX')}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Transfer CFX\n",
+    "\n",
+    "Now we can afford the transaction fee to transfer. For example, we can send 1 CFX to zero address."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "balance for cfxtest:aaswj28188e35rh1vguksgnuz2xy4f8apye3745zxb: 998.999979 CFX\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Now acct has CFX\n",
+    "# send 1 CFX to zero address\n",
+    "w3.cfx.send_transaction({\n",
+    "    \"to\": w3.address.zero_address(),\n",
+    "    \"value\": 10**18,\n",
+    "}).executed()\n",
+    "print(f\"balance for {acct.address}: {w3.cfx.get_balance(acct.address).to('CFX')}\")"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.9.13 ('venv39': venv)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.13"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "9b7fb9a8ba8be13c6b92820560c2e7f0c114ca03a55934a046d1bf6afa009968"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/en/examples/02-address_account_and_wallet.ipynb b/docs/en/examples/02-address_account_and_wallet.ipynb
new file mode 100644
index 0000000..e015173
--- /dev/null
+++ b/docs/en/examples/02-address_account_and_wallet.ipynb
@@ -0,0 +1,277 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Account, Address and Wallet\n",
+    "\n",
+    "Run this example online by clicking `🚀` -> `Binder` on the top bar!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Preparation\n",
+    "\n",
+    "This part prepares the `web3` instance and key `private_key` to use in the following part of this documentation."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# claim 1000 CFX\n",
+    "from pprint import pprint\n",
+    "from conflux_web3 import Web3\n",
+    "\n",
+    "w3_ = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+    "\n",
+    "acct = w3_.account.create()\n",
+    "\n",
+    "w3_.cfx.default_account = acct\n",
+    "\n",
+    "faucet = w3_.cfx.contract(name=\"Faucet\")\n",
+    "tx_receipt = faucet.functions.claimCfx().transact().executed()\n",
+    "\n",
+    "# we use a new w3 object for the following part\n",
+    "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+    "private_key: str = acct._private_key.hex()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Account and Address\n",
+    "\n",
+    "In web3, typically, owning an account means knowing a **secret**, or **private key**. Although private key should be kept secret, ***address*** can be revealed. Address is a string one-way derived from the private key, and identifies an account. Different blockchain might adopt different approach to derive an address, e.g. bitcoin and ethereum use different methods to generate account addresses .In Conflux, addresses are encoded in base32 format defined by [CIP-37](https://github.com/Conflux-Chain/CIPs/blob/master/CIPs/cip-37.md).\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### `LocalAccount` Object\n",
+    "\n",
+    "`w3.account` is a factory which is used to produce `LocalAccount` objects (e.g. `random_account`). which can be used to sign transactions.\n",
+    "\n",
+    "**NOTE: it is quite tedious to manually sign a transaction. Refer to [wallet](#wallet) part to see how to sign and send a transaction by using wallet. Or you can refer to [construct_transaction_from_scratch](./11-construct_transaction_from_scratch.ipynb) to see how to manually sign transactions correctly.**\n",
+    "\n",
+    "> More documents: `w3.account` is a `cfx_account.Account` object inherited from `eth_account.Account`, and most of its apis are consistent with [eth_account](https://eth-account.readthedocs.io/en/stable/eth_account.html)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "account address: cfxtest:aasanuf6gvzf5wdv8v496uc9segtp6j012s9sy0kj3\n",
+      "account private key: 0xce965554c2c9c99fed07bb74e33d63e5db7d9f965c5994c6bbbaa8efce49227e\n",
+      "signed raw tx: 0xf867e301843b9aca00825208940000000000000000000000000000000000000000018064018080a00dd4797d0b0eb7f9aaec4495bce49a80336e30f6fef09a5691374ff10ec64218a057a6218d2020a8a59a81b90145863188c788a4dd0a5afcc976942b6721712422\n"
+     ]
+    }
+   ],
+   "source": [
+    "random_account = w3.account.from_key(private_key)\n",
+    "print(f\"account address: {random_account.address}\")\n",
+    "print(f\"account private key: {private_key}\")\n",
+    "\n",
+    "transaction = {\n",
+    "    'to': w3.address.zero_address(),\n",
+    "    'nonce': 1,\n",
+    "    'value': 1,\n",
+    "    'gas': 21000,\n",
+    "    'gasPrice': 10**9,\n",
+    "    'storageLimit': 0,\n",
+    "    'epochHeight': 100,\n",
+    "    'chainId': 1\n",
+    "}\n",
+    "print(f\"signed raw tx: {random_account.sign_transaction(transaction).rawTransaction.hex()}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Conflux Addresses\n",
+    "\n",
+    "In Conflux, addresses are encoded in base32 format following [CIP-37](https://github.com/Conflux-Chain/CIPs/blob/master/CIPs/cip-37.md). You can infer which network the address belongs to simply from the address literal."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# \"cfxtest\" marks an address in testnet\n",
+    "assert random_account.address.startswith(\"cfxtest:\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The addresses returned by SDK are all wrapped by class `Base32Address`. The class provides convenient methods to operate base32 addresses, but you can also use `Base32Address` object as trivial python `str` object. \n",
+    "Refer to [Base32Address documentation](https://conflux-fans.github.io/cfx-address/cfx_address.html#module-cfx_address.address) for more information."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the type of addr: <class 'cfx_address.address.Base32Address'>\n",
+      "cfxtest:aatp533cg7d0agbd87kz48nj1mpnkca8be1rz695j4\n",
+      "['user',\n",
+      " 1,\n",
+      " '0x1ecde7223747601823f7535d7968ba98b4881e09',\n",
+      " 'CFXTEST:TYPE.USER:AATP533CG7D0AGBD87KZ48NJ1MPNKCA8BE1RZ695J4',\n",
+      " 'cfxtest:aat...95j4',\n",
+      " '0x349f086998cF4a0C5a00b853a0E93239D81A97f6',\n",
+      " '0x1ECdE7223747601823f7535d7968Ba98b4881E09']\n"
+     ]
+    }
+   ],
+   "source": [
+    "addr = random_account.address\n",
+    "print(f\"the type of addr: {type(addr)}\")\n",
+    "# a Base32Address object is also a `str`\n",
+    "assert isinstance(addr, str)\n",
+    "\n",
+    "# encode a base32 address from hex address and network_id\n",
+    "# it is also supported to use `w3.address(\"cfxtest:aatp533cg7d0agbd87kz48nj1mpnkca8be1rz695j4\")`\n",
+    "address = w3.address(\"0x1ecde7223747601823f7535d7968ba98b4881e09\", network_id=1)\n",
+    "print(address)\n",
+    "pprint([\n",
+    "    address.address_type,\n",
+    "    address.network_id,\n",
+    "    address.hex_address,\n",
+    "    address.verbose_address,\n",
+    "    address.abbr,\n",
+    "    address.mapped_evm_space_address,\n",
+    "    address.eth_checksum_address,\n",
+    "])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Wallet\n",
+    "\n",
+    "We use a `wallet` middleware to help us sign and send transactions. `w3.wallet` will sign the unsigned transaction sent via `w3.cfx.send_transaction` if the transaction is `from` an account in `w3.wallet`.\n",
+    "\n",
+    "> `wallet` middleware follows the behaviour of `web3.py`'s `construct_sign_and_send_raw_middleware`, but provides more feature. For example, we can use `w3.wallet.add_account`, `w3.wallet.add_accounts`, `w3.wallet.pop` to add or remove accounts dynamically. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "AttributeDict({'transactionHash': HexBytes('0x1f090e610c1a90835a201d28a13a40f364e6f85f7fb9a60c241b9f64e4f0d0e1'),\n",
+       " 'index': 0,\n",
+       " 'blockHash': HexBytes('0x1d51233f0a40914ac50ec6d61d123cd9489b156821e1403e9afdfeb9a1791e70'),\n",
+       " 'epochNumber': 99718058,\n",
+       " 'from': 'cfxtest:aasanuf6gvzf5wdv8v496uc9segtp6j012s9sy0kj3',\n",
+       " 'to': 'cfxtest:aasanuf6gvzf5wdv8v496uc9segtp6j012s9sy0kj3',\n",
+       " 'gasUsed': 21000,\n",
+       " 'gasFee': 21000000000000 Drip,\n",
+       " 'contractCreated': None,\n",
+       " 'logs': [],\n",
+       " 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),\n",
+       " 'stateRoot': HexBytes('0x45accf3716207c1f371fe23e90cdcef4c6ccc0f02d6ea6b95bb4892406888e28'),\n",
+       " 'outcomeStatus': 0,\n",
+       " 'txExecErrorMsg': None,\n",
+       " 'gasCoveredBySponsor': False,\n",
+       " 'storageCoveredBySponsor': False,\n",
+       " 'storageCollateralized': 0,\n",
+       " 'storageReleased': []})"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# wallet serves as a middleware for conflux_web3 and contains a collection of LocalAccount\n",
+    "assert w3.wallet is w3.middleware_onion[\"wallet\"]\n",
+    "\n",
+    "w3.wallet.add_account(random_account)\n",
+    "\n",
+    "assert random_account.address in w3.wallet\n",
+    "w3.cfx.send_transaction({\n",
+    "    \"from\": random_account.address,\n",
+    "    \"to\": random_account.address,\n",
+    "    \"value\": 10**18\n",
+    "}).executed()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### use `w3.cfx.default_account` to add account to wallet\n",
+    "\n",
+    "If `w3.cfx.default_account` is set, `from` field of the sent transaction will be set to `w3.cfx.default_account` if empty. \n",
+    "\n",
+    "`w3.cfx.default_account` is a `Base32Address`, but can be set using a `LocalAccount` object. In this case, the provided `LocalAccount` object will be added to the wallet at the same time. \n",
+    "\n",
+    "```python\n",
+    "w3.cfx.default_account = random_account\n",
+    "```\n",
+    "\n",
+    "is equivalent to\n",
+    "\n",
+    "```python\n",
+    "w3.cfx.default_account = random_account.address\n",
+    "w3.wallet.add_account(random_account)\n",
+    "```"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.9.13 ('sdk')",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.13"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/en/examples/03-trace_transaction_status.ipynb b/docs/en/examples/03-trace_transaction_status.ipynb
new file mode 100644
index 0000000..d881931
--- /dev/null
+++ b/docs/en/examples/03-trace_transaction_status.ipynb
@@ -0,0 +1,124 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Trace Transaction Status\n",
+    "\n",
+    "Run this example online by clicking `🚀` -> `Binder` on the top bar!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Preparation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# preparation: init w3 instance and prepare transaction hash object tx_hash\n",
+    "from conflux_web3 import Web3\n",
+    "\n",
+    "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+    "acct = w3.account.create()\n",
+    "w3.cfx.default_account = acct\n",
+    "faucet = w3.cfx.contract(name=\"Faucet\")\n",
+    "\n",
+    "# get a tx_hash\n",
+    "tx_hash = faucet.functions.claimCfx().transact()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Status of a Transaction in Conflux\n",
+    "\n",
+    "In Conflux, transaction will witness several periods after it is sent:\n",
+    "\n",
+    "1. `pending`: the transaction is sent, but not contained in any block\n",
+    "2. `mined`: the transaction is already contained in a block, but might not be executed\n",
+    "3. `executed`: the transaction is executed\n",
+    "4. `confirmed`: the transaction is confirmed under PoW chain confirmation rule, which means it is extremly unlikely to be reverted unless the PoW chain is under attack.\n",
+    "5. `finalized`: the transaction is **finalized** by PoS chain, which means the transaction is impossible to revert, but it would take 5~10 minutes before a transaction is finalized."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Trace the Status of a Transaction\n",
+    "\n",
+    "We can use `w3.cfx.wait_till_transaction_mined`, `w3.cfx.wait_till_transaction_executed`, `w3.cfx.wait_till_transaction_confirmed`, `w3.cfx.wait_till_transaction_finalized` to wait until transaction reached specific status."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "w3.cfx.wait_till_transaction_mined(tx_hash)\n",
+    "w3.cfx.wait_till_transaction_executed(tx_hash)\n",
+    "w3.cfx.wait_till_transaction_confirmed(tx_hash)\n",
+    "if False: # 5~10 minutes is needed\n",
+    "    w3.cfx.wait_till_transaction_finalized(tx_hash)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Syntactic Sugar\n",
+    "\n",
+    "We often need to trace the status of the sent transaction, so SDK wraps the returned hex transaction hash from `send_transacation` or `send_raw_transaction` to visit the above APIs easily."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "tx_hash.mined()\n",
+    "tx_hash.executed()\n",
+    "tx_hash.confirmed()\n",
+    "if False:\n",
+    "    tx_hash.finalized()"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.9.13 ('sdk')",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.13"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/en/examples/04-query_data_via_RPC.ipynb b/docs/en/examples/04-query_data_via_RPC.ipynb
new file mode 100644
index 0000000..6d21744
--- /dev/null
+++ b/docs/en/examples/04-query_data_via_RPC.ipynb
@@ -0,0 +1,407 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Query Data via RPC\n",
+    "\n",
+    "Run this example online by clicking `🚀` -> `Binder` on the top bar!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Preparation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# preparation: import and init w3 instance\n",
+    "from conflux_web3 import Web3\n",
+    "\n",
+    "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+    "\n",
+    "# prepare constants\n",
+    "transaction_hash = \"0x10a721e2654523a7ff682c1c8d3f868a9fdf78a3be1858bbe1f06147128d6d94\"\n",
+    "epoch = 98943500"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Query Data via RPC\n",
+    "\n",
+    "We can use SDK to invoke RPC calls to query blockchain status, transaction data, block data, and so on. The full RPC document can be found [here](https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc/#json-rpc-methods)."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Query Blockchain Status"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "AttributeDict({'bestHash': HexBytes('0x39c4f587683f82827b5d039e06bcf19ce0ac64a5314d0b7d280d789b8ff318a5'),\n",
+       " 'chainId': 1,\n",
+       " 'ethereumSpaceChainId': 71,\n",
+       " 'networkId': 1,\n",
+       " 'epochNumber': 99720387,\n",
+       " 'blockNumber': 127806498,\n",
+       " 'pendingTxNumber': 0,\n",
+       " 'latestCheckpoint': 99640000,\n",
+       " 'latestConfirmed': 99720322,\n",
+       " 'latestState': 99720383,\n",
+       " 'latestFinalized': 99719940})"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# get_status provides an overview of blockchain status\n",
+    "w3.cfx.get_status()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Several RPC methods can accept an **epoch number parameter**. The epoch number parameter can be:\n",
+    "* an int\n",
+    "* or an epoch tag in string `latest_mined`, `latest_state`, `latest_confirmed` or `latest_finalized`\n",
+    "\n",
+    "The concept of `epoch number` in Conflux is somewhat analogous to the concept of `block number` in other blockchains, but one epoch contains one or more blocks. Refer to https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc#the-default-epochnumber-parameter for more information."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "latest_mined epoch number: 99720387\n",
+      "latest_state epoch numebr: 99720383\n"
+     ]
+    }
+   ],
+   "source": [
+    "# latest_mined epoch number\n",
+    "print(f\"latest_mined epoch number: {w3.cfx.epoch_number}\")\n",
+    "# get epoch number by tag\n",
+    "print(f'latest_state epoch numebr: {w3.cfx.epoch_number_by_tag(\"latest_state\")}')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Query Transaction"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "AttributeDict({'hash': HexBytes('0x10a721e2654523a7ff682c1c8d3f868a9fdf78a3be1858bbe1f06147128d6d94'),\n",
+       " 'nonce': 2,\n",
+       " 'blockHash': HexBytes('0xf0ac5f8d757a7415876e322a245d5eff76349b656b3eadb10d5e09a4a3f7d59d'),\n",
+       " 'transactionIndex': 0,\n",
+       " 'from': 'cfxtest:aan2vyszrgz3sr3tug73ywb8k128y5wa7yhpjm1hn1',\n",
+       " 'to': 'cfxtest:acejjfa80vj06j2jgtz9pngkv423fhkuxj786kjr61',\n",
+       " 'value': 0 Drip,\n",
+       " 'gasPrice': 1000000000 Drip,\n",
+       " 'gas': 41633,\n",
+       " 'contractCreated': None,\n",
+       " 'data': HexBytes('0x5f3cc9f7'),\n",
+       " 'storageLimit': 0,\n",
+       " 'epochHeight': 87083312,\n",
+       " 'chainId': 1,\n",
+       " 'status': 0,\n",
+       " 'v': 1,\n",
+       " 'r': HexBytes('0x17b30481d63a49223092215a2aa503938519df5cac0d20cbff7ebf50569776cd'),\n",
+       " 's': HexBytes('0x5fc96a1e383879cf66c09d106b2df4907c674a263c9a7bba602078c90b0038b1')})"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# get transaction data by hash\n",
+    "# this RPC is usable after transaction is sent\n",
+    "w3.cfx.get_transaction_by_hash(transaction_hash)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "AttributeDict({'transactionHash': HexBytes('0x10a721e2654523a7ff682c1c8d3f868a9fdf78a3be1858bbe1f06147128d6d94'),\n",
+       " 'index': 0,\n",
+       " 'blockHash': HexBytes('0xf0ac5f8d757a7415876e322a245d5eff76349b656b3eadb10d5e09a4a3f7d59d'),\n",
+       " 'epochNumber': 87083316,\n",
+       " 'from': 'cfxtest:aan2vyszrgz3sr3tug73ywb8k128y5wa7yhpjm1hn1',\n",
+       " 'to': 'cfxtest:acejjfa80vj06j2jgtz9pngkv423fhkuxj786kjr61',\n",
+       " 'gasUsed': 35480,\n",
+       " 'gasFee': 35480000000000 Drip,\n",
+       " 'contractCreated': None,\n",
+       " 'logs': [],\n",
+       " 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),\n",
+       " 'stateRoot': HexBytes('0xdbfbe3f9b08aa5fb04ca5218ebc245b3941cce9d30409ab854456f3070b454f6'),\n",
+       " 'outcomeStatus': 0,\n",
+       " 'txExecErrorMsg': None,\n",
+       " 'gasCoveredBySponsor': True,\n",
+       " 'storageCoveredBySponsor': True,\n",
+       " 'storageCollateralized': 0,\n",
+       " 'storageReleased': []})"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# get transaction receipt by hash\n",
+    "# the transaction receipt is available after it is executed\n",
+    "w3.cfx.get_transaction_receipt(transaction_hash)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Query Block\n",
+    "\n",
+    "In Conflux, each epoch contains 1 or more blocks, and one of these blocks is called `pivot block`. The pivot block determines which blocks are in the each epoch."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "blocks in epoch 98943500:\n",
+      "[HexBytes('0xae622377e139608a9202504df4bf20570c4741370d36f668952ae91c57c5da69'), HexBytes('0x104a3549108c7c83a36c65d188e842f6deb9a770d3ca749a222fce628846c04b')]\n",
+      "pivot block hash of epoch 98943500: 0x104a3549108c7c83a36c65d188e842f6deb9a770d3ca749a222fce628846c04b\n"
+     ]
+    }
+   ],
+   "source": [
+    "# query blocks in specific epoch\n",
+    "block_hashes = w3.cfx.get_blocks_by_epoch(epoch)\n",
+    "print(f\"blocks in epoch {epoch}:\\n{block_hashes}\")\n",
+    "# the last element of block_hashes is the pivot block\n",
+    "print(f\"pivot block hash of epoch {epoch}: {block_hashes[-1].hex()}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# if the block is a pivot block, we can get it using epoch number\n",
+    "# and of cource, we can query a block using its hash\n",
+    "assert w3.cfx.get_block_by_epoch_number(epoch) == w3.cfx.get_block_by_hash(block_hashes[-1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "AttributeDict({'hash': HexBytes('0x71b6406338ecbd2f40d12bc2b91304c3567fbb04a165efe299301a9c3acab46a'),\n",
+       " 'parentHash': HexBytes('0x37ab44387ae132e3eea6c666bfb5cd58af50d0b172ab21b0be5ff85073bc5592'),\n",
+       " 'height': 99720384,\n",
+       " 'miner': 'cfxtest:aanpu16mtgc7dke5xhuktyfyef8f00pz8a2z5mc14g',\n",
+       " 'deferredStateRoot': HexBytes('0x413d1a352ecec910bc7e7c5dabba9b8e83e36395ef6485db7881f46e723660f5'),\n",
+       " 'deferredReceiptsRoot': HexBytes('0x09f8709ea9f344a810811a373b30861568f5686e649d6177fd92ea2db7477508'),\n",
+       " 'deferredLogsBloomHash': HexBytes('0xd397b3b043d87fcd6fad1291ff0bfd16401c274896d8c63a923727f077b8e0b5'),\n",
+       " 'blame': 0,\n",
+       " 'transactionsRoot': HexBytes('0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'),\n",
+       " 'epochNumber': 99720384,\n",
+       " 'blockNumber': 127806494,\n",
+       " 'gasLimit': 30000000,\n",
+       " 'gasUsed': 0,\n",
+       " 'timestamp': 1668507784,\n",
+       " 'difficulty': 58688104,\n",
+       " 'powQuality': HexBytes('0x039fc293'),\n",
+       " 'refereeHashes': [],\n",
+       " 'adaptive': False,\n",
+       " 'nonce': HexBytes('0x24d32abf7e0f4c67'),\n",
+       " 'size': 0,\n",
+       " 'custom': [HexBytes('0x02')],\n",
+       " 'posReference': HexBytes('0x11f970d63eb9eaf581315b67f2258c0c59ad13572be29a2187c900ac576d3003'),\n",
+       " 'transactions': []})"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# get_block_by_epoch_number also accepts an epoch number tag\n",
+    "w3.cfx.get_block_by_epoch_number(\"latest_state\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "AttributeDict({'hash': HexBytes('0xf0ac5f8d757a7415876e322a245d5eff76349b656b3eadb10d5e09a4a3f7d59d'),\n",
+       " 'parentHash': HexBytes('0xeaf2f6227c068ae27cb847657af7eb7e3cfd6696f5a795d2f38159074d20a8c9'),\n",
+       " 'height': 87083316,\n",
+       " 'miner': 'cfxtest:aaskvgxcfej371g4ecepx9an78ngrke5ay9f8jtbgg',\n",
+       " 'deferredStateRoot': HexBytes('0xa26347f02f312db0fba655c29b9fa853e8e6242449a67added74c62679122f62'),\n",
+       " 'deferredReceiptsRoot': HexBytes('0x09f8709ea9f344a810811a373b30861568f5686e649d6177fd92ea2db7477508'),\n",
+       " 'deferredLogsBloomHash': HexBytes('0xd397b3b043d87fcd6fad1291ff0bfd16401c274896d8c63a923727f077b8e0b5'),\n",
+       " 'blame': 0,\n",
+       " 'transactionsRoot': HexBytes('0xdc62bb0e7115a9727688811f4e090efdfd203a516953ff7829e21dea29e1f166'),\n",
+       " 'epochNumber': 87083316,\n",
+       " 'blockNumber': 110979562,\n",
+       " 'gasLimit': 30000000,\n",
+       " 'gasUsed': 35480,\n",
+       " 'timestamp': 1660093852,\n",
+       " 'difficulty': 54757256,\n",
+       " 'powQuality': HexBytes('0x0365f39d'),\n",
+       " 'refereeHashes': [],\n",
+       " 'adaptive': False,\n",
+       " 'nonce': HexBytes('0xe72421314ac723e6'),\n",
+       " 'size': 113,\n",
+       " 'custom': [HexBytes('0x01')],\n",
+       " 'posReference': HexBytes('0xe7c39fb3312519d78e5606ef4d9040b558b852e7af439a8fcad1632de776cc06'),\n",
+       " 'transactions': [HexBytes('0x10a721e2654523a7ff682c1c8d3f868a9fdf78a3be1858bbe1f06147128d6d94')]})"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# get a block by block number is also viable \n",
+    "w3.cfx.get_block_by_block_number(110979562)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Other RPCs\n",
+    "\n",
+    "Besides above, `conflux-web3` supports all rpc methods under cfx Namespace. You can visit https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc#json-rpc-methods for more information.\n",
+    "\n",
+    "Here are some examples:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1000000000 Drip"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "w3.cfx.gas_price"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5964"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(w3.cfx.get_code(\"cfxtest:acejjfa80vj06j2jgtz9pngkv423fhkuxj786kjr61\"))"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.9.13 ('sdk')",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.13"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/en/examples/05-interact_with_contracts_and_process_logs.ipynb b/docs/en/examples/05-interact_with_contracts_and_process_logs.ipynb
new file mode 100644
index 0000000..7c8e57a
--- /dev/null
+++ b/docs/en/examples/05-interact_with_contracts_and_process_logs.ipynb
@@ -0,0 +1,406 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Interact with Contracts and Process Logs\n",
+    "\n",
+    "Run this example online by clicking `🚀` -> `Binder` on the top bar!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Preparation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1000 CFX"
+      ]
+     },
+     "execution_count": 1,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import pprint\n",
+    "from conflux_web3 import Web3\n",
+    "\n",
+    "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+    "account = w3.account.create()\n",
+    "w3.cfx.default_account = account\n",
+    "\n",
+    "faucet = w3.cfx.contract(name=\"Faucet\")\n",
+    "faucet.functions.claimCfx().transact().executed()\n",
+    "w3.cfx.get_balance(account.address).to(\"CFX\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Interact with Contracts\n",
+    "\n",
+    "In the [Preparation](#preparation) part, we have already shown how to interact with a contract. A contract instance can be initialized from `w3.cfx.contract`, and with the `name` paramter, some frequently used contract instance can be created. However, it is quite often that we need to compile and deploy contracts written by ourselves. This part will show how to compile and deploy a contract, and how to interact with the newly-deployed one."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Compile and Deploy a Contract\n",
+    "\n",
+    "A contract is a program running on the blockchain. And we need to firstly **deploy** a contract to the blockchain if we want to interact with a program written by ourselves.\n",
+    "\n",
+    "Here is a simple smart contract:\n",
+    "\n",
+    "``` solidity\n",
+    "// SPDX-License-Identifier: MIT\n",
+    "// modified from https://solidity-by-example.org/first-app/\n",
+    "pragma solidity ^0.8.13;\n",
+    "\n",
+    "contract Counter {\n",
+    "    uint public count;\n",
+    "\n",
+    "    event Change(address indexed sender, uint new_value);\n",
+    "\n",
+    "    constructor(uint init_value) {\n",
+    "        count = init_value;\n",
+    "    }\n",
+    "\n",
+    "    // Function to get the current count\n",
+    "    function get() public view returns (uint) {\n",
+    "        return count;\n",
+    "    }\n",
+    "\n",
+    "    // Function to increment count by 1\n",
+    "    function inc() public {\n",
+    "        count += 1;\n",
+    "        emit Change(msg.sender, count);\n",
+    "    }\n",
+    "}\n",
+    "```\n",
+    "\n",
+    "After this contract is compiled and deployed, you can:\n",
+    "\n",
+    "* read the value of `count` from interface `get`\n",
+    "* add the variable `count` by invoking `inc`\n",
+    "\n",
+    "Besides, the contract will emit an event `Change` after `inc` is executed, we can know what has happened on chain by analyzing the logs.\n",
+    "\n",
+    "Now we are going to compile the contract. You might need to run `pip install py-solc-x` if you are running the the codes in your local environment."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# py-solc-x is already installed in the test environment\n",
+    "from solcx import install_solc, compile_source\n",
+    "source_code = r\"\"\"\n",
+    "// SPDX-License-Identifier: MIT\n",
+    "// modified from https://solidity-by-example.org/first-app/\n",
+    "pragma solidity ^0.8.13;\n",
+    "\n",
+    "contract Counter {\n",
+    "    uint public count;\n",
+    "\n",
+    "    event Change(address indexed sender, uint new_value);\n",
+    "\n",
+    "    constructor(uint init_value) {\n",
+    "        count = init_value;\n",
+    "    }\n",
+    "\n",
+    "    // Function to get the current count\n",
+    "    function get() public view returns (uint) {\n",
+    "        return count;\n",
+    "    }\n",
+    "\n",
+    "    // Function to increment count by 1\n",
+    "    function inc() public {\n",
+    "        count += 1;\n",
+    "        emit Change(msg.sender, count);\n",
+    "    }\n",
+    "}\n",
+    "\"\"\"\n",
+    "metadata = compile_source(\n",
+    "    source_code,\n",
+    "    output_values=['abi', 'bin'],\n",
+    "    solc_version=install_solc(version=\"0.8.13\")\n",
+    ").popitem()[1]\n",
+    "# \"abi\" defines the interface, \"bin\" is the contract bytecode\n",
+    "assert \"abi\" in metadata and \"bin\" in metadata"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "contract deployed: cfxtest:acaxdwzd845fj0sgg97aky6r78tw2kfdzezfes8w01\n"
+     ]
+    }
+   ],
+   "source": [
+    "# init contract from metadata, bytecode is needed to deploy a contract\n",
+    "factory = w3.cfx.contract(abi=metadata[\"abi\"], bytecode=metadata[\"bin\"])\n",
+    "\n",
+    "# deploy the contract\n",
+    "tx_receipt = factory.constructor(init_value=0).transact().executed()\n",
+    "contract_address = tx_receipt[\"contractCreated\"]\n",
+    "assert contract_address is not None\n",
+    "print(f\"contract deployed: {contract_address}\")\n",
+    "\n",
+    "# init a contract with address param, now we can interact with it\n",
+    "deployed_contract = w3.cfx.contract(address=contract_address, abi=metadata[\"abi\"])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Interact with the Deployed Contract"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "counter added to 1\n"
+     ]
+    }
+   ],
+   "source": [
+    "tx_hash = deployed_contract.functions.inc().transact()\n",
+    "inc_receipt = w3.cfx.wait_for_transaction_receipt(tx_hash)\n",
+    "\n",
+    "# \"call\" a contract means virtually execute the transaction without actually sending a transaction\n",
+    "# 2 ways to call, either is ok\n",
+    "current_counter = deployed_contract.functions.get().call()\n",
+    "current_counter_ = deployed_contract.caller().get()\n",
+    "assert current_counter == current_counter_ == 1\n",
+    "print(\"counter added to 1\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Process Logs\n",
+    "\n",
+    "We can check transaction logs to know what has happened after transaction execution. However, raw logs are encoded in hex and is hard to read."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "raw log: \n",
+      "{'address': 'cfxtest:acaxdwzd845fj0sgg97aky6r78tw2kfdzezfes8w01',\n",
+      " 'blockHash': HexBytes('0x46af0e6efae89cc3d4c179359992dc41a6f7bc11ce899d74e5ff372d4119f625'),\n",
+      " 'data': HexBytes('0x0000000000000000000000000000000000000000000000000000000000000001'),\n",
+      " 'epochNumber': 99722005,\n",
+      " 'logIndex': 0,\n",
+      " 'topics': [HexBytes('0x05b5d46649ab2015d3a08705cbaa391e094d9594c393ce89d3afffe960744da1'),\n",
+      "            HexBytes('0x00000000000000000000000016e78b2b41c9d216eba6008c244e5338096e9278')],\n",
+      " 'transactionHash': HexBytes('0x799bcf4d207d6adf2d515ca6ca47a43617fc27e2a69d1fe0d4fe3083fe053a57'),\n",
+      " 'transactionIndex': 0,\n",
+      " 'transactionLogIndex': 0}\n"
+     ]
+    }
+   ],
+   "source": [
+    "# get_logs parameter definitions: https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc#cfx_getlogs\n",
+    "fromEpoch = inc_receipt[\"epochNumber\"]\n",
+    "# use get_logs to get raw logs\n",
+    "logs = w3.cfx.get_logs(fromEpoch=fromEpoch, address=contract_address)\n",
+    "print(\"raw log: \")\n",
+    "pprint.pprint(dict(logs[0]))\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "In the following parts, we present several approaches to process and filter logs.\n",
+    "\n",
+    "We can use `contract.event` to process logs. The `args` field of processed log presents the information we need."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{'address': 'cfxtest:acaxdwzd845fj0sgg97aky6r78tw2kfdzezfes8w01',\n",
+      " 'args': AttributeDict({'sender': 'CFXTEST:TYPE.USER:AANSTC3NJHE7EF1NY2AJ2KCSMP6AW5YWTA3MMFYGZX', 'new_value': 1}),\n",
+      " 'blockHash': HexBytes('0x46af0e6efae89cc3d4c179359992dc41a6f7bc11ce899d74e5ff372d4119f625'),\n",
+      " 'epochNumber': 99722005,\n",
+      " 'event': 'Change',\n",
+      " 'logIndex': None,\n",
+      " 'transactionHash': HexBytes('0x799bcf4d207d6adf2d515ca6ca47a43617fc27e2a69d1fe0d4fe3083fe053a57'),\n",
+      " 'transactionIndex': 0,\n",
+      " 'transactionLogIndex': 0}\n"
+     ]
+    }
+   ],
+   "source": [
+    "processed_logs = deployed_contract.events.Change.process_receipt(inc_receipt)\n",
+    "processed_log = processed_logs[0]\n",
+    "assert processed_log[\"args\"][\"sender\"] == w3.cfx.default_account\n",
+    "assert processed_log[\"args\"][\"new_value\"] == 1\n",
+    "\n",
+    "# for log processed from transaction receipt, field \"logIndex\" is None\n",
+    "pprint.pprint(dict(processed_log))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Besides, we can use `contract.events` to encode contract topics to filter logs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "log filtered by topics:\n",
+      "{'address': 'cfxtest:acaxdwzd845fj0sgg97aky6r78tw2kfdzezfes8w01',\n",
+      " 'blockHash': HexBytes('0x46af0e6efae89cc3d4c179359992dc41a6f7bc11ce899d74e5ff372d4119f625'),\n",
+      " 'data': HexBytes('0x0000000000000000000000000000000000000000000000000000000000000001'),\n",
+      " 'epochNumber': 99722005,\n",
+      " 'logIndex': 0,\n",
+      " 'topics': [HexBytes('0x05b5d46649ab2015d3a08705cbaa391e094d9594c393ce89d3afffe960744da1'),\n",
+      "            HexBytes('0x00000000000000000000000016e78b2b41c9d216eba6008c244e5338096e9278')],\n",
+      " 'transactionHash': HexBytes('0x799bcf4d207d6adf2d515ca6ca47a43617fc27e2a69d1fe0d4fe3083fe053a57'),\n",
+      " 'transactionIndex': 0,\n",
+      " 'transactionLogIndex': 0}\n"
+     ]
+    }
+   ],
+   "source": [
+    "# generate topics to use getLogs\n",
+    "filter_topics = deployed_contract.events.Change.get_filter_topics(\n",
+    "    sender=w3.cfx.default_account\n",
+    ")\n",
+    "new_logs = w3.cfx.get_logs(fromEpoch=fromEpoch, topics=filter_topics)\n",
+    "print(\"log filtered by topics:\")\n",
+    "pprint.pprint(dict(new_logs[0]))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Or we can use `get_logs` interface from `contract.events`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "processed log from contract event get_logs\n",
+      "{'address': 'cfxtest:acaxdwzd845fj0sgg97aky6r78tw2kfdzezfes8w01',\n",
+      " 'args': AttributeDict({'sender': 'CFXTEST:TYPE.USER:AANSTC3NJHE7EF1NY2AJ2KCSMP6AW5YWTA3MMFYGZX', 'new_value': 1}),\n",
+      " 'blockHash': HexBytes('0x46af0e6efae89cc3d4c179359992dc41a6f7bc11ce899d74e5ff372d4119f625'),\n",
+      " 'epochNumber': 99722005,\n",
+      " 'event': 'Change',\n",
+      " 'logIndex': 0,\n",
+      " 'transactionHash': HexBytes('0x799bcf4d207d6adf2d515ca6ca47a43617fc27e2a69d1fe0d4fe3083fe053a57'),\n",
+      " 'transactionIndex': 0,\n",
+      " 'transactionLogIndex': 0}\n"
+     ]
+    }
+   ],
+   "source": [
+    "# event get_logs will return processed logs\n",
+    "new_processed_logs = deployed_contract.events.Change.get_logs(\n",
+    "    argument_filters={\n",
+    "        \"sender\": w3.cfx.default_account\n",
+    "    },\n",
+    "    fromEpoch=fromEpoch\n",
+    ")\n",
+    "print(\"processed log from contract event get_logs\")\n",
+    "pprint.pprint(dict(new_processed_logs[0]))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "`conflux_web3`'s apis are consistent with `web3.py`'s apis. You can also try the examples from `web3.py`'s documentation.\n",
+    "* https://web3py.readthedocs.io/en/stable/contracts.html\n",
+    "* https://web3py.readthedocs.io/en/stable/examples.html#working-with-contracts\n",
+    "* https://web3py.readthedocs.io/en/stable/examples.html#working-with-an-erc20-token-contract"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.9.13 ('sdk')",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.13"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/en/examples/10-send_raw_transaction.ipynb b/docs/en/examples/10-send_raw_transaction.ipynb
new file mode 100644
index 0000000..8708748
--- /dev/null
+++ b/docs/en/examples/10-send_raw_transaction.ipynb
@@ -0,0 +1,237 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Send a Transaction Using `send_raw_transaction`\n",
+    "\n",
+    "Run this example online by clicking `🚀` -> `Binder` on the top bar!\n",
+    "\n",
+    "This example shows how to sign a transaction without using `w3.wallet` and how to send a transaction using `send_raw_transaction`. This method is more flexible but simultaneously more complex to use. Refer to [quickstart](./01-quickstart.ipynb) if you only want to get acquiantance to how to send a transaction. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import pprint\n",
+    "from conflux_web3 import Web3\n",
+    "from conflux_web3.utils import fill_transaction_defaults\n",
+    "\n",
+    "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+    "account = w3.account.from_key(\"0x....\") # replace your secret key with \"0x....\""
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Manully Send a Transaction\n",
+    "\n",
+    "Basiclly, we follow the workflow of 4 steps to send a transaction:\n",
+    "\n",
+    "* build transaction\n",
+    "* sign transaction\n",
+    "* send transaction to the blockchain node(s)\n",
+    "* wait for transaction execution result\n",
+    "\n",
+    "If an account is added to the `w3.wallet`, SDK will help to finish the first 3 steps in a row,\n",
+    "otherwise you will need to do the first 3 steps manually."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Build a Simple Transaction\n",
+    "Only necessary parameters are provided here, and other params are filled by `fill_transaction_defaults`.\n",
+    "Refer to [constuct_transaction_from_scratch](./11-constuct_transaction_from_scratch.ipynb) to see how to manually fill each field of a transaction."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "built_trivial_tx = fill_transaction_defaults(w3, {\n",
+    "    'from': account.address,\n",
+    "    'to': w3.account.create().address,\n",
+    "    'value': 100,\n",
+    "})"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Sign a Transaction"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "signed_tx = account.sign_transaction(built_trivial_tx)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Send the Transaction"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "h = w3.cfx.send_raw_transaction(signed_tx.rawTransaction)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Wait for Transaction Execution"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "tx_receipt = h.executed()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Interact with a Contract"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "deployed contract address: cfxtest:acfgtrw53v4ju9jaydmr9yyf9xyvfxpe0e8ny2fd4d\n"
+     ]
+    }
+   ],
+   "source": [
+    "# if you want to get contract object from metadata file, use\n",
+    "# >>> erc20_metadata = json.load(open(\"path/to/ERC20metadata.json\"))\n",
+    "# >>> erc20 = web3.cfx.contract(bytecode=erc20_metadata[\"bytecode\"], abi=erc20_metadata[\"abi\"])\n",
+    "erc20 = w3.cfx.contract(name=\"ERC20\")\n",
+    "\n",
+    "# build a transaction\n",
+    "# parameters such as 'from'/'gasPrice'/... can be specified in `build_transaction`\n",
+    "built_constuct_tx = erc20.constructor(name=\"Coin\", symbol=\"C\", initialSupply=10**18).build_transaction({\n",
+    "    'from': account.address,\n",
+    "})\n",
+    "# sign the transaction\n",
+    "construct_tx = account.sign_transaction(built_constuct_tx)\n",
+    "# send & wait for execution result\n",
+    "contract_address = w3.cfx.send_raw_transaction(construct_tx.rawTransaction).executed()['contractCreated']\n",
+    "print(f\"deployed contract address: {contract_address}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "erc20 transfer receipt: \n",
+      "{'blockHash': HexBytes('0x9b8a0a0e5eb33d67b2c85d4e951b0251e1b972cd00f7c18c53ecacb7fd7edfd3'),\n",
+      " 'contractCreated': None,\n",
+      " 'epochNumber': 99051304,\n",
+      " 'from': 'cfxtest:aanhtnrex2nj56kkbws4yx0jeab34ae16pcap53w13',\n",
+      " 'gasCoveredBySponsor': False,\n",
+      " 'gasFee': 37063000000000 Drip,\n",
+      " 'gasUsed': 37063,\n",
+      " 'index': 0,\n",
+      " 'logs': [AttributeDict({'address': 'cfxtest:acfgtrw53v4ju9jaydmr9yyf9xyvfxpe0e8ny2fd4d', 'topics': [HexBytes('0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'), HexBytes('0x0000000000000000000000001677ada49e168df1290c9daa4ec820039d0097e3'), HexBytes('0x0000000000000000000000001ab7c2bb12a3484451a55ed15285a4cf10196312')], 'data': HexBytes('0x0000000000000000000000000000000000000000000000000000000000000064')})],\n",
+      " 'logsBloom': HexBytes('0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000200008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000040000200000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000200000000400000000000000000000020000000000000000'),\n",
+      " 'outcomeStatus': 0,\n",
+      " 'stateRoot': HexBytes('0xa14515ac4ad59a0ab8b7c4c1740eb5a97d0b55eabf3b5a0b185867e41d1a1699'),\n",
+      " 'storageCollateralized': 64,\n",
+      " 'storageCoveredBySponsor': False,\n",
+      " 'storageReleased': [],\n",
+      " 'to': 'cfxtest:acfgtrw53v4ju9jaydmr9yyf9xyvfxpe0e8ny2fd4d',\n",
+      " 'transactionHash': HexBytes('0x224e75f10580194685cd2566bd7ec5fdefd09578fe770bddae2ba9f77842f11a'),\n",
+      " 'txExecErrorMsg': None}\n"
+     ]
+    }
+   ],
+   "source": [
+    "# interact with the deployed contract\n",
+    "contract = w3.cfx.contract(address=contract_address, name=\"ERC20\")\n",
+    "\n",
+    "# build a transaction\n",
+    "# parameters such as 'from'/'gasPrice'/... can be specified in `build_transaction`\n",
+    "built_transfer_tx = contract.functions.transfer(\n",
+    "    w3.account.create().address,\n",
+    "    100\n",
+    ").build_transaction({\n",
+    "    'from': account.address\n",
+    "})\n",
+    "\n",
+    "# sign the transaction\n",
+    "signed_transfer_tx = account.sign_transaction(\n",
+    "    built_transfer_tx\n",
+    ")\n",
+    "\n",
+    "# send & wait for execution result\n",
+    "print(\"erc20 transfer receipt: \")\n",
+    "pprint.pprint(\n",
+    "    dict(w3.cfx.send_raw_transaction(signed_transfer_tx.rawTransaction).executed())\n",
+    ")"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.9.13 ('sdk')",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.13"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/en/examples/11-construct_transaction_from_scratch.ipynb b/docs/en/examples/11-construct_transaction_from_scratch.ipynb
new file mode 100644
index 0000000..efb27bd
--- /dev/null
+++ b/docs/en/examples/11-construct_transaction_from_scratch.ipynb
@@ -0,0 +1,88 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Construct Transaction from Sratch\n",
+    "\n",
+    "Run this example online by clicking `🚀` -> `Binder` on the top bar!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from conflux_web3 import Web3\n",
+    "\n",
+    "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+    "account = w3.account.from_key(\"0x....\") # fill your secret key here"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The meaning of each field is expalained [here](https://developer.confluxnetwork.org/introduction/en/conflux_basics#transaction-fields). And here presents how to choose each field."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "prebuilt_tx = {\n",
+    "    'from': account.address,\n",
+    "    'nonce': w3.cfx.get_next_nonce(account.address),\n",
+    "    'to': w3.account.create().address,\n",
+    "    'value': 100,\n",
+    "    'gasPrice': w3.cfx.gas_price,\n",
+    "    'chainId': w3.cfx.chain_id,\n",
+    "    # 'gas': 21000, \n",
+    "    # 'storageLimit': 0,\n",
+    "    'epochHeight': w3.cfx.epoch_number\n",
+    "}\n",
+    "\n",
+    "# estimate\n",
+    "estimate_result = w3.cfx.estimate_gas_and_collateral(prebuilt_tx)\n",
+    "\n",
+    "prebuilt_tx['gas'] = estimate_result['gasLimit']\n",
+    "prebuilt_tx['storageLimit'] = estimate_result['storageCollateralized']\n",
+    "\n",
+    "w3.cfx.send_raw_transaction(\n",
+    "    account.sign_transaction(prebuilt_tx).rawTransaction \n",
+    ").executed()"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.9.13 ('sdk')",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.13"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/logo.png b/docs/logo.png
new file mode 100644
index 0000000..4c87e0c
Binary files /dev/null and b/docs/logo.png differ
diff --git a/docs/requirements-doc.txt b/docs/requirements-doc.txt
new file mode 100644
index 0000000..47a56ab
--- /dev/null
+++ b/docs/requirements-doc.txt
@@ -0,0 +1,1 @@
+jupyter-book
\ No newline at end of file
diff --git a/docs/zh-CN/README.md b/docs/zh-CN/README.md
new file mode 100644
index 0000000..427447e
--- /dev/null
+++ b/docs/zh-CN/README.md
@@ -0,0 +1,78 @@
+# Introduction
+
+[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/conflux-chain/python-conflux-sdk/dev?urlpath=tree/docs/en/examples/01-quickstart.ipynb)
+[![Documentation Status](https://readthedocs.org/projects/python-conflux-sdk/badge/?version=latest)](https://python-conflux-sdk.readthedocs.io/en/latest/?badge=latest)
+[![gitlocalized ](https://gitlocalize.com/repo/8175/whole_project/badge.svg)](https://gitlocalize.com/repo/8175/whole_project?utm_source=badge)
+
+[README](https://python-conflux-sdk.readthedocs.io/en/latest/README.html) | [中文文档](https://python-conflux-sdk.readthedocs.io/zh_CN/latest/README.html)
+
+- [Introduction](#introduction)
+  - [概览](#概览)
+  - [Quickstart](#quickstart)
+  - [文档](#文档)
+    - [在线运行示例代码](#在线运行示例代码)
+    - [本地化](#本地化)
+
+
+## 概览
+
+Python-conflux-sdk 帮助开发者使用 python 与 Conflux 区块链交互，本库基于 [web3.py](https://github.com/ethereum/web3.py) 构建且大部分 API 与 `web3.py` 兼容。
+
+## Quickstart
+
+安装需求: python >= 3.7
+
+```bash
+pip3 install conflux-web3
+```
+
+```python
+from conflux_web3 import Web3
+
+w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
+
+acct = w3.account.from_key("0xxxxxxxxxxxxxx")
+w3.cfx.default_account = acct
+w3.cfx.contract(name="Faucet").claimCfx().transact().executed()
+
+w3.cfx.send_transaction({
+    'to': w3.address.zero_address(),
+    'value': 10**18,
+}).executed()
+```
+
+您也可以按照 `web3.py` 的 API 风格使用本 SDK： 
+
+``` python
+# 由 https://web3py.readthedocs.io/en/stable/middleware.html#signing 修改而来
+from conflux_web3 import Web3
+w3 = Web3("https://test.confluxrpc.com")
+from conflux_web3.middleware import construct_sign_and_send_raw_middleware
+from cfx_account import Account
+acct = Account.create('KEYSMASH FJAFJKLDSKF7JKFDJ 1530')
+w3.middleware_onion.add(construct_sign_and_send_raw_middleware(acct))
+w3.cfx.default_account = acct.address
+
+transaction = {
+    'to': w3.address.zero_address(),
+    'value': 22,
+}
+w3.cfx.send_transaction(transaction)
+```
+
+## 文档
+
+更详细的文档与用例可以参考 [文档](https://python-conflux-sdk.readthedocs.io/zh-CN/latest/README.html)。
+
+### 在线运行示例代码
+
+文档中提供的示例代码可以通过[mybinder](https://mybinder.org/)在线运行。 您可以依次点击代码示例页顶部的 `🚀` -> `Binder` 来启动环境。环境中已配置好运行代码的必备依赖，因此相关代码可以直接运行。
+
+### 本地化
+
+当前的文档支持两种语言:
+
+* 英文版本
+* 中文版本
+
+欢迎您通过 [GitLocalize](https://gitlocalize.com/repo/8175) 为我们提供翻译。
diff --git a/docs/zh-CN/_config.yml b/docs/zh-CN/_config.yml
new file mode 100644
index 0000000..3008378
--- /dev/null
+++ b/docs/zh-CN/_config.yml
@@ -0,0 +1,24 @@
+# Book settings
+# Learn more at https://jupyterbook.org/customize/config.html
+# Comprehensive example: https://github.com/executablebooks/jupyter-book/blob/master/docs/_config.yml
+
+title: python-conflux-sdk
+author: Read the Docs team
+logo: ../logo.png
+
+# Force re-execution of notebooks on each build.
+# See https://jupyterbook.org/content/execute.html
+execute:
+  execute_notebooks: cache
+
+# Information about where the book exists on the web
+repository:
+  url: https://github.com/conflux-chain/python-conflux-sdk  # Online location of your book
+  path_to_book: docs/zh-CN  # Optional path to your book, relative to the repository root
+  branch: dev  # Which branch of the repository should be used when creating links (optional)
+
+# Add GitHub buttons to your book
+# See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository
+html:
+  use_issues_button: true
+  use_repository_button: true
diff --git a/docs/zh-CN/_toc.yml b/docs/zh-CN/_toc.yml
new file mode 120000
index 0000000..74b631a
--- /dev/null
+++ b/docs/zh-CN/_toc.yml
@@ -0,0 +1,1 @@
+../en/_toc.yml
\ No newline at end of file
diff --git a/docs/zh-CN/examples/01-quickstart.ipynb b/docs/zh-CN/examples/01-quickstart.ipynb
new file mode 100644
index 0000000..cb3b1a8
--- /dev/null
+++ b/docs/zh-CN/examples/01-quickstart.ipynb
@@ -0,0 +1,198 @@
+{
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "# 快速开始\n",
+        "\n",
+        "点击顶部栏上的`🚀` -> `Binder`按钮能够在线运行此示例。\n",
+        "\n",
+        "这个例子将展示：\n",
+        "\n",
+        "- 如何通过节点连接到区块链\n",
+        "- 如何创建和使用`account`\n",
+        "- 如何与合约交互，如何发送交易"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 连接到节点\n",
+        "\n",
+        "我们一般会通过节点连接到 Conflux 区块链。您可以按照[本教程](https://developer.confluxnetwork.org/conflux-doc/docs/get_started/)在本地运行节点。为了演示的方便，在这个例子中，我们连接到的节点为[Conflux 公共 RPC](https://developer.confluxnetwork.org/sdks-and-tools/en/conflux_rpcs)来连接到测试网。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 1,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "from conflux_web3 import Web3\n",
+        "\n",
+        "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+        "assert w3.is_connected()"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 创建一个帐户\n",
+        "\n",
+        "在 web3 中，拥有一个帐户往往意味着知道一个**秘密值**，该值也被称为账户的**私钥/密钥**。也就是说，知道私钥的人也就控制了账户。\n",
+        "\n",
+        "在SDK中，我们可以使用`w3.account.create()`创建一个新帐户。该函数使用一个随机生成的密钥创建帐户对象。\n",
+        "\n",
+        "SDK 也支持使用`w3.account.from_key(\"0x....\")`来使用私钥（**但不要在不安全的环境中使用私钥** ）"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 2,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "account address: cfxtest:aaswj28188e35rh1vguksgnuz2xy4f8apye3745zxb\n",
+            "account secret key: 0x54d957b2485980fc2119ccce6480ad0d53219161595424fbf7dc452d59c6bc82\n",
+            "balance for cfxtest:aaswj28188e35rh1vguksgnuz2xy4f8apye3745zxb: 0 Drip\n"
+          ]
+        }
+      ],
+      "source": [
+        "acct = w3.account.create()\n",
+        "print(f\"account address: {acct.address}\")\n",
+        "# 注意: 不要在生产环境中运行下面这行，私钥应该保密\n",
+        "print(f\"account secret key: {acct._private_key.hex()}\")\n",
+        "balance = w3.cfx.get_balance(acct.address)\n",
+        "# 随机账户，因此余额为 0\n",
+        "assert balance == 0\n",
+        "print(f\"balance for {acct.address}: {balance}\")"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 通过测试网水龙头合约领取 CFX\n",
+        "\n",
+        "因为账户的余额是`0`，所以该账户无法支付发送交易所需的交易费（gas）。但是，Conflux 的[赞助机制](https://forum.conflux.fun/t/conflux-sponsorship-mechanism/12764)允许用户在不支付 gas 的情况下与智能合约进行交互，因此我们可以从[测试网水龙头合约](https://testnet.confluxscan.net/address/cfxtest:acejjfa80vj06j2jgtz9pngkv423fhkuxj786kjr61)中领取 CFX。\n",
+        "\n",
+        "> 智能合约是什么：智能合约是部署在区块链网络上的程序。它提供了用于执行特定逻辑的接口。在下面示例中，调用水龙头合约的 `claimCfx` 方法将为您提供 1000 个测试网 CFX。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 3,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "tx hash is: 0xf174cf4be19b33da58504ef850bfd055bd031324135093276abbee1c34df854d\n",
+            "conflux scan link: https://testnet.confluxscan.net/transaction/0xf174cf4be19b33da58504ef850bfd055bd031324135093276abbee1c34df854d\n"
+          ]
+        }
+      ],
+      "source": [
+        "# 首先设置 `w3.cfx.default_account` 为 `acct`,\n",
+        "# 这样交易能够被自动签名发送。\n",
+        "w3.cfx.default_account = acct\n",
+        "\n",
+        "# 与测试网水龙头合约交互\n",
+        "faucet = w3.cfx.contract(name=\"Faucet\")\n",
+        "tx_hash = faucet.functions.claimCfx().transact()\n",
+        "\n",
+        "print(f\"tx hash is: {tx_hash.hex()}\\n\"\n",
+        "      f\"confluxscan link: https://testnet.confluxscan.net/transaction/{tx_hash.hex()}\")"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 4,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "balance for cfxtest:aaswj28188e35rh1vguksgnuz2xy4f8apye3745zxb: 1000 CFX\n"
+          ]
+        }
+      ],
+      "source": [
+        "# 在 Conflux, 交易上链 5 个 epoch 之后才会被执行\n",
+        "# `tx_hash.executed()` 与 `w3.cfx.wait_for_transaction_receipt(tx_hash)` 是等价的\n",
+        "tx_hash.executed()\n",
+        "# Drip 与 CFX 是 Conflux 区块链中的代币单位\n",
+        "# 1 CFX = 10**18 Drip\n",
+        "print(f\"balance for {acct.address}: {w3.cfx.get_balance(acct.address).to('CFX')}\")"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 进行 CFX 转账\n",
+        "\n",
+        "现在我们能够支付交易费了。接下来我们可以进行转账操作，例如将 1 个 CFX 发送到零地址。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 5,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "balance for cfxtest:aaswj28188e35rh1vguksgnuz2xy4f8apye3745zxb: 998.999979 CFX\n"
+          ]
+        }
+      ],
+      "source": [
+        "# Now acct has CFX\n",
+        "# send 1 CFX to zero address\n",
+        "w3.cfx.send_transaction({\n",
+        "    \"to\": w3.address.zero_address(),\n",
+        "    \"value\": 10**18,\n",
+        "}).executed()\n",
+        "print(f\"balance for {acct.address}: {w3.cfx.get_balance(acct.address).to('CFX')}\")"
+      ]
+    }
+  ],
+  "metadata": {
+    "kernelspec": {
+      "display_name": "Python 3.9.13 ('sdk')",
+      "language": "python",
+      "name": "python3"
+    },
+    "language_info": {
+      "codemirror_mode": {
+        "name": "ipython",
+        "version": 3
+      },
+      "file_extension": ".py",
+      "mimetype": "text/x-python",
+      "name": "python",
+      "nbconvert_exporter": "python",
+      "pygments_lexer": "ipython3",
+      "version": "3.9.13"
+    },
+    "orig_nbformat": 4,
+    "vscode": {
+      "interpreter": {
+        "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+      }
+    }
+  },
+  "nbformat": 4,
+  "nbformat_minor": 2
+}
diff --git a/docs/zh-CN/examples/02-address_account_and_wallet.ipynb b/docs/zh-CN/examples/02-address_account_and_wallet.ipynb
new file mode 100644
index 0000000..21523db
--- /dev/null
+++ b/docs/zh-CN/examples/02-address_account_and_wallet.ipynb
@@ -0,0 +1,276 @@
+{
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "# 账户、地址与钱包\n",
+        "\n",
+        "单击顶部栏上的`🚀` -&gt; `Binder`在线运行此示例！"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 准备\n",
+        "\n",
+        "本部分将准备`web3`对象与私钥`private_key`，提供后文代码所需的变量。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 2,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "# 领取 1000 CFX 到私钥对应的账户\n",
+        "from pprint import pprint\n",
+        "from conflux_web3 import Web3\n",
+        "\n",
+        "w3_ = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+        "\n",
+        "acct = w3_.account.create()\n",
+        "\n",
+        "w3_.cfx.default_account = acct\n",
+        "\n",
+        "faucet = w3_.cfx.contract(name=\"Faucet\")\n",
+        "tx_receipt = faucet.functions.claimCfx().transact().executed()\n",
+        "\n",
+        "# 新建w3对象以便演示API的用法\n",
+        "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+        "private_key: str = acct._private_key.hex()"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 账户与地址\n",
+        "\n",
+        "在 web3 中，控制着一个帐户意味着知道一个私钥。虽然私钥应该保密，但***地址***不必。地址是从私钥单向派生的字符串，用于标识帐户。不同区块链常常会使用不同方式编码账户地址，例如比特币与以太坊的地址编码方式就存在区别。在 Conflux 中，地址以[CIP-37](https://github.com/Conflux-Chain/CIPs/blob/master/CIPs/cip-37.md)定义的 base32 格式编码。\n"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### `LocalAccount`对象\n",
+        "\n",
+        "`w3.account`是一个工厂对象，用于生成用来签署交易的`LocalAccount`对象（例如`random_account` ）。\n",
+        "\n",
+        "**注意：手动签署交易相当繁琐。请参阅[钱包](#wallet)部分了解如何使用钱包签名和发送交易。或者您可以参考[从头构建交易](./11-construct_transaction_from_scratch.ipynb)了解如何正确手动签名交易。**\n",
+        "\n",
+        "> 更多文档： `w3.account`是一个`cfx_account.Account`对象，其继承自`eth_account.Account` ，大部分api与[eth_account](https://eth-account.readthedocs.io/en/stable/eth_account.html)一致。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 3,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "account address: cfxtest:aanywwykvp5nv9atnh7p287s2r48wcgf9j3xjce7kj\n",
+            "account private key: 0x11d748040e0c1da3d4342a25e98ac4f9463b9b11491a04201834914c35b5670c\n",
+            "signed raw tx: 0xf867e301843b9aca00825208940000000000000000000000000000000000000000018064018001a0eedd9a79b05d1a42f75e972e2ef2b6536a49de81a11f26d9095c146ce95ee314a00ed7bd5f8cef819175525988970c4eb7739755b7138afdd4d5b671acb55c9b49\n"
+          ]
+        }
+      ],
+      "source": [
+        "random_account = w3.account.from_key(private_key)\n",
+        "print(f\"account address: {random_account.address}\")\n",
+        "print(f\"account private key: {private_key}\")\n",
+        "\n",
+        "transaction = {\n",
+        "    'to': w3.address.zero_address(),\n",
+        "    'nonce': 1,\n",
+        "    'value': 1,\n",
+        "    'gas': 21000,\n",
+        "    'gasPrice': 10**9,\n",
+        "    'storageLimit': 0,\n",
+        "    'epochHeight': 100,\n",
+        "    'chainId': 1\n",
+        "}\n",
+        "print(f\"signed raw tx: {random_account.sign_transaction(transaction).rawTransaction.hex()}\")"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### Conflux 地址\n",
+        "\n",
+        "在 Conflux 中，地址按照[CIP-37](https://github.com/Conflux-Chain/CIPs/blob/master/CIPs/cip-37.md)以 base32 格式编码。你可以简单地从地址字面推断出该地址属于主网、测试网或其他网络。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 4,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "# \"cfxtest\" 代表该地址为测试网地址\n",
+        "assert random_account.address.startswith(\"cfxtest:\")"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "SDK 返回的地址都被类`Base32Address`包裹。该类提供了方便的方法来操作 base32 地址，但你也可以将`Base32Address`对象用作普通的 python `str`对象。[Base32Address 文档](https://conflux-fans.github.io/cfx-address/cfx_address.html#module-cfx_address.address)提供了更详细的代码示例。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 5,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "the type of addr: <class 'cfx_address.address.Base32Address'>\n",
+            "cfxtest:aatp533cg7d0agbd87kz48nj1mpnkca8be1rz695j4\n",
+            "['user',\n",
+            " 1,\n",
+            " '0x1ecde7223747601823f7535d7968ba98b4881e09',\n",
+            " 'CFXTEST:TYPE.USER:AATP533CG7D0AGBD87KZ48NJ1MPNKCA8BE1RZ695J4',\n",
+            " 'cfxtest:aat...95j4',\n",
+            " '0x349f086998cF4a0C5a00b853a0E93239D81A97f6',\n",
+            " '0x1ECdE7223747601823f7535d7968Ba98b4881E09']\n"
+          ]
+        }
+      ],
+      "source": [
+        "addr = random_account.address\n",
+        "print(f\"the type of addr: {type(addr)}\")\n",
+        "# a Base32Address object is also a `str`\n",
+        "assert isinstance(addr, str)\n",
+        "\n",
+        "# encode a base32 address from hex address and network_id\n",
+        "# it is also supported to use `w3.address(\"cfxtest:aatp533cg7d0agbd87kz48nj1mpnkca8be1rz695j4\")`\n",
+        "address = w3.address(\"0x1ecde7223747601823f7535d7968ba98b4881e09\", network_id=1)\n",
+        "print(address)\n",
+        "pprint([\n",
+        "    address.address_type,\n",
+        "    address.network_id,\n",
+        "    address.hex_address,\n",
+        "    address.verbose_address,\n",
+        "    address.abbr,\n",
+        "    address.mapped_evm_space_address,\n",
+        "    address.eth_checksum_address,\n",
+        "])"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 钱包\n",
+        "\n",
+        "我们使用钱包中间件(`w3.wallet`)来帮助我们签名发送交易。如果某未签名交易的`from`账户已添加至`w3.wallet`中，它将对通过`w3.cfx.send_transaction`发送的未签名交易进行签名。\n",
+        "\n",
+        "> `wallet`中间件的行为与`web3.py`的`construct_sign_and_send_raw_middleware`基本一致，但提供了更多功能。例如，我们可以使用`w3.wallet.add_account` 、 `w3.wallet.add_accounts` 、 `w3.wallet.pop`来动态添加或删除帐户。 "
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 6,
+      "metadata": {},
+      "outputs": [
+        {
+          "data": {
+            "text/plain": [
+              "AttributeDict({'transactionHash': HexBytes('0x1b53a9e6efa47aa2380ab457b2d7a3a079d14fc362a7bc8830d53e56287f1aa2'),\n",
+              " 'index': 0,\n",
+              " 'blockHash': HexBytes('0x466eeaec283b8a272179e3d5adcec05f7aadd010e28ab740bd18d68da9272f8a'),\n",
+              " 'epochNumber': 99718048,\n",
+              " 'from': 'cfxtest:aanywwykvp5nv9atnh7p287s2r48wcgf9j3xjce7kj',\n",
+              " 'to': 'cfxtest:aanywwykvp5nv9atnh7p287s2r48wcgf9j3xjce7kj',\n",
+              " 'gasUsed': 21000,\n",
+              " 'gasFee': 21000000000000 Drip,\n",
+              " 'contractCreated': None,\n",
+              " 'logs': [],\n",
+              " 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),\n",
+              " 'stateRoot': HexBytes('0x23e4baa1f61ece6aaa6aa05fb74d9877e03be1efa316300a977617a88dc9cb10'),\n",
+              " 'outcomeStatus': 0,\n",
+              " 'txExecErrorMsg': None,\n",
+              " 'gasCoveredBySponsor': False,\n",
+              " 'storageCoveredBySponsor': False,\n",
+              " 'storageCollateralized': 0,\n",
+              " 'storageReleased': []})"
+            ]
+          },
+          "execution_count": 6,
+          "metadata": {},
+          "output_type": "execute_result"
+        }
+      ],
+      "source": [
+        "# wallet是 conflux_web3 的中间件，可向其中添加 LocalAccount\n",
+        "assert w3.wallet is w3.middleware_onion[\"wallet\"]\n",
+        "\n",
+        "w3.wallet.add_account(random_account)\n",
+        "\n",
+        "assert random_account.address in w3.wallet\n",
+        "w3.cfx.send_transaction({\n",
+        "    \"from\": random_account.address,\n",
+        "    \"to\": random_account.address,\n",
+        "    \"value\": 10**18\n",
+        "}).executed()"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 使用`w3.cfx.default_account`将账户添加到钱包\n",
+        "\n",
+        "当 `w3.cfx.default_account` 被设置后，若交易的 `from` 字段未指定，则将被自动设置为 `w3.cfx.default_account`。\n",
+        "\n",
+        "`w3.cfx.default_account`是一个地址类型的变量，但可以使用`LocalAccount`对象进行设置。在这种情况下，该`LocalAccount`将同时添加到钱包中。\n",
+        "\n",
+        "```python\n",
+        "w3.cfx.default_account = random_account\n",
+        "```\n",
+        "\n",
+        "相当于\n",
+        "\n",
+        "```python\n",
+        "w3.cfx.default_account = random_account.address\n",
+        "w3.wallet.add_account(random_account)\n",
+        "```"
+      ]
+    }
+  ],
+  "metadata": {
+    "kernelspec": {
+      "display_name": "Python 3.9.13 ('sdk')",
+      "language": "python",
+      "name": "python3"
+    },
+    "language_info": {
+      "codemirror_mode": {
+        "name": "ipython",
+        "version": 3
+      },
+      "file_extension": ".py",
+      "mimetype": "text/x-python",
+      "name": "python",
+      "nbconvert_exporter": "python",
+      "pygments_lexer": "ipython3",
+      "version": "3.9.13"
+    },
+    "orig_nbformat": 4,
+    "vscode": {
+      "interpreter": {
+        "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+      }
+    }
+  },
+  "nbformat": 4,
+  "nbformat_minor": 2
+}
diff --git a/docs/zh-CN/examples/03-trace_transaction_status.ipynb b/docs/zh-CN/examples/03-trace_transaction_status.ipynb
new file mode 100644
index 0000000..475a5f3
--- /dev/null
+++ b/docs/zh-CN/examples/03-trace_transaction_status.ipynb
@@ -0,0 +1,124 @@
+{
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "# 跟踪交易状态\n",
+        "\n",
+        "单击顶部栏上的`🚀` -&gt; `Binder`在线运行此示例！"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 准备"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 1,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "# 准备阶段：初始化 web3 对象并提供交易哈希对象 tx_hash\n",
+        "from conflux_web3 import Web3\n",
+        "\n",
+        "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+        "acct = w3.account.create()\n",
+        "w3.cfx.default_account = acct\n",
+        "faucet = w3.cfx.contract(name=\"Faucet\")\n",
+        "\n",
+        "# get a tx_hash\n",
+        "tx_hash = faucet.functions.claimCfx().transact()"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## Conflux 中的交易状态\n",
+        "\n",
+        "在 Conflux 中，交易在发送后会经历几个阶段：\n",
+        "\n",
+        "1. `pending` ：交易已发送，但不包含在任何区块中。\n",
+        "2. `mined` ：交易已经包含在一个区块中，但可能尚未被执行。\n",
+        "3. `executed` ：交易被执行。\n",
+        "4. `confirmed` ：交易在 PoW 链确认规则下被确认，这意味着除非 PoW 链受到攻击，否则它极不可能被逆转。\n",
+        "5. `finalized` ：交易已被 PoS 链**最终确认**，这意味着该交易不可能被逆转。但需要 5~10 分钟交易才会被最终确认。"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 跟踪交易的状态\n",
+        "\n",
+        "我们可以使用`w3.cfx.wait_till_transaction_mined` 、 `w3.cfx.wait_till_transaction_executed` 、 `w3.cfx.wait_till_transaction_confirmed` 、 `w3.cfx.wait_till_transaction_finalized`等待交易达到特定状态。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 2,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "w3.cfx.wait_till_transaction_mined(tx_hash)\n",
+        "w3.cfx.wait_till_transaction_executed(tx_hash)\n",
+        "w3.cfx.wait_till_transaction_confirmed(tx_hash)\n",
+        "if False: # 需要 5~10 分钟\n",
+        "    w3.cfx.wait_till_transaction_finalized(tx_hash)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 语法糖\n",
+        "\n",
+        "我们经常需要跟踪已发送交易的状态，因此SDK 将`send_transacation`或`send_raw_transaction`返回的交易哈希进行了封装，以便访问上述API。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 3,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "tx_hash.mined()\n",
+        "tx_hash.executed()\n",
+        "tx_hash.confirmed()\n",
+        "if False:\n",
+        "    tx_hash.finalized()"
+      ]
+    }
+  ],
+  "metadata": {
+    "kernelspec": {
+      "display_name": "Python 3.9.13 ('sdk')",
+      "language": "python",
+      "name": "python3"
+    },
+    "language_info": {
+      "codemirror_mode": {
+        "name": "ipython",
+        "version": 3
+      },
+      "file_extension": ".py",
+      "mimetype": "text/x-python",
+      "name": "python",
+      "nbconvert_exporter": "python",
+      "pygments_lexer": "ipython3",
+      "version": "3.9.13"
+    },
+    "orig_nbformat": 4,
+    "vscode": {
+      "interpreter": {
+        "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+      }
+    }
+  },
+  "nbformat": 4,
+  "nbformat_minor": 2
+}
diff --git a/docs/zh-CN/examples/04-query_data_via_RPC.ipynb b/docs/zh-CN/examples/04-query_data_via_RPC.ipynb
new file mode 100644
index 0000000..416fbd1
--- /dev/null
+++ b/docs/zh-CN/examples/04-query_data_via_RPC.ipynb
@@ -0,0 +1,408 @@
+{
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "# 通过 RPC 查询数据\n",
+        "\n",
+        "单击顶部栏上的`🚀` -&gt; `Binder`在线运行此示例！"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 准备"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 2,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "# 准备阶段: 初始化 w3 对象\n",
+        "from conflux_web3 import Web3\n",
+        "\n",
+        "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+        "\n",
+        "# 准备后文需要的常量\n",
+        "transaction_hash = \"0x10a721e2654523a7ff682c1c8d3f868a9fdf78a3be1858bbe1f06147128d6d94\"\n",
+        "epoch = 98943500"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 通过 RPC 查询数据\n",
+        "\n",
+        "我们可以使用 SDK 通过 JSON-RPC 来查询区块链状态、交易数据、区块数据等。完整的 RPC 文档可以在[这里](https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc/#json-rpc-methods)找到。"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 查询区块链状态"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 3,
+      "metadata": {},
+      "outputs": [
+        {
+          "data": {
+            "text/plain": [
+              "AttributeDict({'bestHash': HexBytes('0xfccec01b7d00bf7c60039ac24e832cda36c3f99847d85bdebea5ad9c23e72af0'),\n",
+              " 'chainId': 1,\n",
+              " 'ethereumSpaceChainId': 71,\n",
+              " 'networkId': 1,\n",
+              " 'epochNumber': 99720385,\n",
+              " 'blockNumber': 127806496,\n",
+              " 'pendingTxNumber': 0,\n",
+              " 'latestCheckpoint': 99640000,\n",
+              " 'latestConfirmed': 99720321,\n",
+              " 'latestState': 99720381,\n",
+              " 'latestFinalized': 99719940})"
+            ]
+          },
+          "execution_count": 3,
+          "metadata": {},
+          "output_type": "execute_result"
+        }
+      ],
+      "source": [
+        "# get_status 提供了区块链当前状态的概览\n",
+        "w3.cfx.get_status()"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "多个 RPC 方法都可以接受**epoch number 参数**。`epoch number`（纪元）参数可以是：\n",
+        "\n",
+        "- 一个整数\n",
+        "- 或者是字符串形式的 epoch tag`latest_mined` , `latest_state` , `latest_confirmed`或`latest_finalized`\n",
+        "\n",
+        "Conflux 中的`epoch number`的概念类似于其他区块链中的`block number`的概念，但一个 epoch 包含一个或多个区块。详细信息请参阅 https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc#the-default-epochnumber-parameter。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 4,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "latest_mined epoch number: 99720385\n",
+            "latest_state epoch numebr: 99720381\n"
+          ]
+        }
+      ],
+      "source": [
+        "# latest_mined epoch number\n",
+        "print(f\"latest_mined epoch number: {w3.cfx.epoch_number}\")\n",
+        "# 通过 tag 获取纪元\n",
+        "print(f'latest_state epoch numebr: {w3.cfx.epoch_number_by_tag(\"latest_state\")}')"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 查询交易"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 5,
+      "metadata": {},
+      "outputs": [
+        {
+          "data": {
+            "text/plain": [
+              "AttributeDict({'hash': HexBytes('0x10a721e2654523a7ff682c1c8d3f868a9fdf78a3be1858bbe1f06147128d6d94'),\n",
+              " 'nonce': 2,\n",
+              " 'blockHash': HexBytes('0xf0ac5f8d757a7415876e322a245d5eff76349b656b3eadb10d5e09a4a3f7d59d'),\n",
+              " 'transactionIndex': 0,\n",
+              " 'from': 'cfxtest:aan2vyszrgz3sr3tug73ywb8k128y5wa7yhpjm1hn1',\n",
+              " 'to': 'cfxtest:acejjfa80vj06j2jgtz9pngkv423fhkuxj786kjr61',\n",
+              " 'value': 0 Drip,\n",
+              " 'gasPrice': 1000000000 Drip,\n",
+              " 'gas': 41633,\n",
+              " 'contractCreated': None,\n",
+              " 'data': HexBytes('0x5f3cc9f7'),\n",
+              " 'storageLimit': 0,\n",
+              " 'epochHeight': 87083312,\n",
+              " 'chainId': 1,\n",
+              " 'status': 0,\n",
+              " 'v': 1,\n",
+              " 'r': HexBytes('0x17b30481d63a49223092215a2aa503938519df5cac0d20cbff7ebf50569776cd'),\n",
+              " 's': HexBytes('0x5fc96a1e383879cf66c09d106b2df4907c674a263c9a7bba602078c90b0038b1')})"
+            ]
+          },
+          "execution_count": 5,
+          "metadata": {},
+          "output_type": "execute_result"
+        }
+      ],
+      "source": [
+        "# 通过交易哈希获取交易\n",
+        "# 交易发出后这个 RPC 立刻可用\n",
+        "w3.cfx.get_transaction_by_hash(transaction_hash)"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 6,
+      "metadata": {},
+      "outputs": [
+        {
+          "data": {
+            "text/plain": [
+              "AttributeDict({'transactionHash': HexBytes('0x10a721e2654523a7ff682c1c8d3f868a9fdf78a3be1858bbe1f06147128d6d94'),\n",
+              " 'index': 0,\n",
+              " 'blockHash': HexBytes('0xf0ac5f8d757a7415876e322a245d5eff76349b656b3eadb10d5e09a4a3f7d59d'),\n",
+              " 'epochNumber': 87083316,\n",
+              " 'from': 'cfxtest:aan2vyszrgz3sr3tug73ywb8k128y5wa7yhpjm1hn1',\n",
+              " 'to': 'cfxtest:acejjfa80vj06j2jgtz9pngkv423fhkuxj786kjr61',\n",
+              " 'gasUsed': 35480,\n",
+              " 'gasFee': 35480000000000 Drip,\n",
+              " 'contractCreated': None,\n",
+              " 'logs': [],\n",
+              " 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'),\n",
+              " 'stateRoot': HexBytes('0xdbfbe3f9b08aa5fb04ca5218ebc245b3941cce9d30409ab854456f3070b454f6'),\n",
+              " 'outcomeStatus': 0,\n",
+              " 'txExecErrorMsg': None,\n",
+              " 'gasCoveredBySponsor': True,\n",
+              " 'storageCoveredBySponsor': True,\n",
+              " 'storageCollateralized': 0,\n",
+              " 'storageReleased': []})"
+            ]
+          },
+          "execution_count": 6,
+          "metadata": {},
+          "output_type": "execute_result"
+        }
+      ],
+      "source": [
+        "# 通过交易哈希获取交易receipt\n",
+        "# 交易执行后才能获取到 receipt \n",
+        "w3.cfx.get_transaction_receipt(transaction_hash)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 查询块\n",
+        "\n",
+        "在 Conflux 中，每个 epoch 包含 1 个或多个区块，其中一个块称为`pivot`区块。`pivot`区块确定各个 epoch 中都包含哪些区块。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 7,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "blocks in epoch 98943500:\n",
+            "[HexBytes('0xae622377e139608a9202504df4bf20570c4741370d36f668952ae91c57c5da69'), HexBytes('0x104a3549108c7c83a36c65d188e842f6deb9a770d3ca749a222fce628846c04b')]\n",
+            "pivot block hash of epoch 98943500: 0x104a3549108c7c83a36c65d188e842f6deb9a770d3ca749a222fce628846c04b\n"
+          ]
+        }
+      ],
+      "source": [
+        "# 查询某个 epoch 中包含的区块\n",
+        "block_hashes = w3.cfx.get_blocks_by_epoch(epoch)\n",
+        "print(f\"blocks in epoch {epoch}:\\n{block_hashes}\")\n",
+        "# block_hashes 中最后一个元素一定为 pivot 区块\n",
+        "print(f\"pivot block hash of epoch {epoch}: {block_hashes[-1].hex()}\")"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 8,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "# 如果某个区块为 pivot 区块, 我们可以通过 epoch 查询到该区块\n",
+        "# 当然，我们也可以通过哈希查询区块\n",
+        "assert w3.cfx.get_block_by_epoch_number(epoch) == w3.cfx.get_block_by_hash(block_hashes[-1])"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 9,
+      "metadata": {},
+      "outputs": [
+        {
+          "data": {
+            "text/plain": [
+              "AttributeDict({'hash': HexBytes('0x37ab44387ae132e3eea6c666bfb5cd58af50d0b172ab21b0be5ff85073bc5592'),\n",
+              " 'parentHash': HexBytes('0x9130a237d15b696d48daf1decf6f2908a98a57c9d2b543d1cce7f55c296cf7fd'),\n",
+              " 'height': 99720383,\n",
+              " 'miner': 'cfxtest:aang4d91rejdbpgmgtmspdyefxkubj2bbywrwm9j3z',\n",
+              " 'deferredStateRoot': HexBytes('0x48edc4d8dbe77ac589cf30087ad3165ee533101882698812f9f4bcff0ff66252'),\n",
+              " 'deferredReceiptsRoot': HexBytes('0x09f8709ea9f344a810811a373b30861568f5686e649d6177fd92ea2db7477508'),\n",
+              " 'deferredLogsBloomHash': HexBytes('0xd397b3b043d87fcd6fad1291ff0bfd16401c274896d8c63a923727f077b8e0b5'),\n",
+              " 'blame': 0,\n",
+              " 'transactionsRoot': HexBytes('0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'),\n",
+              " 'epochNumber': 99720383,\n",
+              " 'blockNumber': 127806493,\n",
+              " 'gasLimit': 30000000,\n",
+              " 'gasUsed': 0,\n",
+              " 'timestamp': 1668507784,\n",
+              " 'difficulty': 58688104,\n",
+              " 'powQuality': HexBytes('0x12b15fcb'),\n",
+              " 'refereeHashes': [HexBytes('0xb18df88debc7ab3fb8a2dc105e927d9f2bc6575b5a38c5e84b5c84c7c41b5525')],\n",
+              " 'adaptive': False,\n",
+              " 'nonce': HexBytes('0x2caff98a7d0bf272'),\n",
+              " 'size': 0,\n",
+              " 'custom': [HexBytes('0x02')],\n",
+              " 'posReference': HexBytes('0x11f970d63eb9eaf581315b67f2258c0c59ad13572be29a2187c900ac576d3003'),\n",
+              " 'transactions': []})"
+            ]
+          },
+          "execution_count": 9,
+          "metadata": {},
+          "output_type": "execute_result"
+        }
+      ],
+      "source": [
+        "# get_block_by_epoch_number 也支持通过 epoch tag 查询\n",
+        "w3.cfx.get_block_by_epoch_number(\"latest_state\")"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 10,
+      "metadata": {},
+      "outputs": [
+        {
+          "data": {
+            "text/plain": [
+              "AttributeDict({'hash': HexBytes('0xf0ac5f8d757a7415876e322a245d5eff76349b656b3eadb10d5e09a4a3f7d59d'),\n",
+              " 'parentHash': HexBytes('0xeaf2f6227c068ae27cb847657af7eb7e3cfd6696f5a795d2f38159074d20a8c9'),\n",
+              " 'height': 87083316,\n",
+              " 'miner': 'cfxtest:aaskvgxcfej371g4ecepx9an78ngrke5ay9f8jtbgg',\n",
+              " 'deferredStateRoot': HexBytes('0xa26347f02f312db0fba655c29b9fa853e8e6242449a67added74c62679122f62'),\n",
+              " 'deferredReceiptsRoot': HexBytes('0x09f8709ea9f344a810811a373b30861568f5686e649d6177fd92ea2db7477508'),\n",
+              " 'deferredLogsBloomHash': HexBytes('0xd397b3b043d87fcd6fad1291ff0bfd16401c274896d8c63a923727f077b8e0b5'),\n",
+              " 'blame': 0,\n",
+              " 'transactionsRoot': HexBytes('0xdc62bb0e7115a9727688811f4e090efdfd203a516953ff7829e21dea29e1f166'),\n",
+              " 'epochNumber': 87083316,\n",
+              " 'blockNumber': 110979562,\n",
+              " 'gasLimit': 30000000,\n",
+              " 'gasUsed': 35480,\n",
+              " 'timestamp': 1660093852,\n",
+              " 'difficulty': 54757256,\n",
+              " 'powQuality': HexBytes('0x0365f39d'),\n",
+              " 'refereeHashes': [],\n",
+              " 'adaptive': False,\n",
+              " 'nonce': HexBytes('0xe72421314ac723e6'),\n",
+              " 'size': 113,\n",
+              " 'custom': [HexBytes('0x01')],\n",
+              " 'posReference': HexBytes('0xe7c39fb3312519d78e5606ef4d9040b558b852e7af439a8fcad1632de776cc06'),\n",
+              " 'transactions': [HexBytes('0x10a721e2654523a7ff682c1c8d3f868a9fdf78a3be1858bbe1f06147128d6d94')]})"
+            ]
+          },
+          "execution_count": 10,
+          "metadata": {},
+          "output_type": "execute_result"
+        }
+      ],
+      "source": [
+        "# 通过 block number 查询也是可行的\n",
+        "w3.cfx.get_block_by_block_number(110979562)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 其他 RPC\n",
+        "\n",
+        "除此之外， `conflux-web3`支持 cfx 命名空间下的所有 rpc 方法。[JSON-RPC-methods](https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc#json-rpc-methods)中提供了更多信息。\n",
+        "\n",
+        "这里提供了部分例子："
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 11,
+      "metadata": {},
+      "outputs": [
+        {
+          "data": {
+            "text/plain": [
+              "1000000000 Drip"
+            ]
+          },
+          "execution_count": 11,
+          "metadata": {},
+          "output_type": "execute_result"
+        }
+      ],
+      "source": [
+        "w3.cfx.gas_price"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 12,
+      "metadata": {},
+      "outputs": [
+        {
+          "data": {
+            "text/plain": [
+              "5964"
+            ]
+          },
+          "execution_count": 12,
+          "metadata": {},
+          "output_type": "execute_result"
+        }
+      ],
+      "source": [
+        "len(w3.cfx.get_code(\"cfxtest:acejjfa80vj06j2jgtz9pngkv423fhkuxj786kjr61\"))"
+      ]
+    }
+  ],
+  "metadata": {
+    "kernelspec": {
+      "display_name": "Python 3.9.13 ('sdk')",
+      "language": "python",
+      "name": "python3"
+    },
+    "language_info": {
+      "codemirror_mode": {
+        "name": "ipython",
+        "version": 3
+      },
+      "file_extension": ".py",
+      "mimetype": "text/x-python",
+      "name": "python",
+      "nbconvert_exporter": "python",
+      "pygments_lexer": "ipython3",
+      "version": "3.9.13"
+    },
+    "orig_nbformat": 4,
+    "vscode": {
+      "interpreter": {
+        "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+      }
+    }
+  },
+  "nbformat": 4,
+  "nbformat_minor": 2
+}
diff --git a/docs/zh-CN/examples/05-interact_with_contracts_and_process_logs.ipynb b/docs/zh-CN/examples/05-interact_with_contracts_and_process_logs.ipynb
new file mode 100644
index 0000000..878bae6
--- /dev/null
+++ b/docs/zh-CN/examples/05-interact_with_contracts_and_process_logs.ipynb
@@ -0,0 +1,407 @@
+{
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "# 与智能合约交互，处理日志\n",
+        "\n",
+        "单击顶部栏上的`🚀` -&gt; `Binder`在线运行此示例！"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 准备"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 2,
+      "metadata": {},
+      "outputs": [
+        {
+          "data": {
+            "text/plain": [
+              "1000 CFX"
+            ]
+          },
+          "execution_count": 2,
+          "metadata": {},
+          "output_type": "execute_result"
+        }
+      ],
+      "source": [
+        "import pprint\n",
+        "from conflux_web3 import Web3\n",
+        "\n",
+        "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+        "account = w3.account.create()\n",
+        "w3.cfx.default_account = account\n",
+        "\n",
+        "faucet = w3.cfx.contract(name=\"Faucet\")\n",
+        "faucet.functions.claimCfx().transact().executed()\n",
+        "w3.cfx.get_balance(account.address).to(\"CFX\")"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 与合约交互\n",
+        "\n",
+        "在[准备](#preparation)部分，我们已经展示了如何与合约交互。我们可以通过`w3.cfx.contract`初始化合约实例，并使用`name`参数创建一些常用的合约实例。但我们常常需要自行编写合约，本部分将展示如何编译、部署合约，并与已部署的合约进行交互。"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 编译和部署合约\n",
+        "\n",
+        "合约是在区块链上运行的程序。如果我们想与自己编写的程序进行交互，我们需要首先将合约**部署**到区块链上。\n",
+        "\n",
+        "这是一个简单的智能合约：\n",
+        "\n",
+        "```solidity\n",
+        "// SPDX-License-Identifier: MIT\n",
+        "// modified from https://solidity-by-example.org/first-app/\n",
+        "pragma solidity ^0.8.13;\n",
+        "\n",
+        "contract Counter {\n",
+        "    uint public count;\n",
+        "\n",
+        "    event Change(address indexed sender, uint new_value);\n",
+        "\n",
+        "    constructor(uint init_value) {\n",
+        "        count = init_value;\n",
+        "    }\n",
+        "\n",
+        "    // Function to get the current count\n",
+        "    function get() public view returns (uint) {\n",
+        "        return count;\n",
+        "    }\n",
+        "\n",
+        "    // Function to increment count by 1\n",
+        "    function inc() public {\n",
+        "        count += 1;\n",
+        "        emit Change(msg.sender, count);\n",
+        "    }\n",
+        "}\n",
+        "```\n",
+        "\n",
+        "编译部署此合约后，你可以：\n",
+        "\n",
+        "- 从接口`get`读取`count`的值\n",
+        "- 通过调用`inc`添加变量`count`\n",
+        "\n",
+        "另外，合约在`inc`执行后会发出`Change`事件，我们可以通过分析日志知道链上发生了什么。\n",
+        "\n",
+        "接下来我们将编译上述合约。如果你在本地环境中运行代码，则可能需要运行`pip install py-solc-x`来安装相关依赖。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 3,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "# py-solc-x is already installed in the test environment\n",
+        "from solcx import install_solc, compile_source\n",
+        "source_code = r\"\"\"\n",
+        "// SPDX-License-Identifier: MIT\n",
+        "// modified from https://solidity-by-example.org/first-app/\n",
+        "pragma solidity ^0.8.13;\n",
+        "\n",
+        "contract Counter {\n",
+        "    uint public count;\n",
+        "\n",
+        "    event Change(address indexed sender, uint new_value);\n",
+        "\n",
+        "    constructor(uint init_value) {\n",
+        "        count = init_value;\n",
+        "    }\n",
+        "\n",
+        "    // Function to get the current count\n",
+        "    function get() public view returns (uint) {\n",
+        "        return count;\n",
+        "    }\n",
+        "\n",
+        "    // Function to increment count by 1\n",
+        "    function inc() public {\n",
+        "        count += 1;\n",
+        "        emit Change(msg.sender, count);\n",
+        "    }\n",
+        "}\n",
+        "\"\"\"\n",
+        "metadata = compile_source(\n",
+        "    source_code,\n",
+        "    output_values=['abi', 'bin'],\n",
+        "    solc_version=install_solc(version=\"0.8.13\")\n",
+        ").popitem()[1]\n",
+        "# \"abi\" defines the interface, \"bin\" is the contract bytecode\n",
+        "assert \"abi\" in metadata and \"bin\" in metadata"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 4,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "contract deployed: cfxtest:acc0mmk9t5sukfybrg8sy2sbw49tar6u8jf4r1u7tg\n"
+          ]
+        }
+      ],
+      "source": [
+        "# 根据metadata的abi与bytecode字段初始化contract对象\n",
+        "factory = w3.cfx.contract(abi=metadata[\"abi\"], bytecode=metadata[\"bin\"])\n",
+        "\n",
+        "# 部署合约\n",
+        "tx_receipt = factory.constructor(init_value=0).transact().executed()\n",
+        "contract_address = tx_receipt[\"contractCreated\"]\n",
+        "assert contract_address is not None\n",
+        "print(f\"contract deployed: {contract_address}\")\n",
+        "\n",
+        "# 使用address参数初始化合约，这样我们可以调用该对象的链上接口\n",
+        "deployed_contract = w3.cfx.contract(address=contract_address, abi=metadata[\"abi\"])"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 与已部署的合约交互"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 5,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "counter added to 1\n"
+          ]
+        }
+      ],
+      "source": [
+        "tx_hash = deployed_contract.functions.inc().transact()\n",
+        "inc_receipt = w3.cfx.wait_for_transaction_receipt(tx_hash)\n",
+        "\n",
+        "# \"call\" 代表着模拟执行但不真正发送交易\n",
+        "# 下面两种方法都能调用\"call\"\n",
+        "current_counter = deployed_contract.functions.get().call()\n",
+        "current_counter_ = deployed_contract.caller().get()\n",
+        "assert current_counter == current_counter_ == 1\n",
+        "print(\"counter added to 1\")"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 处理日志\n",
+        "\n",
+        "我们可以通过查看交易日志来了解交易执行中发生了什么。但原始的日志以十六进制编码，可读性较差。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 6,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "raw log: \n",
+            "{'address': 'cfxtest:acc0mmk9t5sukfybrg8sy2sbw49tar6u8jf4r1u7tg',\n",
+            " 'blockHash': HexBytes('0x5d7f3bc654370883359835aa22be509a7a36a8215d011e21bf0c2ca4592c6665'),\n",
+            " 'data': HexBytes('0x0000000000000000000000000000000000000000000000000000000000000001'),\n",
+            " 'epochNumber': 99721993,\n",
+            " 'logIndex': 0,\n",
+            " 'topics': [HexBytes('0x05b5d46649ab2015d3a08705cbaa391e094d9594c393ce89d3afffe960744da1'),\n",
+            "            HexBytes('0x0000000000000000000000001f4bffef33cdf6e6b854f6aaf2c4498f18027bb1')],\n",
+            " 'transactionHash': HexBytes('0x1d703cd4602bb02603b8154ca43ec4f4ff8107e757afd11b4b8d118db03cc222'),\n",
+            " 'transactionIndex': 0,\n",
+            " 'transactionLogIndex': 0}\n"
+          ]
+        }
+      ],
+      "source": [
+        "# get_logs parameter definitions: https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc#cfx_getlogs\n",
+        "fromEpoch = inc_receipt[\"epochNumber\"]\n",
+        "# use get_logs to get raw logs\n",
+        "logs = w3.cfx.get_logs(fromEpoch=fromEpoch, address=contract_address)\n",
+        "print(\"raw log: \")\n",
+        "pprint.pprint(dict(logs[0]))\n"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "在以下部分中，我们将介绍几种处理和过滤日志的方法。\n",
+        "\n",
+        "我们可以使用`contract.event`来处理日志。处理后，日志的`args`字段包含了我们需要的信息。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 7,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "{'address': 'cfxtest:acc0mmk9t5sukfybrg8sy2sbw49tar6u8jf4r1u7tg',\n",
+            " 'args': AttributeDict({'sender': 'CFXTEST:TYPE.USER:AATY199TGTG9R3Z2MX5MZ60EKGHVUAX50EC9SFY3HB', 'new_value': 1}),\n",
+            " 'blockHash': HexBytes('0x5d7f3bc654370883359835aa22be509a7a36a8215d011e21bf0c2ca4592c6665'),\n",
+            " 'epochNumber': 99721993,\n",
+            " 'event': 'Change',\n",
+            " 'logIndex': None,\n",
+            " 'transactionHash': HexBytes('0x1d703cd4602bb02603b8154ca43ec4f4ff8107e757afd11b4b8d118db03cc222'),\n",
+            " 'transactionIndex': 0,\n",
+            " 'transactionLogIndex': 0}\n"
+          ]
+        }
+      ],
+      "source": [
+        "processed_logs = deployed_contract.events.Change.process_receipt(inc_receipt)\n",
+        "processed_log = processed_logs[0]\n",
+        "assert processed_log[\"args\"][\"sender\"] == w3.cfx.default_account\n",
+        "assert processed_log[\"args\"][\"new_value\"] == 1\n",
+        "\n",
+        "# 从交易receipt拿到的日志中, 字段 \"logIndex\" 为 None\n",
+        "pprint.pprint(dict(processed_log))"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "此外，我们可以使用`contract.events`对合约topics进行编码以用于过滤日志"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 8,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "log filtered by topics:\n",
+            "{'address': 'cfxtest:acc0mmk9t5sukfybrg8sy2sbw49tar6u8jf4r1u7tg',\n",
+            " 'blockHash': HexBytes('0x5d7f3bc654370883359835aa22be509a7a36a8215d011e21bf0c2ca4592c6665'),\n",
+            " 'data': HexBytes('0x0000000000000000000000000000000000000000000000000000000000000001'),\n",
+            " 'epochNumber': 99721993,\n",
+            " 'logIndex': 0,\n",
+            " 'topics': [HexBytes('0x05b5d46649ab2015d3a08705cbaa391e094d9594c393ce89d3afffe960744da1'),\n",
+            "            HexBytes('0x0000000000000000000000001f4bffef33cdf6e6b854f6aaf2c4498f18027bb1')],\n",
+            " 'transactionHash': HexBytes('0x1d703cd4602bb02603b8154ca43ec4f4ff8107e757afd11b4b8d118db03cc222'),\n",
+            " 'transactionIndex': 0,\n",
+            " 'transactionLogIndex': 0}\n"
+          ]
+        }
+      ],
+      "source": [
+        "# 编码topics以用于get_logs\n",
+        "filter_topics = deployed_contract.events.Change.get_filter_topics(\n",
+        "    sender=w3.cfx.default_account\n",
+        ")\n",
+        "new_logs = w3.cfx.get_logs(fromEpoch=fromEpoch, topics=filter_topics)\n",
+        "print(\"log filtered by topics:\")\n",
+        "pprint.pprint(dict(new_logs[0]))"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "或者我们可以使用`contract.events`中的`get_logs`接口"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 9,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "processed log from contract event get_logs\n",
+            "{'address': 'cfxtest:acc0mmk9t5sukfybrg8sy2sbw49tar6u8jf4r1u7tg',\n",
+            " 'args': AttributeDict({'sender': 'CFXTEST:TYPE.USER:AATY199TGTG9R3Z2MX5MZ60EKGHVUAX50EC9SFY3HB', 'new_value': 1}),\n",
+            " 'blockHash': HexBytes('0x5d7f3bc654370883359835aa22be509a7a36a8215d011e21bf0c2ca4592c6665'),\n",
+            " 'epochNumber': 99721993,\n",
+            " 'event': 'Change',\n",
+            " 'logIndex': 0,\n",
+            " 'transactionHash': HexBytes('0x1d703cd4602bb02603b8154ca43ec4f4ff8107e757afd11b4b8d118db03cc222'),\n",
+            " 'transactionIndex': 0,\n",
+            " 'transactionLogIndex': 0}\n"
+          ]
+        }
+      ],
+      "source": [
+        "# event get_logs 接口会直接返回已处理的日志\n",
+        "new_processed_logs = deployed_contract.events.Change.get_logs(\n",
+        "    argument_filters={\n",
+        "        \"sender\": w3.cfx.default_account\n",
+        "    },\n",
+        "    fromEpoch=fromEpoch\n",
+        ")\n",
+        "print(\"processed log from contract event get_logs\")\n",
+        "pprint.pprint(dict(new_processed_logs[0]))"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "`conflux_web3`的 api 与`web3.py`的 api 一致。您还可以尝试`web3.py`文档中的示例。\n",
+        "\n",
+        "- https://web3py.readthedocs.io/en/stable/contracts.html\n",
+        "- https://web3py.readthedocs.io/en/stable/examples.html#working-with-contracts\n",
+        "- https://web3py.readthedocs.io/en/stable/examples.html#working-with-an-erc20-token-contract"
+      ]
+    }
+  ],
+  "metadata": {
+    "kernelspec": {
+      "display_name": "Python 3.9.13 ('sdk')",
+      "language": "python",
+      "name": "python3"
+    },
+    "language_info": {
+      "codemirror_mode": {
+        "name": "ipython",
+        "version": 3
+      },
+      "file_extension": ".py",
+      "mimetype": "text/x-python",
+      "name": "python",
+      "nbconvert_exporter": "python",
+      "pygments_lexer": "ipython3",
+      "version": "3.9.13"
+    },
+    "orig_nbformat": 4,
+    "vscode": {
+      "interpreter": {
+        "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+      }
+    }
+  },
+  "nbformat": 4,
+  "nbformat_minor": 2
+}
diff --git a/docs/zh-CN/examples/10-send_raw_transaction.ipynb b/docs/zh-CN/examples/10-send_raw_transaction.ipynb
new file mode 100644
index 0000000..0667a20
--- /dev/null
+++ b/docs/zh-CN/examples/10-send_raw_transaction.ipynb
@@ -0,0 +1,236 @@
+{
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "# 通过`send_raw_transaction`发送交易\n",
+        "\n",
+        "单击顶部栏上的`🚀` -&gt; `Binder`在线运行此示例！\n",
+        "\n",
+        "这个例子展示了如何在不使用`w3.wallet`的情况下签名交易，并通过`send_raw_transaction`发送交易。这种方法更灵活，但同时使用起来也更复杂。如果你希望了解更简单的发送交易的方法，请参考[Quickstart](./01-quickstart.ipynb)中发送交易的示例代码。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 1,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "import pprint\n",
+        "from conflux_web3 import Web3\n",
+        "from conflux_web3.utils import fill_transaction_defaults\n",
+        "\n",
+        "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+        "account = w3.account.from_key(\"0x....\") # 用你的私钥替换 \"0x....\""
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 手动发送交易\n",
+        "\n",
+        "基本上，我们按照如下 4 步来发送交易：\n",
+        "\n",
+        "- 构造交易\n",
+        "- 为交易签名\n",
+        "- 向区块链节点发送交易\n",
+        "- 等待交易执行结果\n",
+        "\n",
+        "如果`w3.wallet`中添加了帐户，SDK 可以帮助将前三步一起完成，否则你需要手动完成前 3 步的内容。"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 构造一个简单的交易\n",
+        "\n",
+        "我们在这里只提供必要的参数，其他参数由`fill_transaction_defaults`填充。也可以阅读[从零开始构造交易](./11-constuct_transaction_from_scratch.ipynb)来了解如何手动填充交易的每个字段。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 2,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "built_trivial_tx = fill_transaction_defaults(w3, {\n",
+        "    'from': account.address,\n",
+        "    'to': w3.account.create().address,\n",
+        "    'value': 100,\n",
+        "})"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 为交易签名"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 3,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "signed_tx = account.sign_transaction(built_trivial_tx)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 发送交易"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 4,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "h = w3.cfx.send_raw_transaction(signed_tx.rawTransaction)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "### 等待交易执行完成"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 5,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "tx_receipt = h.executed()"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "## 与合约交互"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 6,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "deployed contract address: cfxtest:acfgtrw53v4ju9jaydmr9yyf9xyvfxpe0e8ny2fd4d\n"
+          ]
+        }
+      ],
+      "source": [
+        "# 如果需要从合约metadata文件创建合约对象, 使用如下代码\n",
+        "# >>> erc20_metadata = json.load(open(\"path/to/ERC20metadata.json\"))\n",
+        "# >>> erc20 = web3.cfx.contract(bytecode=erc20_metadata[\"bytecode\"], abi=erc20_metadata[\"abi\"])\n",
+        "erc20 = w3.cfx.contract(name=\"ERC20\")\n",
+        "\n",
+        "# 构造交易\n",
+        "# 可以在`build_transaction`中额外指定'from', 'gasPrice' 等交易参数\n",
+        "built_constuct_tx = erc20.constructor(name=\"Coin\", symbol=\"C\", initialSupply=10**18).build_transaction({\n",
+        "    'from': account.address,\n",
+        "})\n",
+        "# 签名交易\n",
+        "construct_tx = account.sign_transaction(built_constuct_tx)\n",
+        "# 发送交易并等待执行结果\n",
+        "contract_address = w3.cfx.send_raw_transaction(construct_tx.rawTransaction).executed()['contractCreated']\n",
+        "print(f\"deployed contract address: {contract_address}\")"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 7,
+      "metadata": {},
+      "outputs": [
+        {
+          "name": "stdout",
+          "output_type": "stream",
+          "text": [
+            "erc20 transfer receipt: \n",
+            "{'blockHash': HexBytes('0x9b8a0a0e5eb33d67b2c85d4e951b0251e1b972cd00f7c18c53ecacb7fd7edfd3'),\n",
+            " 'contractCreated': None,\n",
+            " 'epochNumber': 99051304,\n",
+            " 'from': 'cfxtest:aanhtnrex2nj56kkbws4yx0jeab34ae16pcap53w13',\n",
+            " 'gasCoveredBySponsor': False,\n",
+            " 'gasFee': 37063000000000 Drip,\n",
+            " 'gasUsed': 37063,\n",
+            " 'index': 0,\n",
+            " 'logs': [AttributeDict({'address': 'cfxtest:acfgtrw53v4ju9jaydmr9yyf9xyvfxpe0e8ny2fd4d', 'topics': [HexBytes('0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'), HexBytes('0x0000000000000000000000001677ada49e168df1290c9daa4ec820039d0097e3'), HexBytes('0x0000000000000000000000001ab7c2bb12a3484451a55ed15285a4cf10196312')], 'data': HexBytes('0x0000000000000000000000000000000000000000000000000000000000000064')})],\n",
+            " 'logsBloom': HexBytes('0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000200008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000040000200000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000200000000400000000000000000000020000000000000000'),\n",
+            " 'outcomeStatus': 0,\n",
+            " 'stateRoot': HexBytes('0xa14515ac4ad59a0ab8b7c4c1740eb5a97d0b55eabf3b5a0b185867e41d1a1699'),\n",
+            " 'storageCollateralized': 64,\n",
+            " 'storageCoveredBySponsor': False,\n",
+            " 'storageReleased': [],\n",
+            " 'to': 'cfxtest:acfgtrw53v4ju9jaydmr9yyf9xyvfxpe0e8ny2fd4d',\n",
+            " 'transactionHash': HexBytes('0x224e75f10580194685cd2566bd7ec5fdefd09578fe770bddae2ba9f77842f11a'),\n",
+            " 'txExecErrorMsg': None}\n"
+          ]
+        }
+      ],
+      "source": [
+        "# 与已部署的合约交互\n",
+        "contract = w3.cfx.contract(address=contract_address, name=\"ERC20\")\n",
+        "\n",
+        "# 构造交易\n",
+        "# 可以在`build_transaction`中额外指定'from', 'gasPrice' 等交易参数\n",
+        "built_transfer_tx = contract.functions.transfer(\n",
+        "    w3.account.create().address,\n",
+        "    100\n",
+        ").build_transaction({\n",
+        "    'from': account.address\n",
+        "})\n",
+        "\n",
+        "# 签名交易\n",
+        "signed_transfer_tx = account.sign_transaction(\n",
+        "    built_transfer_tx\n",
+        ")\n",
+        "\n",
+        "# 发送交易并等待执行结果\n",
+        "print(\"erc20 transfer receipt: \")\n",
+        "pprint.pprint(\n",
+        "    dict(w3.cfx.send_raw_transaction(signed_transfer_tx.rawTransaction).executed())\n",
+        ")"
+      ]
+    }
+  ],
+  "metadata": {
+    "kernelspec": {
+      "display_name": "Python 3.9.13 ('sdk')",
+      "language": "python",
+      "name": "python3"
+    },
+    "language_info": {
+      "codemirror_mode": {
+        "name": "ipython",
+        "version": 3
+      },
+      "file_extension": ".py",
+      "mimetype": "text/x-python",
+      "name": "python",
+      "nbconvert_exporter": "python",
+      "pygments_lexer": "ipython3",
+      "version": "3.9.13"
+    },
+    "orig_nbformat": 4,
+    "vscode": {
+      "interpreter": {
+        "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+      }
+    }
+  },
+  "nbformat": 4,
+  "nbformat_minor": 2
+}
diff --git a/docs/zh-CN/examples/11-construct_transaction_from_scratch.ipynb b/docs/zh-CN/examples/11-construct_transaction_from_scratch.ipynb
new file mode 100644
index 0000000..63c2692
--- /dev/null
+++ b/docs/zh-CN/examples/11-construct_transaction_from_scratch.ipynb
@@ -0,0 +1,88 @@
+{
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "# 从零开始构建交易\n",
+        "\n",
+        "单击顶部栏上的`🚀` -&gt; `Binder`在线运行此示例！"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 1,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "from conflux_web3 import Web3\n",
+        "\n",
+        "w3 = Web3(Web3.HTTPProvider(\"https://test.confluxrpc.com\"))\n",
+        "account = w3.account.from_key(\"0x....\") # fill your secret key here"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {},
+      "source": [
+        "[这里](https://developer.confluxnetwork.org/introduction/en/conflux_basics#transaction-fields)解释了每个字段的含义。下面展示了各个字段的常见构造方法。"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": null,
+      "metadata": {},
+      "outputs": [],
+      "source": [
+        "prebuilt_tx = {\n",
+        "    'from': account.address,\n",
+        "    'nonce': w3.cfx.get_next_nonce(account.address),\n",
+        "    'to': w3.account.create().address,\n",
+        "    'value': 100,\n",
+        "    'gasPrice': w3.cfx.gas_price,\n",
+        "    'chainId': w3.cfx.chain_id,\n",
+        "    # 'gas': 21000, \n",
+        "    # 'storageLimit': 0,\n",
+        "    'epochHeight': w3.cfx.epoch_number\n",
+        "}\n",
+        "\n",
+        "# estimate\n",
+        "estimate_result = w3.cfx.estimate_gas_and_collateral(prebuilt_tx)\n",
+        "\n",
+        "prebuilt_tx['gas'] = estimate_result['gasLimit']\n",
+        "prebuilt_tx['storageLimit'] = estimate_result['storageCollateralized']\n",
+        "\n",
+        "w3.cfx.send_raw_transaction(\n",
+        "    account.sign_transaction(prebuilt_tx).rawTransaction \n",
+        ").executed()"
+      ]
+    }
+  ],
+  "metadata": {
+    "kernelspec": {
+      "display_name": "Python 3.9.13 ('sdk')",
+      "language": "python",
+      "name": "python3"
+    },
+    "language_info": {
+      "codemirror_mode": {
+        "name": "ipython",
+        "version": 3
+      },
+      "file_extension": ".py",
+      "mimetype": "text/x-python",
+      "name": "python",
+      "nbconvert_exporter": "python",
+      "pygments_lexer": "ipython3",
+      "version": "3.9.13"
+    },
+    "orig_nbformat": 4,
+    "vscode": {
+      "interpreter": {
+        "hash": "a3057bbf184bca29acc6a0538c16f383babaf4f383bee8205e8e826137244d0e"
+      }
+    }
+  },
+  "nbformat": 4,
+  "nbformat_minor": 2
+}
diff --git a/examples/01-quick_start.py b/examples/01-quick_start.py
deleted file mode 100644
index 5260e5f..0000000
--- a/examples/01-quick_start.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import os, pprint
-from conflux_web3 import Web3
-
-web3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
-
-# Run export TESTNET_SECRET="0xxxxxxxxx" in your console, where "0xxxxxxxxx" is your testnet secret key
-# You can claim testnet token at https://faucet.confluxnetwork.org/
-account = web3.account.from_key(os.environ.get("TESTNET_SECRET"))
-web3.wallet.add_account(account)
-web3.cfx.default_account = account
-
-balance = web3.cfx.get_balance(account.address)
-assert balance > 0
-
-# send 1 CFX to a random address
-tx_hash = web3.cfx.send_transaction({
-    "to": web3.account.create().address,
-    "value": 1**18,
-})
-# in Conflux, the transaction will be executed only after it appears on the chain for 5 epoch 
-# tx_hash.executed() is equivalent to web3.cfx.wait_for_transaction_receipt(tx_hash)
-tx_receipt = tx_hash.executed()
-pprint.pprint(dict(tx_receipt))
diff --git a/examples/02-address_account_and_wallet.py b/examples/02-address_account_and_wallet.py
deleted file mode 100644
index 8b273d1..0000000
--- a/examples/02-address_account_and_wallet.py
+++ /dev/null
@@ -1,60 +0,0 @@
-import os
-from cfx_address import Base32Address
-from conflux_web3 import Web3
-
-web3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
-# web3.account is a cfx_account.Account object inherited from eth_account.Account
-# most of its apis are consistent with eth_account (https://eth-account.readthedocs.io/en/stable/eth_account.html)
-random_account = web3.account.create()
-# account created from web3.account will have the same network_id as web3.cfx.chain_id
-print(f"network id of the account: {random_account.network_id}")
-
-# a Base32Address object, see https://github.com/Conflux-Chain/CIPs/blob/master/CIPs/cip-37.md for more information
-addr = random_account.address
-
-print(f"account address: {addr}") # expected to be cfxtest:a....
-print(f"account private key: {addr}")
-
-# the network id of an account can be set
-random_account.network_id = 1029
-print(f"account address after network id changing: {random_account.address}") # expected to be cfx:a....
-
-
-
-# a Base32Address is also a str
-assert isinstance(addr, Base32Address)
-assert isinstance(addr, str)
-# visit https://conflux-fans.github.io/cfx-address/cfx_address.html#module-cfx_address.address for more information
-address = Base32Address("0x1ecde7223747601823f7535d7968ba98b4881e09", network_id=1)
-print([
-    address.address_type,
-    address.network_id,
-    address.hex_address,
-    address.verbose_address,
-    address.abbr,
-    address.mapped_evm_space_address,
-    address.eth_checksum_address,
-])
-
-
-
-# wallet serves as a middleware for conflux_web3 and contains a collection of LocalAccount
-assert web3.wallet is web3.middleware_onion["wallet"]
-secret = os.environ.get("TESTNET_SECRET")
-account = web3.account.from_key(secret)
-
-random_account.network_id = web3.cfx.chain_id
-web3.wallet.add_account(account)
-# if the transaction["from"] account is in the wallet
-web3.cfx.send_transaction({
-    "from": account.address,
-    "to": random_account.address,
-    "value": 10**18
-}).executed()
-
-# or set the web3.cfx.default_account, then the from field of the transaction can be automatically filled
-web3.cfx.default_account = account.address
-web3.cfx.send_transaction({
-    "to": random_account.address,
-    "value": 10**18
-}).executed()
diff --git a/examples/03-query_and_lookup.py b/examples/03-query_and_lookup.py
deleted file mode 100644
index b5f84d6..0000000
--- a/examples/03-query_and_lookup.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from conflux_web3.dev import get_testnet_web3
-
-# equivalent to Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
-web3 = get_testnet_web3()
-
-status = web3.cfx.get_status()
-
-block_hash = "0x10a721e2654523a7ff682c1c8d3f868a9fdf78a3be1858bbe1f06147128d6d94"
-transaction_hash = "0x10a721e2654523a7ff682c1c8d3f868a9fdf78a3be1858bbe1f06147128d6d94"
-
-# get transaction data/receipt by hash
-transaction_data = web3.cfx.get_transaction_by_hash(transaction_hash)
-transaction_receipt = web3.cfx.get_transaction_receipt(transaction_hash)
-
-block_data = web3.cfx.get_block_by_hash(block_hash)
-# an epoch number (int) or epoch number tag (str) can be the parameter, 
-# see https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc#the-default-epochnumber-parameter for more information
-latest_state_block = web3.cfx.get_block_by_epoch_number("latest_state")
-
-# besides above, conflux-web3 supports all rpc methods under cfx Namespace
-# see https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc#json-rpc-methods for more information
diff --git a/examples/04-interact_with_contracts_and_logs.py b/examples/04-interact_with_contracts_and_logs.py
deleted file mode 100644
index e4e1513..0000000
--- a/examples/04-interact_with_contracts_and_logs.py
+++ /dev/null
@@ -1,79 +0,0 @@
-import json, os, pprint
-from conflux_web3 import Web3
-
-web3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
-web3.wallet.add_account(
-    account := web3.account.from_key(os.environ.get("TESTNET_SECRET"))
-)
-web3.cfx.default_account = account.address
-
-# if you want to get contract object from metadata file, uses 
-# >>> erc20_metadata = json.load(open("path/to/ERC20metadata.json"))
-# >>> erc20 = web3.cfx.contract(bytecode=erc20_metadata["bytecode"], abi=erc20_metadata["abi"])
-erc20 = web3.cfx.contract(name="ERC20")
-
-# you might need to change the argument name depending on the solidity source code
-# below works if wallet middleware and default account is set 
-# see examples/10-send_raw_transactions.py if you want to manually sign and send transactions
-hash = erc20.constructor(name="Coin", symbol="C", initialSupply=10**18).transact()
-# or use 
-# contract_address = hash.executed()["contractCreated"]
-contract_address = web3.cfx.wait_for_transaction_receipt(hash)["contractCreated"] 
-assert contract_address is not None
-print(f"contract deployed: {contract_address}")
-print()
-
-contract = web3.cfx.contract(contract_address, name="ERC20")
-random_account = web3.account.create()
-# contract.functions.transfer(random_account.address, 100) prebuilt the transaction
-# the transaction is not send until .transact() is called
-prebuilt_tx = contract.functions.transfer(random_account.address, 100)
-hash = prebuilt_tx.transact()
-transfer_receipt = web3.cfx.wait_for_transaction_receipt(hash)
-
-# 2 ways to call, either is ok
-balance = contract.functions.balanceOf(random_account.address).call()
-balance1 = contract.caller().balanceOf(random_account.address)
-assert balance1 == balance == 100
-print("transfer success")
-print()
-
-# parameter definitions: https://developer.confluxnetwork.org/conflux-doc/docs/json_rpc#cfx_getlogs
-fromEpoch = transfer_receipt["epochNumber"]
-logs = web3.cfx.get_logs(fromEpoch=fromEpoch, address=contract_address)
-print("raw log: ")
-pprint.pprint(dict(logs[0]))
-print()
-    
-# use contract event to process logs
-processed_logs = contract.events.Transfer.process_receipt(transfer_receipt)
-processed_log = processed_logs[0]
-assert processed_log["args"]["from"] == web3.cfx.default_account
-assert processed_log["args"]["to"] == random_account.address
-assert processed_log["args"]["value"] == 100
-# for log in transaction["logs"], field "logIndex" are not included
-print("processed log: (no logIndex)")
-pprint.pprint(dict(processed_log))
-print()
-
-# generate topics to use getLogs
-filter_topics = contract.events.Transfer.get_filter_topics(
-    value=100,
-    to=random_account.address
-)
-new_logs = web3.cfx.get_logs(fromEpoch=fromEpoch, topics=filter_topics)
-print("log filtered by topics:")
-pprint.pprint(dict(new_logs[0]))
-print()
-
-# event get_logs will return processed logs
-new_processed_logs = contract.events.Transfer.get_logs(
-    argument_filters={
-        "value": 100,
-        "to": random_account.address
-    },
-    fromEpoch=fromEpoch
-)
-print("processed log from contract event get_logs")
-pprint.pprint(dict(new_processed_logs[0]))
-print()
diff --git a/examples/10-send_raw_transaction.py b/examples/10-send_raw_transaction.py
deleted file mode 100644
index e6b8f0f..0000000
--- a/examples/10-send_raw_transaction.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# This example shows how to sign and send transactions without using web3.wallet
-# This method provides is more flexible but is also more complex than using wallet
-# If you are new to web3 development, we recommend you refer to the example to send transactions in examples/01_quick_start.py
-
-import os, json, pprint
-from conflux_web3 import Web3
-from conflux_web3.utils import fill_transaction_defaults
-
-web3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
-account = web3.account.from_key(os.environ.get("TESTNET_SECRET"))
-
-# Basiclly, we follow the workflow of 4 steps to send a transaction:
-#    "build transaction" 
-# -> "sign transaction" 
-# -> "send transaction to the blockchain node(s)" 
-# -> "wait for transaction execution result"
-# if any account is added to the wallet, the first 3 steps will be combined,
-# otherwise you will need to do the first 3 steps individually
-
-# "build transaction"
-# we provide necessary params here, and other params are filled
-# see 11-constuct_transaction_from_scratch.py to see how to construct a transaction from scratch
-built_trivial_tx = fill_transaction_defaults(web3, {
-    'from': account.address,
-    'to': web3.account.create().address,
-    'value': 100,
-})
-# "sign transaction"
-signed_tx = account.sign_transaction(built_trivial_tx)
-# "send transaction to the blockchain node(s)"
-h = web3.cfx.send_raw_transaction(signed_tx.rawTransaction)
-# "wait"
-tx_receipt = h.executed()
-pprint.pprint(dict(tx_receipt))
-
-
-# if you want to get contract object from metadata file, uses 
-# >>> erc20_metadata = json.load(open("path/to/ERC20metadata.json"))
-# >>> erc20 = web3.cfx.contract(bytecode=erc20_metadata["bytecode"], abi=erc20_metadata["abi"])
-erc20 = web3.cfx.contract(name="ERC20")
-
-# "build transaction"
-built_constuct_tx = erc20.constructor(name="Coin", symbol="C", initialSupply=10**18).build_transaction({
-    'from': account.address,
-})
-# "sign transaction"
-construct_tx = account.sign_transaction(built_constuct_tx)
-# "send" & "wait"
-contract_address = web3.cfx.send_raw_transaction(construct_tx.rawTransaction).executed()['contractCreated']
-print(f"deployed contract address: f{contract_address}")
-
-
-# interact with contract
-contract = web3.cfx.contract(address=contract_address, name="ERC20")
-# "build transaction"
-built_transfer_tx = contract.functions.transfer(
-    web3.account.create().address,
-    100
-).build_transaction({
-    'from': account.address
-})
-# "sign transaction"
-signed_transfer_tx = account.sign_transaction(
-    built_transfer_tx
-)
-# "send" and "wait"
-print("erc20 transfer receipt: ")
-pprint.pprint(
-    dict(web3.cfx.send_raw_transaction(signed_transfer_tx.rawTransaction).executed())
-)
diff --git a/examples/11-construct_transaction_from_scratch.py b/examples/11-construct_transaction_from_scratch.py
deleted file mode 100644
index 27a89dd..0000000
--- a/examples/11-construct_transaction_from_scratch.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# this example shows how to constuct a transaction from scratch
-# If you are new to web3 development, we recommend you refer to the example to send transactions in examples/01_quick_start.py
-
-import os, pprint
-from conflux_web3 import Web3
-
-
-web3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com"))
-account = web3.account.from_key(os.environ.get("TESTNET_SECRET"))
-
-prebuilt_tx = {
-    'from': account.address,
-    'nonce': web3.cfx.get_next_nonce(account.address),
-    'to': web3.account.create().address,
-    'value': 100,
-    'gasPrice': web3.cfx.gas_price,
-    'chainId': web3.cfx.chain_id,
-    # 'gas': 21000, 
-    # 'storageLimit': 0,
-    'epochHeight': web3.cfx.epoch_number
-}
-
-# estimate
-estimate_result = web3.cfx.estimate_gas_and_collateral(prebuilt_tx)
-
-prebuilt_tx['gas'] = estimate_result['gasLimit']
-prebuilt_tx['storageLimit'] = estimate_result['storageCollateralized']
-
-tx_receipt = web3.cfx.send_raw_transaction(
-    account.sign_transaction(prebuilt_tx).rawTransaction 
-).executed()
-pprint.pprint(dict(tx_receipt))
diff --git a/postBuild b/postBuild
new file mode 100644
index 0000000..e92d7d7
--- /dev/null
+++ b/postBuild
@@ -0,0 +1,3 @@
+#!/bin/bash
+set -e
+pip install py-solc-x
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 3ab7efb..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-# hexbytes~=0.2.1
-web3~=6.0.0b4
-cfx-account>=0.1.0b2
-cfx-address~=0.0.4
-# eth-account~=0.5.4
-# cytoolz~=0.11.0
-# rlp~=2.0.1
-# setuptools~=54.1.2
\ No newline at end of file
diff --git a/runtime.txt b/runtime.txt
new file mode 100644
index 0000000..3cd3102
--- /dev/null
+++ b/runtime.txt
@@ -0,0 +1,1 @@
+python-3.8
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 7174c72..b79d655 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@
     setup,
 )
 
-VERSION = "1.0.0-beta.6"
+VERSION = "1.0.0-beta.7"
 DESCRIPTION = 'Python SDK for Conflux network'
 with open('./README.md') as readme:
     long_description = readme.read()
@@ -14,14 +14,15 @@
     'tester': [
         "docker>=5.0.0,<6",
         "pytest>=6.2.5,<7",
-        "typing_extensions"
+        "typing_extensions",
+        "pytest-cov",
         # "py-geth>=3.8.0,<4",
     ],
     'linter': [
         "black>=22.1.0,<23.0",
         # "flake8==3.8.3",
         # "isort>=4.2.15,<4.3.5",
-        "mypy==0.910",
+        # "mypy==0.910",
         # "types-setuptools>=57.4.4,<58",
         # "types-requests>=2.26.1,<3",
         # "types-protobuf==3.19.13",
@@ -35,7 +36,8 @@
         # "py-geth>=3.8.0,<4",
         # "py-solc>=0.4.0",
         # "pytest>=6.2.5,<7",
-        "sphinx>=4.2.0,<5",
+        # "sphinx>=4.2.0,<5",
+        "jupyter-book",
         # "sphinx_rtd_theme>=0.1.9",
         # "toposort>=1.4",
         # "towncrier==18.5.0",
@@ -85,10 +87,10 @@
                   "cfxpm": ["py.typed"]},
     url='https://github.com/conflux-chain/python-conflux-sdk',
     install_requires=[
-        "web3==6.0.0b5",
-        "cfx-address>=1.0.0b13",
-        "cfx-account>=0.1.0b6",
-        "cfx-utils>=1.0.0b10",
+        "web3==6.0.0b7",
+        "cfx-address>=1.0.0b14",
+        "cfx-account>=0.1.0b8",
+        "cfx-utils>=1.0.0b12",
         "cached_property==1.5.2",
         # "eth-account>=0.6.0,<0.7.0"
     ],  # add any additional packages that


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 56b31b7..f9e38a8 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -14,7 +14,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        python-version: ["3.8", "3.9", "3.10"]
+        python-version: ["3.8", "3.9", "3.10"] # 3.7 is tested in coverage
 
     steps:
     - uses: actions/checkout@v3
diff --git a/tests/_test_helpers/node.py b/tests/_test_helpers/node.py
index c5f4963..481dfde 100644
--- a/tests/_test_helpers/node.py
+++ b/tests/_test_helpers/node.py
@@ -104,8 +104,9 @@ def __init__(self, image_name=DEV_IMAGE_FULL_NAME, node_name=LOCAL_NODE_NAME):
         self._node_name = node_name
         self._url = f"http://{LOCAL_HOST}:{PORT}"
         self._client = docker.from_env()
+        container = get_existed_container(self._client, self._node_name)
         
-        if container := get_existed_container(self._client, self._node_name):
+        if container:
             self._container = container
         else:
             pull_image(self._client, self._image_name)
@@ -166,8 +167,8 @@ def __init__(self, image_name=TESTNET_IMAGE_FULL_NAME, node_name=TESTNET_NODE_NA
         self._node_name = node_name
         self._url = f"http://{LOCAL_HOST}:{TESTNET_HOST_PORT}"
         self._client = docker.from_env()
-        
-        if container := get_existed_container(self._client, self._node_name):
+        container = get_existed_container(self._client, self._node_name)
+        if container:
             self._container = container
         else:
             pull_image(self._client, self._image_name)
diff --git a/tests/_test_helpers/type_check.py b/tests/_test_helpers/type_check.py
index 9cc55cb..59360fa 100644
--- a/tests/_test_helpers/type_check.py
+++ b/tests/_test_helpers/type_check.py
@@ -1,22 +1,19 @@
 from typing import (
     Any,
     ForwardRef,
-    Literal,
     Type,
-    TypedDict, 
-    get_args, 
-    get_origin, 
     Union,
 )
 import typing
 import sys
 from typing_extensions import (
+    Literal,
+    TypedDict, 
+    get_args,
+    get_origin, 
     is_typeddict,
 )
 import collections.abc
-import warnings
-
-from cfx_address import Base32Address
 
 import conflux_web3.types
 
diff --git a/tests/middleware/test_wallet.py b/tests/middleware/test_wallet.py
index b5e4432..effbaba 100644
--- a/tests/middleware/test_wallet.py
+++ b/tests/middleware/test_wallet.py
@@ -102,7 +102,8 @@ def test_default_wallet_middleware_adding(w3: Web3, account: LocalAccount):
 
 def test_wallet_duplicate_adding_warning(w3: Web3):
     with pytest.warns(UserWarning):
-        wallet = Wallet(random_account:=w3.account.create(), w3.cfx.chain_id)
+        random_account = w3.account.create()
+        wallet = Wallet(random_account, w3.cfx.chain_id)
         wallet.add_account(random_account)
 
 def test_wallet_chain_id_compatibility(w3: Web3):
@@ -127,17 +128,28 @@ def test_wallet_chain_id_compatibility(w3: Web3):
 
 def test_wallet_accounts_property():
     wallet = Wallet()
+    account = Account.create()
     wallet.add_account(
-        account := Account.create()
+        account
     )
     assert account.address in wallet.accounts
     
 def test_wallet_operators():
     wallet = Wallet()
+    account = Account.create()
     wallet.add_account(
-        account := Account.create()
+        account
     )
     # __contains__
     assert account.address in wallet
     # __getitem__
     assert wallet[account.address]
+
+def test_wallet_pop():
+    wallet = Wallet()
+    account = Account.create()
+    wallet.add_account(
+        account
+    )
+    assert wallet.pop(account.address).address == account.address
+    assert account.address not in wallet
diff --git a/tests/rpcs/test_cfx_rpcs.py b/tests/rpcs/test_cfx_rpcs.py
index 5b74b35..2df92d9 100644
--- a/tests/rpcs/test_cfx_rpcs.py
+++ b/tests/rpcs/test_cfx_rpcs.py
@@ -190,12 +190,12 @@ def test_get_transaction_count(self, w3: Web3, address):
         nonce = w3.cfx.get_transaction_count(address)
         assert nonce >= 0
 
-    def test_get_next_nonce_empty_param(self, w3: Web3, use_testnet):
-        # TODO: remove use_testnet if statement after testnet node is repaired
-        if use_testnet:
-            return
-        with pytest.raises(ValueError):
-            w3.cfx.get_next_nonce()
+    # def test_get_next_nonce_empty_param(self, w3: Web3, use_testnet):
+    #     # TODO: remove use_testnet if statement after testnet node is repaired
+    #     if use_testnet:
+    #         return
+    #     with pytest.raises(ValueError):
+    #         w3.cfx.get_next_nonce()
 
 def test_get_tx(moduled_w3: Web3, contract_address):
     """test get_transaction(_by_hash) and get_transaction_receipt
diff --git a/tests/utils/test_test_utils.py b/tests/utils/test_test_utils.py
index 10d91a7..2bd598b 100644
--- a/tests/utils/test_test_utils.py
+++ b/tests/utils/test_test_utils.py
@@ -1,9 +1,11 @@
 from typing import (
     List,
-    TypedDict,
     Union,
     Sequence,
 )
+from typing_extensions import (
+    TypedDict,
+)
 from tests._test_helpers.type_check import (
     TypeValidator
 )