简体   繁体   English

可靠性:调用另一个合约的函数时出错。 错误:发送值时应向构造函数付款

[英]Solidity: Error when calling a function of another contract. Error: The constructor should be payable when you send value

I am playing around with Solidity and I thought of seeing how a test marketplace would function. 我在与Solidity一起玩耍,并且想到要看测试市场如何运作。 However, I seem to have run into an issue which I cant seem to figure out. 但是,我似乎遇到了一个似乎无法解决的问题。 The code is shabby because I am just trying to figure out how it works on the testnet so please forgive me for that. 该代码是简陋的,因为我只是想弄清楚它在测试网上的工作方式,因此请原谅我。

Basically, when trying to buy an item using the below function(for which a seller and a product should be created) 基本上,当尝试使用以下功能购买商品时(应为此创建卖家和商品)

  function buyItem(uint _no, address[] _sigs, uint _amount) public payable {
    Product storage productIndex = productsArray[_no];
    Seller storage productSeller = sellers[productIndex.oneSeller];
    address buyer = msg.sender;
    address seller = productSeller.sellerAddress;
    uint amount = _amount;
    bytes32 transactionHash = keccak256(abi.encodePacked(buyer, seller, amount, _sigs));
    txHash.push(transactionHash);

    require(msg.sender != 0);
    require(msg.sender != productSeller.sellerAddress, "Buyer address is same as Seller Address");
    require(amount >= productIndex.price);
    require(productIndex.inStock);

    escrow.createTransaction(buyer, seller, transactionHash, _sigs, amount);
    //address(escrow).transfer(amount);

    productIndex.quantity--;
  } 

I get this error: https://i.stack.imgur.com/1JnmS.jpg 我收到此错误: https : //i.stack.imgur.com/1JnmS.jpg

I am trying to create a transaction entry which is stored in the escrow account. 我正在尝试创建存储在托管帐户中的交易条目。 The createTransaction function below takes in all the information and stores it in the escrow account. 下面的createTransaction函数接收所有信息,并将其存储在托管帐户中。 At least this is what i want it to do. 至少这是我想要的。 Perhaps I am making some rudimentary error somewhere? 也许我在某个地方犯了一些基本的错误?

escrow.createTransaction(buyer, seller, transactionHash, _sigs, amount);

Below is the entire code for both contracts: 以下是两个合同的完整代码:

