0

I wrote a contract source which is just a FIFO queue below:

pragma solidity ^0.4.0;
contract queue
{
    struct Queue {
        uint256[] data;
        uint256 front;
        uint256 back;
    }
    /// @dev the number of elements stored in the queue.
    function length(Queue storage q) constant internal returns (uint256) {
        return q.back - q.front;
    }
    /// @dev the number of elements this queue can hold
    function capacity(Queue storage q) constant internal returns (uint256) {
        return q.data.length - 1;
    }
    /// @dev push a new element to the back of the queue
    function push(Queue storage q, uint256 data) internal
    {
        if ((q.back + 1) % q.data.length == q.front)
            return; // throw;
        q.data[q.back] = data;
        q.back = (q.back + 1) % q.data.length;
    }
    /// @dev remove and return the element at the front of the queue
    function pop(Queue storage q) internal returns (uint256 r)
    {
        if (q.back == q.front)
            return; // throw;
        r = q.data[q.front];
        delete q.data[q.front];
        q.front = (q.front + 1) % q.data.length;
        return r;
    }
    Queue requests;
    function queue() {
        requests.data.length = 200;
    }
    function addRequest(uint256 d) {
        push(requests, d);
    }
    function popRequest() constant returns (uint256) {
        return pop(requests);
    }
    function queueLength()  constant returns (uint256) {
        return length(requests);
    }
    function hello() constant returns(string s){ 
        return 'hello world!';
    }
}

and then I compile it on online compiler https://ethereum.github.io/browser-solidity. I got the contents from the Web3 deploy box, which is :

var queue_sol_queueContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"hello","outputs":[{"name":"s","type":"string"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"d","type":"uint256"}],"name":"addRequest","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"queueLength","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"popRequest","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[],"payable":false,"type":"constructor"}]);
var queue_sol_queue = queue_sol_queueContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x6060604052341561000c57fe5b5b60c860006000018161001f9190610026565b505b610077565b81548183558181151161004d5781836000526020600020918201910161004c9190610052565b5b505050565b61007491905b80821115610070576000816000905550600101610058565b5090565b90565b610339806100866000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806319ff1d211461005c5780634ca1fad8146100f5578063ab91c7b014610115578063e4690a0b1461013b575bfe5b341561006457fe5b61006c610161565b60405180806020018281038252838181518152602001915080519060200190808383600083146100bb575b8051825260208311156100bb57602082019150602081019050602083039250610097565b505050905090810190601f1680156100e75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156100fd57fe5b61011360048080359060200190919050506101a6565b005b341561011d57fe5b6101256101b5565b6040518082815260200191505060405180910390f35b341561014357fe5b61014b6101c7565b6040518082815260200191505060405180910390f35b6101696102f9565b604060405190810160405280600c81526020017f68656c6c6f20776f726c6421000000000000000000000000000000000000000081525090505b90565b6101b16000826101d9565b5b50565b60006101c16000610253565b90505b90565b60006101d36000610268565b90505b90565b8160010154826000018054905060018460020154018115156101f757fe5b0614156102035761024f565b8082600001836002015481548110151561021957fe5b906000526020600020900160005b50819055508160000180549050600183600201540181151561024557fe5b0682600201819055505b5050565b6000816001015482600201540390505b919050565b600081600101548260020154141561027f576102f4565b81600001826001015481548110151561029457fe5b906000526020600020900160005b505490508160000182600101548154811015156102bb57fe5b906000526020600020900160005b5060009055816000018054905060018360010154018115156102e757fe5b0682600101819055508090505b919050565b6020604051908101604052806000815250905600a165627a7a7230582052aa3a94b7e1e757a3b8de91244871650c0e29a8114a06384386ab323fae210e0029', 
     gas: '800000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

Ok, I click the create button to test it and it works well. Then I deploy it on my geth but its response isn't good enough:

> eth.defaultAccount = eth.accounts[0]
"0x047347096a6dc73f8626afb520c383a02efda314"
> queue_sol_queue.addRequest(2)
I0405 16:19:43.308834 internal/ethapi/api.go:1076] Tx(0xc42776310dde4eb79798ba02f33176bcbb0a8283aa3bb4508af0fd30ed34175e) to: 0x1666d22ba16ff64f94d938301f8ec252f88813a3
"0xc42776310dde4eb79798ba02f33176bcbb0a8283aa3bb4508af0fd30ed34175e"
> queue_sol_queue.addRequest.call(2)
[]
> queue_sol_queue.addRequest.call(2)
[]
> queue_sol_queue.addRequest.call(2)
[]
> queue_sol_queue.popRequest()
0
> queue_sol_queue.popRequest.call()
0

