【主要内容】
今天开始使用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