【问题标题】:Deployed contract failed to execute部署的合约无法执行
【发布时间】:2018-07-07 13:20:20
【问题描述】:

我在这里有一份合同:

pragma solidity ^0.4.2;

contract Charity{

    mapping (address => uint) public coinBalanceOf;
    event CoinTransfer(address sender, address receiver, uint amount);

    function charity(uint supply){

        coinBalanceOf[msg.sender] = supply;
    }


    function sendCoin(address receiver, uint amount) returns (bool sufficient)
    {

        if (coinBalanceOf[msg.sender] < amount) return false;

        coinBalanceOf[msg.sender] -= amount;
        coinBalanceOf[receiver]   += amount;

        CoinTransfer(msg.sender, receiver, amount);

        return true;

    }

}

当我使用 web3 1.0.0-beta 部署时

import * as fs       from 'fs'       ;
import * as solc     from 'solc'     ;
import * as Web3     from 'web3'     ; 

var web3   = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:8546'));


var contract_path : string = "../solidity/contracts/Charity.sol"
const input       = fs.readFileSync(contract_path)
const output      = solc.compile(input.toString(), 1);
var contract_name = ":" + pr.last(contract_path.split("/")).split(".")[0]
const bytecode    = output.contracts[contract_name].bytecode
const abi_        = JSON.parse(output.contracts[contract_name].interface);

web3.eth.getAccounts().then(accounts => {

    var coinbase = accounts[0];
    var receiver = accounts[1];

    // create contract
    var myContract = new web3.eth.Contract(abi_, coinbase,
        {
            from    : coinbase,
            gasPrice: "2000000"
        });


    var deployedContract = myContract.deploy({

        data: '0x' + bytecode,

    }).send({

        from: coinbase,
        gas : 1500000 ,
        gasPrice: '30000000000000'            

    }, (err, hash) => {

        if (err) { console.log("error on deployment: ", err) }
        console.log("Hash: ", hash)

    })


    myContract.methods.sendCoin(receiver, 7000000).send({ 

        from: coinbase,
        gas: 100000,
        gasPrice: '10000000'
    }, (err,val) => {
            if (err) { console.log(err) }
            else {
                console.log("sent coin: ", val)
            }
        })
    .then(console.log)  

});

但是,当我将其部署在正在挖矿的私有区块链上时,我发现接收方的余额没有任何变化。

=================== 编辑 =========================== ==

我按照下面的答案将供应参数传递到合同中,但它仍然没有执行。可能是时间问题,所以我把sendCoin函数移到了回调中,如下所示,但还是没有执行:

   var myContract = new web3.eth.Contract(abi_, coinbase,
        {
            from    : coinbase,
            gasPrice: "2000000",
        });

    /**
        maybe there should be a callback up there ----^ ???
    */

    var deployedContract = myContract.deploy({

        data: '0x' + bytecode,
        arguments: [2406927999999]  // this is not sending
        // web3.eth.getBalance(coinbase)] note the raw number gets error: number-to-bn
        // is it because it's too big?

    }).send({

        from: coinbase,
        gas : 1500000 ,
        gasPrice: '30000000000000'            

    }, (err, hash) => {

        if (err) { console.log("error on deployment: ", err) }


        console.log("contract deployed with Hash: [REDACTED]")


    }).then((v) => {

            /**
                maybe this should happen in the callback?

            */
            myContract.methods.sendCoin(receiver, 70000000000).send({ 

                from: coinbase,
                gas : 100000  ,
                gasPrice: '10000000'

            }, (err,val) => {
                    if (err) { console.log(err) }
                    else {
                        console.log("---------------------------------------")
                        console.log("sent coin: ", val)
                        console.log("---------------------------------------")

                    }
            })
            console.log(".then callback with value.options: ", v.options)

            console.log('=====================================================')



    })

});

【问题讨论】:

  • 我看不到您在部署合同时在哪里初始化 supplycoinBalanceOf[msg.sender] 将始终为 0 导致 sendCoin() 简单地返回。此外,从非常量函数返回值也没有意义。你不会在你的客户中收到它。将if (coinBalanceOf[msg.sender] &lt; amount) return false; 替换为require(coinBalance[msg.sender &gt;= amount);
  • 你在哪里初始化供应?此后 API 发生了很大变化:github.com/ethereum/go-ethereum/wiki/Contract-Tutorial

标签: blockchain ethereum solidity web3js web3


【解决方案1】:

您需要在初始化合约时传入supply 的值。你可以这样传入:

var deployedContract = myContract.deploy({
  data: '0x' + bytecode,
  arguments: [999999999]
}).send({
  from: coinbase,
  gas : 1500000 ,
  gasPrice: '30000000000000'            
}, (err, hash) => {
  if (err) { console.log("error on deployment: ", err) }
  console.log("Hash: ", hash)
})

请参阅部署 here 的文档,了解如何将参数传递给合约构造函数。

此外,请确保在函数名称中大写 Charity 以匹配合约名称(否则它不是构造函数)。

【讨论】:

  • 好的@Adam Kipnis我按照你说的运行了它,但是合同仍然未能执行。我开始这可能是异步的时间问题。为了测试这个假设,我将myContract.methods.sendCoin 移动到var deployedContract = ... 中的.then 回调,但是它仍然没有执行。有什么想法吗?我在上面的问题中添加了代码
  • 我认为你的异步操作是正确的。 then 块中的函数是否正在执行?如果是这样,如果将myContract.methods.sendCoin 更改为v.methods.sendCoin 会发生什么?传递给该函数的参数(您称为v)是新的合约实例,其合约地址现在在成功部署后设置。
  • 我得到错误:Error: Provider not set or invalid。我可以请您提供一个可行的答案吗?或者解释部署合约时会发生什么? myContract、deployedContract 和 v 有什么区别?很难理解正在发生的事情的操作语义。
  • 此外,时间问题令人困惑,因为我在文档中的示例中没有看到它:web3js.readthedocs.io/en/1.0/web3-eth-contract.html
猜你喜欢
  • 2017-11-26
  • 2022-07-27
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-15
  • 1970-01-01
  • 2017-12-21
相关资源
最近更新 更多