1

I have a simple contract as below.

pragma solidity ^0.4.9;

/* Contract accepting ethers during 10 minutes */
contract SimpleBidding {

    address receivingAccount;
    uint deadline;

    struct Asset {
        string name;
        uint price;
        uint barcode;
        uint stockCount;
    }

    struct Vendor {
        string name;
        address account;
        Asset asset;
    }

    Vendor[] vendors;
    uint numberOfRequests = 0;
    event AssetRequested(uint barcode);
    event AssetSold(uint vendorID);
    event RequestProcessed();

    /*  at initialization, setup the owner */
    function SimpleBidding(address _vendor0, address _vendor1, address _vendor2) {
        // create 2 assets
        Asset memory asset0 = Asset("Asset", 11, 1234, 1);
        vendors.push(Vendor("Vendor0", _vendor0, asset0));

        Asset memory asset1 = Asset("Asset", 12, 1234, 3);
        vendors.push(Vendor("Vendor1", _vendor1, asset1));

        Asset memory asset2 = Asset("Asset", 10, 1234, 1);
        vendors.push(Vendor("Vendor2", _vendor2, asset2));

        // set the deadline as 10 minutes
        deadline = now + 10 * 1 minutes;
    }  

    function getVendor(uint id) constant returns (string name, address acc, string assetName, uint assetPrice, uint barcode, uint numAssets) {
        var vendor = vendors[id];
        name = vendor.name;
        acc = vendor.account;
        assetName = vendor.asset.name;
        assetPrice = vendor.asset.price;
        barcode = vendor.asset.barcode;
        numAssets = vendor.asset.stockCount;
    }

    function requestAsset(uint barcode) {
        numberOfRequests++;  
        AssetRequested(barcode);
    }

    modifier afterAssetRequested() { if (numberOfRequests == 0) throw; _;}

    function processRequest() afterAssetRequested {
        // find the cheapest vendor who has the asset in its stock
        uint minIndex = 0;
        for (uint i=1; i<vendors.length; i++) {
            if (vendors[i].asset.price < vendors[minIndex].asset.price) {
                if (vendors[i].asset.stockCount > 0) {
                    minIndex = i;
                }
            }
        }

        if (vendors[minIndex].asset.stockCount > 0) {
            // the cheapest vendor sells the asset
            vendors[minIndex].asset.stockCount--;
            AssetSold(minIndex);
        }

        // wait for new asset request
        numberOfRequests = 0;

        RequestProcessed();
    }

    modifier afterDeadline() { if (now >= deadline) _; }

    /* checks if the time limit has been reached and ends the contract */
    function dispose() afterDeadline {
        suicide(receivingAccount);
    }
}

It works fine on online compiler. Functions work, events are generated. Then I try to use it via geth. I created a JS file as below with input paramaters to the constructor and watching mechanisms for the events.

