Intro
在用etherjs或者web3py的时候,有没有奇怪,不提供账号和private key,也照样执行contract 的函数。这是如何做到的?
分析
我们都知道,像ehterjs 或者web3py这种,是通过rpc连接到node上的。rpc 有自己的接口规范。
在官方文档中是这样写的,我们直接用JsonRpcProvider,是只读模式
连接了signer,也就是提供private key或者 通过metamask等钱包的方式,是写入模式。
问题是,什么是只读模式,什么是写入模式?很多教程写的是只读就是调用
pure
/view
函数,不对链上数据产生影响的函数,实际是这样吗?实验
function _approve( address owner, address spender, uint256 amount ) private { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); }
简单的部署一个ERC20合约,调用approve 会报ERC20: approve from the zero address 的错误。由此可以看出,交易是由0地址发出的。
在ERC20的基础上添加两个测试函数,add_num 可以改变storage。
uint public test = 0; function add_num(uint a) public returns(uint) { test = test + a; return test; } function get_num() public view returns(uint) { return test; }
再执行add_num(3)后,return 3.这说明函数是顺利执行的。
但是再之后执行get_num的时候,返回0,说明刚才的更改并没有生效.
结论
在使用RpcProvider,不提供账号private key的情况下,contract 的函数都可以执行,并且是用0账号发起。
这里的只读,意思是只在node里执行并且返回结果,但不写入区块链。相当于无论什么函数,都只是在node的evm里执行一下,不上链,也就不用gas。