web3py第一课:web3合约交互基础部分
这一篇是正式建立DFarm DAO以来的第一篇文章了,本来这周不准备分享。但是感觉基础的一些知识可以先讲,大家先熟悉一下,所以今天就分享一下web3py跟智能合约交互的一些基础知识。 这部分都是非常简单的代码,希望大家尝试一下。安装python、pycharm这些环境和开发工具大家自行安装即可,网上一搜都是教程,比我写的好很多,这部分内容不再赘述。 web3py文档: https://web3py.readthedocs.io/en/stable/index.html web3py应该是python上跟智能合约交互最好用的包了,首先我们安装一下。 如果你是mac系统,直接使用:`pip install web3` 进行安装。 如果你是windows系统,则需要先装一下c++环境。 下载 vs_buildtools: https://visualstudio.microsoft.com/zh-hant/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16 之后如图安装下面勾选的包,一定要装全,已包含和可选两部分你都要装...
web3py第三课:游戏脚本编写 & 不开源合约调用
终于到了大家心心念念的游戏脚本编写的教程了,今天我会以前段时间比较火的游戏“掰手腕”为例子,来教大家如何写一个游戏脚本。教程无论哪个游戏,我们要写脚本,都是要先进行一下交互,看自己的交互记录来写脚本。 这里我展示一下我的一次fight记录:从这个记录中,我们可以得到很多信息。比如游戏的合约地址、方法名、参数名、参数值。 其实知道这些就可以写脚本了,但是我们还需要ABI才可以进行调用,如果我们打开合约的源代码看到的这是这样:这说明该合约没有开源,所以无法看到合约的源代码,这时候我们要怎么寻找ABI呢?如果你学习过智能合约的一些知识,可能会发现,网站(DAPP)也是通过ABI+web3.js跟智能合约做交互,我们web3py也是一样的道理。所以这些游戏网站都会有ABI来让你调用,也就是说我们去扒一扒网站的源代码即可!通过搜索,在网站的源代码中很容易可以找到。如果JS比较多,需要一个一个看。如果你用safari浏览器可以全局搜索,Chrome好像要一个一个的去找一下。 然后ABI一般都非常长,我们如果只用一个fight方法,完全可以只取这一段:[{"inputs":[{"interna...
Quarter I 2022
原文作者:Ansem(推特@blknoiz06) 原文链接: https://blknoiz06.substack.com/p/quarter-i-2022?token=eyJ1c2VyX2lkIjoxNTEzODUxLCJwb3N0X2lkIjo0NDk3NTUwMywiXyI6Impza3RSIiwiaWF0IjoxNjQxMDAyOTU4LCJleHAiOjE2NDEwMDY1NTgsImlzcyI6InB1Yi0zNDg4NDgiLCJzdWIiOiJwb3N0LXJlYWN0aW9uIn0.Cqy5UR9NIQI5frgMTGectMzDdH_0CF2RZHRcrmNejs4 译者:Evelyn、AluAyi、Henson、Rex|W3.Hitchhiker2022市场整体展望你好!对于我的堕落同胞(fellow degenerates)和其他不知何故闯入这个页面的读者们,我将尝试在这里梳理今年一季度的一些想法。这是我第二次写这样的长篇大论,所以请忍耐一下(哈哈),希望它比从我推特发出来的数百条零零散散的推文更有条理。 2021年对于加密资产来说很显然是突破性的一年,从...
web3py第一课:web3合约交互基础部分
这一篇是正式建立DFarm DAO以来的第一篇文章了,本来这周不准备分享。但是感觉基础的一些知识可以先讲,大家先熟悉一下,所以今天就分享一下web3py跟智能合约交互的一些基础知识。 这部分都是非常简单的代码,希望大家尝试一下。安装python、pycharm这些环境和开发工具大家自行安装即可,网上一搜都是教程,比我写的好很多,这部分内容不再赘述。 web3py文档: https://web3py.readthedocs.io/en/stable/index.html web3py应该是python上跟智能合约交互最好用的包了,首先我们安装一下。 如果你是mac系统,直接使用:`pip install web3` 进行安装。 如果你是windows系统,则需要先装一下c++环境。 下载 vs_buildtools: https://visualstudio.microsoft.com/zh-hant/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16 之后如图安装下面勾选的包,一定要装全,已包含和可选两部分你都要装...
web3py第三课:游戏脚本编写 & 不开源合约调用
终于到了大家心心念念的游戏脚本编写的教程了,今天我会以前段时间比较火的游戏“掰手腕”为例子,来教大家如何写一个游戏脚本。教程无论哪个游戏,我们要写脚本,都是要先进行一下交互,看自己的交互记录来写脚本。 这里我展示一下我的一次fight记录:从这个记录中,我们可以得到很多信息。比如游戏的合约地址、方法名、参数名、参数值。 其实知道这些就可以写脚本了,但是我们还需要ABI才可以进行调用,如果我们打开合约的源代码看到的这是这样:这说明该合约没有开源,所以无法看到合约的源代码,这时候我们要怎么寻找ABI呢?如果你学习过智能合约的一些知识,可能会发现,网站(DAPP)也是通过ABI+web3.js跟智能合约做交互,我们web3py也是一样的道理。所以这些游戏网站都会有ABI来让你调用,也就是说我们去扒一扒网站的源代码即可!通过搜索,在网站的源代码中很容易可以找到。如果JS比较多,需要一个一个看。如果你用safari浏览器可以全局搜索,Chrome好像要一个一个的去找一下。 然后ABI一般都非常长,我们如果只用一个fight方法,完全可以只取这一段:[{"inputs":[{"interna...
Quarter I 2022
原文作者:Ansem(推特@blknoiz06) 原文链接: https://blknoiz06.substack.com/p/quarter-i-2022?token=eyJ1c2VyX2lkIjoxNTEzODUxLCJwb3N0X2lkIjo0NDk3NTUwMywiXyI6Impza3RSIiwiaWF0IjoxNjQxMDAyOTU4LCJleHAiOjE2NDEwMDY1NTgsImlzcyI6InB1Yi0zNDg4NDgiLCJzdWIiOiJwb3N0LXJlYWN0aW9uIn0.Cqy5UR9NIQI5frgMTGectMzDdH_0CF2RZHRcrmNejs4 译者:Evelyn、AluAyi、Henson、Rex|W3.Hitchhiker2022市场整体展望你好!对于我的堕落同胞(fellow degenerates)和其他不知何故闯入这个页面的读者们,我将尝试在这里梳理今年一季度的一些想法。这是我第二次写这样的长篇大论,所以请忍耐一下(哈哈),希望它比从我推特发出来的数百条零零散散的推文更有条理。 2021年对于加密资产来说很显然是突破性的一年,从...
Subscribe to ourens.eth
Subscribe to ourens.eth
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers
前面几节课讲了很多内容,但是没有说nonce的几个坑,今天我就来好好说说。
关于nonce的使用建议可以参考下面群友发的内容:

然后我们就说说nonce。
如果跑过前面几课的代码,你会发现跑我的例子都能成功。当你写一个批量交易的脚本就会出问题,尤其是同一个地址发送多次请求时会遇到各种各样的问题,大部分原因就是nonce产生的问题。
我们都知道获取nonce的方法就是:`web3.eth.getTransactionCount(address)`
这句方法就是取你的地址下一个nonce的值是多少,但是这个方法取出来的值会有几个坑。
坑1:当你的上一次交易还没有打包完,你取到的nonce跟上一次的值是一样。
坑2:上一次交易已经成功打包了,得到的nonce值居然还跟上一次的一样。
坑3:上一次交易已经成功打包了,得到的nonce值居然还小于上一次的值。
这些坑产生的具体原因不在这里讨论了,其实我也没有去深入去查,但是有一些解决办法跟大家分享一下。
我在我的代码中,都把发送交易的方法封装了,因为都是通用的代码。在里面我加上了一步,就是如果交易成功被矿工打包上链了,再返回。
这就相当于作了一种同步方式,因为这种同步的方式比较方便查错,虽然效率低了,但是开发过程比较顺畅。
首先是查询交易状态的代码:
web3.eth.getTransactionReceipt(tx_hash)['status']
这句话可以根据tx来查询状态,1:完成 0:失败 其他:等待
我们判定这个返回值为1,再继续,可以用循环这种比较笨的方法改一下:
def send_transaction(func, params):
tx = func.buildTransaction(params)
signed_tx = self.web3.eth.account.sign_transaction(tx, private_key=wallet_key)
tx_hash = self.web3.eth.sendRawTransaction(signed_tx.rawTransaction)
while True:
status = get_transaction_status(tx_hash)
if status == 1:
break
elif status == 0:
print('失败')
exit()
time.sleep(1)
return tx_hash
经过这样的改造,你的send_transaction方法就变成同步了,只有矿工打包之后才会返回tx。
然后我们再处理nonce,在构造params之前,你可以这样处理一下:
global old_nonce
nonce = self.web3.eth.getTransactionCount(self.wallet_address)
num = 0
while True:
if num > 20:
break
if nonce <= old_nonce and nonce != 0:
nonce = self.web3.eth.getTransactionCount(self.wallet_address)
print(f'发现nonce[{old_nonce}]重复,已重新获取。[{nonce}]')
time.sleep(1)
else:
break
num = num + 1
params = {
...
}
old_nonce = nonce
我在这里存了上一次的nonce为old_nonce,每次会判断一下是否大于小于上一次的值,如果不对继续取。注意,我这里加了num为20,是只去重试20次,20次都取不到就是别的问题了。
一般如果你把发送交易方法改成了同步,后面遇到nonce这个问题就会少很多。
上面这几个方法都比较民科,如果有更科学的方式欢迎跟我讨论~
上面的这些方法我也经过了一些时间的验证,解决问题肯定是可以的!
这周我多发了一篇文章哦,如果下周我鸽了也很正常~
前面几节课讲了很多内容,但是没有说nonce的几个坑,今天我就来好好说说。
关于nonce的使用建议可以参考下面群友发的内容:

然后我们就说说nonce。
如果跑过前面几课的代码,你会发现跑我的例子都能成功。当你写一个批量交易的脚本就会出问题,尤其是同一个地址发送多次请求时会遇到各种各样的问题,大部分原因就是nonce产生的问题。
我们都知道获取nonce的方法就是:`web3.eth.getTransactionCount(address)`
这句方法就是取你的地址下一个nonce的值是多少,但是这个方法取出来的值会有几个坑。
坑1:当你的上一次交易还没有打包完,你取到的nonce跟上一次的值是一样。
坑2:上一次交易已经成功打包了,得到的nonce值居然还跟上一次的一样。
坑3:上一次交易已经成功打包了,得到的nonce值居然还小于上一次的值。
这些坑产生的具体原因不在这里讨论了,其实我也没有去深入去查,但是有一些解决办法跟大家分享一下。
我在我的代码中,都把发送交易的方法封装了,因为都是通用的代码。在里面我加上了一步,就是如果交易成功被矿工打包上链了,再返回。
这就相当于作了一种同步方式,因为这种同步的方式比较方便查错,虽然效率低了,但是开发过程比较顺畅。
首先是查询交易状态的代码:
web3.eth.getTransactionReceipt(tx_hash)['status']
这句话可以根据tx来查询状态,1:完成 0:失败 其他:等待
我们判定这个返回值为1,再继续,可以用循环这种比较笨的方法改一下:
def send_transaction(func, params):
tx = func.buildTransaction(params)
signed_tx = self.web3.eth.account.sign_transaction(tx, private_key=wallet_key)
tx_hash = self.web3.eth.sendRawTransaction(signed_tx.rawTransaction)
while True:
status = get_transaction_status(tx_hash)
if status == 1:
break
elif status == 0:
print('失败')
exit()
time.sleep(1)
return tx_hash
经过这样的改造,你的send_transaction方法就变成同步了,只有矿工打包之后才会返回tx。
然后我们再处理nonce,在构造params之前,你可以这样处理一下:
global old_nonce
nonce = self.web3.eth.getTransactionCount(self.wallet_address)
num = 0
while True:
if num > 20:
break
if nonce <= old_nonce and nonce != 0:
nonce = self.web3.eth.getTransactionCount(self.wallet_address)
print(f'发现nonce[{old_nonce}]重复,已重新获取。[{nonce}]')
time.sleep(1)
else:
break
num = num + 1
params = {
...
}
old_nonce = nonce
我在这里存了上一次的nonce为old_nonce,每次会判断一下是否大于小于上一次的值,如果不对继续取。注意,我这里加了num为20,是只去重试20次,20次都取不到就是别的问题了。
一般如果你把发送交易方法改成了同步,后面遇到nonce这个问题就会少很多。
上面这几个方法都比较民科,如果有更科学的方式欢迎跟我讨论~
上面的这些方法我也经过了一些时间的验证,解决问题肯定是可以的!
这周我多发了一篇文章哦,如果下周我鸽了也很正常~
No activity yet