Solidity

使用 sendTransaction 從智能合約中檢索數據

  • February 23, 2018

讓我們來看一個非常基本的智能合約,它有一個功能,您可以在其中發送一個數字,它會返回正方形。它有另一個返回固定字元串的函式。

contract MyContract {
 uint public version;
 address public previousPublishedVersion;

 function ping() returns (string param){
   param = "pong";
 }

 function squareNumber(uint num) returns (uint256 numSqr) {
   numSqr = (num * num);
 }
}

現在部署我使用的契約

myContract.new({
 data: MyContract.compiled_code,
 gas: gasNeeded * ethConfig.gas_factor,
 from: ethConfig.primary_address
}, (err, myContract) => {
   if(!err) {
    if(!myContract.address) {
        console.log('contract trasnaction hash ' + myContract.transactionHash)
    } else {
       console.log('contract address ' + myContract.address)
       resolve({
        primary_address: ethConfig.primary_address,
        contract_address: myContract.address,
        gas_estimate: gasNeeded
       })
    }
 } else {
   reject(err)
 }
});

這會觸發兩個回調,一個是交易雜湊,一個是探勘後的地址。但是,此方法不適用於sendTransaction. 我已經讀過使用getTransactionReceipt或檢查區塊號是檢查交易是否已被探勘的好方法。

 myContract.ping.call(null, (err, data) => {
   if (err) {
     reject(err)
   } else {
     resolve({
       primary_address: ethConfig.primary_address,
       returnValue: data
     })
   }
 })

但是為了平方我使用的數字

 myContract.squareNumber.estimateGas(10, (err, gasNeeded) => {
   if (err) reject(err)
   myContract.squareNumber.sendTransaction(
     10,
     {
       gas: gasNeeded * config.ethConfig.gas_factor,
       from: config.ethConfig.primary_address
     }, (err, data) => {
     if (err) reject(err)
     resolve({
       primary_address: config.ethConfig.primary_address,
       numSquare : data
     })
   })
 })

現在對於一個call函式,我可以直接獲取數據而無需進行任何探勘,但是文件說從 sendTransaction() 返回的值是它的雜湊值,然後我們將用於getTransactionReceipt()實際確認該塊何時被探勘.

我的問題很簡單,我該如何構造我的web3js程式碼,以從 solidity 函式中獲取返回的值 (10*10) squareNumber()

我已經將上面顯示的所有 API 包裝在 Promise 中,但只是跳過了該部分,因為它很長並且與 web3js 沒有任何關係。

添加事件後SquareComputed(請參閱 如何獲取非常量事務函式返回的值?)和 web3.js契約事件範例

var event = myContractInstance.MyEvent({valueA: 23} [, additionalFilterObject])

// watch for changes
event.watch(function(error, result){
  if (!error)
    console.log(result);
});

這將導致如下程式碼:

var event = myContractInstance.SquareComputed({});

// watch for changes
event.watch(function(error, result){
 if (!error)
   resolve({
       primary_address: config.ethConfig.primary_address,
       numSquare : result  // need to access the properties of result to obtain the actual square 
   })
 event.stopWatching();
});

之前 做以上myContractInstance.squareNumber.sendTransactionresolve({numSquare:...})應將原始程式碼中的 移至上述內部watch

web3.eth.filter也可以使用 其他 web3.js API (請參閱如何從 The DAO 檢索已投票的事件)。

這個問題詢問“我如何準確地建構我的 web3js 程式碼,以獲取從solidity 函式 squareNumber() 返回的值 (10*10)”,否則請參閱事務和呼叫之間的區別是什麼?.

使用 Web3.js v1.0.0,您可以獲得由 SquareComputed 事務觸發的事件(現在是sendTransation()等效方法send()),請參閱文件send() return

引用自:https://ethereum.stackexchange.com/questions/11419