通过DocInfo合约调用DocumentContract存数后查询为空,求问题排查
我帮你排查了下,调用GetDocument返回空(实际是返回地址类型的默认值address(0))的原因大概率是以下几个点,咱们逐个拆解:
1. 未替换合约地址占位符
你在DocInfo合约里写的<<Document contract address>>是占位符,必须替换为实际部署的DocumentContract的真实链上地址。如果没替换,相当于你在调用一个不存在的合约,写入操作完全不会生效,自然查不到任何数据。
修复方式:把两处<<Document contract address>>替换成部署DocumentContract后生成的十六进制地址(比如0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D这类格式)。
2. 调用CreateDocument时用了静态调用而非交易
DocInfo.CreateDocument内部调用了DocumentContract的写操作(修改链上状态),所以你必须通过发送带gas的交易来调用它,不能用eth_call这类静态调用方法——静态调用只会模拟执行,不会真正修改链上数据,等于白调用了。
验证方法:调用后去区块链浏览器查对应的交易哈希,确认交易已上链;或者直接查看DocumentContract的doc映射是否有对应数据。
3. 参数顺序传反(隐性坑)
仔细核对DocInfo.CreateDocument的调用参数:函数定义是function CreateDocument(address digitalID, string memory documentId),也就是第一个参数是地址,第二个是文档编号。如果调用时你把参数传反了(比如先传文档编号再传地址),会导致DocumentContract里用地址的字符串形式作为键存储数据,你用原文档编号查询自然会返回默认值address(0)。
额外调试建议:添加事件日志
为了更直观确认数据是否写入,建议给DocumentContract的CreateDocument函数加上事件日志,每次写入都会在链上留下记录,方便排查:
pragma solidity 0.5.0; contract DocumentContract { struct Document{ string DocumentNo; address DigitalID; } // 新增事件,带索引便于查询 event DocumentCreated(string indexed documentNo, address indexed digitalId); mapping(string=>Document) doc; function CreateDocument(string calldata DocumentNo,address DigitalID) external { doc[DocumentNo] = Document({ DocumentNo: DocumentNo, DigitalID: DigitalID }); // 触发事件 emit DocumentCreated(DocumentNo, DigitalID); } function GetDocument(string calldata documentNumber) external view returns(address) { Document memory document = doc[documentNumber]; return (document.DigitalID); } }
这样每次成功写入后,你都能在区块链浏览器里看到对应的事件日志,直接确认数据是否正确存储。
内容的提问来源于stack exchange,提问作者brindabs

