建议和反馈

请填写你的反馈内容

使用Python编译,部署和调用以太坊智能合约

2020-01-13 ·4489次阅读 ·读完需要2分钟

我们在Ubuntu 16.04上使用Python 3.5.3,并进行以下设置:

  1. pip3 install web3==4.7.2 py-solc==3.2.0

  2. python3 -m solc.install v0.4.24

  3. export PATH="$PATH:$HOME/.py-solc/solc-v0.4.24/bin

核心软件包是:

  1. web3  :与以太坊区块链交互的官方python界面

  2. py-solcsolcsolidity编译器)的官方python包装器。因此solc需要安装(在上面的设置中覆盖)

要在文件(.sol)中编译实体智能合约,我们可以使用以下方法:

  1. def compile_contract(contract_source_file, contractName=None):

  2.    """

  3.    Reads file, compiles, returns contract name and interface

  4.    """

  5.    with open(contract_source_file, "r") as f:

  6.        contract_source_code = f.read()

  7.    compiled_sol = compile_source(contract_source_code) # Compiled source code

  8.    if not contractName:

  9.        contractName = list(compiled_sol.keys())[0]

  10.        contract_interface = compiled_sol[contractName]

  11.    else:

  12.        contract_interface = compiled_sol[':' + contractName]        

  13.    return contractName, contract_interface

要部署已编译的智能合约,我们使用:

  1. def deploy_contract(acct, contract_interface, contract_args=None):

  2.    """

  3.    deploys contract using self-signed tx, waits for receipt, returns address

  4.    """

  5.    contract = w3.eth.contract(abi=contract_interface['abi'], bytecode=contract_interface['bin'])

  6.    constructed = contract.constructor() if not contract_args else contract.constructor(*contract_args)

  7.    tx = constructed.buildTransaction({

  8.        'from': acct.address,

  9.        'nonce': w3.eth.getTransactionCount(acct.address),

  10.    })

  11.    print ("Signing and sending raw tx ...")

  12.    signed = acct.signTransaction(tx)

  13.    tx_hash = w3.eth.sendRawTransaction(signed.rawTransaction)

  14.    print ("tx_hash = {} waiting for receipt ...".format(tx_hash.hex()))

  15.    tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash, timeout=120)

  16.    contractAddress = tx_receipt["contractAddress"]

  17.    print ("Receipt accepted. gasUsed={gasUsed} contractAddress={contractAddress}".format(**tx_receipt))

  18.    return contractAddress

部署后,我们可以创建合约对象来调用其公共读取方法或属性:

  1. contract = w3.eth.contract(address=contract_address, abi=contract_interface['abi'])

  2. # call public methods

  3. val = contract.functions.get().call()

  4. # call public attributes

  5. val = contract.functions.storedData().call()

但是为了调用write / update方法,我们需要创建一个事务:

  1. def exec_contract(acct, nonce, func):

  2.    """

  3.    call contract transactional function func

  4.    """

  5.    construct_txn = func.buildTransaction({'from': acct.address, 'nonce': nonce})

  6.    signed = acct.signTransaction(construct_txn)

  7.    tx_hash = w3.eth.sendRawTransaction(signed.rawTransaction)

  8.    return tx_hash.hex()

这是一个使用上述方法来编译,部署和调用简单智能合约的示例:

  1. // contract.sol

  2. pragma solidity ^0.4.21;

  3. contract simplestorage {

  4.  uint public storedData;

  5.  event Updated(address by, uint _old, uint _new);

  6.  function set(uint x) {

  7.    uint old = storedData;

  8.    storedData = x;

  9.    emit Updated(msg.sender, old, x);

  10.  }

  11.  function get() constant returns (uint retVal) {

  12.    return storedData;

  13.  }

  14. }

    1. from web3 import Web3, HTTPProvider

    2. from solc import compile_source

    3. import random

    4. # config

    5. RPC_ADDRESS = 'http://localhost:8545'

    6. CONTRACT_SOL = 'contract.sol'

    7. CONTRACT_NAME = 'simplestorage'

    8. PRIVATE_KEY = "yourprivatekey"

    9. # instantiate web3 object

    10. w3 = Web3(HTTPProvider(RPC_ADDRESS, request_kwargs={'timeout': 120}))    

    11. acct = w3.eth.account.privateKeyToAccount(PRIVATE_KEY)

    12. # compile contract to get abi

    13. print('Compiling contract..')

    14. contract_name, contract_interface = compile_contract(CONTRACT_SOL, CONTRACT_NAME)

    15. # deploy contract    

    16. print('Deploying contract..')

    17. contract_address = deploy_contract(acct, contract_interface)

    18. # create contract object

    19. contract = w3.eth.contract(address=contract_address, abi=contract_interface['abi'])

    20. # call non-transactional method

    21. val = contract.functions.get().call()

    22. print('Invoke get()={}'.format(val))

    23. assert val == 0

    24. # call transactional method

    25. nonce = w3.eth.getTransactionCount(acct.address)

    26. from_block_number = w3.eth.blockNumber  

    27. new_val = random.randint(1, 100)      

    28. contract_func = contract.functions.set(new_val)

    29. print('Invoke set()={}'.format(new_val))

    30. tx_hash = exec_contract(acct, nonce, contract_func)

    31. print('tx_hash={} waiting for receipt..'.format(tx_hash))

    32. tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash, timeout=120)        

    33. print("Receipt accepted. gasUsed={gasUsed} blockNumber={blockNumber}". format(**tx_receipt))

    34. # catch event

    35. contract_filter = contract.events.Updated.createFilter(fromBlock=from_block_number)

    36. entries = None

    37. print('Waiting for event..')

    38. while not entries: entries = contract_filter.get_all_entries()    

    39. # _new == new_val

    40. args = entries[0].args

    41. print(args)

    42. assert args._old == 0

    43. assert args._new == new_val

    44. assert args.by == acct.address

    45. # call non-transactional method

    46. val = contract.functions.get().call()

    47. print('Invoke get()={}'.format(val))

    48. assert val == new_val

如果您使用的是infura.io,则此代码也将适用,但“ catch event”部分除外,因为infura.io不支持  eth_newFilter

完整的代码可以在我的github中找到。请享用!

评论(0)问答(0)
请先登录或注册

请先登陆或注册

相关推荐

形象理解生态最活跃的公链金融生态:以太坊的四层「乐高」

以太坊作为一个生机勃勃的繁荣生态系统,有着推动自身成倍增长的网络效应。在以太坊之上建立的金融体系作为货币的 ETH比特币,作为一个设计十分简洁的网络,完美契合价值存储理念。人们很难操控比特币,它的主要......
faint · 2020-08-13
918阅读 · 0赞赏 · 0问答

零基础入门 DeFi:手把手教你在 MakerDAO 创建 CDP 赚取以太坊

几句话回顾下 Maker在 Maker 的系统里面:你质押你的 ETH,生成 Dai你质押的 ETH 的价格要大于生成 Dai 的价格的 150%在质押和生成 Dai 之前,你首先需要创建一个 CDP......
Ethan · 2020-08-13
984阅读 · 0赞赏 · 0问答

从 Layer 1 至 4,详解以太坊 2.0 如何重塑债券市场

以太坊是一个平台,目的是建立一个金融上层建筑。这个上层建筑中的用户行为,产生了推动其内部资产运作的力量。金融堆栈上每一层的指标将展示以太坊的经济状态。下面的文章将对此进行总结。以太坊是一组相互叠加的分......
七乐彩 · 2020-08-12
964阅读 · 0赞赏 · 0问答

成都链安:以太坊2.0技术浅析

就在刚过去的7月31日,加密货币市值第二高的以太坊迎来了5周年生日。随着以太坊的不断发展,社会各界对以太坊的关注也在不断增加,用户及应用的不断激增,也使得大家对以太坊 2.0的呼声不断高涨。 **......
成都链安 · 2020-08-11
435阅读 · 0赞赏 · 0问答

我们如何选择开发平台:超级账本还是以太坊?

在区块链的世界里,超级账本(Hyperledger)和(Ethereum)都产生了创新的浪潮。这两个流行的开源区块链平台在行业中不仅发现了大量区块链应用,而且它们还鼓励世界各地的区块链开发者参与区块链......
论坛咸鸟 · 2020-08-11
1162阅读 · 0赞赏 · 0问答

我们如何选择开发平台:超级账本还是以太坊?

在区块链的世界里,超级账本(Hyperledger)和(Ethereum)都产生了创新的浪潮。这两个流行的开源区块链平台在行业中不仅发现了大量区块链应用,而且它们还鼓励世界各地的区块链开发者参与区块链......
区块链技术 · 2020-08-10
1159阅读 · 0赞赏 · 0问答

HBO

4714

LK币

19

粉丝

52

笔记

感谢"HBO"

这篇精彩的笔记,目前已经帮助

  • 0
  • 4
  • 4
  • 8
  • 9
喜欢0
链客社群 加入

微博进入

商务合作>

广告投放>

公司名称:北京链客行科技有限公司

联系方式:010-67707199

ICP备案号:京ICP备18032136号

Copyright:链客区块链技术问答社区 版权所有

感谢您的提问,问题被社区永久收入以便新人查看。一定要记得采纳最佳答案哦!加油!

感谢您的善举,每一次解答会成为新人的灯塔,回答被采纳后获得20算力和相应的LK币奖励

您将赞赏给对方2LK币的奖励哦!感谢您的赞赏!

您将赞赏给对方2LK币的奖励哦!感谢您的赞赏!