pragma solidity ^0.4.25;

    contract Escrow {

      enum Status{FUNDED, RELEASED}

      struct Transaction {
        address seller;
        address buyer;
        uint value;
        uint lastFunded;
        bytes32 transactionHash;
        address[] signatures;
        Status status;
        mapping(address => bool) isOwner;
        mapping(address => bool) voted;
      }

      mapping(bytes32 => Transaction) public transactions;
      bytes32[] public transactionID;

      modifier onlyOwner(bytes32 _transactionHash) {
        require(msg.sender == transactions[_transactionHash].buyer);
        _;
      }


      function createTransaction(address _buyer, address _seller, bytes32 _transactionHash, address[] _signatures, uint _value) public payable {
        Transaction memory newTransaction = Transaction({
            buyer: _buyer,
            seller: _seller,
            value: _value,
            lastFunded: block.timestamp,
            transactionHash: _transactionHash,
            signatures: _signatures,
            status: Status.FUNDED
          });

        transactions[_transactionHash] = newTransaction;
        transactions[_transactionHash].isOwner[_seller] = true;
        transactions[_transactionHash].isOwner[_buyer] = true;
        transactionID.push(_transactionHash);
      }

      function addOwners(bytes32 _transactionHash) private {
        Transaction storage transaction = transactions[_transactionHash];
        for(uint i = 0; i < transaction.signatures.length; i++) {
          require(transaction.signatures[i] != 0);
          require(!transaction.isOwner[transaction.signatures[i]]);

          transaction.isOwner[transaction.signatures[i]] = true;
        }
      }

      function addFunds(bytes32 _transactionHash) public payable onlyOwner(_transactionHash) {
        uint _value = msg.value;
        require(_value > 0);

        //transactions[_transactionHash].value = transactions[_transactionHash].value.add(_value);
        transactions[_transactionHash].lastFunded = block.timestamp;
      }

      function transferFunds(bytes32 _transactionHash, uint _amount, address _destination) private returns(uint _valueTransferred) {
        Transaction storage transaction = transactions[_transactionHash];

        require(_amount > 0);
        require(_destination != address(0) && transaction.isOwner[_destination]);

        _valueTransferred = _amount;
        _destination.transfer(_amount);
      }

      function confirmHash(bytes32 _transactionHash) public view {
        require(_transactionHash != 0);
        bytes32 calculatedHash = getHash(_transactionHash);

        require(_transactionHash == calculatedHash);
      }

      function getHash(bytes32 _transactionHash) internal view returns(bytes32 hash) {
        Transaction storage transaction = transactions[_transactionHash];
        hash = keccak256(abi.encodePacked(transaction.buyer, transaction.seller, transaction.signatures, transaction.value));
      }

    }

    contract MarketPlace is Escrow{

      Escrow escrow;

    //Has all the information of a particular product

      struct Product {
        string itemName;
        string color;
        string description;
        string warranty;
        string manufacturer;
        uint quantity;
        uint price;
        bool inStock;
        address oneSeller;
      }

    //Has all the information of the seller and the number of products this seller has.

      struct Seller {
        string sellerName;
        address sellerAddress;
        string sellerPhoneNumber;
        string sellerEmail;
        uint noOfProducts;
        mapping(uint => Product) products;
      }


      event AddedSeller(address seller, string sellerName, string sellerPhoneNumber, string sellerEmail);
      event AddedItem(address seller, string itemName, string color, string description, string warranty, string manufacturer, uint price, uint quantity);

    //Array of Seller struct. Can iterate through the number of sellers that have registered and get their information.
    //Array of Product struct. Can iterate through the number of products that are there in the marketplace. Used an array here to retrieve the products to the marketplace to display them to users.
    //Address of the owner of the marketplace contract. Used to deploy it the first time.
    //Addresses of all the sellers.
    //To hold all the paymentIDs
    //msg.sender is associated with the seller information when he/she is asked to fill in the details before adding products to the page.
    //To make sure that the seller is already in the system to avoid duplications.
    //Payment Details are all held here associated with their UIDs as keys

      Seller[] public sellerList;
      Product[] public productsArray;

      address public owner;
      address[] public sellersAdd;

      bytes32[] public txHash;

      mapping(address => Seller) public sellers;
      mapping(address => bool) public isSeller;


    //Constructor function.
      function MarketPlace() public {
        owner = msg.sender;
      }

    //Function to add a seller.
    //Must be a new seller. Hence, seller address should not exist in the isSeller Mapping.
    //New Seller struct variable is created to push to "Seller[] public sellerList"
    //Adding the struct to the mapping of address to struct.
    //Added seller struct to the array of struct.
    //Marked seller address as true to check later to avoid duplications.
    //Added the seller address to the array of addresses that hold all the sellers.

      function addSeller(string _sellerName, string _sellerPhoneNumber, string _sellerEmail) public {
        require(!isSeller[msg.sender]);

        Seller memory newSeller = Seller({
          sellerName: _sellerName,
          sellerAddress: msg.sender,
          sellerPhoneNumber: _sellerPhoneNumber,
          sellerEmail: _sellerEmail,
          noOfProducts: 0
        });

        sellers[msg.sender] = newSeller;
        sellerList.push(newSeller);
        isSeller[msg.sender] = true;
        sellersAdd.push(msg.sender);

        emit AddedSeller(msg.sender, _sellerName, _sellerPhoneNumber, _sellerEmail);
      }

    //Function to add an Item.
    //Must be an existing seller. Therefore we check to see if the address exists as a registered seller.
    //A new product struct is created to be pushed with the product details to "Product[] public productsArray"
    //noOfProducts holds the amount of products each seller has under his/her account. This value increases as more products are added.
    //The new product is added to the mapping using itemNo as mapping key(uint) which is later incremented to make room for next product
    //noOfProducts is now incremented for when the next product is to be entered
    /*Thew new product is also pushed to an array of products call productsArray. I used arrays here as well on top of mappings just so that I could iterate through the values without having to have any knowledge of mapping keys.*/

      function addItem(string _itemName, string _color, string _description, string _warranty, string _manufacturer, uint _price, uint _quantity) public {
        require(isSeller[msg.sender]);

        Product memory newProduct = Product({
          itemName: _itemName,
          color: _color,
          description: _description,
          warranty: _warranty,
          manufacturer: _manufacturer,
          price: _price,
          quantity: _quantity,
          inStock: true,
          oneSeller: msg.sender
        });

        uint itemNo = sellers[msg.sender].noOfProducts;
        sellers[msg.sender].products[itemNo] = newProduct;
        sellers[msg.sender].noOfProducts++;
        productsArray.push(newProduct);
        emit AddedItem(msg.sender, _itemName, _color, _description, _warranty, _manufacturer, _price, _quantity);
      }

    //Function to get sellers count.

      function getSellerCount() public view returns(uint) {
        return sellerList.length;
      }

    //Function to get the products count so we can iterate through all products and display them.

      function getProductCount() public view returns(uint) {
        return productsArray.length;
      }

    /*Function for buying an item. THIS WAS JUST A SIMPLE FUNCTION I MADE TO KIND OF GET AN IDEA HOW IT WOULD WORK.*/

      function buyItem(uint _no, address[] _sigs, uint _amount) public payable {
        Product storage productIndex = productsArray[_no];
        Seller storage productSeller = sellers[productIndex.oneSeller];
        address buyer = msg.sender;
        address seller = productSeller.sellerAddress;
        uint amount = _amount;
        bytes32 transactionHash = keccak256(abi.encodePacked(buyer, seller, amount, _sigs));
        txHash.push(transactionHash);

        require(msg.sender != 0);
        require(msg.sender != productSeller.sellerAddress, "Buyer address is same as Seller Address");
        require(amount >= productIndex.price);
        require(productIndex.inStock);

        escrow.createTransaction(buyer, seller, transactionHash, _sigs, amount);
        //address(escrow).transfer(amount);

        productIndex.quantity--;
      }
    }

