Windows下使用web3.py进行以太坊Dapp开发笔记--第3篇(关于账户解锁和离线签名)

1.账户解锁

这是一种==“不安全的”==方法,目前应该很少采用了,但刚开始学的时候,每发送一个修改区块链数据的交易就需要unlock一次账户(ps:如果仅仅是调用智能合约中查询数据的函数,不需要unlock)。

  • 以太坊客户端解锁账户的形式如下:
    在这里插入图片描述
    第一个函数参数是以太坊地址address,第二个参数是申请以太坊账户时设置的密码,以字符串形式输入。
  • 使用web3.py解锁账户的形式如下:
from web3 import Web3

class eth_handler():
    def __init__(self):
        self.web3 = Web3(Web3.WebsocketProvider("ws://127.0.0.1:8546"))
        # 检查是否连接成功
        if self.web3.isConnected():
            print("Successfully connected!")
            # 先看看链上账户
            accounts = self.web3.eth.accounts
            print(accounts)
            # 随便解锁一个账户,看下返回值
            res = self.web3.geth.personal.unlockAccount(accounts[0],"123")
            print(res)


if __name__ == '__main__':
    eth=eth_handler()

由于每次调用智能合约函数时,一旦函数会修改链上数据,就需要unlock账户。这里使用web3.py调用unlock有一个坑:就是在启动geth客户端命令中必须使personal api显式可调用,即:
在这里插入图片描述
由于连接以太坊客户端使用的时websocket方式,故需要在wsapi中打开personal,否则不能在web3.py中调用unlock。

由于unlockAccount的不安全性,以太坊官方推荐使用的是“离线签名”方式发送交易

2.离线签名

使用web3.py实现离线签名在web3.py开发文档的__“Working with Local Private Keys”__中有示例代码。
参照开发文档示例代码,自我实现的部分代码如下:

"""检查传入地址是否正确,不正确则转换为正确地址并返回"""
def CheckAddress(self,_address):
    if self.web3.isChecksumAddress(_address):
        return _address
    else:
        return self.web3.toChecksumAddress(_address)

def GetNounce(self,_address):
    '''
    返回地址的交易数目
    :param _address:
    :return:
    '''
    return self.web3.eth.getTransactionCount(
        self.CheckAddress(_address)
    )

def My_Transaction(_myaddress,_privatekey):
	nonce = self.GetNounce(_myaddress)
	txn_dict = 	self.myContract.functions.SmartContractFunc(params).buildTransaction({
	'chainId':9,
    'gas':3000000,
    'gasPrice':self.web3.toWei('1','gwei'),
    'nonce':nonce,
	})
	signed_txn = self.web3.eth.account.signTransaction(txn_dict,private_key=_privatekey)
	txhash = self.web3.eth.sendRawTransaction(signed_txn.rawTransaction)
	# 其实执行到txhash=...这一步已经将交易发送至区块链
	# 为了保证交易成功被打包,还需要等待
	receipt = self.web3.waitForTransactionReceipt(self.web3.toHex(txhash))

补充:
chainId是初始化区块链时的创世文件中设定的,需要一致。(查看我的第一篇笔记)
privatekey是需要从keystore密钥文件中解出的私钥。(查看我的第二篇笔记)

一开始做以太坊Dapp毕设的时候,因为在启动以太坊geth客户端时没有使personal api可调用,导致在代码中无法使用unlockAccount,只能每调用一个智能合约函数就在geth客户端unlockAccount,这样十分麻烦,后来想了想,这个技术不可能这么麻烦的呀,然后查到了离线签名发送交易。也许是太笨了,希望大家一开始接触的时候就使用离线签名交易吧。少走点弯路,节省点时间弄别的!

              偷得浮生半日闲,又摘桃花换酒钱!

你可能感兴趣的:(Windows下使用web3.py进行以太坊Dapp开发笔记--第3篇(关于账户解锁和离线签名))