# 学习WEB3PY

By [SuperFoxMan](https://paragraph.com/@hexying) · 2023-03-27

---

由于我学习的是python,所以就用web3py进行演示，这是随写，想到哪写到哪，可能有些细节问题没有细究，会出错或不太严谨，还请各位看官多多斧正，谢谢大家。

1、想要使用web3py

*   需要安装，我用的是vscode.需要在终端输入：
    

`pip install web3py`

*   在vscode里面新建一个以”py”结尾的文档，譬如：web3pyTest.py
    
*   首行需要引用web3
    
*   `from web3 import Web3` 注意后面一个Web3中的大美妞是大写的。
    
*   `polygon_main = Web3(Web3.HTTPProvider('http://rpc.ankr.com/polygon'))`
    

2、这样就算在python里面引入了web3py模块，就可以正式学习web3py的一些方法，在此说一些比较简单的，也是我觉的需要用的最多的。

*   检查是否链接成功.
    
*   `polygon_main.isConnected()`
    
*   检查所链接RPC的chainId.
    
*   `polygon_main.eth.chain_id`
    
*   检查当前的gas费
    
*   `polygon_main.eth.gas_price`
    
*   检查当前的区块高度
    
*   `polygon_main.eth.get_block_number()`
    
    3、wei、gwei、ether之间的转换
    
    在传输过程中，都是转换wei的形式进行。web3py提供了toWei,fromWei方法。
    
*   `polygon_main.toWei(1,“gwei”)`
    
    \= 1,000,000,000
    
*   `polygon_main.toWei(1,”ether”)`
    
    \= 1,000,000,000,000,000,000
    
*   `polygon_main.fromWei(1000000000,’gwei’)`
    
    \= 1
    
    上面的单位是gwei。
    
    4、账户的建立。
    
*   简单多了，学会这个就不会再网站上心惊胆颤的生成地址，用着不安心了。
    
    *   `myAccount = polygon_main.eth.account.create(‘this is address have 100 btc.‘)`
        
    *   create后面的小括号你爱输啥就输啥，字节，字符，数字都成，如果实在幸运撞到一个大佬，直接自由，当然有这运气别忘记我~,话不多说，我们要取回私钥和地址。
        
    *   privateKey = `polygon_main.toHex(`myAccont.privateKey)
        
        有上面的privateKey就可以导入钱包了，比如小狐狸啥的。接下来我们再找出我们的地址，看有没人给我们打钱~
        
    *   myAddress = myAccount.address
        
        5、既然地址有了，那就再说说关于交易的那些事。以太区块交易要构造交易信息，需要nonce，可以理解为地址的交易次数，value，也就是转账的金额，所在链的链id，gasPrice，想要支付的gasPrice费用,要换算成wei。gas，最大gas默认21000，如果与合约交互，数值就比较大了。纵观以上，查链上当前gasPrice,chainId我们会了，value是主观输入，剩下的就是获取nonce了。
        
        myNonce = `polygon_main.eth.get_transaction_count(myAccount.address)`
        
    *   结下来就构造交易信息；
        
    *   tx = {
        
               “nonce“:myNonce,
            
               “to“:发给哪个地址啊\~，
            
               “gas”:21000,
            
               “gasPrice“:`polygon_main.eth.gas_price,`
            
               “value“:发送的数额。再次提示一下，这是以wei为单位的。
            
              “chainId”:`polygon_main.eth.chain_id`
            
        
        }
        
        到这里有聪明的小伙伴就会问了，这样能成功吗？是的，能成功吗？我觉的应该可以或者应该不可以，为啥呢？我们要对地址里面的余额进行计算，在链上转账需要花费gas的，如果你要更快的转账就需要更多的gas消耗。在此我们对上面的优化一下，如果我们要对这个地址进行token清零操作，我们应该怎么做呢？
        
    *   首先，获取该地址的余额信息
        
        value = `polygon_main.get_balance(address)`
        
    *   获取该地址nonce并记录，
        
        `myNonce = polygon_main.eth.get_transaction_count(address)`
        
    *   查询当前的gas费,最大gas是21000。
        
        gasPrice = `polygon_main.eth.gas_price`
        
    *   对转账花费手续费进行计算:
        
        useGas = 21000 \* gasPrice
        
    *   对比value和useGas。如果余额大于开销就转账，否则就停止，都不够转账消费的。
        
        finallyValue = value - useGas
        
    *   生成新的tx
        
    *   tx = {
        
               “nonce“:myNonce,
            
               “to“:vitakl，
            
               “gas”:21000,
            
               “gasPrice“:`polygon_main.eth.gas_price,`
            
               “value“:finallyValue,
            
              “chainId”:`polygon_main.eth.chain_id`
            
        
        }
        
    *   用私钥进行签名。
        
        signTx = `polygon_main.eth.account.sign_transaction(tx,privateKey)`
        
    *   签名后发送，并记录相应的txHash.
        
    *   txHash = `polygon_main.eth.send_raw_transaction(signTx.RawTransaction)`
        
    *   生成的txHash不好识别，用`polygon_main.toHex(txHash)即可用链上浏览器进行查看。`
        
    *   对以上的操作，写了一个方法。可以看下。
        
            def transactionAll(web,faddress,fprivate,taddress,value,gaslimit=21000):
                gBalance = web.eth.get_balance(faddress)
                gasPrice = web.eth.gas_price
            
                #1、如果账户数量不足以转账，返回错误。
                if gBalance < web.toWei(value,'ether') + gasPrice * gaslimit:
                    print(f'余额不足！ {web.fromWei(gBalance,'ether')}')
                    return -1
                
                #2、检查待发送地址格式，并获取发送方nonce.
                toAdd = web.tochecksumAddress(taddress)
                nonce2 = web.eth.get_transaction_count(faddress)
            
                #3、生成数据格式.
                tx = {
                    "nonce":nonce2,
                    "to":toAdd,
                    "gas":gaslimit,
                    "gasPrice":gasPrice,
                    "value":value,
                    "chainId":web.eth.chain_Id
                }
            
                #4、用私钥签名数据->发送数据至区块。
                signTx = web.eth.account.sign_transaction(tx,fprivate)
                txHash = web.eth.send_raw_transaction(signTx.Rawtransaction)
                return web.toHex(txHash)

---

*Originally published on [SuperFoxMan](https://paragraph.com/@hexying/web3py)*
