web3 从合约调用的函数不起作用

Posted

技术标签:

【中文标题】web3 从合约调用的函数不起作用【英文标题】:the function called from contract by web3 isn't working 【发布时间】:2021-10-17 10:15:45 【问题描述】:

我正在做合同,想通过 web3 连接到 js 和 html。当我尝试在合约 save.sol 中执行功能 saveData 时,ganache 网络没有创建新块,但它应该这样做。

为什么 index.js 中的 contract.methods.saveData(date, resource, mycalculate, material) 不起作用?

web3的版本是1.5.1

代码如下所示

index.html:

<!DOCTYPE html>
ignored

          <div style="text-align: center;">
            <button type="submit" class="btn btn-primary" id="button_formCarbonEmission">Save</button>
            <a href="./home.html" class="btn btn-primary">Back</a>
          </div>

          <script>
            const form = document.querySelector('form')
            const submitButton = document.querySelector('#button_formCarbonEmission')
      
            submitButton.addEventListener('click', function onSubmitButtonClicked(event)
              form.classList.add('was-validated')
            )
      
            form.addEventListener('submit', function onFormSubmit(event)
              if(!form.checkValidity())
                event.preventDefault()
                event.stopPropagation()
              
            )
          </script>

        </form>
      </div>
      
    </div>
    
    <script src="../function/web3.min.js"></script>
    <script src="../function/index.js"></script>
    ignored    
  </body>
</html>

index.js:

// Initialize Web3
var web3 = new Web3('http://localhost:7545');

// Set Account
web3.eth.defaultAccount = '0x16E15b184F39c4fBE1A4B29052CE018c5748610B';

// Set Contract Abi
var ABI = [myabi];

// Set Contract Address
var contractAddress = 'myaddr'; // Add Your Contract address here!!!

// Set the Contract
var contract = new web3.eth.Contract(ABI, contractAddress);

// get the current time 
var today = new Date();
var date = today.getFullYear()+'-' + (today.getMonth()+1) + '-' + today.getDate() + '-'
today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds;


//get the formCarbonEmission data
const submitBtn = document.getElementById("button_formCarbonEmission");
submitBtn.addEventListener('click', processFormData);

contract.methods.test().call().then(console.log);//work normally

function processFormData() 
  const form = document.forms['formCarbonEmission'];
  const material = form.elements.material.value;
  const resource = form.elements.resource.value;
  const mycalculate = form.elements.mycalculate.value;

    //save the data
  contract.methods.saveData(date, resource, mycalculate, material).call(); **//this function isn't work**

    //alert
    alert("saved!");

保存.sol:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Storage

    string b = "calculation a";
    struct UserInfo 
        string time;
        string source;
        uint emission;
    
    mapping (string => UserInfo) users;
    
    function test() public view returns(string memory) 
        return b;
    

    function saveData(string memory input_time, string memory input_source, string memory input_mycalculate, uint input_material) public 
        users[input_source].time = input_time;
        if (keccak256(abi.encodePacked(input_mycalculate)) == keccak256(abi.encodePacked(b)))
            users[input_source].emission = input_material * 3 / 2;//solidity isn't support integer
        else
            users[input_source].emission = input_material * 5 / 2;//solidity isn't support integer
    
    
/*     function get() public view returns (string memory, uint, string memory) 
        return (source, emission, time);
     */ 
    
    function search(string memory input_source) public view returns (uint, string memory) 
        return (users[input_source].emission, users[input_source].time);
    

【问题讨论】:

【参考方案1】:

我通过创建文件“web3.js”并将文件注入到 index.js 中解决了这个问题

并添加了savedata的账号:

contract.methods.saveData(date, resource, mycalculate, material).send(
        from:web3.eth.defaultAccount
    )

【讨论】:

【参考方案2】:

contract.methods.saveData(date, resource, mycalculate, material) 必须通过以下方式调用:

call(params) - 读取/模拟操作 send(params) - 写操作

如您所见,您的 call() 没有工作,因为您没有提供任何参数,但 send(params) 确实有效。

【讨论】:

以上是关于web3 从合约调用的函数不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Solidity 合约不起作用

简单传输在注入的 Web3 中不起作用

使用 javascript 调用 solidity 智能合约来铸造代币似乎不起作用

主网在 Remix Solidity 智能合约中部署地址数组作为构造函数参数不起作用

为啥从函数调用分配给属性 innerHTML 不起作用?

从 AppDelegate 调用委托函数不起作用