personal.unlockAccount(eth.accounts[0],"Node01Account00")
personal.unlockAccount(eth.accounts[1],"Node01Account01")
personal.unlockAccount(eth.accounts[2],"Node01Account02")
var _vendor0 = eth.accounts[1] ;
var _vendor1 = eth.accounts[2] ;
var _vendor2 = eth.accounts[2] ;
// contract code
var simplebidding_sol_simplebiddingContract = web3.eth.contract([{"constant":false,"inputs":[{"name":"barcode","type":"uint256"}],"name":"requestAsset","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"dispose","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"id","type":"uint256"}],"name":"getVendor","outputs":[{"name":"name","type":"string"},{"name":"acc","type":"address"},{"name":"assetName","type":"string"},{"name":"assetPrice","type":"uint256"},{"name":"barcode","type":"uint256"},{"name":"numAssets","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"processRequest","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"_vendor0","type":"address"},{"name":"_vendor1","type":"address"},{"name":"_vendor2","type":"address"}],"payable":false,"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"barcode","type":"uint256"}],"name":"AssetRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"vendorID","type":"uint256"}],"name":"AssetSold","type":"event"},{"anonymous":false,"inputs":[],"name":"RequestProcessed","type":"event"}]);
var simplebidding_sol_simplebidding = simplebidding_sol_simplebiddingContract.new(
   _vendor0,
   _vendor1,
   _vendor2,
   {
     from: web3.eth.accounts[0], 
     data: '0x6060604052600060035534156200001257fe5b60405160608062000b928339810160409081528151602083015191909201515b6200003c6200045f565b620000466200045f565b620000506200045f565b6040805160c0810182526005608082019081527f417373657400000000000000000000000000000000000000000000000000000060a08301528152600b60208201526104d2918101919091526001606082018190526002805492955091908101620000bc838262000490565b916000526020600020906006020160005b506040805160a0810182526007606082018181527f56656e646f72300000000000000000000000000000000000000000000000000060808401908152908352600160a060020a038c1660208401529282018890529092916200013291839190620004c5565b50602082810151600183018054600160a060020a031916600160a060020a0390921691909117905560408301518051805191926002850192620001799284920190620004c5565b506020820151816001015560408201518160020155606082015181600301555050505050608060405190810160405280604060405190810160405280600581526020017f41737365740000000000000000000000000000000000000000000000000000008152508152602001600c81526020016104d28152602001600381525091506002805480600101828162000211919062000490565b916000526020600020906006020160005b506040805160a0810182526007606082018181527f56656e646f72310000000000000000000000000000000000000000000000000060808401908152908352600160a060020a038b1660208401529282018790529092916200028791839190620004c5565b50602082810151600183018054600160a060020a031916600160a060020a0390921691909117905560408301518051805191926002850192620002ce9284920190620004c5565b506020820151816001015560408201518160020155606082015181600301555050505050608060405190810160405280604060405190810160405280600581526020017f41737365740000000000000000000000000000000000000000000000000000008152508152602001600a81526020016104d28152602001600181525090506002805480600101828162000366919062000490565b916000526020600020906006020160005b506040805160a0810182526007606082018181527f56656e646f72320000000000000000000000000000000000000000000000000060808401908152908352600160a060020a038a166020840152928201869052909291620003dc91839190620004c5565b50602082810151600183018054600160a060020a031916600160a060020a0390921691909117905560408301518051805191926002850192620004239284920190620004c5565b50602082015181600101556040820151816002015560608201518160030155505050505042610258016001819055505b50505050505062000637565b608060405190810160405280620004756200054b565b81526020016000815260200160008152602001600081525090565b815481835581811511620004bf57600602816006028360005260206000209182019101620004bf91906200055d565b5b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200050857805160ff191683800117855562000538565b8280016001018555821562000538579182015b82811115620005385782518255916020019190600101906200051b565b5b5062000547929150620005c7565b5090565b60408051602081019091526000815290565b620005c491905b80821115620005475760006200057b8282620005eb565b600182018054600160a060020a03191690556002820160006200059f8282620005eb565b50600060018201819055600282018190556003909101555060060162000564565b5090565b90565b620005c491905b80821115620005475760008155600101620005ce565b5090565b90565b50805460018160011615610100020316600290046000825580601f1062000613575062000633565b601f016020900490600052602060002090810190620006339190620005c7565b5b50565b61054b80620006476000396000f300606060405263ffffffff60e060020a6000350416632b25d4fd81146100425780634c86659e1461005757806365de1eb3146100695780638fc5668b146101a0575bfe5b341561004a57fe5b6100556004356101b2565b005b341561005f57fe5b6100556101f2565b005b341561007157fe5b61007c60043561020d565b604051808060200187600160a060020a0316600160a060020a03168152602001806020018681526020018581526020018481526020018381038352898181518152602001915080519060200190808383600083146100f5575b8051825260208311156100f557601f1990920191602091820191016100d5565b505050905090810190601f1680156101215780820380516001836020036101000a031916815260200191505b5083810382528751815287516020918201918901908083838215610160575b80518252602083111561016057601f199092019160209182019101610140565b505050905090810190601f16801561018c5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b34156101a857fe5b61005561039e565b005b6003805460010190556040805182815290517f51e8e8b94149a977554c20a9c8555c5fc6084bc3b3b169cc5d79239ea5c009ed9181900360200190a15b50565b600154421061020957600054600160a060020a0316ff5b5b5b565b61021561050d565b600061021f61050d565b600060006000600060028881548110151561023657fe5b906000526020600020906006020160005b50805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292935083918301828280156102cf5780601f106102a4576101008083540402835291602001916102cf565b820191906000526020600020905b8154815290600101906020018083116102b257829003601f168201915b505050506001838101546002808601805460408051602061010097841615979097026000190190921693909304601f8101869004860282018601909352828152959c50600160a060020a039092169a50909250908301828280156103745780601f1061034957610100808354040283529160200191610374565b820191906000526020600020905b81548152906001019060200180831161035757829003601f168201915b505050600384015460048501546005860154949950909750955091935050505b5091939550919395565b60006000600354600014156103b257610000565b506000905060015b60025481101561044d5760028054839081106103d257fe5b906000526020600020906006020160005b506003015460028054839081106103f657fe5b906000526020600020906006020160005b5060030154101561044357600060028281548110151561042357fe5b906000526020600020906006020160005b50600501541115610443578091505b5b5b6001016103ba565b600060028381548110151561045e57fe5b906000526020600020906006020160005b506005015411156104d957600280548390811061048857fe5b906000526020600020906006020160005b5060050180546000190190556040805183815290517f804f01d74e64efde8ba1f4104b9b4c9b61b30b383a4217177c9c72987d07a5329181900360200190a15b600060038190556040517f8d2f03fc18f15ed01faff19cf793332a0573380cf03a28a25a9f98e32434e07d9190a15b5b5050565b604080516020810190915260008152905600a165627a7a72305820552fb9dfafa6d158fb68746d6177392f42a229d441123e953cc57e6fcba514c00029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
     // configure the event to watch for changes
     var event = simplebidding_sol_simplebidding.AssetSold();
     event.watch(function(error, result){
       if (!error)
         console.log("[Asset sold: Vendor: " + result.args.vendorID + " ]");
     });
     var event2 = simplebidding_sol_simplebidding.RequestProcessed();
     event2.watch(function(error, result){
       if (!error)
         console.log("[Request processed!]");
     });
     var event3 = simplebidding_sol_simplebidding.AssetRequested();
     event2.watch(function(error, result){
       if (!error)
         console.log("[Asset:" + result.args.barcode + " requested!]");
     });
    }
 })

