The former doesn't work because a SomeStruct storage
is a pointer to the contract's storage space, and the way Solidity handles storage requires deriving that address from the organization of the structs you're writing it to - that is, its address in storage is directly dependent on the variable you're going to store it in. Without knowing what variable it's going in, it can't write to storage.
Your second snippet works because it first copies the data into a known location in storage, then copies it a second time to a new location, but as you'd expect, that's very inefficient. A better approach is to make your temporary struct in memory:
contract StructExample {
struct SomeStruct {
int someNumber;
string someString;
}
SomeStruct[] someStructs;
function addSomeStruct() {
SomeStruct memory someStruct = SomeStruct(123, "test");
someStructs.push(someStruct);
}
}
Solidity will automatically generate code that copies the struct data from memory into storage.
Where exactly the contract code get stored, i read that it kind of
stores in block chain, so does that mean every node that has a
instance of a full block chain has the contract code too??
The state gets stored in the blockchain, yes. You are also correct in saying that every full-node has a copy of the entire blockchain, including all the states.
Should a miner in order to mine a new block first run all the contract
calls and set the values and then start too looking for POW puzzle
solving and nonce value, and if so then can we have ASIC miners for
ethereum like bitcoin, because they can do only a specific job but
running a contract codes are different every time??
The miners job is to simply solve the POW puzzle. When they do that, they have the ability to mine the block. They now choose which transactions they want included in that specific block. These transactions define all the state changes that were made, so the miner technically doesn't have to look into that.
In terms of the ASIC question, Ethereum POW was designed to be memory-hard, meaning that it is difficult for ASICs to mine.
When a miner wants to verify a transaction which has a contract call
should it run the contract code?? if so, does it mean that each
contract gets to run multiple time until finally one miner can find
the right nonce and solve the pow puzzle? if thats true it means the
contract code gets to run many times unnecessarily?
See my answer above as the answer to this question as well. To summarize, the miner simply chooses a transaction. The reason it doesn't get run multiple times is because there is only one miner that finds the block first and gets rewarded for it. This is the only miner that broadcasts the transaction, as well as the contract calls, to the Ethereum network.
Where does the values of contract variables store, i mean if we have a
solidity mapping it can contains lots of key values, so where does
this key, values stores?? if they store in block chain then they
should be stored in every node that has a copy of block chain which
means a massive data gets to store over and over and over again, and
that would be such a storage waste
See answer one. You are correct—blockchains (as they stand) are quite inefficient and slow, and each node does hold a copy of this state.
When a contract Self-destructs what exactly happens, it mentioned that
the code will be removed from block chain, so does it mean a
transaction make it unavailable for following transactions or it
really really alter the block chain and remove it coded from older
blocks??
It does not alter the blockchain, as that is impossible. What it does do (without getting too technical) is disallows anybody from calling that contract again. The best example to look at is the Parity wallet exploit, as it is a critical example of the usage of selfdestruct
.
Best Answer
Setting a word of storage (i.e. all 32 bytes/256 bits) to zero is identical to removing it from storage completely: it will no longer form part of the blockchain state. You get a refund of 15000 gas for doing this (Appendix G, R_sclear in the Yellow Paper: "Refund given (added into refund counter) when the storage value is set to zero from non-zero").
Note that Solidity sometimes stores multiple smaller types within one storage word (e.g. up to eight
uint32
s). To remove the word from storage, all of the component variables need to be set to zero/deleted.Examples
This results in just one storage word being persisted since
x
andy
are packed into one word:After calling
bar()
in the following, you will have no storage persisted:After calling
bar()
in the following, you will again have no storage persisted. It is identical to the above.Function
bar()
in the following will leave the whole storage word persisted (no gas refund) sincex
andy
share the word.