Truffle

在測試期間無法從智能合約中檢索數據

  • March 11, 2019

我正在為我的智能合約 Solidity 版本 0.4.24 編寫松露測試。測試正在發出事件以通過智能合約將數據寫入記憶體。但我無法從函式中檢索數據。

這是我的智能合約功能:

以前的農場 ID = 0;

struct Location {
       string latitude;
       string longitude;
       string locationAddress;
   }

   struct Farm {
       uint farmId;
       string farmName;
       Location location;
   }

mapping (uint => Farm) farms;

function registerFarm(string _farmName, string _farmLatitude, string _farmLongitude, string _locationAddress) public {

       previousFarmId = previousFarmId + 1;

       Location memory newLocation = farmLocation[previousFarmId];
       newLocation.latitude = _farmLatitude;
       newLocation.longitude = _farmLongitude;
       newLocation.locationAddress = _locationAddress;

       Farm memory newFarm = farms[previousFarmId];
       newFarm.farmId = previousFarmId;
       newFarm.farmName = _farmName;
       newFarm.location = newLocation;

       emit FarmRegistered(previousFarmId);

   }

   function getFarmInfo(uint _farmId) public view 
   returns (uint farmId, string farmName, string latitude, string longitude, string locationAddress) {
       Farm memory returnFarm = farms[_farmId];
       farmId = returnFarm.farmId;
       farmName = returnFarm.farmName;
       latitude = returnFarm.location.latitude;
       longitude = returnFarm.location.longitude;
       locationAddress = returnFarm.location.locationAddress;
   }

這是松露測試:

常量農場ID = 1;

it("Testing smart contract function harvestGrapes() that allows producer to harvest grapes", async() => {

       const supplyChain = await SupplyChain.deployed();

       await supplyChain.addProducer(producerID, {from: deployerID});

       await supplyChain.registerFarm(farmName, farmLatitude, farmLongitude, farmAddress, {from: producerID});

       const resultFarms = await supplyChain.getFarmInfo.call(farmID);

       console.log('Farm ID: ' + resultFarms[0]);
       console.log('Farm Name: ' + resultFarms[1]);
       console.log('Farm Latitude: ' + resultFarms[2]);
       console.log('Farm Longitude: ' + resultFarms[3]);
       console.log('Farm Address: ' + resultFarms[4]); 
}

控制台日誌:

Farm ID: 0
Farm Name:
Farm Latitude:
Farm Longitude:
Farm Address:

測試期間發出的事件:

  ProducerAdded(account: <indexed>)
   FarmRegistered(farmId: 1)
   GrapesHarvested(grapesId: 1)

這部分不符合您的要求。

function registerFarm(string _farmName, string _farmLatitude, string _farmLongitude, string _locationAddress) public {

       previousFarmId = previousFarmId + 1;

       Location memory newLocation = farmLocation[previousFarmId];
       newLocation.latitude = _farmLatitude;
       newLocation.longitude = _farmLongitude;
       newLocation.locationAddress = _locationAddress;

       Farm memory newFarm = farms[previousFarmId];
       newFarm.farmId = previousFarmId;
       newFarm.farmName = _farmName;
       newFarm.location = newLocation;

       emit FarmRegistered(previousFarmId);

   }

首先將函式參數分配給memory變數newLocation。然後,將參數分配給另一個memory變數newFarm。他們都是memory,所以他們不會堅持下去。

考慮:

function registerFarm(string _farmName, string _farmLatitude, string _farmLongitude, string _locationAddress) public {

       previousFarmId = previousFarmId + 1;

       Location storage newLocation = farmLocation[previousFarmId];
       newLocation.latitude = _farmLatitude;
       newLocation.longitude = _farmLongitude;
       newLocation.locationAddress = _locationAddress;

       emit FarmRegistered(previousFarmId);

   }

newLocation是一個儲存指針,因此對它的分配直接進入儲存。函式執行完成後,儲存將持續存在。memory變數在其函式或函式內範圍(新編譯器進一步縮小範圍)完成時消失。

在進行單元測試之前,您可能會發現 Remix 非常適合進行表面和手動測試。

希望能幫助到你。

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