Go智能合约链码分析器panic错误:ast类型转换失败解决方案咨询
解决chaincode-analyzer分析fabcar.go时的panic错误
问题场景
运行hyperledger-labs的chaincode-analyzer分析Go语言智能合约文件fabcar.go时触发panic,错误信息如下:
panic: interface conversion: ast.Expr is *ast.CallExpr, not *ast.Ident
完整调用栈:
goroutine 1 [running]: github.com/hyperledger-labs/chaincode-analyzer/analyze.pickUpTargetVar(0xc0000d2210, 0x684a30, 0xc0000b8d00) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:466 +0xf3c github.com/hyperledger-labs/chaincode-analyzer/analyze.walkAssignStmt(0xc0000d2210, 0xc0000b8d40) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:554 +0x26f github.com/hyperledger-labs/chaincode-analyzer/analyze.walkStmt(0xc0000d2210, 0x686c18, 0xc0000b8d40) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:679 +0x4ac github.com/hyperledger-labs/chaincode-analyzer/analyze.walkStmt(0xc0000d2210, 0x686d38, 0xc00008f590) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:682 +0x10e github.com/hyperledger-labs/chaincode-analyzer/analyze.walkRangeStmt(0xc0000d2210, 0xc0000818b0) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:649 +0x6d github.com/hyperledger-labs/chaincode-analyzer/analyze.walkStmt(0xc0000d2210, 0x687278, 0xc0000818b0) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:696 +0x7cc github.com/hyperledger-labs/chaincode-analyzer/analyze.walkStmt(0xc0000d2210, 0x686d38, 0xc00008f5c0) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:682 +0x10e github.com/hyperledger-labs/chaincode-analyzer/analyze.(*file).storeInfo.func1(0x684cb0, 0xc00008f5f0, 0x685000) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:743 +0xe5 github.com/hyperledger-labs/chaincode-analyzer/analyze.walker.Visit(0xc0001c1938, 0x684cb0, 0xc00008f5f0, 0x0, 0x0) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:1119 +0x3a go/ast.Walk(0x684348, 0xc0001c1938, 0x684cb0, 0xc00008f5f0) /usr/local/go/src/go/ast/walk.go:52 +0x63 go/ast.walkDeclList(0x684348, 0xc0001c1938, 0xc0000ca500, 0xa, 0x10) /usr/local/go/src/go/ast/walk.go:38 +0x9e go/ast.Walk(0x684348, 0xc0001c1938, 0x684c60, 0xc0000c8400) /usr/local/go/src/go/ast/walk.go:353 +0x2446 github.com/hyperledger-labs/chaincode-analyzer/analyze.(*file).walk(...) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:1111 github.com/hyperledger-labs/chaincode-analyzer/analyze.(*file).storeInfo(0xc00011a550, 0xc0000d2210) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:737 +0x94 github.com/hyperledger-labs/chaincode-analyzer/analyze.(*file).analyze(0xc00011a550) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:1090 +0x385 github.com/hyperledger-labs/chaincode-analyzer/analyze.(*pkg).analyze(0xc000081310, 0xc00008e960, 0x7fff19af23b9, 0x9) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:115 +0xcc github.com/hyperledger-labs/chaincode-analyzer/analyze.(*Analyzer).AnalyzeFiles(0xc0000a7b28, 0xc0000812c0, 0xc0000a7c38, 0x9, 0xc0000a7d98, 0x0, 0x0, 0xc00008c510) /home/aai/go/pkg/mod/github.com/hyperledger-labs/chaincode-analyzer@v0.0.0-20200326141029-a98b7983ce34/analyze/analyze.go:63 +0x5e5 main.analyzeFiles(0xc0000812c0, 0xc00008c530, 0x1, 0x1) /usr/local/go/bin/chaincode-analyzer-master/ccanalyzer.go:120 +0x1b9 main.main() /usr/local/go/bin/chaincode-analyzer-master/ccanalyzer.go:66 +0x517
原因分析
这个panic是因为chaincode-analyzer的pickUpTargetVar函数(位于analyze.go第466行)在处理Go抽象语法树(AST)时,直接将ast.Expr类型断言为*ast.Ident,但遇到了*ast.CallExpr类型的节点(比如函数调用表达式),导致类型转换失败触发panic。
解决方案
方案1:修复chaincode-analyzer源码
- 找到chaincode-analyzer的
analyze.go文件,定位到第466行的pickUpTargetVar函数。 - 修改类型断言逻辑,增加对
*ast.CallExpr的判断,避免直接panic:
func pickUpTargetVar(a *Analyzer, expr ast.Expr) (*ast.Ident, error) { // 先尝试断言为标识符 ident, ok := expr.(*ast.Ident) if ok { return ident, nil } // 处理函数调用表达式的情况 callExpr, ok := expr.(*ast.CallExpr) if ok { // 如果函数调用的主体是标识符,提取该标识符 if funIdent, ok := callExpr.Fun.(*ast.Ident); ok { return funIdent, nil } // 也可以根据需求处理其他类型的Fun,比如选择器表达式等 } // 其他未处理的类型,返回错误而非panic return nil, fmt.Errorf("unsupported expression type: %T", expr) }
- 重新编译chaincode-analyzer:
go build -o chaincode-analyzer github.com/hyperledger-labs/chaincode-analyzer
方案2:调整fabcar.go代码
如果暂时不想修改分析器,可以检查fabcar.go中的赋值语句,找到直接将函数调用赋值的代码,比如:
result := getCarById("CAR001")
改成先将函数调用结果存入临时变量,再进行后续操作:
tmp := getCarById("CAR001") result := tmp
这种写法可以避开分析器对函数调用表达式的处理缺陷。
方案3:升级chaincode-analyzer
当前使用的是2020年的旧版本(v0.0.0-20200326141029-a98b7983ce34),可以执行以下命令更新到最新版本:
go get -u github.com/hyperledger-labs/chaincode-analyzer
更新完成后重新运行分析命令。
内容的提问来源于stack exchange,提问作者Neel Shah
相关产品推荐
相关产品推荐

