zoukankan      html  css  js  c++  java
  • 孤荷凌寒自学python第113天区块链027以太坊智能合约006

    【主要内容】

    今天开始使用python代码来通过infura.io网站提供的免费托管节点来连接上eth网络,然后对自己发布的智能合约进行访问操作,但连第一步都没有完成。学习共用时34分钟。

    (此外整理作笔记花费了约96分钟)

    因为来自remix的在线编辑器对中文支持不好,于是就想在vscode中能够编辑sol文件要多好于是就先进行了尝试,然后就开始写Python代码来调用自己的合约,于是又踩了巨多坑,也没有进行测试。

    详细学习过程见文末学习过程屏幕录像。

     

    【学习笔记】

    一、vscode编辑器是支持进行solidity文件进行编辑的,甚至可以进行编译

    只需要在vscode界面的左侧选择“扩展”,搜索“solidity”,选择其中一个叫做“solidity0.50”的扩展安装即可。

    这时vscode就可以对solidity文件进行直接编辑了,有语法高亮提示等。

    但还不能进行solidity文件的编译执行,需要安装solidity的编译包,但我只是想对sol文件进行编辑罢,就没有安装编译器。

    此外找到了web3.py的官方文档:https://web3py.readthedocs.io/en/stable/middleware.html

     

    二、准备书写第一个可以与eth网络上的自己发布的合约进行交互的py程序

    仍然参照这篇博文:https://blog.csdn.net/mongo_node/article/details/85043799

    原代码如下:

    import time

    from web3 import Web3, HTTPProvider

     

    contract_address="0xfbf6d79f50219505ff8e10b2f0ca1435a1210ffc"  #提供服务的合约地址,就是我自己创建(部署)的智能合约

    wallet_private_key="D8EF07D32389148E9DA6C54237BD5A39C92917D59340AA5D6064485C01E96FB2" #狐狸钱包的私钥

    wallet_address="0x5227C3EF48B5A1bcF784593e46D9579D26a3b592" #狐狸钱包的公钥,就是钱包地址,是eth网络上的一个节点。

    w3 = Web3(HTTPProvider("ropsten.infura.io/v3/79124269dc454e47bee73f964c971d3c")) #里面的参数字符串是在infura.io网站上申请 到的一个节点地址。

     

    def send_ether_to_contract(amount_in_ether):

        amount_in_wei = w3.toWei(amount_in_ether,'ether')

        nonce = w3.eth.getTransactionCount(wallet_address) #此处vscode提示eth下层对象不存在,是误报错误,因为web3类在定义时,它的下层对象是通过代码软性加载的,所以vscode无法检测到。

        '''

        web3类软性加载它的一些下层对象的代码如下:所以vscode通过静态代码去查找这些下层以对象是找不到的,所以报错。

            for module_name, module_class in modules.items():

                module_class.attach(self, module_name)

        module_class中就包含了包括eth在内的多个web3类的下层对象。

        以上是花了大量时间查找思考 后的个人见解,可能有错,恳请高手指点。

        '''

     

        txn_dict={

            'to': contract_address,

            'value': amount_in_wei,

            'gas': 2000000,

            'gasPrice': w3.toWei('40','gwei'),

            'nonce': nonce,

            'chainId': 3

        }

     

        signed_txn = w3.eth.account.signTransaction(txn_dict, wallet_private_key)

        txn_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction)

        txn_receipt = None

        count = 0

     

        while txn_receipt is None and (count < 30):

            txn_receipt = w3.eth.getTransactionReceipt(txn_hash)

            print(txn_receipt)

            time.sleep(10)

     

        if txn_receipt is None:

            return {'status':'failed','error':'timeout'}

     

        return {'status':'added','txn_receipt':txn_receipt}

     

    而且vscode编辑器,还有个毛病,明明是w3.eth处报错,却连def定义语句处还先报错,害了半天没有定位问题所在(具体可见我的学习过程屏幕录像)

    正因为这儿耗费了时间,于是没有完成后续测试。

    于是就想通过

    web3.eth.blockNumber

    代码来验证是否通过代理节点连接上了eth网络,并获取 最后一个区块的编号 id,测试代码被简化了:

    from web3 import Web3

     

    web3 = Web3(Web3.HTTPProvider("ropsten.infura.io/v3/79124269dc454e47bee73f964c971d3c"))

    print(web3.eth.blockNumber)

    却直接报错:

    Traceback (most recent call last):

      File "i:MAKEAPPpythonPython365边学习边测试文件夹自学PYTHON部分第二阶段113自学python_区块链027 ry2.py", line 4, in <module>

        print(web3.eth.blockNumber)

      File "G:w10_1pythonpython365libsite-packagesweb3eth.py", line 102, in blockNumber

        return self.web3.manager.request_blocking("eth_blockNumber", [])

      File "G:w10_1pythonpython365libsite-packagesweb3manager.py", line 109, in request_blocking

        response = self._make_request(method, params)

      File "G:w10_1pythonpython365libsite-packagesweb3manager.py", line 92, in _make_request

        return request_func(method, params)

      File "cytoolz/functoolz.pyx", line 232, in cytoolz.functoolz.curry.__call__

      File "G:w10_1pythonpython365libsite-packagesweb3middlewareformatting.py", line 50, in apply_formatters

        response = make_request(method, params)

      File "G:w10_1pythonpython365libsite-packagesweb3middlewaregas_price_strategy.py", line 18, in middleware

        return make_request(method, params)

      File "cytoolz/functoolz.pyx", line 232, in cytoolz.functoolz.curry.__call__

      File "G:w10_1pythonpython365libsite-packagesweb3middlewareformatting.py", line 50, in apply_formatters

        response = make_request(method, params)

      File "G:w10_1pythonpython365libsite-packagesweb3middlewareattrdict.py", line 18, in middleware

        response = make_request(method, params)

      File "cytoolz/functoolz.pyx", line 232, in cytoolz.functoolz.curry.__call__

      File "G:w10_1pythonpython365libsite-packagesweb3middlewareformatting.py", line 50, in apply_formatters

        response = make_request(method, params)

      File "G:w10_1pythonpython365libsite-packagesweb3middleware ormalize_errors.py", line 9, in middleware

        result = make_request(method, params)

      File "cytoolz/functoolz.pyx", line 232, in cytoolz.functoolz.curry.__call__

      File "G:w10_1pythonpython365libsite-packagesweb3middlewareformatting.py", line 50, in apply_formatters

        response = make_request(method, params)

      File "cytoolz/functoolz.pyx", line 232, in cytoolz.functoolz.curry.__call__

      File "G:w10_1pythonpython365libsite-packagesweb3middlewareformatting.py", line 50, in apply_formatters

        response = make_request(method, params)

      File "G:w10_1pythonpython365libsite-packagesweb3middlewareexception_retry_request.py", line 80, in middleware

        return make_request(method, params)

      File "G:w10_1pythonpython365libsite-packagesweb3providers pc.py", line 68, in make_request

        **self.get_request_kwargs()

      File "G:w10_1pythonpython365libsite-packagesweb3utils equest.py", line 26, in make_post_request

        response = session.post(endpoint_uri, data=data, *args, **kwargs)

      File "G:w10_1pythonpython365libsite-packages equestssessions.py", line 559, in post

        return self.request('POST', url, data=data, json=json, **kwargs)

      File "G:w10_1pythonpython365libsite-packages equestssessions.py", line 498, in request

        prep = self.prepare_request(req)

      File "G:w10_1pythonpython365libsite-packages equestssessions.py", line 441, in prepare_request

        hooks=merge_hooks(request.hooks, self.hooks),

      File "G:w10_1pythonpython365libsite-packages equestsmodels.py", line 309, in prepare

        self.prepare_url(url, params)

      File "G:w10_1pythonpython365libsite-packages equestsmodels.py", line 383, in prepare_url

        raise MissingSchema(error)

    requests.exceptions.MissingSchema: Invalid URL 'mainnet.infura.io/v3/79124269dc454e47bee73f964c971d3c': No

    schema supplied. Perhaps you meant http://mainnet.infura.io/v3/79124269dc454e47bee73f964c971d3c?

     

    这完全不知道为何,连接不上我从infura.io上申请到的节点地址。

    又将代码修改如下:

    from web3 import Web3, HTTPProvider

    from web3.contract import ConciseContract

    from web3.middleware import geth_poa_middleware

     

    INFURA_API_KEY = "79124269dc454e47bee73f964c971d3c"

     

    ACCOUNT_PASSWORD = "3c79be182e7448a98dc0ed86f4c7cdec"

     

    w3 = Web3(HTTPProvider('https://ropsten.infura.io/{}'.format(INFURA_API_KEY)))

     

    w3.middleware_stack.inject(geth_poa_middleware, layer=0)

     

    print(w3.eth.blockNumber)

    这次参照了多篇博文的描述,加上了infura.io提供的projectID与password。然而事实上,代码中也根本没有用上password,不是?(因为在infura.io界面我没有设置要求必须使用密码。)

    不过却神奇般的成功了,输出了最后一个区块的编号 id:

    5854380

     

    这时,仿佛神灵助我一般,我恍然大悟,仔细对比两段代码的不同,发现:

    最开始的代码:

    "ropsten.infura.io/v3/79124269dc454e47bee73f964c971d3c"

    与现在的代码:

    'https://ropsten.infura.io/{}'.format(INFURA_API_KEY)

    所不同的地方在于,网络格式头的不同:

    上一行代码,没有指明网络协议,则会默认为:http://

    而下一行代码,明确指明了网络协议,正确的就应当是:https://

    正可谓简直要仔细,因为这到处都是坑,而且还很深!

     

    【学习后记】

    最后完整修改的代码如下,没有进行尝试:

    ```

    #来自博文:https://blog.csdn.net/mongo_node/article/details/85043799

    import time

    from web3 import Web3, HTTPProvider

     

    contract_address="0xfbf6d79f50219505ff8e10b2f0ca1435a1210ffc"  #提供服务的合约地址,就是我自己创建(部署)的智能合约

    wallet_private_key="D8EF07D32389148E9DA6C54237BD5A39C92917D59340AA5D6064485C01E96FB2" #狐狸钱包的私钥

    wallet_address="0x5227C3EF48B5A1bcF784593e46D9579D26a3b592" #狐狸钱包的公钥,就是钱包地址,是eth网络上的一个节点。

    w3 = Web3(HTTPProvider("https://ropsten.infura.io/v3/79124269dc454e47bee73f964c971d3c")) #里面的参数字符串是在infura.io网站上申请 到的一个节点地址。

     

    def send_ether_to_contract(amount_in_ether):

        amount_in_wei = w3.toWei(amount_in_ether,'ether')

        nonce = w3.eth.getTransactionCount(wallet_address) #此处vscode提示eth下层对象不存在,是误报错误,因为web3类在定义时,它的下层对象是通过代码软性加载的,所以vscode无法检测到。

        '''

        web3类软性加载它的一些下层对象的代码如下:所以vscode通过静态代码去查找这些下层以对象是找不到的,所以报错。

            for module_name, module_class in modules.items():

                module_class.attach(self, module_name)

        module_class中就包含了包括eth在内的多个web3类的下层对象。

        以上是花了大量时间查找思考 后的个人见解,可能有错,恳请高手指点。

        '''

     

        txn_dict={

            'to': contract_address,

            'value': amount_in_wei,

            'gas': 2000000,

            'gasPrice': w3.toWei('40','gwei'),

            'nonce': nonce,

            'chainId': 3

        }

     

        signed_txn = w3.eth.account.signTransaction(txn_dict, wallet_private_key)

        txn_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction)

        txn_receipt = None

        count = 0

     

        while txn_receipt is None and (count < 30):

            txn_receipt = w3.eth.getTransactionReceipt(txn_hash)

            print(txn_receipt)

            time.sleep(10)

     

        if txn_receipt is None:

            return {'status':'failed','error':'timeout'}

     

        return {'status':'added','txn_receipt':txn_receipt}



    ```

     

    我从编程世界的完全门外汉走到今天,每一步是很缓慢且不断踩坑,但是这是完全自学必经的道路,那么不自学不是更好吗?我非常赞同一句话——真正的学习就是自学。

    过去20年我积累完整的自学方法论,历经实践验证,我正准备在我创建的【就是要学 终身成长】社群中与大家分享讨论这一话题,欢迎立志于终身学习,终身成长的朋友们加入社群,共同交流学习。Qq群号码:646854445

    或访问:www.941xue.com

     

    【关于坚持自学的例行说明】

    最后例行说明下,我为什么要坚持自学。

     

    “如果我不曾见过太阳,我本可以忍受黑暗,然而阳光已使我的荒凉,成为更新的荒凉。”

    ——艾米莉·狄金森

    如果要问我对自己的前半生如何看待时,我想昨天和今天的答案都将完全不同。

    昨天的我,生活在荒凉的满意之中,自觉怡然自得,拿着包身包月的工资,听着仁慈的命令,过着几乎一成不变的生活;时而与周遭的人儿和睦互往,时而唇舌相抵斤斤计较,演出着生活的鸡毛蒜皮,工作的吹拉弹唱;忘我,忘我,才能融入这平和无奇的乐章中,迈着细碎的步伐,原地踏步。那时的我觉得这就是悠然自得的听天由命的平凡人生,也就是我的宿命了。

    可是某一天,我见到了不一样的太阳以及太阳下不一样的人生光景——那并不荒凉。

    今天的我,生活在荒凉的痛苦之中,自觉渴望改变,迈着不知所措的步伐,看着流逝的年华,睁着悔恨错失一切的双眼… …

    我知道我将再无法回到过去的我,只有改变才是唯一正确的方向。

     

    一、为什么一把年纪还在学习

    放弃很多去聚餐,去HI歌,去游玩,去看电影,去追剧……的时间,然后进行着这个年纪似乎已不应当再进行的学习,引来身边人们无尽的不解与鄙夷甚至可怜……

    但我不想放弃终身学习的誓言。

    因为——

    我对我今天的生活现状并不认同!

    罗伯特清崎告诉过我们,反省自己当下的生活是不是自己想要的,这难道不是最好的动力与答案?

    走过了大半生,然后才发现曾经、当下所正在进行的人生并不是自己想要的,那是一种怎样的体验?

    只有心中真切的感受才能回答这个问题,而任凭再丰富的语言也是无法描绘出来的。

    经历半生的跋涉,却发现走得并不正确,有多少人有勇气承认自己过去的一切都是错误的呢?

    而我愿意告诉过去的我:“你错了!”

    那么已经历半生错误,年岁之大又压于头顶,还有希望从这架的梯子的半端重新爬下,再蹒跚着爬上另一架梯子吗?

    我宁愿相信还有希望!

    这便是我为什么要继续坚持终身学习下去的全部理由。

     

    二、这个年纪还在学这些技术有意义吗

    纯的技术对这把年纪其实已没有意义。

    但兴趣可以超越意义。

    但技术可以引来思想的变革,这才是意义。

    投资自己的头脑 ,改革自己的思想,这是最保值,更长远的投资,过去我从来没有投资过,错过太多,那就从投资自己头脑开始吧。

    罗伯特清崎告诉我们,真正的富有是时间的富有;真正的自由是可以决定自己愿意做什么的自由。

    因为我愿意做我兴趣所在的事,所以我希望我有自由选择的那一天,虽然今天离那一天可能还是那么遥远,但我愿意相信,每天多赶几步,离希望就更近一步。

    再者,虽然我可能再已无法完全完整的掌握这些技术了,但技术本身却可以启迪心的觉醒,激发灵感,那么只要多了解一点,我相信我将离那个正离我而去跑得越来越快的未来更近一点,不至于被未知的那个未来抛弃得太远。

    于是我怎能放弃追逐求索的步伐?

    我要坚信:感觉太迟的时候,也许还不算太迟。

     

    感谢一直以来关注我,鼓励我的你!

    若不嫌弃这一个到了高龄才长大的可笑可叹的我,请不吝赐教。

    我的q号是:578652607,敬候你的指点。

     

     

    【同步语音笔记】

    https://www.ximalaya.com/keji/19103006/265138726

     

    【学习过程屏幕录屏】

    https://www.bilibili.com/video/av93955098

     

    欢迎大家添加我为好友: QQ: 578652607
  • 相关阅读:
    python 01
    Node.js 基础库
    Node 编程规范
    Linux_异常_08_本机无法访问虚拟机web等工程
    inux_异常_07_ftp查看不到文件列表
    Linux_异常_04_ftp: command not found...
    Linux_异常_03_Failed to restart iptables.service: Unit not found.
    Linux_异常_02_WinSCP上传文件时显示Permission denied
    Linux_异常_01_CentOS7无法ping 百度
    Linux_配置_02_配置dns
  • 原文地址:https://www.cnblogs.com/lhghroom/p/12445779.html
Copyright © 2011-2022 走看看