1. 程式人生 > >Python與以太坊互動實戰

Python與以太坊互動實戰

Python與鏈上互動

環境

  • Linux VM-0-11-ubuntu 4.4.0-130-generic
  • Python3.6
  • vim 8.0

安裝

  • node 和 npm 安裝
  • 安裝web3.py

    $ sudo pip3.6 install web3
    • 需要注意的幾個點:
      • 必須要python3.5以上,實測3.6 ok
      • 安裝過程中報錯正常,可能缺少依賴,參考這裡
  • 安裝pysolc
$ sudo pip3.6 install py-solc

執行

  • 我們測試最簡單的一個合約
pragma solidity ^0.4.4;
contract MyTest {
    function
multiply(uint a) public pure returns(uint d) {
return a * 7; } function say() public pure returns (string) { return "Hello Contract"; } function deposit() returns(address){ return msg.sender; } }
# -*- coding:utf8 -*-
from web3 import Web3, HTTPProvider # from web3.contract import ConciseContract import logging class BaseEthDao(object): def __init__(self, http_addr=''): self.web3 = self.get_web3(http_addr) def get_web3(self, http_addr): if not http_addr: http_addr = 'http://localhost:8545'
return Web3(HTTPProvider(http_addr)) def to_check_addr(self, addr): return Web3.toChecksumAddress(addr) def check_addr(self, addr): return Web3.isChecksumAddress(addr) def get_balance(self, addr): try: balance = self.web3.eth.getBalance(addr) return 0, balance except Exception as e: return -1, str(e)

contract_dal.py

# -*- coding:utf8 -*-
from base_dao import BaseEthDao
from solc import compile_source


def compile_source_file(file_path):
    with open(file_path, 'rt') as f:
       source = f.read()
    return compile_source(source)


class ContractDal(BaseEthDao):
    def __init__(self, contract_addr="", abi="", http_addr=""):
        super().__init__(http_addr)
        self.addr = contract_addr
        self.abi = abi

    def set_addr(self, addr):
        self.addr = addr

    def set_abi(self, abi):
        self.abi = abi

    def get_contract_instance(self, addr="", abi=""):
        if not addr:
            addr = self.addr
        if not abi:
            abi = self.abi
        if not self.check_addr(addr):
            addr = self.to_check_addr(addr)
        try:
            contract_instance = self.web3.eth.contract(address=addr, abi=abi)
            return 0, contract_instance
        except Exception as e:
            return -1, str(e)

    def get_abi(self, sol_path):
        compiled_sol = compile_source_file(sol_path)
        contract_id, contract_interface = compiled_sol.popitem()
        return contract_interface["abi"]

    def compile_sol(self, file_path):
        compiled_sol = compile_source_file(file_path)
        contract_id, contract_interface = compiled_sol.popitem()
        return contract_id, contract_interface


if __name__ == "__main__":
    contract_dal = ContractDal()
    # addr是合約地址,在truffle部署之後的build檔案中找到對應的json檔案可以發現裡面的address
    code, contract_instance = contract_dal.get_contract_instance(addr='0xd0021ccef861690cf2fbfadec87c10cb666c2719',
                                                                 abi=contract_dal.get_abi('./Greeter.sol'))
    print(contract_instance.functions.say().call())
  • 執行上面程式碼
$ python3.6 install contract_dal.py

流程走通