it seems that the push can't push any data and pop can't pop any data ,So how do it work like a FIFO queue? thank you very much.

After getting help from some nice people. I have a new question here: How to return the value pushed before with only one function? I read some information about events, so I think it may be a solution, but it doesn't return the exact value pushed before. There is my new source below which added events:

pragma solidity ^0.4.0;
////////////////////////////////////////////////////////////
// This is an example contract hacked together at a meetup.
// It is by far not complete and only used to show some
// features of Solidity.
////////////////////////////////////////////////////////////
contract queue
{
    struct Queue {
        uint256[] data;
        uint256 front;
        uint256 back;
    }
    /// @dev the number of elements stored in the queue.
    function length(Queue storage q) constant internal returns (uint256) {
        return q.back - q.front;
    }
    /// @dev the number of elements this queue can hold
    function capacity(Queue storage q) constant internal returns (uint256) {
        return q.data.length - 1;
    }
    /// @dev push a new element to the back of the queue
    function push(Queue storage q, uint256 data) internal
    {
        if ((q.back + 1) % q.data.length == q.front)
            return; // throw;
        q.data[q.back] = data;
        q.back = (q.back + 1) % q.data.length;
    }


    /// @dev remove and return the element at the front of the queue
    function pop(Queue storage q) internal returns (uint256 r)
    {
        if (q.back == q.front)
            return; // throw;
        r = q.data[q.front];
        delete q.data[q.front];
        q.front = (q.front + 1) % q.data.length;
        return r;
    }
    Queue requests;
    event PopEvent(bool ok); //my event designed by me here.(*^__^*) 嘻嘻……
    function queue() {
        requests.data.length = 200;
    }
    function addRequest(uint256 d) {
        push(requests, d);
    }
    function popRequest()  returns (uint256) {
        PopEvent(true);
        return pop(requests);
    }
    function queueLength()  constant returns (uint256) {
        return length(requests);
    }
    function hello() constant returns(string s){ 
        return 'hello world!';
    }
}

Hence, can any body help me? thank you!!!

1

Regarding addRequest: in web3 console, the function call should also specify the from argument to tell which account to use for authorizing the trasaction:

> queue_sol_queue.addRequest(2, { from: web3.eth.accounts[0] })

Regarding the popRequest: since there is state change for popping the element out of the queue, the function should not be constant. You can remove it and try again.

  • > queue_sol_queue.addRequest(2, { from: web3.eth.accounts[0] }) I0405 17:20:58.392193 internal/ethapi/api.go:1076] Tx(0xa4d56e43de8f9378493ea4c8ce2f7bb9db4d975a8d7823288ea0c4894299393b) to: 0xc8cf1ea4b0287d559078ad47e12dcc94dd699431 "0xa4d56e43de8f9378493ea4c8ce2f7bb9db4d975a8d7823288ea0c4894299393b" > queue_sol_queue.popRequest() I0405 17:22:36.338967 internal/ethapi/api.go:1076] Tx(0x94ed63dbd0b1dd4ff5b6d0a881602b322d517e746c40e197af641dafe517fac6) to: 0xc8cf1ea4b0287d559078ad47e12dcc94dd699431 "0x94ed63dbd0b1dd4ff5b6d0a881602b322d517e746c40e197af641dafe517fac6" is it works well? – jiebang Apr 5 '17 at 9:23
  • And what is the return value like : queue_sol_queue.addRequest(2, { from: web3.eth.accounts[0] }) I0405 17:20:58.392193 internal/ethapi/api.go:1076] Tx(0xa4d56e43de8f9378493ea4c8ce2f7bb9db4d975a8d7823288ea0c4894299393b) to: 0xc8cf1ea4b0287d559078ad47e12dcc94dd699431 "0xa4d56e43de8f9378493ea4c8ce2f7bb9db4d975a8d7823288ea0c4894299393b" – jiebang Apr 5 '17 at 9:25
  • It seems to be OK, you can check the queueLength() to confirm it works. The return value is the transaction address for this function call. – Yuanfei Zhu Apr 5 '17 at 9:53
  • Thank you very much .but I want to it return the exact value such as popRequest() return the value which is pushed before. How can it do like that ? – jiebang Apr 5 '17 at 11:47
  • Check this answer about the difference between transaction and function calls. – Yuanfei Zhu Apr 5 '17 at 12:14
0

As for returning values, you could have a constant function to read followed by the pop to clear it out. function getFront() public constant returns (uint) { return request.data[front];}

From web3.js you can set up a batch request to call getFront() and pop() in sequence.

  • thank you for your help. But I want to just only one function to return the value. So what is the solution? I use event in my source, but it doesn't work now. – jiebang Apr 6 '17 at 8:36

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.