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读方法,即viewpure函数,这些是可以有返回值并且可以在js里获取的。

为什么 EVM 这么设计
因为:
交易 return value
不会存链

区块链只保存:
state
logs
receipt

类型 作用
storage 状态数据库
event/log 消息队列/索引
return value 临时执行结果

真正重要的数据
不要只依赖 event

posted on 2026-05-26 21:28  幽州散人  阅读(10)  评论(0)    收藏  举报

导航