Appreciate your help! 感谢您的帮助! :) :)

I understand from the error message that the constructor must be payable. 我从错误消息中了解到,构造函数必须是可付款的。

  function MarketPlace() public PAYABLE {
    owner = msg.sender;
  }

Having the contract name has function as constructor is now deprecated according to the debugger. 现在,根据调试器,不建议使用具有合同名的功能作为构造函数。 You can use: 您可以使用:

constructor() public payable {

}

Hope this helps. 希望这可以帮助。

Never-mind, I figured out the problem. 没关系,我想出了问题。 I had to pass the contract address of Escrow into the instance variable. 我必须将Escrow的合同地址传递到实例变量中。 There was no reference of any address that was passed so it was reverting: 没有引用任何传递的地址,因此它正在还原:

contract MarketPlace is Escrow {
    Escrow escrow;
    constructor(address _escrowContractAddress) public payable {
        owner = msg.sender;

        //This was the missing code.
        escrow = Escrow(_escrowContractAddress);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 solidity 交易错误,如果您发送 value 应该支付调用的 function 并且您发送的 value 应该小于您当前的余额 - solidity transaction error, The called function should be payable if you send value and the value you send should be less than your current balance Solidity:“如果您发送价值,则应支付称为 function 并且您发送的价值应小于当前余额” - Solidity: "The called function should be payable if you send value and the value you send should be less than your current balance" 我收到“如果您发送价值并且您发送的价值应该小于您当前的余额,则应该支付所谓的 function。” - I am getting "The called function should be payable if you send value and the value you send should be less than your current balance." 如何测试 Solidity 应付合同 - How to test a Solidity payable contract 当我们想编译solidity合约但发生错误时 - when we want to compile the solidity Contract but error occur web3上调用solidity合约function时如何添加ETH作为参数 - How to add ETH as parameter when calling solidity contract function on web3 在另一个合约中调用 function - Solidity - Call a function in another contract - Solidity 在构造函数中使用多个参数时与solidity中的编译错误有关 - Related to compilation error in solidity when using multiple parameter in constructor Solidity 智能合约构造函数关税值 - Solidity Smart contract constructor tariff value 在 Solidity 中调用 contract.transfer 方法时如何调试运行时错误? - How can I debug the runtime error when call contract.transfer method in Solidity?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM