zoukankan      html  css  js  c++  java
  • solidity 智能合约操作

    合约编译

    #!/usr/bin/env python
    # coding: utf8
    
    import json
    import os
    
    # Solc Compiler
    from functools import reduce
    
    SOLC = "solc"
    
    BASE_PATH = os.path.dirname(os.path.abspath(__file__))
    
    src_dir = os.path.join(BASE_PATH, "contracts")
    dst_dir = os.path.join(BASE_PATH, "build")
    # dst_tmp = os.path.join(BASE_PATH, "build/contracts")
    
    bin_dir = os.path.join(BASE_PATH, "build/bin")
    abi_dir = os.path.join(BASE_PATH, "build/abi")
    ast_dir = os.path.join(BASE_PATH, "build/ast")
    
    src_entry = os.path.join(src_dir, "main.sol")
    build_target = os.path.join(BASE_PATH, "build/contracts.json")
    
    
    def rmdir(path):
        for root, dirs, files in os.walk(path, topdown=False):
            for name in files:
                os.remove(os.path.join(root, name))
            for name in dirs:
                os.rmdir(os.path.join(root, name))
        os.rmdir(path)
    
    
    def diff_path():
        if not os.path.exists(dst_dir):
            os.mkdir(dst_dir)
        # if not os.path.exists(dst_tmp):
        #     os.mkdir(dst_tmp)
        if not os.path.exists(bin_dir):
            os.mkdir(bin_dir)
        if not os.path.exists(abi_dir):
            os.mkdir(abi_dir)
        if not os.path.exists(ast_dir):
            os.mkdir(ast_dir)
    
        assert (os.path.exists(src_dir) and os.path.isdir(src_dir))
        assert (os.path.exists(dst_dir) and os.path.isdir(dst_dir))
        # assert (os.path.exists(dst_tmp) and os.path.isdir(dst_tmp))
    
        assert (os.path.exists(bin_dir) and os.path.isdir(bin_dir))
        assert (os.path.exists(abi_dir) and os.path.isdir(abi_dir))
        assert (os.path.exists(ast_dir) and os.path.isdir(ast_dir))
    
        # src_paths = map(lambda root, dirs, files: root.replace(src_dir, ""), os.walk(src_dir))
        # dst_paths = map(lambda root, dirs, files: root.replace(dst_tmp, ""), os.walk(dst_tmp))
        # _paths = filter(lambda p: p not in src_paths, dst_paths)
        # paths = map(lambda p: os.path.join(dst_tmp, p[1:] if p.startswith("/") else p), _paths)
        # map(lambda p: rmdir(p), paths)
    
        # _paths = filter(lambda p: p not in dst_paths, src_paths)
        # paths = map(lambda p: os.path.join(dst_tmp, p[1:] if p.startswith("/") else p), _paths)
        # map(lambda p: os.mkdir(p), paths)
    
    
    def clean_dst_path():
        if os.path.exists(dst_dir):
            rmdir(dst_dir)
        os.mkdir(dst_dir)
    
    
    def find_compilers():
        paths = os.environ["PATH"].split(":")
        solc = [p for p in paths if os.path.exists(os.path.join(p, "solc")) and os.path.isfile(os.path.join(p, "solc"))]
        serpent = [p for p in paths if
                   os.path.exists(os.path.join(p, "serpent")) and os.path.isfile(os.path.join(p, "serpent"))]
        lllc = [p for p in paths if os.path.exists(os.path.join(p, "lllc")) and os.path.isfile(os.path.join(p, "lllc"))]
    
        result = []
        if len(solc) > 0:
            result.append("Solidity")
        if len(serpent) > 0:
            result.append("Serpent")
        if len(lllc) > 0:
            result.append("LLL")
        return result
    
    
    def complie_soldity():
        """
            solc --optimize --bin -o ./build/bin contract.sol
            solc --optimize --ast -o ./build/ast contract.sol
            solc --optimize --abi -o ./build contract.sol
        """
        assert (os.path.exists(src_entry) and os.path.isfile(src_entry))
    
        commands = [
            [SOLC, "--optimize", "--bin", "--overwrite", "-o", os.path.relpath(bin_dir), os.path.relpath(src_entry)],
            [SOLC, "--optimize", "--ast", "--overwrite", "-o", os.path.relpath(
                ast_dir), os.path.relpath(src_entry)],
            [SOLC, "--optimize", "--abi", "--overwrite", "-o", os.path.relpath(abi_dir), os.path.relpath(src_entry)]
        ]
    
        print("======================Complie Solidity Language=========================")
        for cmd in commands:
            command = " ".join(cmd)
            print(command)
            os.system(command)
    
            # os.system("cp %s/* %s" % (bin_dir, dst_dir))
    
            # result = map(lambda cmd: os.system(" ".join(cmd)), commands )
            # print(result)
    
    
    def restruct():
        contract = {}
        bin_files = [os.path.join(root, f) for root, dirs, files in os.walk(bin_dir) for f in files]
        abi_files = [os.path.join(root, f) for root, dirs, files in os.walk(abi_dir) for f in files]
        ast_files = [os.path.join(root, f) for root, dirs, files in os.walk(ast_dir) for f in files]
    
        def path_handle(data, filepath):
            _, filename = os.path.split(filepath)
            assert (filename.endswith(".bin") or filename.endswith(".abi"))
    
            key = ""
            if filename.endswith(".bin"):
                key = "code"
            elif filename.endswith(".abi"):
                key = "interface"
            else:
                pass
    
            object_name = filename[:-4]
            _tmp = object_name.split(":")
            if len(_tmp) > 1:
                object_name = _tmp[-1]
    
            if object_name not in data or type(data[object_name]) != dict:
                data[object_name] = {}
            if key not in data[object_name]:
                res = open(filepath, "rb").read()
                if key == "interface":
                    open(os.path.join(abi_dir, object_name + ".abi"), "wb").write(res)
                    data[object_name][key] = json.loads(res)
                elif key == "code":
                    res = "" + res.decode("utf-8")
                    data[object_name][key] = res
                else:
                    data[object_name][key] = res
    
            return data
    
        data = reduce(path_handle, abi_files, reduce(path_handle, bin_files, {}))
    
        print("======================Contract=========================")
        output = json.dumps(data)
        open(build_target, "w").write(output)
    
    
    def usage():
        message = """
            $ python solidity.py -src ./src -entry main.sol -out ./build -target contract.json
    
                -src    solidity source dir
                -entry  source entry file
                -out    output dir
                -target solidity bytecode and interface file (JSON Format)
                --help  show this help text
        """
        print(message)
    
    
    def main():
        compilers = find_compilers()
        print("====================Compilers====================")
        print(compilers)
        assert ("Solidity" in compilers)
    
        clean_dst_path()
        diff_path()
        complie_soldity()
        restruct()
        os.system("ls -lah build/")
    
    
    if __name__ == '__main__':
        main()
    

    合约部署

    from __future__ import unicode_literals
    
    import json
    import sys
    from time import sleep, time
    
    from web3 import Web3, HTTPProvider
    
    contracts_path = "build/contracts.json"
    deploy_address_path = "deploy_address.json"
    contracts_address_path = "contracts_address.json"
    
    
    def check_deploy():
        contracts_address = json.loads(open(contracts_path).read() or "{}")
        deploy_address = json.loads(open(deploy_address_path).read() or "{}")
    
        for name, deploy_addr in list(deploy_address.items()):
            if name == "version":
                break
    
            web3 = Web3(HTTPProvider('http://106.15.40.225:8545'))
            web3.eth.defaultAccount = b'0x8c0f94d8a7974aa60ebf4e9a9e742da29dcf7590'
            _count = 0
            deploy_receipt = None
            while 1:
                sleep(2)
                deploy_receipt = web3.eth.getTransactionReceipt(deploy_addr)
                if deploy_receipt:
                    print("{0} 部署成功".format(name))
                    print(deploy_receipt, "
    
    ")
                    break
                if _count > 10:
                    break
    
                _count += 1
    
            if deploy_receipt:
                contracts_address[name]["contract_address"] = deploy_receipt["contractAddress"]
    
        print("检查成功
    
    ")
    
        contracts_address["version"] = deploy_address["version"]
        open(contracts_address_path, "w").write(json.dumps(contracts_address))
    
    
    def deploy():
        contracts = json.load(open(contracts_path)) or {}
    
        _data = {}
        for name, contract in contracts.items():
            _abi = contract["interface"]
            _code = contract["code"]
    
            web3 = Web3(HTTPProvider('http://106.15.40.225:8545'))
            web3.eth.defaultAccount = b'0x8c0f94d8a7974aa60ebf4e9a9e742da29dcf7590'
    
            _Contract = web3.eth.contract(abi=_abi, bytecode=_code)
    
            print("start deploy {0}".format(name))
            deploy_txn = _Contract.deploy(
                # transaction={
                #     'from': web3.eth.defaultAccount,
                #     'value': 12345,
                # },
                # args=('DGD', 18)
            )
    
            print("{0} address: {1}
    
    ".format(name, deploy_txn))
            _data[name] = deploy_txn
        else:
            print("部署成功")
            _data["version"] = str(time())
            open(deploy_address_path, "w").write(json.dumps(_data))
    
    
    if __name__ == '__main__':
        if len(sys.argv) == 1:
            print(
                """
                python solidity_deploy.py deploy #部署合约
                python solidity_deploy.py check #检查合约是否部署成功
                """
            )
    
        if len(sys.argv) > 1:
            _argv = sys.argv[1]
            if _argv == "deploy":
                deploy()
            if _argv == "check":
                check_deploy()
    

    合约调用

    import web3.personal as wp
    from web3 import Web3, HTTPProvider
    
    web3 = Web3(HTTPProvider('http://127.0.0.1:8545'))
    web3.eth.defaultAccount = b'account address 0x336495440ce8dd55029bd394f'
    
    print("unlockAccount")
    p = wp.Personal(web3)
    print(p.unlockAccount("account address", "account passwd"))
    print("unlockAccount ok")
    
    
    _BYTECODE="6060604052341561000f57600080fd5b5b61070c8061001f6000396000f300606060405263ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630c90d8448114610048578063685a4bd21461017c575b600080fd5b341561005357600080fd5b61009960046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061026595505050505050565b604051808060200180602001838103835285818151815260200191508051906020019080838360005b838110156100db5780820151818401525b6020016100c2565b50505050905090810190601f1680156101085780820380516001836020036101000a031916815260200191505b50838103825284818151815260200191508051906020019080838360005b8381101561013f5780820151818401525b602001610126565b50505050905090810190601f16801561016c5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390f35b341561018757600080fd5b61025160046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284378201915050505050509190803590602001908201803590602001908080601f01602080910402602001604051908101604052818152929190602084018383808284378201915050505050509190803590602001908201803590602001908080601f0160208091040260200160405190810160405281815292919060208401838380828437509496506104af95505050505050565b604051901515815260200160405180910390f35b61026d61062e565b61027561062e565b600080846040518082805190602001908083835b602083106102a957805182525b601f199092019160209182019101610289565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051908190039020600381015490915060ff1615156001141561043b578060010181600201818054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561038f5780601f106103645761010080835404028352916020019161038f565b820191906000526020600020905b81548152906001019060200180831161037257829003601f168201915b50505050509150808054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561042b5780601f106104005761010080835404028352916020019161042b565b820191906000526020600020905b81548152906001019060200180831161040e57829003601f168201915b50505050509050925092506104a9565b604080519081016040908152600182527f300000000000000000000000000000000000000000000000000000000000000060208301528051908101604052600181527f3100000000000000000000000000000000000000000000000000000000000000602082015290935091505b50915091565b600080846040518082805190602001908083835b602083106104e357805182525b601f1990920191602091820191016104c3565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040519081900390206003015460ff1615156001141561053057506000610627565b608060405190810160405280858152602001848152602001838152602001600115158152506000856040518082805190602001908083835b6020831061058857805182525b601f199092019160209182019101610568565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040519081900390208151819080516105d0929160200190610640565b506020820151816001019080516105eb929160200190610640565b50604082015181600201908051610606929160200190610640565b506060820151600391909101805460ff191691151591909117905550600190505b9392505050565b60206040519081016040526000815290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061068157805160ff19168380011785556106ae565b828001600101855582156106ae579182015b828111156106ae578251825591602001919060010190610693565b5b506106bb9291506106bf565b5090565b6106dd91905b808211156106bb57600081556001016106c5565b5090565b905600a165627a7a72305820c903731c0280c5e226e2d07bdd2b07723ef114b68febe6991b33363f6e01e7960029"
    _ABI=json.loads("""
    [
          {
            "constant": true,
            "inputs": [
              {
                "name": "_dna",
                "type": "string"
              }
            ],
            "name": "getDNA",
            "outputs": [
              {
                "name": "_type_",
                "type": "string"
              },
              {
                "name": "_version",
                "type": "string"
              }
            ],
            "payable": false,
            "stateMutability": "view",
            "type": "function"
          },
          {
            "constant": false,
            "inputs": [
              {
                "name": "_dna",
                "type": "string"
              },
              {
                "name": "_type_",
                "type": "string"
              },
              {
                "name": "_version",
                "type": "string"
              }
            ],
            "name": "addDNA",
            "outputs": [
              {
                "name": "",
                "type": "bool"
              },
              {
                "name": "",
                "type": "string"
              }
            ],
            "payable": false,
            "stateMutability": "nonpayable",
            "type": "function"
          }
        ]
        """)
    
    MathContract = web3.eth.contract(
        abi=_ABI,
        # bytecode=_BYTECODE,
    )
    
    
    print("isConnected:", web3.isConnected())
    
    deploy_receipt = web3.eth.getTransactionReceipt(b"0xb2e contract deploy tx address")
    print(deploy_receipt)
    assert deploy_receipt is not None
    
    
    # math_contract = MathContract(address=deploy_receipt["contractAddress"])
    # math_contract = MathContract(address="0xec7c803dcc6e917c468139037513b9281574b395")
    
    # 发送一个tx到区块链上
    # print(math_contract.transact().addDNA(_a, _a, _a))
    
    # 发送一个tx到本地执行,不会写入到区块链上
    # print(math_contract.call().addDNA(_a, _a, _a))
    # print(math_contract.call().getDNA(_a))
    
  • 相关阅读:
    STM32 GPIO 配置之ODR, BSRR, BRR 详解
    Understanding the STM32F0's GPIO
    STM32F4 External interrupts
    Calculate CAN bit timing parameters -- STM32
    禁用SQL Server Management Studio的IntelliSense
    SQL Server 2016中In-Memory OLTP继CTP3之后的新改进
    一张图解释SQL Server集群、镜像、复制、日志传送
    SQL Server出现错误: 4014
    SQL Server 2016五大优势挖掘企业用户数据价值
    SQL Server 2008, 2008 R2, 2012 and 2014 完全支持TLS1.2加密传输
  • 原文地址:https://www.cnblogs.com/bergus/p/solidity-zhi-neng-he-yue-cao-zuo.html
Copyright © 2011-2022 走看看