js里调用智能合约读/写函数的方法的区别
javascript用ethers.js调用evm区块链上的智能合约,合约方法函数有读写区别。
写方法,即会改变合约状态,例如:
let seed = "979202789523";
let tx = await contract.drawWinner("activity1",
seed,
new Date().getTime());
let receipt = await tx.wait();
if(receipt.status === 1)
console.log("tx成功: 交易Hash: %s, 区块Hash: %s,区块高度: %s",
receipt.transactionHash,
receipt.blockHash,
receipt.blockNumber);
else
console.log("tx失败: %s", receipt);
这里drawWinner是合约的写方法,
tx = await contract.drawWinner得到的tx是TransactionResponse,这时候得到这个结果只代表“交易已经广播发出去”,还未最终共识上链完成。
receipt = await tx.wait()表示的是已被区块确认上链完成,receipt是TransactionReceipt、即交易回执,可以获取到交易hash,区块hash,区块高度这些。
但是还是有个误区:
Solidity 的 return 对“交易函数”没意义,return 只在 EVM 内部存在,不会写进链上 receipt,solidity里调用有return的函数当然可以拿到返回值,但是从链下调用、交易回执里却是没有的。
即使drawWinner函数有return返回值,但在js里仍然是获取不到的,需要我们在js里主动去合约里查询。
比如:
let luckyIndex = await contract.luckyIndexOf("activity1");
console.log("索引:%s", luckyIndex);
上面的luckyIndexOf即读方法,即view或pure函数,这些是可以有返回值并且可以在js里获取的。
为什么 EVM 这么设计
因为:
交易 return value
不会存链
区块链只保存:
state
logs
receipt
| 类型 | 作用 |
|---|---|
| storage | 状态数据库 |
| event/log | 消息队列/索引 |
| return value | 临时执行结果 |
真正重要的数据
不要只依赖 event
浙公网安备 33010602011771号