16

Error: Can not send value to non-payable contract method or constructor

 3 years ago
source link: https://learnblockchain.cn/question/1949
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Error: Can not send value to non-payable contract method or constructor

Error: Can not send value to non-payable contract method or constructor

Contract的方法已经设置为payable,但是web3还是提示没有payable,remix内交互没有问题,不知道要怎么调整?

// ------------------------------------------------------------------------
    // 1,000,000 UICI Tokens per 1 ETH
    // ------------------------------------------------------------------------
    function setInfo(string _fName, uint _age) public payable {
        fName = _fName;
        age = _age;
        require(now >= startDate && now <= endDate);
        uint tokens;
        if (now <= bonusEnds) {
            tokens = msg.value * 1200000;
        } else {
            tokens = msg.value * 1000000;
        }
        
        balances[msg.sender] = safeAdd(balances[msg.sender], tokens);
        _totalSupply = safeAdd(_totalSupply, tokens);
        Transfer(address(0), msg.sender, tokens);
        owner.transfer(msg.value);
    }
    
    function getInfo() public constant returns (string, uint) {
       return (fName, age);
   }
Error: Can not send value to non-payable contract method or constructor
    at Object.o._executeMethod (web3_1.2.6.min.js:1)
    at HTMLButtonElement.<anonymous> ((index):82)
    at HTMLButtonElement.dispatch (jquery.js:3)
    at HTMLButtonElement.q.handle (jquery.js:3)

完整代码:

contract uiciToken is ERC20Interface, Owned, SafeMath {
    string public symbol;
    string public  name;
    uint8 public decimals;
    uint public _totalSupply;
    uint public startDate;
    uint public bonusEnds;
    uint public endDate;
    string fName;
    uint age;
    mapping(address => uint) balances;
    mapping(address => mapping(address => uint)) allowed;


    // ------------------------------------------------------------------------
    // Constructor
    // ------------------------------------------------------------------------
    function uiciToken() public{
        symbol = "UICI";
        name = "UICI Token";
        decimals = 18;
        bonusEnds = now + 2 weeks;
        endDate = now + 10 weeks;

    }


    // ------------------------------------------------------------------------
    // Total supply
    // ------------------------------------------------------------------------
    function totalSupply() public constant returns (uint) {
        return _totalSupply  - balances[address(0)];
    }


    // ------------------------------------------------------------------------
    // Get the token balance for account `tokenOwner`
    // ------------------------------------------------------------------------
    function balanceOf(address tokenOwner) public constant returns (uint balance) {
        return balances[tokenOwner];
    }


    // ------------------------------------------------------------------------
    // Transfer the balance from token owner's account to `to` account
    // - Owner's account must have sufficient balance to transfer
    // - 0 value transfers are allowed
    // ------------------------------------------------------------------------
    function transfer(address to, uint tokens) public returns (bool success) {
        balances[msg.sender] = safeSub(balances[msg.sender], tokens);
        balances[to] = safeAdd(balances[to], tokens);
        Transfer(msg.sender, to, tokens);
        return true;
    }


    // ------------------------------------------------------------------------
    // Token owner can approve for `spender` to transferFrom(...) `tokens`
    // from the token owner's account
    //
    // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
    // recommends that there are no checks for the approval double-spend attack
    // as this should be implemented in user interfaces
    // ------------------------------------------------------------------------
    function approve(address spender, uint tokens) public returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        Approval(msg.sender, spender, tokens);
        return true;
    }


    // ------------------------------------------------------------------------
    // Transfer `tokens` from the `from` account to the `to` account
    //
    // The calling account must already have sufficient tokens approve(...)-d
    // for spending from the `from` account and
    // - From account must have sufficient balance to transfer
    // - Spender must have sufficient allowance to transfer
    // - 0 value transfers are allowed
    // ------------------------------------------------------------------------
    function transferFrom(address from, address to, uint tokens) public returns (bool success) {
        balances[from] = safeSub(balances[from], tokens);
        allowed[from][msg.sender] = safeSub(allowed[from][msg.sender], tokens);
        balances[to] = safeAdd(balances[to], tokens);
        Transfer(from, to, tokens);
        return true;
    }


    // ------------------------------------------------------------------------
    // Returns the amount of tokens approved by the owner that can be
    // transferred to the spender's account
    // ------------------------------------------------------------------------
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining) {
        return allowed[tokenOwner][spender];
    }


    // ------------------------------------------------------------------------
    // Token owner can approve for `spender` to transferFrom(...) `tokens`
    // from the token owner's account. The `spender` contract function
    // `receiveApproval(...)` is then executed
    // ------------------------------------------------------------------------
    function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        Approval(msg.sender, spender, tokens);
        ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data);
        return true;
    }

    // ------------------------------------------------------------------------
    // 1,000,000 UICI Tokens per 1 ETH
    // ------------------------------------------------------------------------
    function setInfo(string _fName, uint _age) public payable {
        fName = _fName;
        age = _age;
        require(now >= startDate && now <= endDate);
        uint tokens;
        if (now <= bonusEnds) {
            tokens = msg.value * 1200000;
        } else {
            tokens = msg.value * 1000000;
        }
        
        balances[msg.sender] = safeAdd(balances[msg.sender], tokens);
        _totalSupply = safeAdd(_totalSupply, tokens);
        Transfer(address(0), msg.sender, tokens);
        owner.transfer(msg.value);
    }
    
    function getInfo() public constant returns (string, uint) {
       return (fName, age);
   }   


    // ------------------------------------------------------------------------
    // Owner can transfer out any accidentally sent ERC20 tokens
    // ------------------------------------------------------------------------
    function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) {
        return ERC20Interface(tokenAddress).transfer(owner, tokens);
    }
}

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>First DApp Demo</title>

    <link rel="stylesheet" type="text/css" href="main.css">
    <script src="web3_1.2.6.min.js"></script>

