使用go调用eth踩坑笔记
项目中使用 go-ethereum 相关接口与以太坊网络进行交互,本文整理了中间遇到的一些坑,方便后来人对应来排错。
代币转账
1. 调用合约方法时,报 Error: VM Exception while executing transaction: out of gas 的错误
可能原因:
- 对一个只读方法进行当成改值的方法执行了,比如 constant,view修饰的方法。
- 调用的合约方法有异常,有死循环之类的,造成消耗的gas过多。
- 第三个也就是笔者遇到的情况,接口中获取的预估价格(gasLimit)不准确,低于实际运行合约需要的gasLimit.
笔者的获取gasLimit是通过接口获取的,代码如下:
gasLimit, err := cli.EstimateGas(context.Background(), ethereum.CallMsg{
To: &toAddress,
Data: data,
})
我们是合约转账交易,所以这个toAddress是接收者的地址,data是构造调用的全部数据。然而这个估值并不准确,往往比实际需要的gas要小,所以不得不放弃使用接口获取估值的方式。
最后通过把 gasLimit 改为最大值解决。
2. 调用合约方法,报 Error: VM Exception while executing transaction: revert 错误。
简而言之,方法id必须只截取前四个字节,没有截取,故发生了此报错。
笔者原先是根据这个指南 来实现的代币转账,代码是这样的:
hash := sha3.NewKeccak256()
hash.Write(transferFnSignature)
methodID := hash.Sum(nil)[:4]
新版本中sha3,已经没有 NewKeccak256 方法了,新版本放在了github.com/ethereum/go-ethereum/crypto
包中
methodID := crypto.Keccak256(transferFnSignature)[:4]
在使用新接口时忘记了取前四个字节[:4],故造成悲剧。