使用 python 结合区块链开发时遇到的问题汇总
Varibles
Web3.py 缺陷
web3.py filter 的 get_new_entry 在 filter 的 fromblock 为 0 时,需要先 get_all_entry
日志过滤时间间隔: ganache 等本地节点发起交易后,回显区块形成,但需要稍等 1s 左右(time.sleep(1)),等待日志写入,然后过滤日志才能得到。直接发起交易,过滤日志由于日志没有写上,会导致过滤不到。
ganache bug
checksum 地址过滤,返回空,需要使用 .lower()函数将地址转换为小写的。Apr 27, 2021
- edge.py 日志过滤那部分写的不好,导致运行出错,导致 ganache 出现问题,使得 client.py 正常的过滤功能也无法实现,只能重启 ganache
签名
在以太坊中,常见的区块哈希、交易哈希、状态哈希等等都使用的 Keccak256 哈希算法, 是抗碰撞的
abi.encode() 和 abi.encodePacked()
关于 abi.encode() 和 abi.encodPacked(),stackexchange 上的这个回答比较好:When to use abi.encode, abi.encodePacked or abi.encodeWithSignature in solidity - Ethereum Stack Exchange。结论就是:为节省内存和 Gas,一般使用 abi.encodePacked(),但是当输入存在两个及以上的动态类型(string,动态数组等)时,使用它极易产生碰撞风险,因此该情况下改用 abi.encode().
mload assembly function
Solidity 支持 Inline Assembly,其使用的内联汇编语言叫:Yul.Assembly 可以直接使用 opcodes 直接与 EVM 交互。
mload(0xAB) Loads the word (32byte) located at the memory address 0xAB.
mload and mstore are defined in details in the yellow paper :
![16451713233749](https://blog-1259556217.cos.ap-chengdu.myqcloud.com/image/16451713233749.jpg)
线上验证工具
参考文献
When to use abi.encode, abi.encodePacked or abi.encodeWithSignature in solidity - Ethereum Stack Exchange solidity - understanding mload assembly function - Ethereum Stack Exchange
注意与思考
- 函数以及其参数的命名要尽量通用
- 可以通过设置一个参数可选或者多设置一个参数,来使得该函数复用性增强。
- tcp 数据流服务端并能确定一条消息的开头和结尾 解决:1. 固定长度分割 2. 消息中增加分隔符 3. 消息开头增加消息长度字段标识 Python sockets: how to only receive one message at a time - Stack Overflow
- 修改后的合约需要重新部署
- 部署合约时,别忘了选择 web3 provider
- 日志是相对于合约而言的,修改后新部署的合约没有日志,需要多进行一些交易,然后过滤才能有日志可言。
- 检查类型转换