</head>
<body>
    <div class="container">

        <h1> First DApp Demo</h1>

        <h2 id="info"></h2>

        <label for="name" class="col-lg-2 control-label">姓名:</label>
        <input id="name" type="text">

        <label for="name" class="col-lg-2 control-label">年龄:</label>
        <input id="age" type="text">

        <button id="button">更新</button>


    </div>

    <script src="jquery.js"></script>

    <script>

        function initWeb3() {
            var web3;
            if (window.ethereum) {
                web3 = new Web3(window.ethereum);
            // 请求用户授权
                window.ethereum.enable();
            } else if (typeof web3 !== 'undefined') {
                web3 = new Web3(web3.currentProvider);
                web3.eth.defaultAccount = web3.eth.accounts[0];
                console.log(web3.eth.defaultAccount);
            } else {
                // set the provider you want from Web3.providers
                web3 = new Web3(new Web3.providers.HttpProvider("HTTP://127.0.0.1:8545"));
                console.log("web3 local Provider"+web3)
            }
            return web3;
        }

        var web3 = initWeb3();

        web3.eth.getAccounts((error, accounts) => {
            web3.eth.defaultAccount = accounts[0];
            console.log(accounts)
        })

        
        var info = new web3.eth.Contract(
            [{"constant":true,"inputs":[],"name":"getInfo","outputs":[{"name":"","type":"string"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_fName","type":"string"},{"name":"_age","type":"uint256"}],"name":"setInfo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
            ,'0x402Ed5892bff3Ba8470498947DeE064393E53Cd8');

        info.methods.getInfo().call( 
            function(error, result) {
                console.log(error);
                if(!error) {
                    $("#info").html(result[0]+' ('+result[1]+' years old)');
                    console.log(result);
                } else {
                    console.error(error);
                }
            });


        $("#button").click(function() {
            console.log(info);
            console.log(web3.eth.defaultAccount);

            info.methods.setInfo($("#name").val(), $("#age").val())
            .send({from: web3.eth.defaultAccount, value: web3.utils.toWei('1','ether') },
             function(error, transactionHash) {
                 console.log(error)
            });
            // web3.eth.sendTransaction({
            //     from: web3.eth.defaultAccount,
            //     to: '0xf97De723d0aA8d9c1D47603dA687922C0896b79C',
            //     value: web3.utils.toWei('1','ether')
            // })

        });

    </script>

</body>
</html>


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK