1

i came across some weird problem between storage and memory variables. In my contract i have the following function. the first snippet of code does work. the second doesn't but it does compile!

so i am asking if assiging memory struct doc to a storage variable Documents[hashed] is possible but doesn't work ? when i tested the second snippet i can send transaction and it gets mined with no errors but Documents[hashed] doesn't change at all, but with the first snippet it does change.

Isn't the second snippet supposed not to compile ?

First snippet

function addNewDocument(string hash, string name){
    Document memory doc =  Document(hash,name,bytes32ToString(bytes32(now)),0);
    bytes32  hashed = keccak256(hash,name);
    Documents[hashed]=Document(hash,name,bytes32ToString(bytes32(now)),0);
    DocumentAddresses.push(hashed);
    UserHashes[msg.sender].push(hashed);
}

Second snippet

function addNewDocument(string hash, string name){
    Document memory doc =  Document(hash,name,bytes32ToString(bytes32(now)),0);
    bytes32  hashed = keccak256(hash,name);
    Documents[hashed]=doc;
    DocumentAddresses.push(hashed);
    UserHashes[msg.sender].push(hashed);
}

EDIT : this is how i am calling these methods, nothing special.

    Web3C.methods.addNewDocument(Document.hash,Document.name).send({gas: 3000000, from: accounts})
.then(
    result => {
          //console.log(result);
           res.send(result);
            }
             ).catch(
              err => {
                   res.status(err.statusCode || "500").send({"Web3 Error":err });
                       }
                       )

WebC is the ontract instance created by reading the ABI and setting an address. I am using web3 1.0 beta 30 with NodeJs and Express.

EDIT2 :

Web3C.methods.getHashes().call({gas:3000000, from : accounts}).then(
data=>{
console.log(data);
let Myhashes = data.hashes;
let MyDocuments =[];
let number =0;

for(let hash of Myhashes){
   Web3C.methods.getDocument(hash).call({gas: 3000000, from: accounts})
       .then(
           result => {
               console.log(result);
               // result. time is the value of now on the solidity side
               result.time= web3.utils.toBN(result.time);
               ipfs.getContent(result.hash).then(
                   data=>{
                       result.hash=data ;
                       MyDocuments.push(result);
                       number++;
                       if(number==Myhashes.length){
                           res.status(200).send(MyDocuments);
                       }
                   }
               )

           }
       ).catch(
       err => {
           console.log(err);
       }
   )
}
}
)
  • Both of these should do the same thing. Can you share how you're testing them? – smarx Mar 29 '18 at 17:30
  • I just tested a very similar snippet in Remix, and everything appears to work fine. Double check how you're running and testing the code. The code itself looks correct. – smarx Mar 29 '18 at 17:34
  • @smarx, I am technically calling them using web3. – Kaki Master Of Time Mar 30 '18 at 7:23
  • You seem to have shared the part of the code that works but not the part that doesn't. :-) You said "when i tested the second snippet i can send transaction and it gets mined with no errors but Documents[hashed] doesn't change at all." Where's the code that shows that happening? – smarx Mar 30 '18 at 7:38
  • I edited the reading code, the getHashes method returns nothing when using the second snippet and it returns the correct result when using the first snippet @smarx – Kaki Master Of Time Mar 30 '18 at 7:51

Your Answer

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

Browse other questions tagged or ask your own question.