Storage

Truffle uint 測試腳本不更新儲存變數和奇怪的行為

  • August 2, 2019

在測試時我發現了一個奇怪的松露行為,請先查看主題智能合約程式碼

   uint256 public burningRatePercent = 50;
function onlyOwnerSetBurningRate(uint256 _burningRatePercent) onlyOwner public returns (uint)
{
   burningRatePercent = _burningRatePercent;
   return (burningRatePercent);
}

這是測試腳本

it("should return set value from onlyOwnerSetBurningRate", function() {
   var token;
   return Token.deployed().then(function(instance){
       token = instance;
       const tst = token.onlyOwnerSetBurningRate.call(1234);
       return tst;
   }).then(function(result){
       assert.equal(result.toNumber(), 1234, 'onlyOwnerSetBurningRate failed');
       var ret =  token.burningRatePercent.call();
       return ret;
   }).then(function(result){
       assert.equal(result.toNumber(), 1234, 'Reading BurningRate set value failed');
   }); 
}); 

這裡 ’tst’ 的值清楚地表明變數值更改因此通過 OK 為 “onlyOwnerSetBurningRate failed” ,但在下一行讀取 ‘var ret’ 中相同變數的嘗試返回 ‘50’ 這是初始值,因此 “Reading BurningRate設置值失敗”沒有通過綠色勾號。所以這裡有什麼問題,我的程式碼,或者松露錯誤,非常奇怪,請幫助我

在此處輸入圖像描述

此程式碼工作正常且主題函式傳輸不純或視圖

   it("should transfer token to correct address, include burning, and balance test", function() {
   var token;
   return Token.deployed().then(function(instance){
       token = instance;
       return token.transfer(accounts[1], "500000000000000000000000000");
   }).then(function(){
       return token.balanceOf.call(accounts[1]);
   }).then(function(result){
       assert.equal(result, CP(RP(500000000)), 'accounts[1] balance is wrong');
       return token.balanceOf.call(accounts[0]);
   }).then(function(result){
       assert.equal(result, RP(500000000), 'accounts[0] balance is wrong');
   })
}); 

同樣的 transferfrom 也可以正常工作

   it("should pass test of approve transferfrom and balance check of 0,1,3 after transaction", function() {
   var token;
   return Token.deployed().then(function(instance){
       token = instance;
       return token.approve(accounts[1], "200000000000000000000000000");
   }).then(function(){
       return token.allowance.call(accounts[0], accounts[1]);
   }).then(function(result){
       assert.equal(result, RP(200000000), 'allowance is wrong');
       return token.transferFrom(accounts[0], accounts[2], "200000000000000000000000000", {from: accounts[1]});
   }).then(function(){
       return token.balanceOf.call(accounts[0]);
   }).then(function(result){
       assert.equal(result, RP(300000000), 'accounts[0] balance is wrong');
       return token.balanceOf.call(accounts[1]);
   }).then(function(result){
       assert.equal(result, CP(RP(500000000)), 'accounts[1] balance is wrong');
       return token.balanceOf.call(accounts[2]);
   }).then(function(result){
       assert.equal(result, CP(RP(200000000)), 'accounts[2] balance is wrong');
   })
});

這裡CP是減少一些百分比,RP是增加功率(10**18),這個程式碼也可以正常工作

我的一些更改起作用了,比如如果需要更改儲存變數,需要在沒有的情況下呼叫函式call(),如果call()我覺得松露可能只是將函式作為本地和臨時執行,因此不會影響儲存變數,這就是返回值主題問題不同。

並且每當您覺得即使沒有返回值也不正確call()(我在某些時候也感覺到),那麼只需contract('xxxxxxxx2', function(accounts);在下一行開始一個新的並為下一部分測試重新開始契約。

我不知道松露的內心深處,但我可以想像,這對我有用

@goodvibration 的回答在一定程度上也是正確的,但表達方式並不像我想的那樣直截了當(知道太多是另一種技能,簡化方式表達,直截了當是另一種技能),謝謝大家。

函式onlyOwnerSetBurningRate不是常數(也不pureview)。

因此,您無法從鏈外呼叫中獲取其返回值(即,返回值僅在您在合約中呼叫此函式時才有用)。

所以你在這裡的用法一.call()開始是錯誤的。

刪除後,token.onlyOwnerSetBurningRate(1234)將返回事務對象。

如果您發出包含它的事件(在函式本身中),您將能夠從該對象獲取返回值。

但是,由於您是burningRatePercent直接獲取,因此似乎沒有必要這樣做。

所以簡而言之,只需刪除帶有const tst = token.onlyOwnerSetBurningRate.call(1234).

此外,您可以將功能更改為:

function onlyOwnerSetBurningRate(uint256 _burningRatePercent) onlyOwner public
{
   burningRatePercent = _burningRatePercent;
}

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