cljs-web3 icon indicating copy to clipboard operation
cljs-web3 copied to clipboard

"Cannot send value to non-payable constructor" even though the constructor is payable

Open derekchiang opened this issue 7 years ago • 14 comments

First of all, congrats on the great work! Loving making dapps in ClojureScript so far thanks to your excellent libraries.

I'm attempting to create a contract while also sending it some ether. My event handler returns an effect like this:

   {:web3/call {:web3 web3
                :fns [{:fn web3-eth/contract-new
                       :args [abi
                              {:data bytecode
                               :arguments []
                               :gas 400000
                               :gasPrice "30000000000"
                               :value 1000000}]
                       :on-success [:contract-created]
                       :on-error [:contract-creation-error]}]}}

On Chrome, I get the following error:

Uncaught Error: Cannot send value to non-payable constructor
    at p.new (inpage.js:14330)
    at Function.cljs.core.js_invoke.cljs$core$IFn$_invoke$arity$variadic (core.cljs:518)
    at Function.cljs.core.js_invoke.cljs$lang$applyTo (core.cljs:514)
    at Function.cljs.core.apply.cljs$core$IFn$_invoke$arity$4 (core.cljs:3870)
    at cljs$core$apply (core.cljs:3870)
    at Function.cljs_web3.utils.js_apply.cljs$core$IFn$_invoke$arity$3 (utils.cljs?rel=1516267498445:47)
    at cljs_web3$utils$js_apply (utils.cljs?rel=1516267498445:41)
    at Function.cljs_web3.eth.contract_new.cljs$core$IFn$_invoke$arity$variadic (eth.cljs?rel=1516267499820:949)
    at Function.cljs_web3.eth.contract_new.cljs$lang$applyTo (eth.cljs?rel=1516267499820:914)
    at Function.cljs.core.apply.cljs$core$IFn$_invoke$arity$2 (core.cljs:3870)
    at cljs$core$apply (core.cljs:3836)
    at web3_fx.cljs?rel=1516267507485:214
    at re_frame$fx$do_fx_after (fx.cljc?rel=1516254953008:73)
    at re_frame$interceptor$invoke_interceptor_fn (interceptor.cljc?rel=1516254952122:67)
    at re_frame$interceptor$invoke_interceptors (interceptor.cljc?rel=1516254952122:105)
    at re_frame$interceptor$execute (interceptor.cljc?rel=1516254952122:198)
    at re_frame$events$handle (events.cljc?rel=1516254952335:64)
    at re_frame.router.EventQueue.re_frame$router$IEventQueue$_process_1st_event_in_queue$arity$1 (router.cljc?rel=1516254952952:175)
    at re_frame$router$_process_1st_event_in_queue (router.cljc?rel=1516254952952:83)
    at re_frame.router.EventQueue.re_frame$router$IEventQueue$_run_queue$arity$1 (router.cljc?rel=1516254952952:194)
    at re_frame$router$_run_queue (router.cljc?rel=1516254952952:85)
    at router.cljc?rel=1516254952952:142
    at re_frame.router.EventQueue.re_frame$router$IEventQueue$_fsm_trigger$arity$3 (router.cljc?rel=1516254952952:165)
    at re_frame$router$_fsm_trigger (router.cljc?rel=1516254952952:79)
    at router.cljc?rel=1516254952952:183
    at <anonymous>

However, my constructor is in fact payable, as can be seen in both the Solidity source and the compiled code:

// skipping non-relevant sections
{
"abi": [
    {
      "inputs": [],
      "payable": true,
      "stateMutability": "payable",
      "type": "constructor"
    }
  ]
}

Any idea why this might be happening?

derekchiang avatar Jan 18 '18 09:01 derekchiang

Thank you! You probably need to add payable modifier into your constructor in Solidity, to be allowed to send funds there. http://solidity.readthedocs.io/en/develop/contracts.html

madvas avatar Jan 18 '18 09:01 madvas

Oh, sry I've read too quickly.

madvas avatar Jan 18 '18 09:01 madvas

Hi @madvas, thanks for the prompt reply. As you can see in the compiled ABI, I have already added payable to my constructor.

derekchiang avatar Jan 18 '18 09:01 derekchiang

Can you paste your Solidity source?

madvas avatar Jan 18 '18 09:01 madvas

Here's a minimal example that can be used to reproduce this issue:

pragma solidity ^0.4.18;

contract MyContract {
  function MyContract(uint whatever) public payable {
  }
}

Curiously, I just found out that if the constructor takes no arguments, I don't get this error. I suspect that this is a bug in web3.js itself. What do you think?

derekchiang avatar Jan 18 '18 10:01 derekchiang

But if you use arguments you need to supply it into :arguments [], do you?

madvas avatar Jan 18 '18 10:01 madvas

Yeah, I do in my real code. The snippet I pasted was simplified; though when I originally opened the issue I did not realize that this error only happens when the constructor takes arguments, which is why I didn't include arguments in the original snippet.

derekchiang avatar Jan 18 '18 10:01 derekchiang

oh, you actually probably need to write it like this.

{:web3/call {:web3 web3
                :fns [{:fn web3-eth/contract-new
                       :args [abi first-arg second-arg
                              {:data bytecode
                               :gas 400000
                               :gasPrice "30000000000"
                               :value 1000000}]
                       :on-success [:contract-created]
                       :on-error [:contract-creation-error]}]}}

madvas avatar Jan 18 '18 10:01 madvas

We don't use web3 1.0 yet, so there's no keyword :arguments

madvas avatar Jan 18 '18 10:01 madvas

Ah, that's good to know! I changed the code but unfortunately still got the same error.

derekchiang avatar Jan 18 '18 10:01 derekchiang

Hmm, that's weird. Not sure what might be the issue then.

madvas avatar Jan 18 '18 12:01 madvas

Update: I tried using web3.js directly and it worked, so the issue is probably in the CLJS land.

derekchiang avatar Jan 18 '18 23:01 derekchiang

@derekchiang Hey, randomly stumbled upon this issue. Getting the same thing with truffle & ethereumjs-testrpc, can hardly find anything about the issue online, was wondering if you had any insight... Constructor is definitely payable, but truffle complaining when I'm deploying the contract with value.

Cheers, Alex

alexwagg avatar Jan 30 '18 23:01 alexwagg

@alexwagg I never figured out the cause of the issue. I just gave up and did the contract creation in JS instead.

derekchiang avatar Jan 31 '18 01:01 derekchiang