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,这样十分麻烦,后来想了想,这个技术不可能这么麻烦的呀,然后查到了离线签名发送交易。也许是太笨了,希望大家一开始接触的时候就使用离线签名交易吧。少走点弯路,节省点时间弄别的!
偷得浮生半日闲,又摘桃花换酒钱!