After I deploy the contract via loadScript("SimpleBidding.js"), I am calling the requestAsset() function via simplebidding_sol_simplebidding.requestAsset.call(1234). However nothing happens. No log is generated as I programmed in the js file.

It seems to me that may be also the modifier afterAssetRequested() is also not working. Any ideas?

1

I played around briefly in Remix and it seemed from looking at the code that it's necessary to send a transaction to requestAsset() first, then processRequest(), so I did it in that order. The transaction was processed without error. I don't think the result (0x) is exactly what you want, but that's another matter.

It looks to me like if you miss the requestAsset() step and do processRequest(), then numberOfRequests==0 and the modifier throws, by design. You get the "nothing happens" sort of experience. The modifier is doing its job when the function throws because conditions aren't right.

Here's a pic from remix showing inputs and log events.

Hope it helps.

enter image description here

Unrelated side note. processRequest() has a for loop that looks like it might be unbounded. This is a potentially show-stopping issue because each iteration through the loop costs gas and there's a hard block gas limit, meaning this will fail if the number of vendors is over a certain limit.

| improve this answer | |
  • Thank you Rob, for your time and your comments. However, I mentioned also question that "It works fine on online compiler. Functions work, events are generated.". As I understand the online compiler does not dealing with the modifiers, right? You need to activate the functions by clicking on their buttons. Or is there a way to see if modifiers are working or not using the online compiler? – Önder Gürcan Mar 13 '17 at 22:08
  • On the other hand, I only want to call the requestAsset() function from the client, and let the processRequest() function activated thanks to the modifier. However, using geth, I am not having the result I am expecting. Normally, when I call requestAsset(), the numOfRequests variable becomes more than zero, and thus the modifier should make the other function work. Am I wrong? – Önder Gürcan Mar 13 '17 at 22:08
  • By the way, what do you mean by send a transaction to requestAsset() first, then processRequest()? In online compiler, you click on the button of the function, but how do you do that in geth? – Önder Gürcan Mar 13 '17 at 22:12
  • @hookercookerman is right about dropping.call() on the JavaScript because that explicitly say don't update the chain state ... hence the chain state is unaffected. No, your off re: Remix and modifiers. Remix respects the bytecode and the modifier is in play. Thankfully not another variable to think about. I too did contract.requestAsset(1234) via remix. No ".call()" for the reasons mentioned. – Rob Hitchens Mar 13 '17 at 22:22
  • 1
    Hi, I discovered how to do it, you need to use simplebidding_sol_simplebidding.requestAsset.sendTransaction(1234, {from: eth.coinbase}) for non-constant functions. – Önder Gürcan Mar 14 '17 at 20:32
1

No call my friend as that is just an RPC call state transition require normal send transaction. Calls are for constant modifiers on functions

| improve this answer | |
  • lol ... yes. Quite right. – Rob Hitchens Mar 13 '17 at 19:49
  • How can I send a transaction and call the function I want? I only know normal sendTransaction method, and it calls the fallback function by default. – Önder Gürcan Mar 13 '17 at 22:18
  • Hi, I discovered how to do it, you need to use simplebidding_sol_simplebidding.requestAsset.sendTransaction(1234, {from: eth.coinbase}) for non-constant functions. – Önder Gürcan Mar 14 '17 at 20:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.